6.828: Operating System Engineering (77)
勉強会開始 30 分前。冷房ががっつりキイた教室でこちら方面に着手。check_boot_pgdir 手続きから確認、ということか。
直前まで設定してた boot_map_segment なソレのチェックになるはず。コメント的にも以下とありますね。
// Checks that the kernel part of virtual address space // has been setup roughly correctly(by i386_vm_init()). // // This function doesn't test every corner case, // in fact it doesn't test the permission bits at all, // but it is a pretty good sanity check.
roughly っちゃそうですね。例えば UPAGES なチェックが以下なのですが
// check pages array n = ROUNDUP(npage*sizeof(struct Page), PGSIZE); for (i = 0; i < n; i += PGSIZE) assert(check_va2pa(pgdir, UPAGES + i) == PADDR(pages) + i);
check_va2pa を確認。
static physaddr_t check_va2pa(pde_t *pgdir, uintptr_t va) { pte_t *p; pgdir = &pgdir[PDX(va)]; if (!(*pgdir & PTE_P)) return ~0; p = (pte_t*) KADDR(PTE_ADDR(*pgdir)); if (!(p[PTX(va)] & PTE_P)) return ~0; return PTE_ADDR(p[PTX(va)]); }
基本的に手続きの名前そのままですね。pages は UPAGES に mapping されているべき、という確認になります。なんとなく思いだしてきました。
次が KERNBASE で、その次が Kernel Stack の mapping な確認。
// check phys mem for (i = 0; i < npage * PGSIZE; i += PGSIZE) { assert(check_va2pa(pgdir, KERNBASE + i) == i); } // check kernel stack for (i = 0; i < KSTKSIZE; i += PGSIZE) assert(check_va2pa(pgdir, KSTACKTOP - KSTKSIZE + i) == PADDR(bootstack) + i); assert(check_va2pa(pgdir, KSTACKTOP - PTSIZE) == ~0);
で、次の assert で随分ハメられた記憶があるのですが、なんとなく定かではないです。
// check for zero/non-zero in PDEs for (i = 0; i < NPDENTRIES; i++) { switch (i) { case PDX(VPT): case PDX(UVPT): case PDX(KSTACKTOP-1): case PDX(UPAGES): assert(pgdir[i]); break; default: if (i >= PDX(KERNBASE)) assert(pgdir[i]); else assert(pgdir[i] == 0); break; } }
上記のどの部分でハマッたんだろ。なんとなく眺めつつ思いだしてみます。ええと boot_pgdir は触ってなければ基本 0 ということで良いのか。ということは pgdir に値が格納されているのはこの時点で
- pgdir[PDX(VPT)]
- pgdir[PDX(UVPT)]
- pgdir[PDX(UPAGES)]
- pgdir[PDX(KSTACKTOP-1)]
- これ、boot_map_segment から呼ばれる pgdir_walk で設定されてると見てるのですがアウトかなぁ
あ、あと pgdir[PDX(KERNBASE)] も boot_map_segment から云々なのかな。
そろそろ
勉強会開始の準備に。