Kernel DMA

    为什么会有DMA(直接内存访问)?我们知道通常情况下,内存数据跟外设之间的通信是通过cpu来传递的。cpu运行io指令将数据从内存拷贝到外设的io端口,或者从外设的io端口拷贝到内存。由于外设的访问速度跟内存的访问速度相比非常慢,因此这种访问操作会严重浪费cpu的指令周期,DMA的出现就是为了解决这个问题。支持DMA机制的系统通常会包含一个DMA控制器,下挂支持DMA的外设,外设和内存之间的数据交换通过DMA控制器完成。

    那么,如何使用DMA?不同平台提供不同的DMA控制器,其控制器驱动也不尽相同,因此DMA控制器驱动不在夲篇分析。支持DMA的设备一般都会提供至少两个io端口(用于设置DMA地址和大小)和中断请求线,io端口用于指定缓存的物理地址(无iommu)或者总线地址(有iommu)和大小,中断请求线用于当设备完成dma操作后,通知cpu开始下一步操作。DMA控制器的通道请求,源地址和目的地址的设置等操作一般由外设完成,无需用户介入。一个DMA的读操作如下:

    (1)cpu分配一块连续的物理内存缓冲区。

    (2)cpu将分配好的内存缓冲区的物理地址或者总线地址和大小写入外设的DMA地址和大小io端口。

    (3)cpu设置外设的控制端口,启动外设进行DMA操作。然后,cpu清除读取完成标志,并将当前读取进程挂起,调度其他任务运行。

    (4)当外设完成了DMA操作之后,通过中断请求线,通知cpu操作完成。

    (5)cpu进入中断处理函数,设置读取完成标志,唤醒挂起在等待队列上的进程。

    (6)读取进程被唤醒后,检查读取完成标志。如果完成,对缓冲区数据进行下一步处理,否则,继续挂起等待。

    DMA的写操作类似这个过程。仔细分析可以发现,用户只需要提供缓存的物理地址或总线地址和大小,注册中断处理函数,并启动设备进行DMA操作即可。那么缓存的物理地址或总线地址是如何得到的呢?DMA缓存的分配是内核DMA编程的核心,下面我们主要分析两种DMA缓存的分配方法:DMA一致性缓存和DMA映射缓存

    (1)DMA一致性缓存分配接口 dma_alloc_coherent():

            我们知道,cpu访问内存使用的是虚拟地址,而外设访问内存使用的是io地址。当外设所在的总线不支持iommu时,io地址就是内存的物理地址,如果外设所在的总线支持iommu,那么io地址经过iommu映射之后才是内存的物理地址。因此,一个DMA缓存对应两种地址,cpu虚拟地址和外设io地址,而这些地址在不同平台配置也不同。以x86为例,x86没有iommu,其io地

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值