6.828: Operating System Engineering (46)
page と pa と va の関係を pmap.h の記述を見つつ確認。
まず、page から pa を求める場合、page2pa という inline な手続きを使う模様。
static inline ppn_t page2ppn(struct Page *pp) { return pp - pages; } static inline physaddr_t page2pa(struct Page *pp) { return page2ppn(pp) << PGSHIFT; }
pages のインデクスを 左に 12bits shift させれば pa になる。pages は基本的に pa を元に作ってるはずなので逆も同様。
static inline struct Page* pa2page(physaddr_t pa) { if (PPN(pa) >= npage) panic("pa2page called with invalid pa"); return &pages[PPN(pa)]; }
問題は次の page2kva だな。
static inline void* page2kva(struct Page *pp) { return KADDR(page2pa(pp)); }
pa を求めて 0xf0000000 を加えてるだけ、だなぁ。
何故にこんな確認したか、というと
以下な試験のあたりについて
// 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));
ええと、page_free の呼び出しが必要なのは page_insert から呼び出されるはずの pgdir_walk 手続きにおいて page table entry が無い場合、page_alloc 使って作れ、ということだから、なのかな。
今のトコ、pp1 はスデに割り当てられてたものになってて、page_insert 手続きでいっちゃん下のチェックを通過する形で page table entry を作ってあげれば良い、ということなのかな、と思ってますが具体的にどうやるんだろ。
む
そーゆー意味だと下から二番目のチェックは page_free された pp0 がリストのいっちゃん先頭にあるので、page table entry を作るために呼び出された page_alloc は pp0 で割り当てられてた領域を戻すな。
なんとなくイメージができてきた (しかも当たってそげ) なので有意義な台風休みになりそうではありますがどうなることやら。