我知道有几种方法可以确定虚拟地址到物理地址的映射,但是我需要一个虚拟地址映射到特定的物理地址。我正在嵌入式系统中使用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
固定的用户空间虚拟地址?还是有更正确的方法来做到这一点?