6.828: Operating System Engineering (27)
昨晩の続き。
呼び出し元の記述は以下。
////////////////////////////////////////////////////////////////////// // create initial page directory. pgdir = boot_alloc(PGSIZE, PGSIZE); memset(pgdir, 0, PGSIZE); boot_pgdir = pgdir; boot_cr3 = PADDR(pgdir);
ええと、なんとゆーか頭がこんがらがってますね。virtual address とか physical address とか。
以下は boot_pgdir とか boot_cr3 について書かれてる i386_vm_init 手続きのコメントの一部なんですが
// Set up a two-level page table:
// boot_pgdir is its linear (virtual) address of the root
// boot_cr3 is the physical adresss of the root
上記のコードてきには材料は同じ boot_alloc 手続きの戻りなのですが、boot_cr3 は PADDR というマクロを介してますね。
/* This macro takes a kernel virtual address -- an address that points above * KERNBASE, where the machine's maximum 256MB of physical memory is mapped -- * and returns the corresponding physical address. It panics if you pass it a * non-kernel virtual address. */ #define PADDR(kva) \ ({ \ physaddr_t __m_kva = (physaddr_t) (kva); \ if (__m_kva < KERNBASE) \ panic("PADDR called with invalid kva %08lx", __m_kva);\ __m_kva - KERNBASE; \ })
KERNBASE の定義は inc/memlayout.h で
#define KERNBASE 0xF0000000
ってことになってます。たしかに boot_pgdir は VA (KERNBASE よりも上) で、PADDR をスルーして取得される boot_cr3 は PA ということになるのか。とりあえず、kernel.ld 見たところではテキストセグメントのてっぺんが 0xF0100000 なので
SECTIONS { /* Load the kernel at this address: "." means the current address */ . = 0xF0100000; .text : { *(.text .stub .text.* .gnu.linkonce.t.*) }
.bss セクションのその下はもっとアレなのか。page directory はおそらくずっとこの位置に確保されたまんまになるのかなぁ
とりあえず
あと、check_boot_pgdir 手続きも確認しつつ、ということで。