6.828: Operating System Engineering (45)

何かが整合してない。
例えば pages は va と関連付けられる形で使われているように見えるけど

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

例えば page_alloc のプロトタイプは以下で

int
page_alloc(struct Page **pp_store)

必要な時に必要なモノを取り出すような形になっていない風に見える。
ので、とりあえず放置していた page_* な手続きのコメントを読んでみます。
とりあえず現時点で Fill this function in なコメントのまま実装未着手な手続きが以下らしい。

  • pgdir_walk
  • page_insert
  • boot_map_segment
  • page_lookup
  • page_remove
  • tlb_invalidate

そもそも

page_alloc の実装と上記 assert な仕様が整合してないのが悪いのは分かってるのですが、どこでナチュラルを爆発させてるのかが分からん。

整理

ええと KERNBASE は 0xf0000000 ということなので virtual memory の末端 250MB が Kernel のために確保されてる領域ってことになるのかな。
てか、ページテーブルの基本的な実装について確認をした方が良さげ。以下なナニ。

 *    KERNBASE ----->  +------------------------------+ 0xf0000000
 *                     |  Cur. Page Table (Kern. RW)  | RW/--  PTSIZE
 *    VPT,KSTACKTOP--> +------------------------------+ 0xefc00000      --+

inc/mmu.h によれば以下な定義な模様。

// Page directory and page table constants.
#define NPDENTRIES	1024		// page directory entries per page directory
#define NPTENTRIES	1024		// page table entries per page table

#define PGSIZE		4096		// bytes mapped by a page
#define PGSHIFT		12		// log2(PGSIZE)

#define PTSIZE		(PGSIZE*NPTENTRIES) // bytes mapped by a page directory entr

とりあえず page directory と page table 一緒に云々、な匂いはしますね。それがおそらくは

    pgdir[PDX(VPT)] = PADDR(pgdir)|PTE_W|PTE_P;

なのかなぁ、と。PDX(VPT) は、1110111111 (0x3bf ?) でソコに pgdir の kernel RW な phys addr がセットされる模様。とは言え、ちょっとまだ明確にイメージできておらず。
あ、でも pgdir って

    pgdir = boot_alloc(PGSIZE, PGSIZE);

な形で実質的に確保されてるサイズは 4096 です。ここのコントロールを誰かがしないといけないはず。そしてその役割を page_alloc あるいは page_init あたりがしないといけないはずなんだけどなぁ、と。

基本的に

page directory と page table な領域は確保されているはず。でもそれは virtual address な世界であって、phys なナニ的には 1024 な部屋しか無いみたい (pages な要素の数、という意味で)。
これを誤魔化すために page_init とか page_alloc で準備をするのかどうなのか。あ、その処理をするのが page_alloc なのかなぁ。
あ、違うや。結局必要な page table の数は npage になるのかな。あ、メモリホール云々のおかげでそれよりは少ないのか。
でもやっぱ page_alloc のプロトタイプは微妙。ってか、結局 page table がどう確保されるのか、というナニがイメージできてないのですよね。