如何获取DRAM地址而不是虚拟地址

时间:2013-12-13 05:03:14

标签: c

我理解如果我尝试打印数组元素的地址,它将是来自虚拟存储器的地址,而不是来自真实存储器的地址,即DRAM。

printf ("Address of A[5] and A[6] are %u and %u", &A[5], &A[6]);

我发现地址是连续的(假设元素是字符)。我实际上理解它们在DRAM中至少不会是连续的。我想知道真正的地址。我怎么做到的?

我需要知道Windows或Linux。

2 个答案:

答案 0 :(得分:3)

您无法从用户代码获取虚拟地址的物理地址;只有内核的最低级别处理物理地址,你必须在那里拦截。

请注意,程序运行时虚拟地址的物理地址可能不会保持不变 - 页面可能会从一个物理地址中分页并重新分页到不同的物理地址。如果你进行系统调用,这个重新映射可能发生在内核识别物理地址和函数调用完成之间,因为请求信息的程序是未调度的,部分分页然后再次分页。

答案 1 :(得分:2)

简单的答案是,一般来说,对于Windows或Linux等多处理操作系统中的用户进程或线程,即使是处理器内存地址空间中的静态变量,也无法找到地址,更不用说了DRAM地址。

这有很多原因:

  1. 分配给进程的内存是虚拟内存。操作系统可以不时地将此进程内存从一个物理地址范围重新映射到另一个物理地址范围,并且无法在用户进程中检测到此重新映射。也就是说,变量的物理地址可以在进程的生命周期内发生变化。
  2. 没有从用户空间到内核空间的接口,允许用户空间进程遍历内核的进程表和页面缓存,以便找到进程的物理地址。在Linux中,您可以编写可以执行此操作的内核模块或驱动程序。
  3. DRAM通常通过内存管理单元(MMU)和内存缓存映射到处理器地址空间。虽然DRAM到处理器地址空间的MMU maping通常只进行一次,但在系统启动期间,处理器使用缓存可能意味着写入变量的值可能无法在所有情况下写入DRAM。
  4. 有一些特定于操作系统的方法可以将已分配内存块“固定”到静态物理位置。这通常由使用DMA的设备驱动程序完成。但是,这需要用户空间进程不可用的一定级别的权限,即使您具有此类块的物理地址,也可以在常用的链接器中使用pragma或指令来为进程分配BSS在这样一个物理地址。

    即使内部 Linux内核,在一般情况下也不可能进行虚拟到物理地址转换,并且需要了解用于分配特定虚拟地址所引用的内存的方法。

    这是一篇名为 Translating Virtual to Physical Address on Windows: Physical Addresses 的文章的链接,它提供了一个关于在Windows上获取物理地址所必须去的极端的提示。