【问题标题】:Using mmap to map different segments in a file使用 mmap 映射文件中的不同段
【发布时间】:2017-09-02 02:10:03
【问题描述】:

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

  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/&lt;PID&gt;/maps 文件中可以看到。

这个问题有好的解决方案吗?除了mmap'ing 一个非常大的 /dev/mem 的一部分,然后只是访问不同的偏移量。

【问题讨论】:

  • 只需删除 MAP_FIXED 标志。如果您使用它,它会告诉mmap() 将映射放在nullptr,这就是导致后续映射被覆盖的原因。如果没有该标志,内核将为映射找到合适的地址,并且不会覆盖任何现有的映射。
  • @NominalAnimal - 实际上这正是操作系统所做的。我用不同的offset_chip_addr_mmap 打了5 个电话。只有最后一个出现在maps 文件中。有大小和偏移值,只显示最后一个。
  • @NominalAnimal - MAP_FIXED 是问题所在。我盯着它,完全错过了它。谢谢。

标签: c++ linux mmap


【解决方案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;
  }

【讨论】:

    【解决方案2】:

    您应该能够使用lseek 移动当前文件偏移量。然后,下一个 write() 将到达该位置。或者,将多个不同的文件描述符映射到同一个文件可能更容易。例如,请参阅这个问题:Can we TWO MMAP on same /dev file

    【讨论】:

      猜你喜欢
      • 2023-03-06
      • 2013-06-14
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      相关资源
      最近更新 更多