内容发布更新时间 : 2024/11/5 13:26:24星期一 下面是文章的全部内容请认真阅读。
然还是内存中的数据,以后访问Cache映射的内存时,它仍然使用陈旧的Cache数据,这就会发生Cache与内存之间数据“不一致性”的错误。一旦出现这样的情况,没有处理好,驱动就将无
法正常运行。那么怎样解决呢?最简单的方法是直接禁止DMA目标地址范围内内存的Cache功能,当然这是牺牲性能的,但却高可靠。不是吗,所以这两者之间究竟怎么平衡,还真不好解决。
其实啊,Cache不一致的情况在其他地方也是可能发生的,比如,对于带MMU功能的ARM处理器,在开启MMU之前,需要设置Cache无效,TLB也是如此。
说了,那么多DMA理论的东西,剩下的来点Linux下DMA编程的东西,当然,这里也是点一下,具体怎么操作,我可要卖个关子到下节了。
在内存中用于与外设交互数据的一块区域被称作DMA缓冲区,在设备不支持scatter/gatherCSG,分散/聚集操作的情况下,DMA缓冲区必须是物理上联系的。
对于ISA设备而言,其DMA操作只能在16MB以下的内存进行,因此,在使用kmalloc()和__get_free_pages()及其类似函数申请DMA缓冲区时应使用GFP_DMA标 志,这样能保证获得的内存是具备DMA能力的。
内核中定义了__get_free_pages()针对DMA的“快捷方式”__get_dma_pages(),它在申请标志中添加了GFP_DMA,如下所示:
#define __get_dma__pages(gfp_mask, order) __get_free_pages((gfp_mask) | GFP_DMA, (order)) \我不想使用order为参数的申请DMA内存,感觉就是怪怪的,那咋办?\小王抱怨道. 那?这样吧,你就用另外一个函数dma_mem_alloc()源代码如下: static unsigned long dma_mem_alloc(int size) {
int order = get_order(size); //大小->指数 return __get_dma_pages(GFP_KERNEL, order); }
\小王,感觉怎样,要不咱们下节继续?看你挺多不懂的地方?\我看到小王那充满疑惑的眼神。 \好,行,我正有这种打算呢\小王又露出了让人陶醉的笑容。