使用多级页表
static void check_pgdir(void) {
// assert(npage <= KMEMSIZE / PGSIZE);
// The memory starts at 2GB in RISC-V
// so npage is always larger than KMEMSIZE / PGSIZE
assert(npage <= KERNTOP / PGSIZE);
//boot_pgdir是页表的虚拟地址
assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0);
assert(get_page(boot_pgdir, 0x0, NULL) == NULL);
//get_page()尝试找到虚拟内存0x0对应的页,现在当然是没有的,返回NULL
struct Page *p1, *p2;
p1 = alloc_page();//拿过来一个物理页面
assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0);//把这个物理页面通过多级页表映射到0x0
pte_t *ptep;
assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL);
assert(pte2page(*ptep) == p1);
assert(page_ref(p1) == 1);
ptep = (pte_t *)KADDR(PDE_ADDR(boot_pgdir[0]));
ptep = (pte_t *)KADDR(PDE_ADDR(ptep[0])) + 1;
assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep);
//get_pte查找某个虚拟地址对应的页表项,如果不存在这个页表项,会为它分配各级的页表
p2 = alloc_page();
assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0);
assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
assert(*ptep & PTE_U);
assert(*ptep & PTE_W);
assert(boot_pgdir[0] & PTE_U);
assert(page_ref(p2) == 1);
assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0);
assert(page_ref(p1) == 2);
assert(page_ref(p2) == 0);
assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
assert(pte2page(*ptep) == p1);
assert((*ptep & PTE_U) == 0);
page_remove(boot_pgdir, 0x0);
assert(page_ref(p1) == 1);
assert(page_ref(p2) == 0);
page_remove(boot_pgdir, PGSIZE);
assert(page_ref(p1) == 0);
assert(page_ref(p2) == 0);
assert(page_ref(pde2page(boot_pgdir[0])) == 1);
free_page(pde2page(boot_pgdir[0]));
boot_pgdir[0] = 0;//清除测试的痕迹
cprintf("check_pgdir() succeeded!\n");
}最后更新于