Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何获取DRAM地址而不是虚拟地址_C - Fatal编程技术网

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

C 如何获取DRAM地址而不是虚拟地址,c,C,我知道,如果我试图打印数组元素的地址,它将是来自虚拟内存的地址,而不是来自真实内存物理内存,即DRAM printf ("Address of A[5] and A[6] are %u and %u", &A[5], &A[6]); 我发现地址是连续的,假设元素是字符。实际上,它们可能不是连续的,至少在DRAM中不是。我想知道真正的地址。我怎么知道 我需要知道Windows或Linux的这一点 您无法从用户代码中获取虚拟地址的物理地址;只有内核的最低级别处理物理地址,您必须在那

我知道,如果我试图打印数组元素的地址,它将是来自虚拟内存的地址,而不是来自真实内存物理内存,即DRAM

printf ("Address of A[5] and A[6] are %u and %u", &A[5], &A[6]);
我发现地址是连续的,假设元素是字符。实际上,它们可能不是连续的,至少在DRAM中不是。我想知道真正的地址。我怎么知道


我需要知道Windows或Linux的这一点

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


请注意,当程序运行时,虚拟地址的物理地址可能不是常数-页面可能从一个物理地址调出,然后调回另一个物理地址。如果你进行系统调用,这种重新映射可能发生在内核标识物理地址和函数调用完成之间,因为请求信息的程序没有计划,部分调出,然后再次调入。

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


请注意,当程序运行时,虚拟地址的物理地址可能不是常数-页面可能从一个物理地址调出,然后调回另一个物理地址。如果您进行系统调用,这种重新映射可能发生在内核识别物理地址的时间和函数调用完成的时间之间,因为请求信息的程序是非计划的,部分调出,然后再次调入。

简单的回答是,通常,对于Windows或Linux等多处理操作系统中的用户进程或线程,即使在处理器的内存地址空间中找到静态变量的地址也不可能,更不用说DRAM地址了

原因有很多:

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

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


这是一篇名为的文章的链接,它向您提示了在Windows上获取物理地址必须达到的极端目的。

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

原因有很多:

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

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


下面是一篇名为的文章的链接,该文章向您提示了在Windows上获取物理地址必须达到的极端目的。

这取决于您所使用的平台,即操作系统。另外请注意,虚拟地址不一定要映射到物理地址。我想知道真实地址:不,你没有!!您认为使用物理地址而不是虚拟地址可以解决的实际问题是什么?数组中的两个连续项几乎肯定会有连续地址,即使在物理内存中也是如此。@CarlNorum这只是一个示例。如果我真的有50个字符,我想,在物理内存中它可能不是连续的。@CarlNorum:不过如果数组的大小超过一页,那么所有的赌注都没有了,对吧?这取决于你使用的是什么平台,即操作系统。另外请注意,虚拟地址不一定要映射到物理地址。我想知道真实地址:不,你没有!!您认为使用物理地址而不是虚拟地址可以解决的实际问题是什么?数组中的两个连续项几乎肯定会有连续地址,即使在物理内存中也是如此。@CarlNorum这只是一个示例。如果是真的,我可能有50个字符,而且我猜,在物理内存中它可能不是连续的。@CarlNorum:不过如果数组的大小超过一页,那么所有的赌注都没有了,对吧?你甚至不必进行系统调用。访问未映射的页面就足够了。另一方面,根据进程权限和系统配置,您可以使用mlock2强制页面驻留在内存中,在这种情况下,它们的物理映射将是稳定的。即使你这样做了,我也不相信有办法找出映射是什么,除了在内核中。@rici对未映射页面的访问是没有用的,因此术语。的确,许多操作系统都提供了一些方法来编写带有硬编码地址的用户模式驱动程序。@potatosatter:s/unmap/swapped out/。当我累了的时候,我不应该评论。你甚至不需要打系统电话。访问未映射的页面就足够了。另一方面,根据进程权限和系统配置,您可以使用mlock2强制页面驻留在内存中,在这种情况下,它们的物理映射将是稳定的。即使你这样做了,我也不相信有办法找出映射是什么,除了在内核中。@rici对未映射页面的访问是没有用的,因此术语。的确,许多操作系统都提供了一些方法来编写带有硬编码地址的用户模式驱动程序。@potatosatter:s/unmap/swapped out/。我累的时候不该评论。