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 のコメント見てるのですが、色々な意味でハードル高いぞ。