Page Table Walk in Linux

时间:2017-10-17 05:02:15

标签: c linux memory operating-system kernel

考虑以下代码:

pgd_t *pgd;
pte_t *ptep;
pud_t *pud;
pmd_t *pmd;
char *addr;

struct page *page = NULL;
struct mm_struct *mm = current->mm;

pgd = pgd_offset(mm, addr);
if (pgd_none(*pgd) || pgd_bad(*pgd))
    goto out;
printk(KERN_NOTICE "Valid pgd");

pud = pud_offset(pgd, addr);
if (pud_none(*pud) || pud_bad(*pud))
    goto out;
printk(KERN_NOTICE "Valid pud");

pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd) || pmd_bad(*pmd))
    goto out;
printk(KERN_NOTICE "Valid pmd");

ptep = pte_offset_map(pmd, addr);
if (!ptep)
    goto out;

addr = ptep->pte;
printk(KERN_INFO "byte = %d\n", *(char *)__va(addr));
pte_unmap(ptep);

如果我理解正确,addr应该是与用户空间虚拟地址对应的物理地址。然后我应该能够使用__va取消引用。但是,它不起作用。但是,如果我使用pte_pagekmap,它的确如此运作。为什么会这样?我在x86-64,所以高内存应该不是问题?还有其他的东西kmap吗?

1 个答案:

答案 0 :(得分:0)

由于TonyTannous,我解决了这个问题。页表条目不仅包含物理地址,还包含用于访问权限等的一些其他位。可以通过使用PTE_PFN_MASK

屏蔽物理地址来获取物理地址
    addr = ptep->pte & PTE_PFN_MASK

然后我可以用__va取消引用它。