Использование 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 2

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;
  }