在linux中分配物理内存缓冲区
Posted
技术标签:
【中文标题】在linux中分配物理内存缓冲区【英文标题】:Allocating a physical memory buffer in linux 【发布时间】:2014-11-11 19:46:26 【问题描述】:我有一个同时具有 DSP 和 ARM 内核的 SoC,我想创建一段共享内存,供我的用户空间软件和 DSP 软件都可以访问。在 Linux 中分配这样的缓冲区的最佳方法是什么?这里有一点背景,现在我有一个内核模块,我在其中使用kmalloc()
获取内核缓冲区,然后使用asm/page.h
中的__pa()
宏来获取内核缓冲区的物理地址。我将此地址保存为 sysfs 条目,以便我的用户空间代码可以获取此缓冲区的物理地址。然后我可以将此地址写入 DSP,以便它知道共享内存位置在哪里,我也可以mmap
/dev/mem
或我自己的内核模块,以便我可以从用户空间访问这个缓冲区(我也可以使用读取/写文件操作)。
出于某种原因,我觉得这太过分了,但我找不到做我想做的事情的最佳方法。
是否有可能只 mmap
\dev\mem
一段内存,然后读写这一段?我的感觉是,这不会从内核“锁定”这部分内存,因此内核仍然可以在我不知道的情况下读取/写入该内存。是不是这种情况。在阅读了 LDD3 的内存管理章节后,我看到 mmap 创建了一个新的映射 VMA。这会锁定这块内存区域,以便其他进程不会分配这块内存吗?
感谢您的任何帮助
【问题讨论】:
内核是否都在同一物理内存总线上?例如,在 android 上,典型的共享内存架构使用 /dev/pmem,并且有一些系统组件使用 RPC 机制在内核之间传输数据。 【参考方案1】:根据您使用的 DMA 类型,您需要使用 dma_alloc_coherent()
分配缓冲区,或使用标准分配和 dma_map_*
函数。
(您不能使用__pa()
;物理地址不一定与DMA 总线地址相同。)
要将缓冲区映射到用户空间,请将dma_mmap_coherent()
用于连贯缓冲区,或手动将内存页面映射为流式缓冲区。
【讨论】:
【参考方案2】:对于我的类似需求,我在 ram 的末尾保留了大约 16 MB 的内存,并在内核和用户空间中使用它。假设您有 128 MB 内存,您可以在引导加载程序中将 BOOTMEM 参数设置为 112 MB。我假设你正在使用 uboot。这将在 ram 末尾保留 16 MB。现在在内核和用户空间中,您可以映射该区域并将其用作共享内存。
【讨论】:
这不是错误的做法,但显然不可移植。通常,这种方法用于需要几百兆共享内存的高速数据采集和数据处理产品。这种方法不适用于预期可以在任何系统中工作的驱动程序。以上是关于在linux中分配物理内存缓冲区的主要内容,如果未能解决你的问题,请参考以下文章