【问题标题】:Using mremap() to merge two identical pages into one physical page使用 mremap() 将两个相同的页面合并为一个物理页面
【发布时间】:2014-05-14 04:22:21
【问题描述】:

我有一个 C 代码,我知道 void *p1 指向的页面内容与页面 void *p2 指向的内容相同。 p1 和 p2 是动态分配的。我的问题是我可以使用 remap() 让这两个页面指向同一个物理页面而不是两个相同的物理页面吗?

编辑:我正在尝试更改此进程页表中的虚拟到物理映射,以便 p1 和 p2 指向相同的物理地址。我不想让 p1 和 p2 虚拟地指向同一个东西。

【问题讨论】:

  • 您是在尝试将两个相同数据结构的存储合并为一个吗?
  • 我正在尝试更改页表中的虚拟到物理映射,以便它们指向相同的东西
  • 所以你在想“2 个虚拟地址指向一个物理地址”?

标签: c linux mmap


【解决方案1】:

如果您尝试使用 linux 页面方案将多个虚拟内存地址映射到单个物理地址,这不是 mremap() 的用途。 mremap 用于移动(重新映射)现有区域,如果您使用它映射到特定的新地址,则到该地址的任何旧映射都将变为无效(根据手册页)。 http://man7.org/linux/man-pages/man2/mremap.2.html

查看重点部分...

MREMAP_FIXED(自 Linux 2.3.31 起) 该标志的作用与 MAP_FIXED 标志的用途相似 地图(2)。如果指定了此标志,则 mremap() 接受 第五个参数,void *new_address,它指定一个页面- 映射必须移动到的对齐地址。 任何 由 new_address 指定的地址范围的先前映射 并且 new_size 未映射。 如果指定了 MREMAP_FIXED,则 还必须指定 MREMAP_MAYMOVE。

如果您只是尝试合并 2 个相同数据结构的存储,则不需要 mremap() 将 2 个“页面”指向同一个相同页面,您需要指向 2 个不同的数据结构指针到同一页面并释放多余的页面。

如果内容相同,则需要将任何指向 p2 的指针转换为地址到 p1。

即使正确使用 mremap 也需要您自己处理指针,但它并不能神奇地为您做到这一点;如果你没有这样做,在重新映射之后你可能会有悬空指针。

PS:我做内核编程已经有好几年了,所以我的下一个陈述可能是错误的或过时的,但我认为你需要使用内核调用(即内核模块/驱动程序级别调用)来获得到物理映射,因为 mmap() 和 mremap() 是用户级调用并在虚拟地址空间内工作。 “页面映射”在内核级别完成,在用户空间之外。

【讨论】:

  • 是的,我还认为它可能需要一些我以前没有做过的内核黑客攻击。不过看来你很有经验。请问您有什么建议从哪里开始学习内核编程吗?你是怎么开始的?因为这绝对是我们在大学里学不到的东西:)。不过谢谢你的回答。真的很有帮助
  • 首先是下载内核源代码(或从您的分发源安装它)。然后买一本关于 Linux 内核编程的书。我上次看亚马逊上有几个。我的很旧,我认为从 2.0 和 2.2 系列开始,但仍然可以提供您入门所需的内容。我可以建议尝试的最好的事情是一个简单的可加载模块,它做一些微不足道的事情,比如一个假的设备驱动程序。我还建议您在 VM 中完成这项工作。在使用 VMware 之前,我每天重启 100 次。但我也没有那么好。 :)
  • 很多事情都可以完全从用户端完成。从不需要内核级别访问的大学级别操作系统课程(IPC、并发编程、TCP/IP 服务器、虚拟机、解释器)的角度来看,有很多东西需要探索。
  • 实际上完全有可能将两个虚拟区域映射到同一个后备存储。如果后备存储是匿名的,我们通常称之为“共享内存”。如果它是一个文件,那么它就更容易掌握:它类似于两个进程在各自的地址空间中打开同一个文件,除了这里我们在同一个地址空间的不同区域内(多个 mmap)。当然,您可以像往常一样通过文件描述符链接它们。见MAP_SHARED。无需更新指针。 (也许我错过了什么,你在那里看起来很自信。)
猜你喜欢
  • 2013-06-13
  • 2011-05-04
  • 2022-12-03
  • 1970-01-01
  • 2016-03-25
  • 2010-10-06
  • 1970-01-01
  • 2014-06-21
  • 2011-05-04
相关资源
最近更新 更多