【问题标题】:Page translation of process code section in Linux. Why does the Page Table Entry get 0 for some pages?Linux中进程代码部分的页面翻译。为什么某些页面的页表条目为 0?
【发布时间】:2011-12-18 18:57:33
【问题描述】:

出于某种原因,我需要将代码段的虚拟地址转换为物理地址。我做了以下实验:

  1. 我从进程A的mm_struct中的start_code和end_code得到虚拟地址,分别是可执行代码的起始地址和终止地址。

  2. 我得到进程 A 的 CR3。

  3. 我将虚拟地址逐页转换为物理地址。例如,进程A中的代码段有10个页面。我将翻译每个页面开头的10个虚拟地址。

  4. 我发现有些页面会得到页表条目 (PTE) == 0。有些页面可以成功转换为物理地址。

  5. 我尝试将 Firefox 和 Minicom 作为我的进程,它们都将进入状态。

我想我的问题是:谁能向我解释为什么 PTE == 0?这是否意味着这些页面已被交换到磁盘?如果是这种情况,我怎样才能找到这些页面?

感谢您的任何意见!

【问题讨论】:

  • 这是在内核模式(如来自约定设备驱动程序)还是用户模式?
  • 感谢您的提问。实际上,这既不是内核模式也不是用户模式。我正在另一台计算机上进行取证。假设我有一个内存转储4G文件,进程A的CR3,进程A的start_code和end_code(虚拟地址)。我需要找出进程A的可执行代码。

标签: memory-management linux-kernel


【解决方案1】:

看起来好像您正在尝试在不使用内核 API 的情况下执行页表自检。请注意,地址空间排列在 vm_area_struct 结构的红黑树中,您可能应该使用遍历它们的 API。映射可能随时更改,因此需要对这些数据结构使用适当的锁定。

例如,参见 get_user_pages() 函数。它可用于交换页面并将页面临时固定到内存中。通常要求使用此功能进行页表自检,因为一旦掌握了物理地址,内核就可以随时换出页面。

【讨论】:

  • 感谢您的回复。我正在尝试在没有内核 API 的情况下进行分页翻译。正如我在上面的 cmets 中所描述的,我试图从内存转储中找出进程可执行代码。但问题是为什么某些进程可执行代码页面的 PTE==0。
  • 内核将可执行文件映射到进程的地址空间时,部分页面没有加载。实际上,除非可执行文件调用 mlock(),否则只有实际运行的代码会导致页面错误,从而将文件的页面加载到 RAM 中。为零的 PTE 对应于未运行的代码部分,因此没有“故障输入”。
  • 这对于执行时间特别有用。一些编译会产生非常大的可执行文件(想想带有大量模板提升的 C++)。内核加载整个可执行代码会在延迟和内存资源方面造成浪费。
  • 感谢您的意见。我想还有两个问题。 1:内核是否会将一些应用程序可执行代码页面交换到磁盘以节省内存? 2.有没有办法强制将这些PTE==0的页面加载到内存中?
  • 我认为这回答了它:stackoverflow.com/questions/3355790/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 2021-09-14
相关资源
最近更新 更多