2011-11-21 36 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); 
    } 

私はrootとしてこれを実行しました。出力は次のとおりです。

/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

OK、CONFIG_STRICT_DEVMEMをオフにしてカーネルを再コンパイルしました。今私は新しいエラー:/ dev/memがオープンしました。 mem_mapが物理アドレスにあります。0x356db000 メモリマップに失敗しました。エラー番号= 22 mmap:引数が無効です。物理アドレスを0にマッピングしようとすると、これは起こりません。 - ありがとう。 – user899159

0

アーチLinuxを搭載したAPU2c4ボードでflashromを使用しようとしたときに同様の問題が発生しました。

sysctlオプションdev.mem.restrictedは私のシステムでは利用できませんでした。自己コンパイルされたカーネルを使用することはできませんでした。

私は、GRUBを経由してrelaxediomem Kernelparameterを設定することで問題を回避働い:もちろん

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

を再起動は、このソリューションのnessesaryです。

参考:FYI
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

関連する問題