分类: LINUX
2009-12-03 09:10:34
DMA是一种无须CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制
DMA方式的数据传输由DMA控制器(DMAC)控制,在传输期间,CPU可以并发地执行其他任务,当DMA结束后,
DMAC通过中断通知CPU数据传输已经结束,然后由CPU执行相应的中断服务程序进行后处理。
解决由于DMA导致的Cache一致性问题的最简单方法是直接禁止DMA目标地址范围内内存的Cache功能。内存中用于与外设交互数据的一块区域被称做DMA缓冲区,在设备不支持scatter/gather CSG,分散/聚集操作的情况下,DMA缓冲区必须是物理上连续的。
对于ISA设备而言,其DMA操作只能在16MB以下的内存中进行,因此,在使用kmalloc()和
__get_free_pages()及其类似函数申请DMA缓冲区时应使用GFP_DMA标志,这样能保证获得的内存时具备DMA
能力的(DMA-capable).
内核中定义了__get_free_pages()针对DMA的“快捷方式”__get_dma_pages(),它在申请标志中添加了GFP_DMA,
如下所示:
#define __get_dma_pages(gfp_mask,order)\ __get_free_pages(gfp_mask|GFP_DMA,(order))
基于DMA的硬件使用总线地址而非物理地址,总线地址是从设备角度上看到的内存地址,物理地址则是从cpu
角度上看到的未经转换的内存地址
申请DMA通道的函数如下:
int request_dma(unsigned int dmanr,const char *device_id);
释放该通道:
void free_dma(unsigned int dmanr);