linux下面的驱动虽然什么样的情形都有,但是dma驱动却并不少见。dma可以有很多的好处,其中最重要的功能就是能够帮助我们将数据搬来搬去,这个时候cpu就由时间去做别的事情了,提高了设备效率。...1、dma驱动在什么地方 drivers/dma 2、如何看s3c的dma驱动,先看Kconfig config S3C24XX_DMAC bool "Samsung S3C24XX DMA support....name = "s3c24xx-dma", }, .id_table = s3c24xx_dma_driver_ids, .probe = s3c24xx_dma_probe...); dma_cap_set(DMA_CYCLIC, s3cdma->slave.cap_mask); dma_cap_set(DMA_PRIVATE, s3cdma->slave.cap_mask...只要完成dma接口的适配,dma就可以正常使用了。当然,前提是,两个engine要进行注册使用。
2.指定DMA设备的寻址范围 include/linux/dma-mapping.h // 用于一致性内存映射的映射范围 static inline int dma_set_coherent_mask...// dma_handle 返回DMA buf的物理地址 // flag 分配标志 // 返回值 DMA buffer的虚拟地址 void *dma_alloc_coherent...释放的DMA buffer大小 // cpu_addr DMA buf的虚拟地址 // dma_handle DMA buf的物理地址 void dma_free_coherent...内存块的物理地址 */ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma) 3.2 流式DMA接口 // dev...enum dma_data_direction dir, unsigned long attrs) // dev 需要映射内存的设备 // addr dma区域的物理地址
这两天整理了调用流程,也找到了dma-coherent的用法。Linux的文档里没有详细说明dma-coherent的用法。...根据代码,如果dma的设备树里有dma-coherent,Linux则认为硬件会维护cache一致性,不会在dma运行过程中执行cache操作。...的定义 dma_map_single()和dma_unmap_single()都在include\linux\dma-mapping.h里定义。...也许Linux之前遇到一些问题,才改成这样的操作。 dma-coherent DMA的设备树里可以配置属性"dma-coherent"。...dev_is_dma_coherent的定义在文件include\linux\dma-noncoherent.h中。
在linux内核映射物理地址的简单代码。 使用request_mem_region和ioremap映射物理地址。 映射之后,可通过虚拟地址读写对应的寄存器。
进一步,针对不同的用途,Linux内核将所有的物理页面划分到3类内存管理区中,如图,分别为ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM。 ?...之所以需要单独管理 DMA 的物理页面,是因为 DMA 使用物理地址访问内存,不经过 MMU,并且需要连续的缓冲区,所以为了能够提供物理上连续的缓冲区,必须从物理地址空间专门划分一段区域用于 DMA。...Linux内核空间虚拟地址分布 ? 在 Kernel Image 下面有 16M 的内核空间用于 DMA 操作。...Linux物理地址和虚拟地址的关系 ? Linux 将 4G 的线性地址空间分为2部分,0~3G 为 user space,3G~4G 为 kernel space。...虽然这样存在效率的问题,但是内核毕竟可以正常的访问所有的物理地址空间了。 到这里我们应该知道了 Linux 是如何用虚拟地址来映射物理地址的,最后我们用一张图来总结一下: ?
System DMA是将DMA作为中心位置挂在总线上,能够被总线上的任何设备所使用。BMD是目前为止发现的基于PCIe总线使用最多的DMA类型(使用Endpoint设备)。...MWr和MRd的TLPs会通过PIO(程控输入输出)被放松到endpoint端 并且被用来监视和控制DMA硬件.目标逻辑的功能是为了更新状态控制寄存器,所有即将到来的MWr数据包是32位宽并且包含一个双字的负载...初始化逻辑在从endpoint传输数据到系统存储中时产生内存写TLPs,DMA写控制和状态寄存器指定发送的地址、大小、负载内容以及TLPs的个数。
1.DMA方式的特点 主存和DMA接口之间有一条直接数据通路。由于DMA方式传送数据不需要经过CPU,因此不必中断现行程序,I/O与主机并行工作,程序和传送并行工作。...2.DMA控制器的组成 对数据传送过程中进行控制的硬件称为DMA控制器(DMA接口)。...当I/O设备需要进行数据传送时,通过DMA控制器向CPU提出DMA传送请求,CPU响应之后让出系统总线,由DMA控制器接管总线进行数据传送。 1)接受外设发出的DMA请求,并向CPU发出总线请求。...DMA请求触发器:每当I/O设备准备好数据后给出一个控制信号,使DMA请求触发器置位。...由此可见,DMA控制器必须具有控制系统总线的能力。 3.DMA的传送方式 主存和DMA控制器之间有一条数据通路,因此主存和I/O设备之间交换信息时。不通过CPU。
直接内存访问(Direct Memory Access,DMA):在计算机体系结构中,DMA 是一种数据传输方式,允许外部设备直接访问计算机的内存,而无需通过中央处理单元(CPU)的干预。...那么,DMA究竟有多快呢? 实践出真知 恰好,最近有个多通道数据采集的项目,受限于通道数多、分辨率高,而系统带宽有限,为了尽可能充分利用有限带宽,就得想办法优化时序,把时间都留给数据采集和传输。...优化方向就是DMA。 硬件链路是ADC通过SPI接口将数据发送给STM32单片机,单片机再将数据发送到上位机。 咱们的目标就是优化SPI这边,先看普通采集模式。...再看下,开启DMA之后的效果。SPI可以连续工作,时钟速率稳定在20MHz,高效工作。 这就是DMA的强大之处! 问题来了,为什么上图中的波形,有这么大的震荡呢?
()对应 //size:释放长度 //cpu_addr:虚拟地址, //handle:物理地址 4) dma_free_coherent(struct device *dev, size_t size..., //handle:物理地址 (PS: dma_free_writecombine()其实就是dma_free_conherent(),只不过是用了#define重命名而已。)...而我们之前用的内存分配kmalloc()函数,是不能用在DMA上,因为分配出来的内存可能在物理地址上是不连续的. 1.2 那么2440开发板如何来启动DMA,先来看2440的DMA寄存器 (PS:实际这些... #include #include #include #include <linux...寄存器,启动一次DMA传输 */ /* 源的物理地址 */ s3c_dma3_regs->disrc3 = source_phys;
长期从事Linux内核驱动开发、Linux内核开发和Linux系统虚拟化(QEMU/KVM),喜欢分析Linux内核子系统基本原理并撰写技术博客,长期关注kernel、QEMU的开源项目,经常参加相关开源社区活动...3.1.1.1 DMA物理地址重映射 (DMA Remapping ) 1)地址空间隔离 在没有iommu的时候,用户态驱动可以通过设备dma可以访问到机器的全部的地址空间,如何保护机器物理内存区对于用户态驱动框架设计带来挑战...引入iommu以后,iommu通过控制每个设备dma地址到实际物理地址的映射转换,可以实现地址空间上的隔离,使设备只能访问规定的内存区域,见图3.1.1.1.1。...图3.1.1.1.1 2)GPA(虚拟机物理地址) --> HPA(宿主机物理地址) 物理PCI设备通过直通的方式进入到虚拟机的客户机时,客户机设备驱动使用透传设备的DMA访问虚拟机内存物理地址时,IOMMU...时,QEMU会将上述操作通过VFIO接口下发给物理PCI设备的DMA,物理设备DMA收到GuestOS中的物理地址GPA,通过IOMMU的映射,找到Host主机物理内存的物理地址HPA,达到物理PCI设备直接访问
前两步在linux里分别对应如下操作: fixed map 加载dtb :Uboot会将kernel image和dtb拷贝到内存中,并且将dtb物理地址告知kernel 系统解析dtb里的内存参数:...「Linux是如何组织物理内存的?」...「zone」: ZONE的意思是把整个物理内存划分为几个区域,每个区域有特殊的含义 enum zone_type { #ifdef CONFIG_ZONE_DMA /* * ZONE_DMA is...故物理地址和pfn的关系是: 物理地址>>PAGE_SHIFT = pfn 「pfn和page的关系」: 内核中支持了好几个内存模型:CONFIG_FLATMEM(平坦内存模型)CONFIG_DISCONTIGMEM...最后 至此linux对物理内存的初始化和虚拟地址和物理地址的映射关系算是告一段落,相信你已经知道 linux 虚拟寻址空间layout的来龙去脉,以及如何把物理内存通过node, zone, page
创作目的 互联网、Linux内核书籍上充满了各种关于Linux DMA ZONE和dma_alloc_coherent、dma_map_single等的各种讲解,由于很多童鞋缺乏自身独立的思考,人云亦云...那么ISA上面假设有个网卡,要DMA,超过16MB以上的内存,它根本就访问不到。所以Linux内核干脆简单一点,把16MB砍一刀,这一刀以下的内存单独管理。...比如我在CSR工作的时候,CSR的primaII芯片,尽管除SD MMC控制器以外的所有的DMA都可以访问整个4GB内存,但MMC控制器的DMA只能访问256MB,我们就把primaII对应Linux的...下面我们架空历史,假设有一个如下的芯片,里面有5个DMA,A、B、C都可以访问所有内存,D只能访问32MB,而E只能访问64MB,你觉得Linux的设计者会把DMA ZONE设置为多大?...当我grep内核源代码的时候,我发现部分SoC确实是这样实现的: baohua@baohua-VirtualBox:~/develop/linux/arch/arm$ git grep arm_coherent_dma_ops
工程师(其他的非Linux工程师也一样)写出高效能代码,以及优化Linux系统的性能是至关重要的。...CPU与设备(其实也可能是个异构处理器,不过在Linux运行的CPU眼里,都是设备,都是DMA)的cache同步问题 先看一下ICACHE和DCACHE同步问题。...这些软件的动作,若我们在Linux编程的时候,使用的是streaming DMA APIs的话,都会被类似这样的API自动搞定: dma_map_single() dma_unmap_single()...dma_sync_single_for_cpu() dma_sync_single_for_device() dma_sync_sg_for_cpu() dma_sync_sg_for_device()...如果是使用的dma_alloc_coherent() API呢,则设备和CPU之间的buffer是cache一致的,不需要每次DMA进行同步。
我们先从计算机组成原理的层面介绍DMA,再简单介绍Linux网络子系统的DMA机制是如何的实现的。 一、计算机组成原理中的DMA 以往的I/O设备和主存交换信息都要经过CPU的操作。...总之,在同样的时间内,DMA方式下CPU执行现行程序的时间最长,即CPU的效率最高。 二、Linux网络子系统中DMA机制的实现 1....dma_mask表示的是该设备通过DMA方式可寻址的物理地址范围,coherent_dma_mask表示所有设备通过DMA方式可寻址的公共的物理地址范围, 因为不是所有的硬件设备都能够支持64bit的地址宽度.../include/linux/dma-mapping.h /* * Set both the DMA mask and the coherent DMA mask to the same thing...其实这个函数还隐式的返回了物理地址,物理地址存在第三个参数中。 指针rxdr指向的是struct e1000_rx_ring这个结构体,该结构体就是接收环形缓冲区。 ?
05 STM32少个DMA资源? 对于大容量的STM32芯片有2个DMA控制器,DMA1有7个通道,DMA2有5个通道。每个通道都可以配置一些外设的地址。...在这里插入图片描述 有DMA传输: 有DMA的话, DMA传输时外设对DMA控制器发出请求。 DMA控制器收到请求,触发DMA工作。...07 DMA传输方式 方法1:DMA_Mode_Normal,正常模式 当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。...当设置了DMA_CCRx寄存器中的MEM2MEM位之后,在软件设置了DMA_CCRx寄存器中的EN位启动DMA通道时,DMA传输将马上开始。当DMA_CNDTRx寄存器变为0时,DMA传输结束。...17 DMA中断标志清除寄存器 (DMA_IFCR) DMA_IFCR 的各位就是用来清除 DMA_ISR 的对应位的,通过写 0 清除。
内存节点结构体在linux内核include/linux/mmzone.h文件中, /* * On NUMA machines, each NUMA node would have a pg_data_t...内存节点被划分为内存区域,内存区域结构体在linux内核include/linux/mmzone.h文件中 struct zone { unsigned long watermark[NR_WMARK...除了上面说的 ZONE_DMA,还有 ZONE_DMA32。在这里你大概理解 DMA 的原理就可以,不必纠结,我们后面会讲 DMA 的机制。...内存区域结构体在linux内核include/linux/mm_types.h文件中 struct page { unsigned long flags; /* Atomic flags, some...其实 Linux 倾向于另外一种从虚拟地址到物理地址的转换方式,称为分页(Paging)。
IOMMU 会把零散的物理页建立一个和 CPU 里一样的页表,然后再把这些零散的物理页 映射成对于 DMA 引擎看起来连续的虚拟页。DMA 引擎就可以访问非连续的物理地址。 ?...当从内存到外设时,一般Linux内核会自动做cache flush,以保证做DMA传输时可以从内存中取到最新的数据。相反,当从外设到内存时,会做cache的invalid动作。...原因是比如调用dma_map_single从内存到外设,Linux内核已经完成cache flush动作,此时如果允许CPU参与,则有可能CPU将cache写得再次比memory新。...页表中除了有虚拟地址到物理地址的对应关系,RWX 权限,user/kernel 权限, 还会记录 cache 特性。...物理地址和虚拟地址的分布 Linux内核内存管理算法Buddy和Slab Linux用户态进程的内存管理
所谓的写传播,指的是某个CPU,向某个物理地址写入一个值的时候,需要通知其他CPU,如果自己的缓存中,有指向这个物理地址的值,需要处理这个事件; 如图,图中有多个CPU的L2缓存均映射到RAM中的某个单元...而所谓的串行化,是指这样的行为: 如对某个内存单元的物理地址进行了多次写入,该写入行为在向各个CPU进行写传播时,其先后次序是一致的。...(物理地址),转换为逻辑地址后,对数据包内容进行分类处理。...在Linux中有一个接口,叫dma_alloc_coherent,可以分配no cache的内存给DMA使用。显然,这会造成CPU访问数据的性能较为低下。...在Linux下,还有一个接口叫做dma_cache_sync,用以实现cache同步,也就是在CPU读写有可能被DMA修改的缓冲区时,读之前同步cache,或写之后同步cache,保证cache和RAM
惠伟:IOMMU(三)-初始化zhuanlan.zhihu.com DMA remapping就是在DMA的过程中IOMMU进行了一次转换,MMU把CPU的虚拟地址(va)转换成物理地址(pa),IOMMU...的作用就是把DMA的虚拟地址(iova)转换成物理地址(pa),MMU转换时用到了pagetable,IOMMU转换也要用到io pagetable,两者都是软件负责创建pagetable,硬件负责转换...IOMMU的作用就是限制DMA可操作的物理内存范围,当一个PCI设备passthrough给虚拟机后,PCI设备DMA的目的地址是虚拟机指定的,必须要有IOMMU限制这个PCI设备只能操作虚拟机用到的物理内存...DMA类型 Requests without address-space-identifier DMA中只带了source-id,也就是PCI设备的bus/dev/funtion。...first level的PML4E,这个指针指向的并不是真正的物理地址,只有经过second level转换一下才能变成真正的物理地址,才能获取first level的PML4E表,从PML4E中得到PDPE
领取专属 10元无门槛券
手把手带您无忧上云