在show_pte 中可以很容易的看出是如何打印pgd/pud/pmd/pte的
void show_pte(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
if (!mm)
mm = &init_mm;
//打印指针直接有%p就可以了,具体可以看后面实际的效果
pr_alert("pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr);
pr_alert("[%08lx] *pgd=%016llx", addr, pgd_val(*pgd));
do {
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
if (pgd_none(*pgd) || pgd_bad(*pgd))
break;
if (pud_none(*pud) || pud_bad(*pud))
break;
pmd = pmd_offset(pud, addr);
printk(", *pmd=%016llx", pmd_val(*pmd));
if (pmd_none(*pmd) || pmd_bad(*pmd))
break;
pte = pte_offset_map(pmd, addr);
printk(", *pte=%016llx", pte_val(*pte));
pte_unmap(pte);
} while(0);
printk("\n");
}
从show_pte 函数可以看到,首先判断mm_struct *mm 是否为null,如果为null的话,说明是在kernel space,则将init_mm 赋值给mm,init_mm表示kernel space的memory分布。
得到mm_struct *mm 后,通过给定的虚拟地址就可以得到pgd的值
pr_alert("pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr);
pr_alert("[%08lx] *pgd=%016llx", addr, pgd_val(*pgd));
这里mm->pgd表示pgd的之,而pgd_val(*pgd)表示pgd这个指针指向的值
得到pgd后
pud = pud_offset(pgd, addr);
printk(", *pud=%016llx", pud_val(*pud));
if (pud_none(*pud) || pud_bad(*pud))
break;
就可以通过pud_offset的的pud的之,通过pud_val(*pud)可以得到pud这个指针指向的值
pmd和pte都是通过类似kernel已经提供好的函数pmd_offset和pte_offset_map来得到其值
但是在show_pte 中默认只打印了pmd/pud/pte指针指向的值,并没有打印其本身的值,说的有点绕,直接看下面的code
void show_pte(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
if (!mm)
mm = &init_mm;
//打印指针直接有%p就可以了,具体可以看后面实际的效果
pr_alert("pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr);
pr_alert("[%08lx] *pgd=%016llx", addr, pgd_val(*pgd));
do {
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
if (pgd_none(*pgd) || pgd_bad(*pgd))
break;
pud = pud_offset(pgd, addr);
打印64 bit的数据可以用%016llx
if (pud_none(*pud) || pud_bad(*pud))
break;
pmd = pmd_offset(pud, addr);
printk(", *pmd=%016llx", pmd_val(*pmd));
if (pmd_none(*pmd) || pmd_bad(*pmd))
break;
pte = pte_offset_map(pmd, addr);
printk(", *pte=%016llx", pte_val(*pte));
pte_unmap(pte);
} while(0);
printk("\n");
}
从show_pte 函数可以看到,首先判断mm_struct *mm 是否为null,如果为null的话,说明是在kernel space,则将init_mm 赋值给mm,init_mm表示kernel space的memory分布。
得到mm_struct *mm 后,通过给定的虚拟地址就可以得到pgd的值
pr_alert("pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr);
pr_alert("[%08lx] *pgd=%016llx", addr, pgd_val(*pgd));
这里mm->pgd表示pgd的之,而pgd_val(*pgd)表示pgd这个指针指向的值
得到pgd后
pud = pud_offset(pgd, addr);
printk(", *pud=%016llx", pud_val(*pud));
if (pud_none(*pud) || pud_bad(*pud))
break;
就可以通过pud_offset的的pud的之,通过pud_val(*pud)可以得到pud这个指针指向的值
pmd和pte都是通过类似kernel已经提供好的函数pmd_offset和pte_offset_map来得到其值
但是在show_pte 中默认只打印了pmd/pud/pte指针指向的值,并没有打印其本身的值,说的有点绕,直接看下面的code
实际效果
得到pmd的虚拟地址是ffff842ffbffd000,减去ffff800000000000,就是对应的物理地址42ffbffd000