在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中分配物理内存缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

linux内存池能分配连续物理内存吗

在 Linux 内核中分配用户空间内存

【深入浅出Linux】关于mmap的解析

linux 在启动时获得专用的缓冲

堆学习

《Linux Device Drivers》第八章 分配内存——note