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 开发者_如何学Cor "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
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)
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.
Open /proc/self/mem
and mmap
the range of virtual addresses you need from it.
精彩评论