如何在Linux上将两个虚拟地址映射到同一物理内存上?
我面临着一个非常棘手的问题。我试图让 2 个虚拟内存区域指向相同的物理内存。重点是不同的内存区域有不同的页面保护参数。
在这个论坛上,用户似乎有一个解决方案,但看起来有点老套,而且很明显可以在性能方面做更好的事情: http: //www.linuxforums.org/forum/programming-scripting/19491-map-two-virtual-memory-addres-same-physical-page.html
作为我也面临着同样的问题,我想在这里尝试一下,看看是否有人有更好的想法。不要害怕提及引擎盖背后的肮脏细节,这就是这个问题的目的。
提前致谢。
I'm facing a quite tricky problem. I'm trying to get 2 virtual memory areas pointing to the same physical memory. The point is to have different page protection parameters on different memory areas.
On this forum, the user seems to have a solution, but it seems kinda hacky and it's pretty clear that something better can be done performance-wise :
http://www.linuxforums.org/forum/programming-scripting/19491-map-two-virtual-memory-addres-same-physical-page.html
As I'm facing the same problem, I want to give a shot here to know if somebody has a better idea. Don't be afraid to mention the dirty details behind the hood, this is what this question is about.
Thank by advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从 Linux 内核 3.17(2014 年 10 月发布)开始,您可以使用
memfd_create
系统调用来创建由匿名内存支持的文件描述符。然后对同一区域进行多次 mmap,如上面答案中所述。请注意,
memfd_create
系统调用的 glibc 包装器已在 glibc 2.27(于 2018 年 2 月发布)中添加。 glibc 手册还描述了如何返回描述符用于创建到同一底层内存的多个映射。Since Linux kernel 3.17 (released in October 2014) you can use
memfd_create
system call to create a file descriptor backed by anonymous memory. Then mmap the same region several times, as mentioned in the above answers.Note that glibc wrapper for the
memfd_create
system call was added in glibc 2.27 (released in February 2018). The glibc manual also describes how the descriptor returned can be used to create multiple mappings to the same underlying memory.mmap
同一文件中的同一区域两次,或使用系统V 共享内存(不需要在内存中映射文件)。mmap
the same region in the same file, twice, or use System V shared memory (which does not require mapping a file in memory).我想如果你不喜欢 Sys V 共享内存,你可以使用 POSIX 共享内存对象。它们不是很流行,但至少可以在 Linux 和 BSD 上使用。
一旦您通过
shm_open
获得 fd,您就可以立即调用shm_unlink
。那么其他进程就不能附加到同一共享内存,并且您可以对其进行多次mmap
。不过仍然有一小段比赛时间。I suppose if you dislike Sys V shared memrory you could use POSIX shared memory objects. They're not very popular but available on Linux and BSDs at least.
Once you get an fd with
shm_open
you could immediately callshm_unlink
. Then no other process can attach to the same shared memory, and you canmmap
it multiple times. Still a small race period available though.根据@PerJohansson 的建议,我写了 &测试了以下代码,它在linux上运行良好,使用带有MAP_SHARED | MAP_FIXED标志的mmap,我们可以多次连续地将POSIX shm对象分配的同一物理页映射到非常大的虚拟内存中。
您可以观察到以这种方法分配的内存的缓存未命中率非常低:
As suggested by @PerJohansson, I wrote & tested following code, it works well on linux, using mmap with MAP_SHARED|MAP_FIXED flag, we can map the same physical page allocated by POSIX shm object multiple times and continuously into very large virtual memory.
You can observe very low cache miss rate on memory allocated in such method:
如果您是 root,则可以
mmap("/dev/mem", ...)
但较新的内核中有一些警告,请参阅 访问 mmaped /dev/mem?If you are root, you can
mmap("/dev/mem", ...)
but there are caveats in the newer kernels, see accessing mmaped /dev/mem?