6.828: Operating System Engineering (42)

なんといいますか、もの凄いイキオイでナチュラルを大爆発させていたことがようやく分かった。そんな気がしてはいたのですが、やはりだったか。

昨日の続き

ナチュラルなソレはスルーとして、続きを見ていきます。

    // there is no page allocated at address 0
    assert(page_lookup(boot_pgdir, (void *) 0x0, &ptep) == NULL);

上記はコメントの通り、0x0 な va にマップされた page frame はなくて、page_alloc も不可能なので、NULL が戻る、と。

    // there is no free memory, so we can't allocate a page table 
    assert(page_insert(boot_pgdir, pp1, 0x0, 0) < 0);

ここも 0x0 な page frame の確保は不可能なので (page_alloc できない) -E_NO_MEM が戻ってくるはず。
次は長いですね。

    // free pp0 and try again: pp0 should be used for page table
    page_free(pp0);
    assert(page_insert(boot_pgdir, pp1, 0x0, 0) == 0);
    assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
    assert(check_va2pa(boot_pgdir, 0x0) == page2pa(pp1));
    assert(pp1->pp_ref == 1);
    assert(pp0->pp_ref == 1);

順に。

  • pp0 がニギッてた page frame を解放
  • page_insert が成功することを確認
    • これ、0x0 な va に対応したページディスクリプタな配列要素が確保されて、pp1 にアドレスが設定されるはず
  • page_free された後の struct Page なポインタ変数の初期化の方法が分からんぞ
    • page_free される時に pages 代入しとけば PTE_ADDR(boot_pgdir[0]) になるかな
  • 0x0 な va で page table entry のアドレスとして取得した値が page2pa(pp1) と同じであること
  • pp1 の pp_ref 属性の値は 1
    • page_insert で pp_ref が増分される、のか
  • pp0 の pp_ref 属性の値は 1
    • これ、page_free では pp_ref は操作しない、ということって理解で良いかな

カン違いはカン違いだったらしいのですが、構わず進めます。
次が以下。

    // should be able to map pp2 at PGSIZE because pp0 is already allocated for page table
    assert(page_insert(boot_pgdir, pp2, (void*) PGSIZE, 0) == 0);
    assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp2));
    assert(pp2->pp_ref == 1);
  • pp2 と PGSIZE を渡して page_insert は成功する

む、なんか微妙なカンジ。ちょっと前に戻って確認。まず、page_free_list を空にして

    // temporarily steal the rest of the free pages
    fl = page_free_list;
    LIST_INIT(&page_free_list);

空きは無いので page_alloc は失敗するはず。

    // should be no free memory
    assert(page_alloc(&pp) == -E_NO_MEM);

空きが無いので page_insert も失敗する模様。

    // there is no free memory, so we can't allocate a page table 
    assert(page_insert(boot_pgdir, pp1, 0x0, 0) < 0);

free memory が無いので page table を allocate できん、とあるな。
で、一旦 pp0 を解放すると

    page_free(pp0);

pp1 による page_insert が成功します。

    assert(page_insert(boot_pgdir, pp1, 0x0, 0) == 0);

pp0 が解放されてるのは良いのですが、pp1 は alloc された状態で page_insert されてる、という記述を見て page discripter はどこを使っても大丈夫って思ったのですが、

    assert(check_va2pa(boot_pgdir, 0x0) == page2pa(pp1));

によるとそうでも無いんだよなぁ。あと、以下な記述もナニ。

    // should be able to map pp2 at PGSIZE because pp0 is already allocated for page table

pp0 が page table で allocate されてるので云々って、ってとりあえず手続きの記述を確認した方が良いな。

とほほ

そろそろええ加減にせぇ、とお叱りを受けそうな勢いだ。週末は天気悪いらしいので、頑張ります。