【发布时间】: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/<PID>/maps 文件中可以看到。
这个问题有好的解决方案吗?除了mmap'ing 一个非常大的 /dev/mem 的一部分,然后只是访问不同的偏移量。
【问题讨论】:
-
只需删除
MAP_FIXED标志。如果您使用它,它会告诉mmap()将映射放在nullptr,这就是导致后续映射被覆盖的原因。如果没有该标志,内核将为映射找到合适的地址,并且不会覆盖任何现有的映射。 -
@NominalAnimal - 实际上这正是操作系统所做的。我用不同的
offset_chip_addr_给mmap打了5 个电话。只有最后一个出现在maps文件中。有大小和偏移值,只显示最后一个。 -
@NominalAnimal -
MAP_FIXED是问题所在。我盯着它,完全错过了它。谢谢。