繁体   English   中英

Linux中的页表遍历

[英]Page Table Walk in Linux

考虑以下代码:

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还有其他功能吗?

感谢TonyTannous,我解决了这个问题。 页表条目不仅包含物理地址,还包含用于访问权限等的其他一些位。 可以通过使用PTE_PFN_MASK进行屏蔽来获取物理地址:

    addr = ptep->pte & PTE_PFN_MASK

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM