【问题标题】:Physical address varies when initializing variable初始化变量时物理地址不同
【发布时间】:2018-06-23 22:03:07
【问题描述】:

出于某种原因,我需要知道某个变量的物理地址。尽管如此,初始化变量后物理地址会发生变化。为了获得物理地址,我使用this function (virt_to_phys(..., uint64_t virtaddr)),它似乎工作正常。一些行为示例:

初始化前:virtual 0x5632692a3780 physical 0x32b2c7c780

初始化后:virtual 0x5632692a3780 physical 0x342147a780

使用这些格式化程序:

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

我正在使用-O2 进行编译,但我也使用了-O0 并且没有任何改变,所以我猜这种行为不是优化。我也在内核 4.13.4-1 的 Arch Linux 中执行此代码。

这可能是一个愚蠢的问题,但我无法理解这种行为背后的原因。

【问题讨论】:

  • 物理地址在内核之外没有意义。你在写内核代码吗?
  • @n.m.是的,我猜到了

标签: c linux memory heap-memory


【解决方案1】:

我要说的第一件事,打印一个指针(地址)是到

  • 使用%p 格式说明符。
  • 将相应的参数转换为(void *)

否则,您将导致 undefined behavior 并且无论如何输出都无法证明。

也就是说,正如other answer by @Anti 中提到的,这里“备份”虚拟内存的物理内存不需要修复。基于分配内存的类型的类型(行为)可能会导致物理内存在后台根据实现进行更改。这就是为什么我们在应用程序代码中使用虚拟内存,并让 OS/MMU 在后台处理映射和转换。

【讨论】:

  • 你是对的;即使初始化后多次打印相同的指针具有相同的输出,因此初始化后会发生一些事情。
【解决方案2】:

除非您锁定内存 (mlock(2)),否则物理地址会随着时间而改变。

如果您的变量未初始化,它将驻留在 BSS 中,并且 BSS 页面最初将指向一个用零填充的共享页面。一旦您写入该页面,整个页面可能必须被复制到另一个页面框架(物理页面),因此物理地址不同。

请注意,复制后页面内的相对偏移量保持不变:0x780,正如正确代码所预期的那样。

【讨论】:

  • 您有任何文件可以检查吗?这就是我正在寻找的答案类型
  • @horro 什么文档 linux内核源代码?! mlock 手册页?
  • @horro 大多数现代操作系统都以这种方式工作。这是常识。你不需要文档,你需要一本操作系统设计的教科书
  • @horro 例如Operating Systems: Design and Implementation,Tanenbaum 的第三版。
  • @n.m.如果您有我没有的经验,这可能是常识,这就是我要求文档的原因
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 2019-04-04
  • 2023-03-29
  • 2019-08-29
  • 2012-03-27
  • 2012-01-23
相关资源
最近更新 更多