收藏 分享(赏)

驱动开发-DMA的开发原理讲解.ppt

上传人:ysd1539 文档编号:8277009 上传时间:2019-06-18 格式:PPT 页数:29 大小:196.50KB
下载 相关 举报
驱动开发-DMA的开发原理讲解.ppt_第1页
第1页 / 共29页
驱动开发-DMA的开发原理讲解.ppt_第2页
第2页 / 共29页
驱动开发-DMA的开发原理讲解.ppt_第3页
第3页 / 共29页
驱动开发-DMA的开发原理讲解.ppt_第4页
第4页 / 共29页
驱动开发-DMA的开发原理讲解.ppt_第5页
第5页 / 共29页
点击查看更多>>
资源描述

1、DMA,,DMA,DMA即Direct Memory access 无需计算机的CPU的干预就可以在内存和外设之间传输数据 通常都有DMA控制器来进行DMA操作,DMA控制器可能是主板上的,也有可能是外设特有的。 为什么需要 DMA?,传输模型,Windows 中的DMA传输基于这个模型,适配器对象(adapter),Windows 2000内核使用一个称为适配器对象的数据结构来描述设备上的DMA特征,并用它来控制访问潜在的共享资源,如系统DMA通道和映射寄存器 通常在StartDevice函数中调用IoGetDmaAdapter获得适配器对象 适配器对象中有一个指针,指向一个DmaOpera

2、tions的结构,该结构包含了所有需要的DMA相关的其它函数,这些函数如下表,传输策略选择,1。如果设备有总线主控能力,那么它就有访问主存的必要硬件部件,因此只需要告诉它几个基本事实,如从哪开始,需要传输多少单位的数据,是输入操作还是输出操作,等等。可以向硬件设计者咨询或者固件程序员咨询以得到细节部分,否则只能参考许多硬件级的说明文档。,传输策略选择,2。一个有分散/聚集(scatter/gather)能力的设备可以在自身与不连续的物理内存区之间传输大块数据。设备的分散/聚集能力对软件十分有利,它可以避免对具有连续页帧的大块的内存的需求。页可以被简单地锁定在所在的物理内存,只要把内存地址告诉设

3、备就可以进行。,传输策略选择,3。如果设备不是总线主控设备,那么需要使用计算机主板上的系统DMA控制器。这种形式的DMA传输被称为从属DMA(slave DMA)。与ISA总线连接的系统DMA控制器对所能访问的物理内存和一次传输的数据量会有些限制。EISA总线的DMA控制器去掉了这些限制。在Windows 2000中,不必知道硬件具体插入到哪种类型的总线,因为系统自动参考这些不同的限定。,传输策略选择,4。通常,DMA操作将包括编程硬件映射寄存器或操作前后的数据复制。如果设备需要连续地读写数据,我们不希望在每次I/O请求中都做这两步,这将大大地降低处理速度,在某些情况下也是不能接受的。因此,应

4、该分配一个公用缓冲区(common buffer),设备和驱动程序可以在任何时间同时访问这个缓冲区。,说明,在涉及DMA传输的过程中策略的选择是第一步也是最重要的一步。 不仅需要参考硬件,还要参考可能的软件需求(主控,从属,包,通用缓冲区) 尽管这四种因素的相互影响会产生许多种不同的结果,但执行的步骤中有许多共同的特征。如下图显示了一次传输过程:,执行DMA传输,基于包(packet-based)的DMA传输。在这种方式中,将使用IRP携带的数据缓冲区来传输一定量的数据。 为了简单,让我们假设面对当前最普通的情况:一个基于PCI的总线主控设备并且没有分散/聚集能力。 为什么简单? 下面按照程序

5、编写的通常步骤来详细说明DMA的过程,缓冲方式,当创建设备对象时,通常指定使用Direct缓冲方式,即设置DO_DIRECT_IO标志。或者在定义CTL_CODE时指定direct input或者direct output方式。 因为调用的MapTransfer函数需要一个MDL作为参数 ,这种方式会在每一个IRP的MdlAddress保存描述用户缓冲区的MDL,创建和销毁适配器对象,在处理start device的pnp请求时,我们除了要取得IO,内存,中断资源外,还要创建一个适配器对象(adapter obiect)。 在处理stop device请求时,除了释放映射的IO,内存资源,断开

6、中断的连接外,还要销毁适配器对象。 例如:DMA.doc,和其它资源区别,前面讲过的IO,内存,和中断资源,我们都回在一个CmResourceTypeXxx类型的case子句中获得,这里不需要CmResourceTypeDma类型的case子句,因为设备是总线主控方式,硬件本身包含有执行DMA传输所必须的所有电路逻辑,所以系统没必要赋予设备DMA资源。,获取DMA通道,为了初始化一个I/O操作,StartIo例程必须首先调用适配器对象的AllocateAdapterChannel例程以获取适配器对象。该函数的一个参数是AdapterControl例程的地址,I/O管理器将在获取操作完成后调用这

