我有一个C代码,我知道void * p1指向的页面内容与页面void * p2指向的内容相同。 p1和p2是动态分配的。我的问题是我可以使用remap()让这两个页面指向同一个物理页面而不是两个相同的物理页面吗?
编辑:我正在尝试更改此进程的页表中的虚拟映射到物理映射,以便p1和p2指向相同的物理地址。我不想让p1和p2虚拟地指向同一个东西。
答案 0 :(得分:1)
如果您尝试将多个虚拟内存地址映射到单个物理地址,请使用linux页面方案,这不是mremap()的用途。 mremap用于移动(重新映射)现有区域,如果使用它映射到特定的新地址,则该地址的任何旧映射都将变为无效(根据手册页)。 http://man7.org/linux/man-pages/man2/mremap.2.html
参见强调部分......
MREMAP_FIXED(自Linux 2.3.31起) 此标志用于与MAP_FIXED标志类似的目的 MMAP(2)。如果指定了此标志,则mremap()接受a 第五个参数,void * new_address,它指定一个页面 - 必须移动映射的对齐地址。的 任何 在new_address指定的地址范围内的先前映射 并且new_size未映射。 如果指定了MREMAP_FIXED,则 还必须指定MREMAP_MAYMOVE。
如果您只是尝试合并2个相同数据结构的存储,则不需要mremap()指向2"页面"对于同一个相同的页面,您需要将2个不同的数据结构指针指向同一页面并释放冗余页面。
如果内容相同,则需要将指向p2的任何指针转换为p1。
即使正确地使用mremap也需要你照顾自己的指针管家,它并不神奇地为你做这件事;如果你没有这样做,在重新映射之后你可能会有悬空指针。
PS:自从我进行内核编程以来已经好几年了,所以我可能在下一个语句中错了或过时,但我认为你需要使用内核调用(即内核模块/驱动程序级调用)来获取到物理映射,因为mmap()和mremap()是用户调用并在虚拟地址空间内工作。 "页面映射"在用户空间之外的内核级别完成。