将缓冲区从内核映射到另一个模块分配的用户空间

时间:2014-04-04 10:05:22

标签: linux-kernel linux-device-driver shared-memory mmap

我正在开发3.4的Linux内核驱动程序。此驱动程序的目的是从可能使用 kzalloc()的其他内核模块中分配的缓冲区向Userspace提供mmap接口(下面有更多详细信息)。 mmap提供的指针必须指向此缓冲区的第一个地址。

我从 virt_to_phys()获取实际地址。我在mmap fops调用中将此地址右移由PAGE_SHIFT转换为 remap_pfn_range()

它现在正在工作,但我认为我没有正确地做这些事情,因为没有什么能确保我的缓冲区位于页面的顶部(如果我错了,请纠正我)。也许mmap()ing不是正确的解决方案?我已经读过LDD3的第15章,但也许​​我错过了什么?

详细说明:

缓冲区实际上是remoteproc模块分配的共享内存区域。该区域用于非对称多处理设计(OMAP4)。由于 rproc_da_to_va()调用,我可以获得此缓冲区。这就是为什么没有办法使用像 get_free_pages()这样的东西。

此致

千电子伏

1 个答案:

答案 0 :(得分:0)

是的,你是对的:无法保证分配的内存位于页面的开头。并没有简单的方法可以保证并使其成为真正的共享内存。

显然,您可以(a)将数据从kzalloc'd地址复制到新分配的页面并将其插入到mmap'ing进程的虚拟地址空间中,但之后它不会与其他人创建的原始数据共享内核模块。

您还可以(b)将其他模块分配的实际页面映射到进程的内存映射中,但不能保证它位于页面边界上,并且您还要共享任何其他内存数据。该页面(这是一个安全问题,也是您共享页面的用户空间进程损坏内核数据的潜在来源)。

我想你可以(c)修改内存管理器,在页面开头返回每个分配数据。这可以工作,但是每当一个驱动程序想要为一些小结构分配12个字节时,它实际上将分配4K字节(或任何你的页面大小)。这将浪费巨大的内存量。

根本没有办法欺骗处理器使内存看起来在页面内的两个不同的偏移量。这在物理上是不可能的。

您最好的选择可能是(d)修改其他驱动程序以分配您希望共享的特定数据位,以确保页面边界上的对齐(即您编写的替换kzalloc的内容)。 / p>