驱动开发10.DMA

上传人:xx****x 文档编号:243021092 上传时间:2024-09-14 格式:PPT 页数:28 大小:149.50KB
返回 下载 相关 举报
驱动开发10.DMA_第1页
第1页 / 共28页
驱动开发10.DMA_第2页
第2页 / 共28页
驱动开发10.DMA_第3页
第3页 / 共28页
点击查看更多>>
资源描述
,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,DMA,1,DMA,DMA即Direct Memory access,无需计算机的CPU的干预就可以在内存和外设之间传输数据,通常都有DMA控制器来进行DMA操作,DMA控制器可能是主板上的,也有可能是外设特有的。,为什么需要 DMA?,2,传输模型,Windows 中的DMA传输基于这个模型,3,适配器对象(adapter),Windows 2000,内核使用一个称为适配器对象的数据结构来描述设备上的,DMA,特征,并用它来控制访问潜在的共享资源,如系统,DMA,通道和映射寄存器,通常在,StartDevice,函数中调用,IoGetDmaAdapter,获得适配器对象,适配器对象中有一个指针,指向一个,DmaOperations,的结构,该结构包含了所有需要的,DMA,相关的其它函数,这些函数如下表,4,DmaOperations Function Pointer,Description,PutDmaAdapter,Destroys adapter object,AllocateCommonBuffer,Allocates a common buffer,FreeCommonBuffer,Releases a common buffer,AllocateAdapterChannel,Reserves adapter and map registers,FlushAdapterBuffers,Flushes intermediate data buffers after transfer,FreeAdapterChannel,Releases adapter object and map registers,FreeMapRegisters,Releases map registers only,MapTransfer,Programs one stage of a transfer,GetDmaAlignment,Gets address alignment required for adapter,ReadDmaCounter,Determines residual count,GetScatterGatherList,Reserves adapter and constructs scatter/gather list,PutScatterGatherList,Releases scatter/gather list,5,传输策略选择,1,。如果设备有总线主控能力,那么它就有访问主存的必要硬件部件,因此只需要告诉它几个基本事实,如从哪开始,需要传输多少单位的数据,是输入操作还是输出操作,等等。可以向硬件设计者咨询或者,固件,程序员咨询以得到细节部分,否则只能参考许多硬件级的说明文档。,6,传输策略选择,2。一个有分散/聚集(scatter/gather)能力的设备可以在自身与不连续的物理内存区之间传输大块数据。设备的分散/聚集能力对软件十分有利,它可以避免对具有连续页帧的大块的内存的需求。页可以被简单地锁定在所在的物理内存,只要把内存地址告诉设备就可以进行。,7,传输策略选择,3。如果设备不是总线主控设备,那么需要使用计算机主板上的系统DMA控制器。这种形式的DMA传输被称为从属DMA(slave DMA)。与ISA总线连接的系统DMA控制器对所能访问的物理内存和一次传输的数据量会有些限制。EISA总线的DMA控制器去掉了这些限制。在Windows 2000中,不必知道硬件具体插入到哪种类型的总线,因为系统自动参考这些不同的限定。,8,传输策略选择,4,。通常,,DMA,操作将包括编程硬件映射寄存器或操作前后的数据复制。如果设备需要连续地读写数据,我们不希望在每次,I/O,请求中都做这两步,这将大大地降低处理速度,在,某些情况,下也是不能接受的。因此,应该分配一个公用缓冲区(,common buffer,),设备和驱动程序可以在任何时间同时访问这个缓冲区。,9,说明,在涉及DMA传输的过程中策略的选择是第一步也是最重要的一步。,不仅需要参考硬件,还要参考可能的软件需求(主控,从属,包,通用缓冲区),尽管这四种因素的相互影响会产生许多种不同的结果,但执行的步骤中有许多共同的特征。如下图显示了一次传输过程:,10,执行DMA传输,基于包,(packet-based),的,DMA,传输。在这种方式中,将使用,IRP,携带的数据缓冲区来传输一定量的数据。,为了简单,让我们假设面对当前最普通的情况:一个基于,PCI,的总线主控设备并且没有分散,/,聚集能力。,为什么简单?,下面按照程序编写的通常步骤来详细说明,DMA,的过程,11,缓冲方式,当创建设备对象时,通常指定使用,Direct,缓冲方式,即设置,DO_DIRECT_IO,标志。或者在定义,CTL_CODE,时指定,direct input,或者,direct output,方式。,因为调用的,MapTransfer,函数需要一个,MDL,作为参数 ,这种方式会在每一个,IRP,的,MdlAddress,保存描述用户缓冲区的,MDL,12,创建和销毁适配器对象,在处理start device的pnp请求时,我们除了要取得IO,内存,中断资源外,还要创建一个适配器对象(adapter obiect)。,在处理stop device请求时,除了释放映射的IO,内存资源,断开中断的连接外,还要销毁适配器对象。,例如:,DMA.doc,13,和其它资源区别,前面讲过的IO,内存,和中断资源,我们都回在一个CmResourceTypeXxx类型的case子句中获得,这里不需要CmResourceTypeDma类型的case子句,因为设备是总线主控方式,硬件本身包含有执行DMA传输所必须的所有电路逻辑,所以系统没必要赋予设备DMA资源。,14,获取DMA通道,为了初始化一个,I/O,操作,,StartIo,例程必须首先调用适配器对象的,AllocateAdapterChannel,例程以获取适配器对象。该函数的一个参数是,AdapterControl,例程的地址,,I/O,管理器将在获取操作完成后调用这个例程。,AllocateAdapterChannel,函数的准备和调用过程:,DMA.doc,15,AllocateAdapterChannel何时完成,AllocateAdapterChannel,做什么?,等待,DMA,控制器,和映射寄存器可用,主控,从属,支持映射寄否?,当,DMA,控制器,和映射寄存器都可用时,,AllocateAdapterChannel,调用,AdapterControl,例程,16,调用AdapterControl,AllocateAdapterChannel最终将调用驱动程序提供的AdapterControl例程(在DISPATCH_LEVEL,就象StartIo例程一样)。,AdapterControl例程的两个任务:,17,AdapterControl例程的两个任务,第一,应该调用适配器对象的,MapTransfer,例程以便为,I/O,操作的第一阶段准备映射寄存器和其它系统资源。如果是总线主控设备,,MapTransfer,将返回一个代表传输第一阶段开始点的逻辑地址。这个逻辑地址可能会与,CPU,的物理内存地址相同,但也可能会不同。所需要知道的就是该地址就是编程设备硬件的正确地址。,第二个任务是执行与“通知设备这个物理地址”操作中涉及的任何设备相关的操作步骤,然后开始操作设备硬件:,DMA.doc,18,DPC,中断通常都发生在传输启动后的很短一段时间后,并且Isr只做很少的事情,比如判断中断类型清除中断状态位,之后,Isr通常都请求一个DPC来处理传输第一阶段的完成,并开始下一个操作。,DMA.doc,19,使用分散集中列表进行传输,如果硬件支持分散,/,聚集能力,那么系统可以更容易地处理设备的,DMA,传输。分散,/,聚集能力允许设备传输所涉及的页在物理内存中不连续。,这种设备的,StartDevice,例程在创建适配器对象上使用与前面讨论的同样的方式,除了,ScatterGather,标志应该设为,TRUE,。,传统方法在安排一个涉及分散,/,聚集功能的,DMA,传输时,几乎等同于前面段“执行,DMA,传输”中的基于包的例子。唯一不同之处是它需要为传输的每个阶段多次调用,MapTransfer,。每次调用后都会得到分散,/,聚集列表中的一个包含物理地址和长度的数组元素。,当循环完成时,可以使用设备专用的方法把分散,/,聚集列表发送到设备,然后开始传输。,DMA.doc,20,使用GetScatterGatherList,这种方法不用手动构建Scatter/gather 列表,DMA.doc,在决定使用GetScatterGatherList 前,以下的前提需要满足:,程序运行在2000及以后系统,98/ME不支持这个函数,如果不确定或者为了程序的兼容性,应该使用传统的循环获取Scatter/gather 列表,21,使用系统DMA控制器,即,slave DMA,所有,slave,设备必须共享有限的,DMA,通道数量。,AllocateAdapterChannel,在这种共享情形中具有真正意义,因为一次只能有一个设备可以使用特定的通道,可以在,PnP,管理器发送的,I/O,资源列表中找到一个,CmResourceTypeDma,资源。,大部分方面和总线,Master,设备类似,,一些差别,22,使用公用缓冲区,通常应该在StartDevice中,在创建适配器对象后分配公用缓冲区:,DMA.doc,23,使用公用缓冲区的,Slave,模式,DMA,传输,必须为接收数据的虚拟地址创建一个,MDL,。,MDL,的实际目的是在最后调用,MapTransfer,中占用一个参数,这个,MDL,指名不需要任何数据复制。,通常应该在,StartDevice,函数中,紧接着分配公用缓冲区之后创建该,MDL,为了执行一个输出操作,首先应通过某些手段,(,如一个明确的内存复制,),使公用缓冲区中包含有要发往到设备的数据,在输入操作的结尾,应该把数据从公用缓冲区复制到其它某个地方,24,使用公用缓冲区的,Slave,模式,DMA,传输,其它部分和进行基于包的,DMA,传输类似:调用,AllocateAdapterChannel,,该函数调用驱动程序提供的适配器控制例程,这个例程又调用,KeFlushIoBuffers(,如果分配了一个可被高速缓冲的缓冲区,),,最后调用,MapTransfer,。,DPC,例程将调用,FlushAdapterBuffers,和,FreeAdapterChannel,函数。,唯一要注意的是应该指定公用缓冲区的,MDL,来代替读写,IRP,携带的,MDL,25,使用公用缓冲区的,master,模式,DMA,传输,如果设备是总线主控模式,那么在分配公用缓冲区后就没有必要调用,AllocateAdapterChannel,、,MapTransfer,、,FreeMapRegisters,函数。,因为,AllocateCommonBuffer,也能保留必要的映射寄存器。每个总线主控设备都有一个适配器对象,该对象不与其它设备共享,因此不必等待。由于拥有可以在任何时间都能访问缓冲区的虚拟地址,又由于设备的总线主控能力允许使用物理地址,(,由,AllocateCommonBuffer,返回,),访问该缓冲区,所以没有额外的工作需要做。,这是所有形式的,DMA,传输中最简单的。,26,使用公用缓冲区的注意事项,在运行系统中,物理上连续的内存是十分稀有的,有时根本得不到这样的内存,除非在系统启动的早期请求这样的内存。内存管理器为了满足请求会对内存页进行重排列,但它的尝试十分有限,并且这个过程会推迟,AllocateCommonBuffer,的返回。有时尝试会失败,所以必须能够处理这种失败情况。公用缓冲区不仅与稀有的物理内存页相关,而且还与其它设备争用映射寄存器。,27,释放公用缓冲区,在处理停止设备时需要释放公用缓冲区,(*pdx-AdapterObject-DmaOperations-FreeCommonBuffer),(,pdx-AdapterObject,pdx-paCommonBuffer,pdx-vaCommonBuffer,FALSE,);,28,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!