对DMA显存的使用有两种形式:
1,一致DMA映射
通过dma_alloc_coherent(structdevice*dev,size_tsize,dma_addr_t*dma_handle,gfp_tflag)来直接得到一块用于dma的显存,同时得到这一段显存的虚拟地址和总线地址,分别用于CPU和device的访问。
通过这些方法得到的dma显存,开发者不用害怕cache的问题,并且要注意在执行DMA操作之前flushwritebuffer。
2,流式DMA映射
先通过kmalloc,get_free_pages等得到一段数学连续的显存空间(注意,除非目标平台有IOMMUlinux修改文件名,否则必须要求数学地址连续,即vmalloc分配得到的显存空间不能用于DMA操作。)
之后使用dma_map_single,dma_map_pages,dma_map_sg将之前分配的显存空间映射,得到总线地址linux kernel安装,使之能被device访问。
这些方法不保证cache的一致性linux课程,须要开发者自动处理(调用dma_sync_single_for_cpu/device函数?);
另外,必须保证显存的虚拟地址空间边界与cachelinelength对齐,因cachelinelength不确定,所以通常选择page对齐。
一致DMA映射具有更长的生命周期,它在driver的整个生命周期内都有效,且不用关心cache效应。
流式DMA映射则只在driver填充完要传输的内容到device完成传输这段时间内有效(理论上是从map到unmap,但有效时间如前所述)linux kernel安装,凡使用流式DMA映射的显存区域在map以后,就只对device有效,driver在unmap之前不能在读写这一段显存区域。或则使用dma_sync_single_for_cpu由cpu获得读写权力,之后driver可对其进行读写。