Faixa de memória virtual de mapeamento do Linux para o intervalo de memória virtual existente?
-
25-09-2019 - |
Pergunta
No Linux, existe uma maneira (no espaço do usuário) para mapear um intervalo de endereços virtuais para as páginas físicas que apóiam um intervalo de endereços virtuais existentes? A função mmap () permite apenas mapear arquivos ou "novas" páginas físicas. Eu preciso ser capaz de fazer algo assim:
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
Solução
Fiquei curioso, então testei a ideia de memória compartilhada sugerida em comentários de perguntas, e parece funcionar:
#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;
}
(Obviamente, o código real vai querer verificar o valor de retorno dos syscalls quanto a erros e limpar depois de si)
Outras dicas
Se você tem o FD para o arquivo mapeado em addr1
, você pode simplesmente mmap
novamente em addr2
.
Caso contrário, o Linux específico remap_file_pages
pode modificar o endereço virtual ⇆ Translação de deslocamento de arquivo em um único VMA, com granularidade do tamanho de uma página, incluindo o mapeamento do mesmo deslocamento de arquivo para vários endereços.
Abrir /proc/self/mem
e mmap
A gama de endereços virtuais que você precisa.