Я знаю, что есть несколько способов определить соответствие виртуального адреса физическому, но мне нужен виртуальный адрес, который сопоставляется с конкретным физическим адресом. Я работаю с драйвером DMA во встроенной системе, использую ветвь ядра 4.14, и мне нужно передать виртуальный адрес пользовательского пространства в модуль ядра, который устанавливает список сбора разброса.
У меня есть рабочий пример, когда код пользовательского пространства выделяет страницу памяти, а затем инициализирует ее:
txbuffer = (unsigned char *) memalign(sysconf(_SC_PAGESIZE),buffer_len);
memset((unsigned char *)txbuffer, 'Z', buffer_len);
Затем передает его в модуль ядра с помощью:
ret = pwrite(datafd, txbuffer, buffer_len, offset);
И модуль ядра вставляет эту память пользовательского пространства в память ядра:
err = get_user_pages_fast((unsigned long) txbuffer, num_alloc_pages,
!(direction), cache_pages);
Моя проблема заключается в том, что txbuffer
представляет собой некоторый произвольный буфер с произвольными данными. Мне нужно вместо этого передать txbuffer
, который указывает на память, расположенную по данному физическому адресу. Я попытался получить виртуальный адрес в пространстве пользователя с помощью mmap
-ing / dev / mem, что работает в других случаях, когда мне нужно получить доступ к физическому адресу из пространства пользователя:
unsigned char *mem;
memfd = open("/dev/mem", O_RDWR);
mem = mmap(0, size, PROT_READ | PROT_WRITE,
MAP_SHARED, memfd, phys_addr);
Но когда я передаю виртуальный адрес mem
модулю ядра, get_user_pages_fast
возвращает -EFAULT
.
Как я могу правильно выделить этот буфер, назначив виртуальный адрес пространства пользователя, который сопоставляется с phys_addr
, который можно закрепить с помощью get_user_pages_fast
? Или есть более правильный способ сделать это?