2011-11-21 18 views
5

Estoy tratando de usar mmap en el espacio de usuario para leer la memoria física donde se inicia 'mem_map'. Es una matriz que contiene todas las páginas físicas. Esta es una máquina i386 que ejecuta kernel 3.0.mmap: operación no permitida

El código es así:

.... 

//define page size 
// 
#define PAGE_SIZE 0x1000 //4096 bytes 
#define PAGE_MASK (PAGE_SIZE - 1) 

.... 

    /* open /dev/mem file*/ 
    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { 
     printf("/dev/mem could not be opened.\n"); 
    perror("open"); 
     exit(1); 
    } else { 
    printf("/dev/mem opened.\n"); 
    } 

    /* Map one page */ 
    printf(" mem_map is at physical addr: 0x%x\n", mem_map_phy_addr); 

    map_base = mmap(0, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, (mem_map_phy_addr & ~PAGE_MASK)); //mem_map_phy_addr is at 0x356f2000 

    if(map_base == (void *) -1) { 
    printf("Memory map failed. err num = %d\n",errno); 
    perror("mmap"); //failed here 
    } else { 
    printf("Memory mapped at address %p.\n", map_base); 
    } 

me corrieron esto como una raíz. La salida es:

/dev/mem opened. 
mem_map is at physical addr: 0x356f2000 
Memory map failed. err num = 1 
mmap: Operation not permitted 

Para estar seguros, busqué en Google el problema y añade la siguiente línea al archivo /etc/sysctl.conf:

vm.mmap_min_addr = 0 

Pero esto tampoco funciona.

¿Alguien sabe por qué la operación mem_map como esta no está permitida y cómo puedo evitarlo?

Gracias.

+2

FYI, es incorrecto usar 'x ~ y PAGE_MASK'. En sistemas de 64 bits, esto truncará las direcciones a 32 bits. Debes convertir a 'uintptr_t' o tipo ancho equivalente antes de tomar el complemento. –

+0

¿Ha ejecutado el comando sysctl para establecer el valor de mmap_min_addr o simplemente edita el archivo conf? Tienes que hacer ambas cosas. –

+0

sí, lo hice "sysctl -p" después. – user899159

Respuesta

8

Parece que el núcleo se ha compilado con CONFIG_STRICT_DEVMEM activado. Esta es una función de seguridad para evitar el acceso de espacio del usuario a la memoria física (posiblemente sensible) por encima de 1 MB (IIRC). Es posible que pueda deshabilitar esto con sysctl dev.mem.restricted.

+0

Sí, mi .config tiene CONFIG_STRICT_DEVMEM = y. ¿Cómo uso "sysctl dev.mem.restricted"? Intenté y el error es:/proc/sys/dev/mem/restricted: No hay tal archivo o directorio. – user899159

+0

Supongo que tendrás que recompilar el kernel con la opción deshabilitada. –

+0

Bien, recompuse el kernel con CONFIG_STRICT_DEVMEM apagado. Ahora tengo un nuevo error:/dev/mem abierto. mem_map está en el directorio físico: 0x356db000 Falló el mapa de memoria. err num = 22 mmap: argumento inválido. Esto no ocurre si traté de asignar la dirección física a 0. ¿Alguna sugerencia? - Gracias. – user899159

0

Tuve un problema similar que ocurría cuando estaba tratando de usar flashrom en una placa APU2c4 con Arch Linux.

La opción sysctl dev.mem.restricted no estaba disponible en mi sistema y el uso de un kernel auto compilado no era una opción para mí.

trabajé todo el problema estableciendo la iomem Kernelparameter a través relaxed Grub:

# /boot/grub/grub.cfg 
linux /boot/vmlinuz-linux iomem=relaxed 

supuesto un reinicio es nessesary para esta solución.

Referencia:
https://www.reddit.com/r/libreboot/comments/6wvyry/flashrom_failures_to_access/
https://www.flashrom.org/FAQ
https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt

Cuestiones relacionadas