所以!可能已经有人问过这个问题,但是我找不到适合我需求的东西。我想制作一个可以映射到用户空间(虚拟连续内存)的缓冲区,同时还能够在其中构建分散列表以进行DMA操作。
这是我想象的样子:
vmalloc
)找到此缓冲区的每个字节的总线地址,构建下表(仅当phys addr的差值大于PAGE_SIZE时,在其中插入新行)
struct scatterlist*
:总线地址|长度)调用dma_map_sg
,它将填充dma_address
个字段。
我用这种方法遇到的问题:
vmalloc
不能指定需要多少个连续内存,尽管我的设备只能接受8192个总线地址,但不能接受更多的内存,这可能会导致PCI设备可以接受的内存更多。基本上,我认为有些事情我不理解,我找不到一个很好的例子来说明如何正确地做到这一点。 Internet上充满了参考表,邮件列表和其他内容,但是每个实际示例都是一个包含成千上万个文件的项目,对于新手来说,这是很难快速完成的。对于我正在尝试实现的方法,感觉就像我正在尝试解决X/Y problem。有更好的方法吗?
编辑:找到了this。看起来我无法直接获取使用vmalloc分配的所有内存物理地址。我应该怎么用呢?
编辑2 :有人会认为我可以简单地使用CMA来代替,而根本不用理会分散列表-由于某些项目规定,我无法重建内核,因此它是内置的默认情况下没有CMA支持。我需要以某种方式分配3个4 GB的内存块,以便我的设备正常工作。
编辑3 :我不知道它是否对某人有帮助...虽然直到我知道它可行,否则它不会作为Q / A回答。
基本上,目前,我可以分配12 GB的内存,而不会引起内核崩溃(这要求您的设备支持64位地址):
dma_set_mask_and_coherent(pdev, DMA_BIT_MASK(64));
dma_pool_create(...);
dma_pool_alloc(...) for as many chunks of memory as you need.
现在的问题是,我是否能够映射所有这些内存块,并有效地循环遍历它们。