在项目驱动过程中会经常用到dma传输数据,而dma需要的内存有自己的特点,一般认为需要物理地址连续,并且内存是不可cache的,在linux内核中提供一个供dma所需内存的申请函数dma_alloc_coherent. 如下所述: dma_alloc_coherent() dma_alloc_coherent() -- 获取物理页,并将该物理页的总线地址保存于dma_handle,返回该物...
所以cache coherent的最简单方法,自然是让CPU访问DMA buffer的时候也不带cache。事实上,缺省情况下,dma_alloc_coherent()申请的内存缺省是进行uncache配置的。 但是,由于现代SoC特别强,这样有一些SoC里面可以用硬件做CPU和外设的cache coherence,如图中的cache coherent interconnect: 这些SoC的厂商就可以把内核的通用实现...
在项目驱动过程中会经常用到dma传输数据,而dma需要的内存有自己的特点,一般认为需要物理地址连续,并且内存是不可cache的,在linux内核中提供一个供dma所需内存的申请函数dma_alloc_coherent. 如下所述: dma_alloc_coherent() dma_alloc_coherent() -- 获取物理页,并将该物理页的总线地址保存于dma_handle,返回该物...
楼主你好,“这种方法简单实用,但是缺点也很明显。如果只是偶尔使用DMA,大部分都是使用数据的话,会由于nocache导致性能损失。这也是Linux系统中dma_alloc_coherent()接口的实现方法。” 这里是不是应该着重强调一下是损失了cpu的对访问dma buffer的性能。 另外问一下,dma传输应该是不经过cache直接到主存吧。 2021-03-...
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag); 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 该函数实际获得两个地址。 1、函数的返回值是一个 void *。代表缓冲区的内核虚拟地址 ...
dma_alloc_coherent()函数是为了达到一致性内存的目的,它分配指定大小的一致性内存,其物理起始地址存放在dma_handle中,函数返回值为这段内存的虚拟起始地址。 dma_alloc_coherent()函数返回的虚拟地址尽量是非缓存的,这样设备向这块地址放数据包,OS响应中断后可以从这块地址拿包。
int dma_set_coherent_mask(struct device *dev, u64 mask); 前者是设定streaming类型的DMA地址掩码,后者是设定coherent类型的DMA地址掩码。为了更好的理解这些接口,我们聊聊参数和返回值。dev指向该设备的struct device对象,一般来说,这个struct device对象应该是嵌入在bus-specific 的实例中,例如对于PCI设备,有一个...
* 常用函数:dma_map_single(), dma_unmap_single(), dma_alloc_coherent(), dma_free_coherent()等。 */ #include <linux/dma-mapping.h> /* * 作用:提供中断处理相关的接口,用于注册、注销中断处理函数,以及处理设备中断。 * 当外设(如DMA控制器)触发中断时,内核会调用驱动程序注册的中断处理函数。
许多驱动程序需要又多又小的一致映射内存区域给DMA描述子或I/O缓存buffer,这使用DMA池比用dma_alloc_coherent分配的一页或多页内存区域好,DMA池用函数dma_pool_create创建,用函数dma_pool_alloc从DMA池中分配一块一致内存,用函数dmp_pool_free放内存回到DMA池中,使用函数dma_pool_destory释放DMA池的资源。
1,一致DMA映射 通过dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)来直接得到一块用于dma的内存,同时得到这一段内存的虚拟地址和总线地址,分别用于CPU和device 的访问。通过这种方式得到的dma内存,开发者不用担心cache的问题,但是要注意在执行DMA操作之前flush ...