Linux 将虚拟内存范围映射到现有虚拟内存范围?

发布于 2024-10-07 02:31:29 字数 339 浏览 8 评论 0原文

在Linux中,有没有一种方法(在用户空间中)将虚拟地址范围映射到支持现有虚拟地址范围的物理页面? mmap() 函数只允许映射文件或“新”物理页。我需要能够做这样的事情:

int* addr1 = malloc(SIZE);
int* addr2 = 0x60000;      // Assume nothing is allocated here
fancy_map_function(addr1, addr2, SIZE);
assert(*addr1 == *addr2);  // Should succeed
assert(addr1 != addr2);    // Should succeed

In Linux, is there a way (in user space) to map a virtual address range to the physical pages that back an existing virtual address range? The mmap() function only allows one to map files or "new" physical pages. I need to be able to do something like this:

int* addr1 = malloc(SIZE);
int* addr2 = 0x60000;      // Assume nothing is allocated here
fancy_map_function(addr1, addr2, SIZE);
assert(*addr1 == *addr2);  // Should succeed
assert(addr1 != addr2);    // Should succeed

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沉鱼一梦 2024-10-14 02:31:29

我很好奇,所以我测试了问题评论中建议的共享内存想法,它似乎有效:(

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <assert.h>

#define SIZE 256
int main (int argc, char ** argv) {
  int fd;
  int *addr1, *addr2;

  fd = shm_open("/example_shm", O_RDWR | O_CREAT, 0777);
  ftruncate( fd, SIZE);
  addr1 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  addr2 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

  printf("addr1 = %p addr2 = %p\n", addr1, addr2);
  *addr1 = 0x12345678;
  assert(*addr1 == *addr2);  // Should succeed
  assert(addr1 != addr2);    // Should succeed

  return 0;
}

显然真实的代码会想要检查系统调用的返回值是否有错误并自行清理)

I was curious so I tested the shared memory idea suggested in question comments, and it seems to work:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <assert.h>

#define SIZE 256
int main (int argc, char ** argv) {
  int fd;
  int *addr1, *addr2;

  fd = shm_open("/example_shm", O_RDWR | O_CREAT, 0777);
  ftruncate( fd, SIZE);
  addr1 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  addr2 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

  printf("addr1 = %p addr2 = %p\n", addr1, addr2);
  *addr1 = 0x12345678;
  assert(*addr1 == *addr2);  // Should succeed
  assert(addr1 != addr2);    // Should succeed

  return 0;
}

(Obviously real code will want to check the return value of the syscalls for errors and clean up after itself)

谷夏 2024-10-14 02:31:29

如果您有映射到 addr1 的文件的 fd,则只需 mmap 再次在 addr2 处。

否则,特定于 Linux 的 remap_file_pages< /code>可以在单个 VMA 内以页面大小的粒度修改虚拟地址⇆文件偏移量转换,包括将相同的文件偏移量映射到多个地址。

If you have the fd for the file mapped at addr1, you can simply mmap it again at addr2.

Otherwise, the Linux-specific remap_file_pages can modify the virtual address ⇆ file offset translation within a single VMA, with page-sized granularity, including mapping the same file offset to multiple addresses.

古镇旧梦 2024-10-14 02:31:29

打开 /proc/self/mem 并从中 mmap 您需要的虚拟地址范围。

Open /proc/self/mem and mmap the range of virtual addresses you need from it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文