Linux kernel 确保支持DMA的内存
我正在阅读下面的“PartID”部分,我不确定该文档与内核2.6.35有多大关系;具体来说,它说:Linux kernel 确保支持DMA的内存,linux-kernel,x86,linux-device-driver,dma,Linux Kernel,X86,Linux Device Driver,Dma,我正在阅读下面的“PartID”部分,我不确定该文档与内核2.6.35有多大关系;具体来说,它说: ..the DMA address of the memory must be within the dma_mask of the device.. 他们建议将某些标志(如GFP_DMA)传递给kmalloc,以确保内存位于提供的DMA掩码内 但是,如果内存是从kmem\u cache\u create创建的缓存池中分配的,并且使用kmem\u cache\u alloc(…GFP\u ATO
..the DMA address of the memory must be within the dma_mask of the device..
他们建议将某些标志(如GFP_DMA
)传递给kmalloc
,以确保内存位于提供的DMA掩码内
但是,如果内存是从kmem\u cache\u create
创建的缓存池中分配的,并且使用kmem\u cache\u alloc(…GFP\u ATOMIC)
,这不符合DMA-API.txt中概述的要求
另一方面,LDD谈到有关传统ISA设备的\uugfp\uDMA
标志,因此我不确定这是否适用于PCI/PCIe设备
这是x86 64位平台,如果重要的话:
pci_set_dma_mask(dev, 0xffffffffffffffffULL);
pci_set_consistent_dma_mask(dev, 0xffffffffffffffffULL);
我希望能听到一些解释
- ISA-使用
时,需要使用kmalloc()
(或GFP\u内核
)按位或\u原子
,原因如下:GFP\u DMA
保证: (1) 当GFP\U DMA
返回多个页面且 (2) 仅返回低于get\u free\u page
的地址<由于ISA限制,电脑上的代码>最大DMA地址为16MBMAX\u DMA\u ADDRESS
- PCI-不需要使用
,因为没有GFP\u DMA
MAX\u DMA\u地址限制
dma\u-map.*
或dma\u-alloc\u-coherent
时,设备会检查dma\u掩码
dma\u alloc\u coherent
确保分配的内存能够被dma\u map.*
使用,这也带来了其他好处。(实现可以选择忽略影响返回内存位置的标志,如GFP_DMA)
您可以参考谢谢。我在书中读到的另一个要求是“建议驱动程序编写器映射从页面边界开始和结束的虚拟区域”。什么内核API保证以页面为单位分配?这可以用kmem\u alloc\u缓存吗?
\u get\u free\u page()
和\u get\u free\u page()
是您想要的kmem\u alloc\u cache
不能保证为您提供完整的页面。有关alloc页面的更多内核API,请参阅/mm/page\u alloc.c
。您可以将SLAB\u HWCACHE\u ALIGN
标志传递给kmem\u cache\u create
,以确保从kmem\u cache\u alloc
获得的所有内存都与缓存线对齐kmalloc
也做了类似的事情。因此kmalloc
还可以保证内存与缓存线对齐。它在内部分配1+个连续的内存,称为slab。但是您不能通过调用kmem\u cache.*
直接获得一个slab。相反,返回给您的内存kmem\u cache\u alloc
的大小是您在它之前提供的kmem\u cache\u create
。