2011-11-21 23 views
5

Sto cercando di usare mmap nello spazio utente per leggere la memoria fisica in cui inizia "mem_map". È un array che contiene tutte le pagine fisiche. Questa è una macchina i386 con kernel 3.0 in esecuzione.mmap: Operazione non consentita

il codice è simile a questo:

.... 

//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); 
    } 

mi sono imbattuto questo come una radice. L'output è:

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

A dire il vero, ho cercato con Google il problema e ha aggiunto la seguente riga al mio file /etc/sysctl.conf:

vm.mmap_min_addr = 0 

Ma questo non funziona neanche.

Qualcuno sa perché un'operazione mem_map come questa non è consentita e come posso aggirarla?

Grazie.

+2

FYI, non è corretto utilizzare 'x & ~ PAGE_MASK'. Sui sistemi a 64 bit, questo troncerà gli indirizzi a 32 bit. Devi lanciare su 'uintptr_t' o un tipo di larghezza equivalente prima di prendere il complemento. –

+0

Hai eseguito il comando sysctl per impostare il valore per mmap_min_addr o semplicemente modificare il file conf? Devi fare entrambe le cose. –

+0

sì, ho fatto "sysctl -p" in seguito. – user899159

risposta

8

Sembra che il kernel sia stato compilato con CONFIG_STRICT_DEVMEM attivato. Questa è una funzione di sicurezza che impedisce allo spazio utente di accedere a memoria fisica (possibilmente sensibile) superiore a 1MB (IIRC). Potresti essere in grado di disabilitarlo con sysctl dev.mem.restricted.

+0

Sì, il mio .config ha CONFIG_STRICT_DEVMEM = y. Come si usa "sysctl dev.mem.restricted"? Ho provato e l'errore è:/proc/sys/dev/mem/restricted: nessun file o directory. – user899159

+0

Immagino che dovrai ricompilare il kernel con l'opzione disabilitata. –

+0

Ok, ho ricompilato il kernel con CONFIG_STRICT_DEVMEM disattivato. Ora ho un nuovo errore:/dev/mem aperto. mem_map è all'indirizzo fisico: 0x356db000 Mappa di memoria non riuscita. err num = 22 mmap: argomento non valido. Questo non succede se ho provato a mappare l'indirizzo fisico a 0. Qualche suggerimento? - Grazie. – user899159

0

Avevo un problema simile che si verificava quando stavo provando a usare la flashrom su una scheda APU2c4 con Arch Linux.

L'opzione sysctl dev.mem.restricted non era disponibile nel mio sistema e l'utilizzo di un kernel compilato automaticamente non era un'opzione per me.

ho lavorato tutto il problema impostando il iomem Kernelparameter a relaxed via Grub:

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

Naturalmente un riavvio è nessesary per questa soluzione.

Riferimento:
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

Problemi correlati