Linux(Ubuntu),C语言:虚拟到物理地址转换

正如标题所示,我有一个从虚拟地址获取物理地址的问题。

让我来解释一下:在进程空间中给定一个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模拟。

感谢所有的帮助和解答!

Solutions Collecting From Web of "Linux(Ubuntu),C语言:虚拟到物理地址转换"

在用户代码中,你不能知道对应于虚拟地址的物理地址。 这是信息不会被导出到内核之外。 它甚至可以在任何时候改变,特别是如果内核决定把你的进程的一部分内存换掉。

/proc/$pid/maps ,您可以获得有关程序地址空间中的虚拟地址(mmapped文件,堆,堆栈等)的信息。 这就是你会得到的。

如果你正在使用内核代码(显然你并不是这样),你可以找出与一页内存相对应的物理地址。 但即使这样, virt_to_phys也不是全部。 我推荐阅读Linux设备驱动程序 (特别是第8章和第 15章)。

头文件asm/io.h是一个内核头文件。 编译用户代码时不可用,因为它的内容没有意义。 它所声明的函数在任何库中都不可用,只能在内核中使用。

由于原始海报的部分回答,Linux内核通过/proc中的一组文件将其映射到userland。 文档可以在这里找到。 简短的摘要:

  1. /proc/$pid/maps提供了一个映射列表及其映射文件的虚拟地址和相应的文件。
  2. /proc/$pid/pagemap提供关于每个映射页面的更多信息,包括物理地址(如果存在)。

作为稍后发现的原始海报, 本示例提供了如何使用这些文件的示例实现。

使用systemcall / procfs将虚拟地址传递给内核,并使用vmalloc_to_pfn 。 通过procfs /寄存器返回物理地址。