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 はおそらくずっとこの位置に確保されたまんまになるのかなぁ
とりあえず

  • make qemu-gdb してみて i386_detect_memory の動作を確認
    • 動作というか値を確認
  • ROUNDUP とか ROUNDDOWN マクロの理解

あと、check_boot_pgdir 手続きも確認しつつ、ということで。