正如标题所示,我遇到了从虚拟地址获取物理地址的问题。
让我解释一下:给定进程空间中的变量声明,如何从OS映射它的物理地址?
我偶然发现了一些定义了/asm/io.h
函数的sys调用virt_to_phys()
;但是看起来这个标题已经过时了,我无法找到解决方法。
然而; io.h
位于:/usr/src/linux-headers-2.6.35-28-generic/arch/x86/include/asm/
。我当前的内核是2.6.35-28
,但io.h
中不包含/usr/include/asm/
?
所以,重申一下:我需要一种从虚拟中获取物理地址的方法。优选地,在运行时从应用程序内派生。但即使是使用/proc/PID/maps
监视器的解决方法也可以。
非常感谢任何想法或评论。
修改的 在对这个主题进行了一些研究之后,我发现了一些在这方面有所帮助。
事实证明这是可行的,尽管需要一些解决方法。
这是一个link到一个分析当前映射页面的简单应用程序。
有问题的文件是(二进制文件)/proc/pid/pagemap
(包含虚拟页面的物理映射)。无论如何,可以修改该链接中的代码以用作监视器应用程序等。
我需要物理地址进行缓存模拟。
感谢所有的帮助和解答!
答案 0 :(得分:21)
在用户代码中,您无法知道与虚拟地址对应的物理地址。这是信息根本不在内核之外导出。它甚至可以随时更改,特别是如果内核决定交换部分进程的内存。
在/proc/$pid/maps
中,您可以获得有关程序地址空间中虚拟地址对应的信息(mmapped文件,堆,堆栈等)的信息。这就是你所能得到的。
如果您正在处理内核代码(显然不是这样),您可以找到与内存页面对应的物理地址。但即便如此,virt_to_phys
也不是全部故事;我建议您阅读Linux Device Drivers(尤其是章节8和15)。
标头asm/io.h
是内核标头。当您编译用户代码时它不可用,因为它的内容没有意义。它声明的函数在任何库中都不可用,只在内核中可用。
答案 1 :(得分:2)
正如原始海报部分回答的那样,Linux内核通过/proc
中的一组文件将其映射公开给用户空间。可以找到文档here。简短摘要:
/proc/$pid/maps
提供了其虚拟地址的映射列表以及映射文件的相应文件。/proc/$pid/pagemap
提供有关每个映射页面的更多信息,包括物理地址(如果存在)。正如稍后发现的原始海报,this example提供了如何使用这些文件的示例实现。
答案 2 :(得分:1)
使用systemcall / procfs将虚拟地址传递给内核并使用vmalloc_to_pfn。通过procfs / registers返回物理地址。