2011-11-21 175 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 

可以肯定的,我用Google搜索的問題,並添加下面一行到我的/etc/sysctl.conf文件:

vm.mmap_min_addr = 0 

但是,這也不行。

任何人都知道爲什麼這樣的mem_map操作是不被允許的以及我如何解決它?

謝謝。

+2

僅供參考,它是不正確的使用'X - 〜PAGE_MASK'。在64位系統上,這會將地址截斷爲32位。在進行補充操作之前,您必須轉換爲'uintptr_t'或等效寬類型。 –

+0

你運行了sysctl命令來設置mmap_min_addr的值還是隻編輯conf文件?你必須這樣做。 –

+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

我有一個類似的問題,當我嘗試在Arch Linux的APU2c4電路板上使用flashrom時發生。

sysctl選項dev.mem.restricted在我的系統中不可用,並且使用自編譯的內核對我來說沒有選擇。

我工作圍繞這個問題通過通過蠐螬的iomem Kernelparameter設置爲relaxed

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

當然的重啓對於所必要的這個解決方案。

參考:
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