使用 mmap 映射文件中的不同段

Using mmap to map different segments in a file

我需要 mmap /dev/mem 地址 space 进入我的进程以访问硬件设备。有几个具有不同偏移量的设备。这个过程应该相当简单,网上有多个例子:

  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 的很大一部分,然后只是在那里访问不同的偏移量。

您应该可以使用 lseek to move the current file offset. Then, the next write() will be to that location. Alternatively, it may be easier to just mmap multiple different file descriptors to the same file. See for instance, this question: Can we TWO MMAP on same /dev file .

发现问题 - 只需要从 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;
  }