Gee*_*kyJ 7 linux linux-device-driver linux-kernel dma pci-e
什么是Linux内核上下文中的DMA映射和DMA引擎?什么时候可以在Linux设备驱动程序中使用DMA映射API和DMA引擎API?任何真正的Linux设备驱动程序示例作为参考都会很棒.
什么是Linux内核上下文中的DMA映射和DMA引擎?
内核通常使用虚拟地址.功能如kmalloc(),vmalloc()通常返回虚拟地址.它可以存储在void*.虚拟内存系统将这些地址转换为物理地址.这些物理地址实际上对驱动程序没用.驱动程序必须使用ioremap()映射空间并生成虚拟地址.
CPU CPU Bus
Virtual Physical Address
Address Address Space
Space Space
+-------+ +------+ +------+
| | |MMIO | Offset | |
| | Virtual |Space | applied | |
C +-------+ --------> B +------+ ----------> +------+ A
| | mapping | | by host | |
+-----+ | | | | bridge | | +--------+
| | | | +------+ | | | |
| CPU | | | | RAM | | | | Device |
| | | | | | | | | |
+-----+ +-------+ +------+ +------+ +--------+
| | Virtual |Buffer| Mapping | |
X +-------+ --------> Y +------+ <---------- +------+ Z
| | mapping | RAM | by IOMMU
| | | |
| | | |
+-------+ +------+
Run Code Online (Sandbox Code Playgroud)
如果设备支持DMA,则驱动程序使用kmalloc或类似的接口设置缓冲区,该接口返回虚拟地址(X).虚拟内存系统将X映射到系统RAM中的物理地址(Y).驱动程序可以使用虚拟地址X来访问缓冲区,但设备本身不能,因为DMA不通过CPU虚拟内存系统.在某些系统中,只有Device可以直接对物理地址执行DMA.在某些系统中,IOMMU硬件用于将DMA地址转换为物理地址.如上图所示,它将Z转换为Y.
什么时候可以在Linux设备驱动程序中使用DMA映射API?
理由使用DMA映射API是驱动器可以返回虚拟地址X到接口等dma_map_single(),其设置任何所需的IOMMU映射并返回DMA地址然后Z.The驱动告知装置做DMA至Z和IOMMU其映射到系统RAM中地址为Y的缓冲区.
参考来自此链接.
任何真正的Linux设备驱动程序示例作为参考都会很棒.
在Linux内核中,您可以查看drivers/dma中的各种真实驱动程序.