2017-06-06 36 views
2

我正在使用2.6.35.3内核的嵌入式Linux系统。在ARM上增加Linux DMA_ZONE内存i.MX287

在设备内部,我们需要一个4MB + 192kB连续的DMA缓存器用于我们的数据采集驱动器之一。驱动程序使用SPI传输将数据复制到此缓冲区。

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

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

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

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

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

回答

2

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

根据您的嵌入式系统和设备硬件,您的设备不受此限制。如果受到此限制,则不存在适用于允许您的设备寻址22MB内存块的软件修复程序,如果修改内核以将DMA地址空间扩展到16MB以上,那么当然是系统会变得不稳定。另一方面,如果您的设备不受此限制(这是它可能写入22MB缓冲区的唯一方式),那么在ZONE_DMA中没有理由分配内存。在这种情况下,我认为如果您只需将alloc_bootmem_low_pages呼叫替换为alloc_bootmem_pages呼叫,则应该可以很好地分配您的22MB缓冲区。如果系统变得不稳定,那很可能是因为你的设备受硬件限制,而你的不能使用22MB缓冲。

+0

理想情况下,alloc_bootmem_pages应根据[link](https://www.kernel.org/doc/gorman/html/understand/understand008.html)从ZONE_NORMAL分配内存。但是,就我而言,当我这样做时,我在启动过程中遇到内核恐慌,并且在分析转储时,我发现恐慌是由dma_alloc_coherent调用触发的。如果alloc_bootmem_pages从ZONE_NORMAL分配内存,那么这种内核恐慌会如何发生?我想这应该是一个单独的问题。 –

+0

我假设你的驱动程序不直接调用'dma_alloc_coherent'。内核恐慌中的错误信息是什么,并且回溯显示''dma_alloc_coherent'是从驱动程序中调用的(特别是在'alloc_bootmem_pages'调用中)?另外,这是什么嵌入式架构? –

+0

这不是我的驱动程序,是什么导致内核恐慌是一些以太网驱动程序调用dma_alloc_coherent。就好像,由于我已经分配了所有内存,系统中的其他一些驱动程序无法分配它所需的DMA缓冲区。内核恐慌说,内存不足。我的架构是ARM iMX287。 –

0

看起来我的第一次尝试答案有点过于通用。我认为,对于您在评论中提到的具体i.MX287架构,DMA区域大小,可通过CONFIG_DMA_ZONE_SIZE参数进行配置,该参数可以大到32Megs。相关的配置选项应该在“系统类型 - >飞思卡尔i.MXS实现 - > DMA内存区域大小”下。

在这个架构上,修改它似乎是安全的,因为它看起来没有解决硬件限制(它在x86架构上的方式),而只是决定如何布置内存。

如果您尝试将其设置为32Meg并在您自己的驱动程序中同时测试alloc_bootmem_pagesalloc_bootmem_low_pages,可能其中一个会起作用。

否则,我觉得我没有想法。