首页 > 解决方案 > 如何将物理地址映射到适合 get_user_pages_fast() 的用户空间虚拟地址?

问题描述

我知道有几种方法可以确定虚拟地址到物理地址的映射,但我需要一个映射到特定物理地址的虚拟地址。我正在使用嵌入式系统中的 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是带有任意数据的任意缓冲区。我需要将 a txbufferwhich 指向位于给定物理地址的内存。我尝试通过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?或者,有没有更正确的方法来做到这一点?

标签: linuxlinux-kerneloperating-systemembedded-linux

解决方案


推荐阅读