6.828: Operating System Engineering (36)
現状ですが、以下がモニタに出力されてます。
/opt/bin/qemu -hda obj/kern/kernel.img -serial mon:stdio 6828 decimal is 15254 octal! Physical memory: 66556K available, base = 640K, extended = 65532K check_page_alloc() succeeded! kernel panic at kern/pmap.c:679: assertion failed: page_insert(boot_pgdir, pp1, 0x0, 0) < 0
679 行目というと以下の引用の末端となります。
// should be no free memory assert(page_alloc(&pp) == -E_NO_MEM); // there is no page allocated at address 0 assert(page_lookup(boot_pgdir, (void *) 0x0, &ptep) == NULL); // there is no free memory, so we can't allocate a page table assert(page_insert(boot_pgdir, pp1, 0x0, 0) < 0);
上記引用の最初の assert はパスするはず。次も未実装ですが NULL を戻してますのでパスするのか。とりあえず page_lookup から、ということになるのですが、どうだろな。
とりあえず page_lookup のコメントが以下。
// Return the page mapped at virtual address 'va'. // If pte_store is not zero, then we store in it the address // of the pte for this page. This is used by page_remove and // can be used to verify page permissions for syscall arguments, // but should not be used by most callers. // // Return NULL if there is no page mapped at va. // // Hint: the TA solution uses pgdir_walk and pa2page.
virtual address 'va' にマップされてる page って、何でしょ。とりあえず、0x0 な va にマップされてるページは無いからね、というのが上記の試験らしいんですが、スデにその意味が微妙だったりしてます。
あ、inc/memlayout.h のコメント見てみたら以下な記述。
* UTEMP --------> +------------------------------+ 0x00400000 --+ * | Empty Memory (*) | | * | - - - - - - - - - - - - - - -| | * | User STAB Data (optional) | PTSIZE * USTABDATA ----> +------------------------------+ 0x00200000 | * | Empty Memory (*) | | * 0 ------------> +------------------------------+ --+
これはどうなのだったか。直後なコメント記述によれば
* (*) Note: The kernel ensures that "Invalid Memory" (ULIM) is *never* * mapped. "Empty Memory" is normally unmapped, but user programs may * map pages there if desired. JOS user programs map pages temporarily * at UTEMP.
とのことなのですが、ちょっと意味不明。
なんとなく、なイメージとして
page_lookup な手続きのプロトタイプなソレが以下で
struct Page * page_lookup(pde_t *pgdir, void *va, pte_t **pte_store)
ええと、pgdir_walk との組合せてきにはどうなるんでしょ。pgdir_walk は pte_t なポインタを戻すので pte_store にセットすれば良いのだとは思いますが、そこからどうやった pa2page を使って戻り値を取得すれば良いのか、な理解が微妙。
む
pa2page 手続きな定義が以下なので
static inline struct Page* pa2page(physaddr_t pa)
ええと KADDR(PTE_ADDR(pte_store)) したソレを pa2page なフィルタにかけてあげれば OK ってことなのだろうか。
ということはやっぱ pgdir_walk が大切なのですね。pgdir_walk のコメント見てるのですが、色々な意味でハードル高いぞ。