c - 增加 ARM i.MX287 上的 Linux DMA_ZONE 内存

标签 c linux arm virtual-memory dma

我正在使用内核为 2.6.35.3 的嵌入式 Linux 系统。

在设备内,我们需要一个 4MB+192kB 连续 DMA 功能的缓冲区,用于我们的数据捕获驱动程序之一。驱动程序使用 SPI 传输将数据复制到该缓冲区中。

用户空间应用程序发出 mmap 系统调用,将缓冲区映射到用户空间,然后直接读取可用数据。

缓冲区是使用“alloc_bootmem_low_pages”调用分配的,因为不可能使用其他方法(例如 kmalloc)分配超过 4 MB 的缓冲区。

但是,由于最近的升级,我们需要将缓冲区空间增加到22MB+192kB。正如我所读到的,Linux 内核只有 16MB 的 DMA 内存。因此,理论上这是不可能的,除非有办法调整此设置。

如果有人知道如何执行此操作,请告诉我?

这是一个好主意还是会导致系统不稳定?

最佳答案

ZONE_DMA 16MB 限制是由某些设备的硬件限制造成的。具体来说,在过去的PC架构上,ISA执行 DMA 的卡需要在物理地址空间的前 16MB 中分配缓冲区,因为 ISA 接口(interface)有 24 条物理地址线,只能寻址物理内存的前 2^24=16MB。因此,这些卡的设备驱动程序将在 ZONE_DMA 区域中分配 DMA 缓冲区,以适应此硬件限制。

您的设备是否受到此限制,具体取决于您的嵌入式系统和设备硬件。如果受到此限制,则没有可以应用的软件修复程序来允许您的设备寻址 22MB 内存块,并且如果您修改内核以将 DMA 地址空间扩展到 16MB 以上,那么当然系统会变得不稳定。

另一方面,如果您的设备不受此限制(这是它可能写入 22MB 缓冲区的唯一方式),则没有理由在 ZONE_DMA 中分配内存。在这种情况下,我认为如果您只是将 alloc_bootmem_low_pages 调用替换为 alloc_bootmem_pages 调用,那么分配 22MB 缓冲区应该可以正常工作。如果系统变得不稳定,则可能是因为您的设备受到硬件限制,并且您无法使用 22MB 缓冲区。

关于c - 增加 ARM i.MX287 上的 Linux DMA_ZONE 内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44391968/

相关文章:

c - 如何在makefile中扩展嵌套变量

linux - system() 调用的 WiringPi gpio 必须使用另一个进程?

linux - Bash 从路径变量重命名

gcc - 为什么交叉编译Arm Linux GCC 出错?

linux - 将 perf_event 与 gem5 内的 ARM PMU 结合使用

c - 用户定义命令

c - C 中的变量替换(在变量名本身中)

c - 一个 IF 可以有多个 ELSE 子句 ?? (C语言编程)

linux - 是否可以在不使用 kill 命令的情况下停止 xsp --nonstop 进程?

linux-kernel - cpu_idle_loop 与halt/wfe/sevl 指令