即给出某个虚拟地址,通过查询页表信息,将其转换成物理地址。
//该函数用于查询address对应的页表。摘自arch/x86/mm/fault.c static void dump_pagetable(unsigned long address) { pgd_t *base = __va(read_cr3() & PHYSICAL_PAGE_MASK); //页目录表基址 pgd_t *pgd = base + pgd_index(address); pud_t *pud; // 页表级数大于 3 pmd_t *pmd; // 页表级数大于 2 pte_t *pte;
if (bad_address(pgd)) goto bad;
printk("PGD %lx ", pgd_val(*pgd));
if (!pgd_present(*pgd)) goto out;
pud = pud_offset(pgd, address); if (bad_address(pud)) goto bad;
printk("PUD %lx ", pud_val(*pud)); if (!pud_present(*pud) || pud_large(*pud)) goto out;
pmd = pmd_offset(pud, address); if (bad_address(pmd)) goto bad;
printk("PMD %lx ", pmd_val(*pmd)); if (!pmd_present(*pmd) || pmd_large(*pmd)) goto out;
pte = pte_offset_kernel(pmd, address); if (bad_address(pte)) goto bad;
printk("PTE %lx", pte_val(*pte)); out: printk("/n"); return; bad: printk("BAD/n"); } |
之后转换成物理地址: pa = (pte_val(*pte) & PAGE_MASK | (address & ~PAGE_MASK);