首先来看看DMA是个什么东西
DMA----direct memory access----直接内存访问
一个DMA基本框架是什么样子的呢?请看下图
系统中包括CPU、dma控制器、内存和外设。
相比cpu,内存和外设的处理速度那是相当的慢,cpu直接与外设交互,大部分时间cpu都处于等待状态,这样就严重浪费了cpu的性能。因此DMA出现了。数据搬运的任务交给dma控制器来完成,cpu只需给dma控制器一个开始传输命令,之后就可以去处理其他任务了,当dma控制器数据处理完成后会通过中断通知cpu,cpu就可以去dma buffer中处理交互后的数据了。
下面介绍一个在dma传输过程中一个比较重要的概念----地址
在dma传输过程中主要涉及三种地址:
虚拟地址、物理地址、总线地址
虚拟地址----即我们程序里使用的内存、Linux内核中通过kmalloc、vmalloc等申请的内存地址都是虚拟地址
物理地址----由虚拟内存系统将虚拟地址转换而来
总线地址----包括但不限于外设寄存器使用的地址空间
三种地址空间的关系如下图所示
三种地址空间关系示意图
此图地址空间划分仅做示意。
dma传输过程中内存地址的使用流程如下
在物理地址空间申请一块物理连续的内存空间作为DMA buffer,
获取这块物理内存的虚拟地址供驱动访问,
将物理地址告诉dma控制器,由dma控制器完成该空间与总线地址空间之间的数据搬运。