7、个例程。 AllocateAdapterChannel函数的准备和调用过程:DMA.doc,AllocateAdapterChannel何时完成,AllocateAdapterChannel做什么? 等待DMA控制器,和映射寄存器可用 主控,从属,支持映射寄否? 当DMA控制器,和映射寄存器都可用时, AllocateAdapterChannel调用AdapterControl例程,调用AdapterControl,AllocateAdapterChannel最终将调用驱动程序提供的AdapterControl例程(在DISPATCH_LEVEL,就象StartIo例程一样)。 Adapter

8、Control例程的两个任务:,AdapterControl例程的两个任务,第一,应该调用适配器对象的MapTransfer例程以便为I/O操作的第一阶段准备映射寄存器和其它系统资源。如果是总线主控设备,MapTransfer将返回一个代表传输第一阶段开始点的逻辑地址。这个逻辑地址可能会与CPU的物理内存地址相同,但也可能会不同。所需要知道的就是该地址就是编程设备硬件的正确地址。 第二个任务是执行与“通知设备这个物理地址”操作中涉及的任何设备相关的操作步骤,然后开始操作设备硬件:DMA.doc,DPC,中断通常都发生在传输启动后的很短一段时间后,并且Isr只做很少的事情,比如判断中断类型清除中

9、断状态位 之后,Isr通常都请求一个DPC来处理传输第一阶段的完成,并开始下一个操作。DMA.doc,使用分散集中列表进行传输,如果硬件支持分散/聚集能力,那么系统可以更容易地处理设备的DMA传输。分散/聚集能力允许设备传输所涉及的页在物理内存中不连续。 这种设备的StartDevice例程在创建适配器对象上使用与前面讨论的同样的方式,除了ScatterGather标志应该设为TRUE。 传统方法在安排一个涉及分散/聚集功能的DMA传输时,几乎等同于前面段“执行DMA传输”中的基于包的例子。唯一不同之处是它需要为传输的每个阶段多次调用MapTransfer。每次调用后都会得到分散/聚集列表中的

10、一个包含物理地址和长度的数组元素。 当循环完成时,可以使用设备专用的方法把分散/聚集列表发送到设备,然后开始传输。DMA.doc,使用GetScatterGatherList,这种方法不用手动构建Scatter/gather 列表 DMA.doc 在决定使用GetScatterGatherList 前,以下的前提需要满足: 程序运行在2000及以后系统,98/ME不支持这个函数 如果不确定或者为了程序的兼容性,应该使用传统的循环获取Scatter/gather 列表,使用系统DMA控制器,即slave DMA 所有slave设备必须共享有限的DMA通道数量。AllocateAdapterCha

11、nnel在这种共享情形中具有真正意义,因为一次只能有一个设备可以使用特定的通道 可以在PnP管理器发送的I/O资源列表中找到一个CmResourceTypeDma资源。 大部分方面和总线Master设备类似,一些差别,使用公用缓冲区,通常应该在StartDevice中,在创建适配器对象后分配公用缓冲区:DMA.doc,使用公用缓冲区的Slave模式DMA传输,必须为接收数据的虚拟地址创建一个MDL。MDL的实际目的是在最后调用MapTransfer中占用一个参数,这个MDL指名不需要任何数据复制。 通常应该在StartDevice函数中,紧接着分配公用缓冲区之后创建该MDL 为了执行一个输出操

12、作,首先应通过某些手段(如一个明确的内存复制)使公用缓冲区中包含有要发往到设备的数据 在输入操作的结尾,应该把数据从公用缓冲区复制到其它某个地方,使用公用缓冲区的Slave模式DMA传输,其它部分和进行基于包的DMA传输类似:调用AllocateAdapterChannel,该函数调用驱动程序提供的适配器控制例程,这个例程又调用KeFlushIoBuffers(如果分配了一个可被高速缓冲的缓冲区),最后调用MapTransfer。DPC例程将调用FlushAdapterBuffers和FreeAdapterChannel函数。 唯一要注意的是应该指定公用缓冲区的MDL来代替读写IRP携带的MD

13、L,使用公用缓冲区的master模式DMA传输,如果设备是总线主控模式,那么在分配公用缓冲区后就没有必要调用AllocateAdapterChannel、MapTransfer、FreeMapRegisters函数。 因为AllocateCommonBuffer也能保留必要的映射寄存器。每个总线主控设备都有一个适配器对象,该对象不与其它设备共享,因此不必等待。由于拥有可以在任何时间都能访问缓冲区的虚拟地址,又由于设备的总线主控能力允许使用物理地址(由AllocateCommonBuffer返回)访问该缓冲区,所以没有额外的工作需要做。 这是所有形式的DMA传输中最简单的。,使用公用缓冲区的注意

14、事项,在运行系统中,物理上连续的内存是十分稀有的,有时根本得不到这样的内存,除非在系统启动的早期请求这样的内存。内存管理器为了满足请求会对内存页进行重排列,但它的尝试十分有限,并且这个过程会推迟AllocateCommonBuffer的返回。有时尝试会失败,所以必须能够处理这种失败情况。公用缓冲区不仅与稀有的物理内存页相关,而且还与其它设备争用映射寄存器。,释放公用缓冲区,在处理停止设备时需要释放公用缓冲区 (*pdx-AdapterObject-DmaOperations-FreeCommonBuffer) (pdx-AdapterObject, , pdx-paCommonBuffer, pdx-vaCommonBuffer, FALSE );,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报