Использование mmap для отображения различных сегментов в файле
Мне нужно mmap
адресное пространство /dev/mem
в мой процесс для доступа к устройствам HW. Существует несколько устройств с различными смещениями. Процесс должен быть достаточно простым с несколькими примерами, доступными в интернете:
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
в процессе. Однако вызов mmap
несколько раз с различными значениями offset_chip_addr_
существенно перезапишет отображенный сегмент с последним вызовом. Это видно из файла /proc/<PID>/maps
.
Есть ли хороший решение этой проблемы? Помимо mmap
' ing действительно большой кусок /dev/mem
один раз, а затем просто доступ к различным смещениям там.
2 ответа:
Вы должны иметь возможность использовать lseek для перемещения текущего смещения файла. Затем следующая запись () будет в этом месте. Кроме того, может быть проще просто сопоставить несколько различных файловых дескрипторов с одним и тем же файлом. Смотрите, например, такой вопрос: можем ли мы использовать два MMAP в одном файле /dev .
Нашел проблему-просто нужно убрать флаг
MAP_FIXED
из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, mem_fd_, offset_chip_addr_); if (mmap_addr_ == MAP_FAILED) { std::cerr << "error in mmap: " << strerror(errno); return false; }