我在用着vmalloc_to_pfn()获取 32 位 PAE Linux 系统上的物理地址。看起来 vmalloc_to_pfn() 返回“unsigned long”,这意味着它在 32 位系统上是 32 位,在 64 位系统上是 64 位。在 64 位 Linux 上,unsigned long 是 64 位,我没有任何问题。
问题:
使用此函数将虚拟转换为物理:
VA: 0xf8ab87fc使用 vmalloc_to_pfn 进行 PA:0x36f7f7fc。但我其实很期待:0x136f7f7fc.
物理地址在 4 到 5 GB 之间。但我无法获得确切的物理地址,我只能获得截断的32位地址。还有其他方法可以得到吗真实的物理地址?
我自己正在研究这个,并且使用的是 32 位 - 所以这不完全是一个答案。但通过挖掘相同的东西,我可以看到来源vmalloc_to_pfn
says:
/*
* Map a vmalloc()-space virtual address to the physical page frame number.
*/
unsigned long vmalloc_to_pfn(const void *vmalloc_addr)
{
return page_to_pfn(vmalloc_to_page(vmalloc_addr));
}
EXPORT_SYMBOL(vmalloc_to_pfn);
因此,它实际上不应该返回地址 - 它应该返回“页框号”(PFN)。与此相关:
http://www.tldp.org/LDP/tlk/mm/memory.html
再次使用上面的示例,进程 Y 的虚拟页帧编号 1 被映射到从 0x8000 (4 x 0x2000) 开始的物理页帧编号 4。添加 0x194 字节偏移量得到最终物理地址 0x8194。
显然,应该将 PFN 乘以PAGE_SIZE
得到一个实际的地址 - 这让事情变得很奇怪,你怎么会得到“返回 32 位address在 Linux 32 系统上”完全可以工作(但话又说回来,我不是专家 - 也许 PFN 相当于 32 位的地址?)。可能是问题 OP 中模块的最小工作示例,以及两者的输出进行比较的平台,本来是有序的。
无论如何,我只是注意到你所拥有的——物理地址扩展(PAE)可能会对分页产生影响;显然,在页面全局目录(PGD)中存储为 PFN 的值是特定于体系结构的,并且根据它的不同定义不同:
typedef unsigned long pgdval_t; // arch/x86/include/asm/pgtable-2level_types.h
typedef u64 pgdval_t; // arch/x86/include/asm/pgtable-3level_types.h
typedef unsigned long pgdval_t; // arch/x86/include/asm/pgtable_64_types.h
总结一下 - 只是使用vmalloc_to_pfn()
获取物理地址可能并不是全部。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)