DMA(Direct Memory Access),直接内存访问,这里的直接是和需要CPU参与的内存访问相对的概念,在我们写程序的时候经常会遇到这样的场景:
-
将数据从一片内存搬运到另一片内存
-
持续不断从IO设备读取数据到内存
-
将大量数据不断写入IO设备
这样的活儿CPU当然能干,不过其他的事情就只能推后再处理,毕竟CPU最擅长的还是串行的逻辑,如果能有一个外设,我们告诉它数据存储的地址和长度,再告诉它从哪里搬运到哪里,它就能任劳任怨的去干,最好干完了能再通知CPU一声,那岂不是太好了。
DMA就是这样的外设,把CPU从数据搬运这样的dirty work里解放出来,并且数据的搬运既可以是从内存到内存,也可以发生在内存和设备之间。DMA像普通的外设一样提供一组控制/状态、数据、中断寄存器,通过访问寄存器来驱动DMA工作。
Linux内核里把DMA分为provider和client两种角色,怎么理解呢?
很多时候DMA并不是独立工作的,而是要和其他与内存之间有数据搬运的外设结合到一起,例如ADC使用DMA将采集到的电压值写入给定内存,SPI使用DMA不断将内存中的数据搬运到SPI数据寄存器从而实现发送。
所谓provider就是DMA控制器驱动,它直接访问寄存器,提供DMA通道,但并不提供用户态可用的系统调用或设备文件,而client则申请使用DMA通道,结合具体外设实现真正