2.Linux中的DMA层DMA(Direct Memory Access)通道建立在设备和RAM之间,DMAC(DMA Controler)与设备I/O控制器相互作用共同实现数据传送。
在PC中,DMA控制器位于主板上负责管理I/O总线的南桥上。典型的PC架构的数据通道示意图如下:
DMAC(DMA Controller)一旦被CPU激活,就可以自行传送数据。在实现DMA传输时,由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移问题。在DMA传输前,CPU要把总线控制权交给DMA控制器。在DMA传输后,DMAC发出一个中断请求,将总线控制权回交给CPU。DMA控制器获得总线控制权后,CPU即刻挂起或只执行内部操作,由DMA控制器输出读写命令,直接控制RAM与I/O接口进行DMA传输。
需要明确的是,I/O设备内部一般自带缓存,即通常所说的设备内存。从数据传输的源宿角度分析,DMA通道的两端分别是RAM和设备内存。设备内存一般选用快速低功耗的SRAM材质,例如AR9331交换芯片PCU单元中有4KB的Tx FIFO和2KB的Rx FIFO,“The GE0 and GE1 support 2K transmit FIFO and 2K receive FIFO.”
使用DMAC最多的是磁盘驱动器和其他需要一次传送大量字节的慢速设备,例如PCI网卡(NIC)。
3.DMA描述符DMA操作的核心是DMA内存映射,包括一致性DMA映射、流式DMA映射和分散/聚集映射。以下是Linux内核DMA层的大体框架图:
从图中可以看出,Linux内核中的DMA层为设备驱动程序提供标准的DMA映射接口,例如一致性映射类型的dma_alloc_coherent和流式映射类型的dma_map_single。这些接口屏蔽了不同平台之间的差异,为设备驱动程序提供了良好的可移植性。
SoC datasheet通常会提供DMA rx/tx的descriptor address和trigger control寄存器。在嵌入式软件开发中,DMA描述符数组是个很重要的概念。
DMA描述符数组(DMA Descriptor Array/Ring/Chain)是一个形如unsigned long* hw_desc[DESC_NUM]的指针数组,每个指针(hw_desc[i])指向一个描述符。这个描述符是由硬件定义的,其数据结构一般由datasheet或sdk定义。
3.1 硬件描述符(h/w descriptor)