首页 > 解决方案 > 为什么我得到的物理地址是 56 位而不是 arm64 上的 48 位?这是正确的方法吗?

问题描述

我写了一个字符驱动程序来做到这一点,但我找不到问题出在哪里?从我输入的虚拟地址,我得到的物理地址是0xe80028bc88d064。我不确定这样做的正确方法。通过使用虚拟地址遍历四级页表,结合pte值和偏移量得到物理地址。

static unsigned long v2p(struct mm_struct *m, unsigned long va){
pgd_t *pgd_tmp = NULL;
p4d_t *p4d_tmp = NULL;
pud_t *pud_tmp = NULL;
pmd_t *pmd_tmp = NULL;
pte_t *pte_tmp = NULL;

unsigned long pa;

printk(KERN_INFO"pgd = 0x%p\n",m->pgd);

if(!find_vma(m,va))
{
    printk(KERN_INFO"virt_addr 0x%lx not available.\n",va);
    return -1;
}

pgd_tmp = pgd_offset(m,va);
printk(KERN_INFO"pgd_tmp = 0x%p\n",pgd_tmp);
printk(KERN_INFO"pgd_val(*pgd_tmp) = 0x%llx\n",pgd_val(*pgd_tmp));
if(pgd_none(*pgd_tmp))
{
    printk(KERN_INFO"Not mapped in pgd.\n");
    return -1;
}
p4d_tmp = p4d_offset(pgd_tmp, va);
printk(KERN_INFO"p4d_tmp = 0x%p\n",p4d_tmp);
printk(KERN_INFO"p4d_val(*p4d_tmp) = 0x%llx\n",p4d_val(*p4d_tmp));
if(p4d_none(*p4d_tmp))
{
    printk(KERN_INFO"Not mapped in p4d.\n");
    return -1;
}

pud_tmp = pud_offset(p4d_tmp, va);
printk(KERN_INFO"pud_tmp = 0x%p\n",pud_tmp);
printk(KERN_INFO"pud_val(*pud_tmp) = 0x%llx\n",pud_val(*pud_tmp));
if(pud_none(*pud_tmp))
{
    printk(KERN_INFO"Not mapped in pud.\n");
    return -1;
}

pmd_tmp = pmd_offset(pud_tmp, va);
printk(KERN_INFO"pmd_tmp = 0x%p\n",pmd_tmp);
printk(KERN_INFO"pmd_val(*pmd_tmp) = 0x%llx\n",pmd_val(*pmd_tmp));
if(pmd_none(*pmd_tmp))
{
    printk(KERN_INFO"Not mapped in pmd.\n");
    return -1;
}

pte_tmp = pte_offset_kernel(pmd_tmp,va);

printk(KERN_INFO"pte_tmp = 0x%p\n",pte_tmp);
printk(KERN_INFO"pte_val(*pte_tmp) = 0x%llx\n",pte_val(*pte_tmp));
if(pte_none(*pte_tmp))
{
    printk(KERN_INFO"Not mapped in pte.\n");
    return -1;
}
if(!pte_present(*pte_tmp)){
    printk(KERN_INFO"pte not in RAM.\n");
    return -1;
}

pa = (pte_val(*pte_tmp) & PAGE_MASK) | (va & ~PAGE_MASK);
printk(KERN_INFO"virt_addr 0x%lx in RAM is 0x%lx\n",va,pa);
return pa;
}

标签: operating-systemdriver

解决方案


推荐阅读