2017-04-06 8 views
2

私は、 /dev/memアドレス空間をHWデバイスにアクセスするために私のプロセスに加える必要があります。オフセットの異なる複数のデバイスがあります。このプロセスは、オンラインで利用可能な複数の例とかなりシンプルでなければなりません:ファイル内の異なるセグメントをマップするためにmmapを使用する

if ((mem_fd_ = open("/dev/mem", O_RDWR)) < 0) { 
    std::cerr << "error opening '/dev/mem' " << strerror(errno); 
    return false; 
    } 

    // Map the kernel memory space 
    mmap_addr_ = (uint8_t *)mmap(nullptr, page_size_, 
           PROT_READ|PROT_WRITE, 
           MAP_SHARED|MAP_FIXED, 
           mem_fd_, 
           offset_chip_addr_); 
    if (mmap_addr_ == MAP_FAILED) { 
    std::cerr << "error in mmap: " << strerror(errno); 
    return false; 
    } 

しかし、すべての例では、プロセスにmmapに一つだけの呼び出しを想定しています。しかし、異なる値のoffset_chip_addr_で複数回mmapを呼び出すと、マップされたセグメントが最後の呼び出しで上書きされます。これは/proc/<PID>/mapsファイルから表示されます。

この問題を解決する方法はありますか? mmapを除いて、本当に大きなチャンクを/dev/memに入れてから、別のオフセットにアクセスしてください。

+2

ただ、 'MAP_FIXED'フラグを削除します。あなたがそれを使うと、 '' mmpt() '](http://man7.org/linux/man-pages/man2/mmap.2.html)に' 'nullptr''にマッピングを置くよう指示します。後続のマッピングが上書きされます。フラグがなければ、カーネルはマッピングに適したアドレスを見つけ、既存のマッピングを上書きしません。 –

+0

@ NominalAnimal - 実際には、OSとまったく同じです。私は 'offset_chip_addr_'で' mmap'を5回呼び出しています。そして最後のものだけが 'maps'ファイルに現れます。サイズとオフセットの値があり、最後のものだけが表示されています。 – ilya1725

+0

@NominalAnimal - 'MAP_FIXED'が問題でした。私はそれを見つめて、それを完全に逃した。ありがとうございました。 – ilya1725

答えて

0

lseekを使用すると、現在のファイルオフセットを移動できます。次に、次のwrite()はその場所になります。あるいは、複数の異なるファイル記述子を同じファイルにmmapするほうが簡単かもしれません。たとえば、この質問を参照してください:Can we TWO MMAP on same /dev file

1

は、問題を発見 - ちょうどmmapからMAP_FIXEDフラグを削除する必要があります。

if ((mem_fd_ = open("/dev/mem", O_RDWR)) < 0) { 
    std::cerr << "error opening '/dev/mem' " << strerror(errno); 
    return false; 
    } 

    // Map the kernel memory space 
    mmap_addr_ = (uint8_t *)mmap(nullptr, page_size_, 
           PROT_READ|PROT_WRITE, 
           MAP_SHARED, 
           mem_fd_, 
           offset_chip_addr_); 
    if (mmap_addr_ == MAP_FAILED) { 
    std::cerr << "error in mmap: " << strerror(errno); 
    return false; 
    } 
関連する問題