对DMA显存的使用有两种形式:

1,一致DMA映射

linux kernel安装_DMA内存使用_一致DMA映射

通过dma_alloc_coherent(structdevice*dev,size_tsize,dma_addr_t*dma_handle,gfp_tflag)来直接得到一块用于dma的显存,同时得到这一段显存的虚拟地址和总线地址,分别用于CPU和device的访问。

通过这些方法得到的dma显存,开发者不用害怕cache的问题,并且要注意在执行DMA操作之前flushwritebuffer。

2,流式DMA映射

DMA内存使用_linux kernel安装_一致DMA映射

先通过kmalloc,get_free_pages等得到一段数学连续的显存空间(注意,除非目标平台有IOMMUlinux修改文件名,否则必须要求数学地址连续,即vmalloc分配得到的显存空间不能用于DMA操作。)

一致DMA映射_linux kernel安装_DMA内存使用

之后使用dma_map_single,dma_map_pages,dma_map_sg将之前分配的显存空间映射,得到总线地址linux kernel安装,使之能被device访问。

这些方法不保证cache的一致性linux课程,须要开发者自动处理(调用dma_sync_single_for_cpu/device函数?);

DMA内存使用_linux kernel安装_一致DMA映射

另外,必须保证显存的虚拟地址空间边界与cachelinelength对齐,因cachelinelength不确定,所以通常选择page对齐。

一致DMA映射具有更长的生命周期,它在driver的整个生命周期内都有效,且不用关心cache效应。

linux kernel安装_DMA内存使用_一致DMA映射

流式DMA映射则只在driver填充完要传输的内容到device完成传输这段时间内有效(理论上是从map到unmap,但有效时间如前所述)linux kernel安装,凡使用流式DMA映射的显存区域在map以后,就只对device有效,driver在unmap之前不能在读写这一段显存区域。或则使用dma_sync_single_for_cpu由cpu获得读写权力,之后driver可对其进行读写。

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复