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

时间:2011-06-05 20:38:30

标签: c linux virtual-memory

正如标题所示,我遇到了从虚拟地址获取物理地址的问题。

让我解释一下:给定进程空间中的变量声明,如何从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(包含虚拟页面的物理映射)。无论如何,可以修改该链接中的代码以用作监视器应用程序等。

我需要物理地址进行缓存模拟。

感谢所有的帮助和解答!

3 个答案:

答案 0 :(得分:21)

在用户代码中,您无法知道与虚拟地址对应的物理地址。这是信息根本不在内核之外导出。它甚至可以随时更改,特别是如果内核决定交换部分进程的内存。

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

如果您正在处理内核代码(显然不是这样),您可以找到与内存页面对应的物理地址。但即便如此,virt_to_phys也不是全部故事;我建议您阅读Linux Device Drivers(尤其是章节815)。

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

答案 1 :(得分:2)

正如原始海报部分回答的那样,Linux内核通过/proc中的一组文件将其映射公开给用户空间。可以找到文档here。简短摘要:

  1. /proc/$pid/maps提供了其虚拟地址的映射列表以及映射文件的相应文件。
  2. /proc/$pid/pagemap提供有关每个映射页面的更多信息,包括物理地址(如果存在)。
  3. 正如稍后发现的原始海报,this example提供了如何使用这些文件的示例实现。

答案 2 :(得分:1)

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