OS自作 4日目 メモリ割り当て(ページング)

少し期間が空きましたが、メモリ割り当てを実装します。

リンカスクリプト修正

メモリを割り当てるにあたって、自由に割り当てて良いメモリ領域を定義します。

   __stack_top = .;

    . = ALIGN(4096);
    __free_ram = .;
    . += 64 * 1024 * 1024; /* 64MB */
    __free_ram_end = .;

目印としてstack_topを載せていますが、更新しているのはstack_top以下の4行です。

_free_ramとして、メモリ割り当て用領域のスタート位置を確保しています。

その前に4096バイト(4KB)境界にするためのアライメントを行っています。

4KB境界である理由は調査したところ以下のようです。 * 典型的なページサイズが4KB * ページ途中をまたがるメモリフラグメンテーションを防ぐことができる。

ページングアルゴリズム

extern char __free_ram[], __free_ram_end[];

paddr_t alloc_pages(uint32_t n) {
    static paddr_t next_paddr = (paddr_t) __free_ram;
    paddr_t paddr = next_paddr;
    next_paddr += n * PAGE_SIZE;

    if (next_paddr > (paddr_t) __free_ram_end)
        PANIC("out of memory");

    memset((void *) paddr, 0, n * PAGE_SIZE);
    return paddr;
}

上記ページングアルゴリズムでは、next_paddrによって指定される物理アドレスの位置からページ割り当てを行います。 next_paddrは__free_ramの位置を定義していますが、staticで定義されているのでalloc_pages関数の呼び出しごとに、未割り当てのメモリにページ割り当てを行うことができます。

ページングのスタート位置から、割り当てるメモリをすべて0クリアするというロジックです。PAGE_SIZEは4KBととして、kernel.hで定義する必要があります。

実験として、2つのページ割り当てを行い、ページングの開始アドレスを確認しましたが、以下のようになっています。

alloc_pages test: paddr0=80231000
alloc_pages test: paddr1=80235000

paddr0に4ページ割り当てましたが、4KB * 4 メモリ分先の位置にページ割り当てが行われていることが確認できました。