简体   繁体   English

初始化变量时物理地址会有所不同

[英]Physical address varies when initializing variable

For some reason, I need to know the physical address of a certain variable. 由于某些原因,我需要知道某个变量的物理地址。 Nonetheless, the physical address changes after initializing the variable. 但是,物理地址在初始化变量后会更改。 To get the physical address I use this function ( virt_to_phys(..., uint64_t virtaddr) ) , which seems to work properly. 为了获得物理地址,我使用了此功能( virt_to_phys(..., uint64_t virtaddr) ,该功能似乎正常工作。 Some examples of the behavior: 该行为的一些示例:

Before initialization: virtual 0x5632692a3780 physical 0x32b2c7c780 初始化之前: virtual 0x5632692a3780 physical 0x32b2c7c780

After initialization: virtual 0x5632692a3780 physical 0x342147a780 初始化后: virtual 0x5632692a3780 physical 0x342147a780

Using these formatters: 使用这些格式化程序:

printf("virtual 0x%llx physical 0x%llx\n", &p, virt_to_phys((uint64_t) &p));

I am compiling with -O2 , but I also used -O0 and nothing changed, so I guess this behavior is not an optimization. 我正在使用-O2编译,但是我也使用了-O0并且没有任何变化,因此我猜这种行为不是一种优化。 I am also executing this code in Arch Linux with kernel 4.13.4-1. 我也在带有内核4.13.4-1的Arch Linux中执行此代码。

This could be a dumb question but I can not understand the reason behind this behavior. 这可能是一个愚蠢的问题,但我无法理解这种行为背后的原因。

The physical address can change over time unless you lock the memory ( mlock(2) ). 除非您锁定内存mlock(2) ),否则物理地址可能会随时间变化。

If your variable is uninitialized, it will reside in BSS, and the BSS pages would originally point to a shared page filled with zeroes . 如果您的变量未初始化,它将驻留在BSS中,并且BSS页面最初将指向填充有零共享页面 As soon as you write to that page, the entire page would probably have to be copied to another page frame (physical page), therefore the different physical address. 写入该页面后,可能必须将整个页面复制到另一个页面框架(物理页面),因此要复制到另一个物理地址。

Notice that the relative offset within the page remains the same after copying: 0x780 , as would be expected from correct code. 请注意,复制后页面内的相对偏移保持不变: 0x780 ,这是正确代码所期望的。

The first thing I'd say, for printing a pointer (address) is to 我要说的第一件事是打印指针 (地址):

  • make use of %p format specifier. 使用%p格式说明符。
  • cast the corresponding argument to (void *) . 将相应的参数强制转换为(void *)

Without that, you're causing undefined behavior and the output cannot be justified anyway. 否则,您将导致未定义的行为,并且无论如何都无法证明输出的合理性。

That said, as mentioned in the other answer by @Anti , the physical memory here, which "backs up" the virtual memory need not be fixed. 就是说,正如@Anti另一个答案中提到的,此处“备份”虚拟内存的物理内存不需要固定。 Based on the type (behavior) of the type for which the memory is allocated can cause the physical memory to be altered in background, based on the implementation. 基于实现,基于分配内存的类型的类型(行为),可以导致物理内存在后台更改。 That is why, we use the virtual memory in application code and let the OS/MMU handle the mapping and transformation under the hood. 因此,我们在应用程序代码中使用虚拟内存,并让OS / MMU在后台处理映射和转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM