2011-11-21 10 views
5

사용자 공간에서 mmap을 사용하여 'mem_map'이 시작되는 물리적 메모리를 읽으려고합니다. 모든 물리적 페이지가 포함 된 배열입니다. 이것은 3.0 커널을 실행하는 i386 시스템입니다.mmap : 작업이 허용되지 않습니다.

코드는 다음과 같다 :

.... 

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

내가 루트로이 달렸다. 출력은 다음과 같습니다

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

은 확실히, 내가 문제를 봤 내으로 /etc/sysctl.conf 파일에 다음 줄을 추가 :

vm.mmap_min_addr = 0 

을하지만이 중 하나가 작동하지 않습니다.

누구나 이런 mem_map 작업이 허용되지 않는 이유와 그 문제를 해결할 수있는 방법을 알고 있습니다.

감사합니다.

+2

,'X & ~ PAGE_MASK'를 사용하는 것이 올바르지 않습니다. 64 비트 시스템에서는 32 비트로 주소가 잘립니다. 보완하기 전에 'uintptr_t'또는 이와 동등한 와이드 타입으로 형변환해야합니다. –

+0

mmap_min_addr에 대한 값을 설정하거나 conf 파일을 편집하기 위해 sysctl 명령을 실행 했습니까? 둘 다해야 해. –

+0

예, 나중에 "sysctl -p"를 수행했습니다. – user899159

답변

8

CONFIG_STRICT_DEVMEM 커널을 컴파일 한 것처럼 들립니다. 이는 1MB (IIRC) 이상의 실제 메모리 액세스 (민감한 경우도 있음)를 방지하는 보안 기능입니다. sysctl dev.mem.restricted를 사용하여이 기능을 비활성화 할 수 있습니다.

+0

예. 내 .config의 CONFIG_STRICT_DEVMEM = y입니다. "sysctl dev.mem.restricted"를 어떻게 사용합니까? 나는 시도했다. 그리고/proc/sys/dev/mem/restricted : 그런 파일이나 디렉토리가 없다. – user899159

+0

옵션이 비활성화 된 상태에서 커널을 재 컴파일해야 할 것 같습니다. –

+0

자, CONFIG_STRICT_DEVMEM을 꺼서 커널을 재 컴파일했습니다. 이제 새로운 오류가 발생했습니다 :/dev/mem이 열렸습니다. mem_map이 (가) 실제 주소에 있습니다. 0x356db000 메모리 맵에 오류가 있습니다. err num = 22 mmap : 인수가 잘못되었습니다. 실제 주소를 0으로 매핑하려고하면이 문제가 발생하지 않습니다. 제안 사항이 있습니까? - 감사. – user899159

0

아치 리눅스가있는 APU2c4 보드에서 flashrom을 사용할 때 비슷한 문제가 발생했습니다.

sysctl 옵션 dev.mem.restricted은 내 시스템에서 사용할 수 없으며 자체 컴파일 된 커널을 사용하는 것은 옵션이 아닙니다.

나는 브를 통해 relaxediomem Kernelparameter를 설정하여 문제를 해결했다 : 물론

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

재부팅이 솔루션에 대한 nessesary입니다.

참조 : 참고로
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

관련 문제