使用DMA的直接IO

使用DMA的设备直接在用户缓冲区上进行IO操作:

上图说明了驱动怎样使用IRP中的MdlAddress来传输数据,此操作为读数据过程。上图中的驱动使用基于包的传输,bus-master模式或system模式都可以。

1、用户空间虚拟地址的某一范围,代表当前线程的缓冲区。缓冲区(虚拟地址空间)的内容实际上可能存储于一些物理上离散的页面中(如上图中的阴影部分)。IO管理器创建一个MDL来描述缓冲区。MDL是一个不透明的数据结构,由内存管理器定义。MDL用于将某一特殊的虚拟地址范围映射到一个或多个基于页的物理地址范围。

2、IO管理器为当前线程的读请求服务。线程传入一个用户空间地址范围,此地址范围代表了一个缓冲区。

3、IO管理器或FSDFile System Dispatch)检查用户适用的缓冲区是否可以访问,并调用MmProbeAndLockPagesMmProbeAndLockPages适用之前创建的MDL作为参数。MmProbeAndLockPages同时填满MDL中相应的物理内存。

如上图所示,表示虚拟地址的MDL可能有几个基于页的物理地址入口。缓冲区的虚拟空间范围可能起始和结束于某些字节偏移,例如,从MDL描述的页面中的第一页起始部分和最后一页起始部分。

4、IO管理器提供了一个MDL的指针,该指针存储于发起传输操作请求的IRP中。在驱动完成IRP的请求,IO管理器或文件系统调用MmUnlockPages函数之前,MDL中描述的物理页一直是锁定的,并且分配给了缓冲区。MDL中的虚拟地址能变成不可见的,甚至在IRP被送到设备驱动(或位于设备驱动上层的中间驱动)之前。

5、如驱动使用基于包的systembus-master DMA,它的AdapterControl例程调用MmGetMdlVirtualAddressMmGetMdlVirtualAddress使用IRP中的MdlAddress指针作为参数,以获取MDL的基于页的入口的虚拟地址基址。

6、AdapterControl例程调用MapTransfer,直接从设备中读取数据到物理内存。MapTransfer使用MmGetMdlVirtualAddress返回的基地址作为参数。

驱动必须时常检查缓冲区的长度。IO管理器并不为长度为0的缓冲区创建MDL

 

(本文议自于MSDN,不明之处请参考原文Using Direct I/O with DMA)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值