正如标题所示,我有一个从虚拟地址获取物理地址的问题。
让我来解释一下:在进程空间中给定一个variables声明,我怎样才能得到它由OS映射的物理地址?
我偶然发现了一些调用virt_to_phys()
函数的sys调用/asm/io.h
; 不过看起来这个标题已经过时了,我找不到工作。
然而; 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
监视器的解决方法也可以。
任何想法或意见将不胜感激。
编辑在做了一些关于这个话题的研究之后,我发现了一些在这方面有所帮助的东西。
事实certificate这是可行的,虽然需要一些解决方法。 这是一个简单的应用程序分析当前映射页面的链接。 有问题的文件结果是(二进制文件) /proc/pid/pagemap
(包含虚拟页面的物理映射)。 无论如何,该链接中的代码可以修改为监视器应用程序或其他东西。
我需要物理地址来进行caching模拟。
感谢所有的帮助和解答!
在用户代码中,你不能知道对应于虚拟地址的物理地址。 这是信息不会被导出到内核之外。 它甚至可以在任何时候改变,特别是如果内核决定把你的进程的一部分内存换掉。
在/proc/$pid/maps
,您可以获得有关程序地址空间中的虚拟地址(mmapped文件,堆,堆栈等)的信息。 这就是你会得到的。
如果你正在使用内核代码(显然你并不是这样),你可以找出与一页内存相对应的物理地址。 但即使这样, virt_to_phys
也不是全部。 我推荐阅读Linux设备驱动程序 (特别是第8章和第 15章)。
头文件asm/io.h
是一个内核头文件。 编译用户代码时不可用,因为它的内容没有意义。 它所声明的函数在任何库中都不可用,只能在内核中使用。
由于原始海报的部分回答,Linux内核通过/proc
中的一组文件将其映射到userland。 文档可以在这里找到。 简短的摘要:
/proc/$pid/maps
提供了一个映射列表及其映射文件的虚拟地址和相应的文件。 /proc/$pid/pagemap
提供关于每个映射页面的更多信息,包括物理地址(如果存在)。 作为稍后发现的原始海报, 本示例提供了如何使用这些文件的示例实现。
使用systemcall / procfs将虚拟地址传递给内核,并使用vmalloc_to_pfn 。 通过procfs /寄存器返回物理地址。