通常在使用consistent dma mapping时,首先需要通过接口来分配一段区域: dma_alloc_coherent用于分配coherent内存,并返回对应的虚拟地址; 进行内存分配时,存在三种方式:1)优先从设备专用的dma池开始分配;2)无专用dma池,如果是dma-direct访问,通过dma_direct_alloc分配,而底层是依赖于CMA来分配;3)使用IOMMU的设备,则通过...
dma_alloc_coherent()申请的内存来自于哪里,不是因为它的名字前面带了个dma_就来自DMA ZONE的,本质上取决于对应的DMA硬件是谁。看代码: 代码语言:javascript 复制 staticvoid*__dma_alloc(struct device*dev,size_t size,dma_addr_t*handle,gfp_t gfp,pgprot_t prot,bool is_coherent,constvoid*caller){u64...
但是,如果IOMMU存在(ARM里面叫SMMU)的话,DMA完全可以访问非连续的内存,并且把物理上不连续的内存,用IOMMU进行重新映射为I/O virtual address (IOVA): 所以dma_alloc_coherent()这个API只是一个前端的界面,它的内存究竟从哪里来,究竟要不要连续,带不带cache,都完全是因人而异的。
dma_alloc_coherent()申请的内存是非cache的吗? 缺省情况下,dma_alloc_coherent()申请的内存缺省是进行uncache配置的。 也可以带cache If the machine sets arm_coherent_dma_ops rather than arm_dma_ops, the memory willbecacheable, 那我们什么时候选择带cache的分配方式呢?当可以用硬件做CPU和外设的cache co...
void *dma_pool_alloc(struct dma_pool_t, int mem_flags, dma_addr_t *handle); (5)使用下面的函数返回不需要的缓冲区: void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t addr); 20.建立流式DMA映射 (1)当建立流式映射时,必须告诉内核数据流动的方向。为此定义了一些符号(dma...
互联网、Linux内核书籍上充满了各种关于Linux DMA ZONE和dma_alloc_coherent、dma_map_single等的各种讲解,由于很多童鞋缺乏自身独立的思考,人云亦云,对这些概念形成了很多错误的理解。本文的目的在于彻底澄清这些误解。 当你发现本文内容与baidu到的内容不一致的时候,以本文内容为准。
从trb_pool获取一个空闲的TRB,trb_pool的索引为dep->trb_enqueu。 设置request状态为开始传输,将request放到started_list链表上。 request保存TRB的虚拟地址、保存TRB的DMA地址、保存绑定TRB的索引、dep->trb_enqueu增大。 TRB保存request中缓冲区的长度、保存request中缓冲区的DMA地址。 设置TRB的控制位。 2.6.2....
是DMA大小不够,于是更改了kernel/arch/arm/mm/dma.mapping.c中的DEFAULT_DMA_COHERENT_POOL_SIZE S_...
dma_addr_t dma_handle; cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp); 其中device 是一个结构设备 *。这可以在带有 GFP_ATOMIC 标志的中断上下文中调用。Size 是您要分配的区域的长度,以字节为单位。该例程将为该区域分配 RAM,因此它的行为类似于 __get_free_pages() (但采用大小而不...
如在DMA写操作之前,需要先将CPU cache中的数据刷到内存上,然后再启动DMA写传输,而在DMA读操作之前,需要先将CPU cache中的数据invalidate掉,再从内存中读取新的数据 3.1 一致性DMA接口的流程 一致性DMA主要包括内存分配和内存释放接口,其接口定义如下: inline void *dma_alloc_coherent(struct device *dev, size_t...