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
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top