最近做了一款pci的视频采集卡(H264压缩),由于数据传输量比较大,所有想采用dma来传输数据,刚开始感觉很简单,后来感觉还是困难重重。

DMA 验证监控直接内存访问 (DMA) 的使用。随着 Windows 的开发,DMA 例程已经发生改变,因此许多驱动程序错误地使用了 DMA 调用。而且,一些驱动程序作者尝试完全绕过 HAL DMA 子系统。这种做法可能将隐含的错误引入驱动程序。

驱动程序验证程序的 DMA 验证选项尝试捕获常见的 DMA 错误。与 !dma 内核调试程序扩展一起使用时,可以验证驱动程序是否在以适当的方式使用 DMA。

此驱动程序验证程序选项也称为“HAL 验证”。驱动程序验证程序生成的一些错误消息可能使用此术语。

此驱动程序验证程序选项仅在 Windows XP 及更高版本中提供。

不同类型的 DMA

DMA 是一种机制,硬件设备通过该机制可以与内存互传数据,而无需使用处理器。设置传输需要使用处理器,并且在设备完成传输时会向处理器发送信号。此系统的优势在于,在执行 DMA 传输时处理器可以执行其他任务。

Windows 2000 及更高版本中使用了若干类型的 DMA。

通用缓冲区 DMA

当系统可以分配硬件和软件都能访问的单个缓冲区时,将执行通用缓冲区 DMA。驱动程序负责对缓冲区的同步访问。不缓存内存,这使得驱动程序执行此同步更方便。在设置通用缓冲区之后,驱动程序和硬件都可以直接写入缓冲区中的地址,而无需 HAL 的任何干预。

数据包 DMA

如果存在一个现有的单一缓冲区,并且必须映射该缓冲区才能供硬件使用,将执行数据包 DMA。使用数据包 DMA 的示例是从内存到磁盘传输文件。在此情况下使用通用缓冲区 DMA 是一种浪费,因为需要将文件传输到通用缓冲区,硬件才能将其传输到磁盘。这时可借助 HAL;它可以为驱动程序提供所需的信息,帮助硬件查找内存中的实际缓冲区。此操作比较复杂,因为需要涉及一些例程跨不同体系结构执行操作。

分散/集中 DMA

分散/集中 DMA 是一次设置若干数据包 DMA 传输的快捷方法。例如,如果通过网络传输数据包,网络数据包的每部分都会添加自己的标头(TCP、IP、以太网等)。这些标头都从内存中的不同位置分配。在此情况下,使用分散/集中 DMA 可以节省时间,该方法通过将批处理请求发送到 HAL 来映射每个标头和数据段以供硬件访问。此方法无需在数据包的每个部分上调用数据包 DMA 例程,而是对每个例程调用一次,并让 HAL 负责分别映射它们。

Note  分散/集中功能并不意味着设备可以使用分散/集中例程。分散/集中功能在设备描述中引用一个标志,该标志指示设备可以从内存中的任何区域读写,而不只是特定范围。

系统 DMA

系统 DMA 的执行方式是在主板上对系统 DMA 控制器进行编程以直接执行传输。只有 ISA 卡可以使用系统 DMA。

DMA 验证的效果

当 DMA 验证处于活动状态时,驱动程序验证程序检测 DMA 例程的错误使用情况,其中包括:

  • DMA 内存缓冲区过载或不足(这些错误可能由硬件或驱动程序造成)。

  • 双重释放通用缓冲区、适配器通道、映射注册表或分散/集中列表。

  • 由于不释放通用缓冲区、适配器通道、映射注册表、分散/集中列表或适配器而导致内存泄漏。

  • 一次对一个适配器提供多个适配器通道。

  • 尝试使用已被释放且不复存在的适配器。

  • 不刷新适配器缓冲区。

  • 一个适配器的未处理引用计数太多。

  • 在可分页缓冲区上执行 DMA(在开始 DMA 传输之前应锁定所有缓冲区)。

  • 在具有已损坏标志的 MDL 上执行 DMA。

  • 在第一个 MDL 之前或第一个 MDL 结束之后引用无效的系统地址,或者使用的传输长度超过 MDL 缓冲区并超过 MDL 中的页面边界。

  • 一次分配的映射注册表太多,或者分配的映射注册表超过允许的最大数。

  • 对映射注册表进行双重映射。

  • 注册表仍在映射时就尝试释放映射注册表。

  • 尝试刷新尚未映射的映射注册表。

  • 在映射注册表文件末尾尝试刷新的字节数太多。

  • 在不正确的 IRQL 上调用 DMA 例程。

  • 将 Null 值 DMA_ADAPTER 传递到 HAL 例程。

  • 在地址未包含在 MDL 中时,将该地址和 MDL 传递到 HAL 例程。

  • 尝试映射已经映射的地址范围。

  • 尝试刷新尚未映射的缓冲区。

  • 尝试为传输映射零长度缓冲区。

  • 调用过时函数 HalGetAdapter(所有驱动程序必须改用
    IoGetDmaAdapter)。

驱动程序验证程序监控驱动程序的行为,如果发生其中的任意冲突,将发送错误检查 0xE6。有关错误检查参数列表,请参阅 Bug Check 0xE6 (DRIVER_VERIFIER_DMA_VIOLATION)。

何时使用 DMA 验证?

直接使用 DMA 的所有驱动程序(通过调用 HAL DMA 例程)都应使用 DMA 验证测试。

此外,还应测试微型端口驱动程序,因为它们通常间接使用 DMA(通过调用使用 DMA 的端口驱动程序)。

DMA 验证还可以作为检测内存损坏的有效方法,因为它可以检测到是驱动程序还是硬件设备造成了 DMA 缓冲区溢出。

监控 DMA 验证

内核调试程序扩展 !dma 可用于显示大量的 DMA 信息。它可以显示有关每个 DMA 适配器行为的各种详情。Windows 程序包的调试工具文档中提供了
!dma 扩展的详细示例以及有关调试程序扩展的常规信息。有关详细信息,请参阅 Windows 调试

激活此选项

通过使用驱动程序验证程序管理器或 Verifier.exe 命令行,可以为一个或多个驱动程序激活 DMA 验证功能。使用命令行

  • 在命令行,DMA 验证选项由 Bit 7 (0x80) 表示。要激活 DMA 验证,请使用标志值 0x80 或将 0x80 添加到该标志值。例如:

    
    
    1. verifier /flags 0x80 /driver MyDriver.sys

    该功能将在下次启动时激活。

    在 Windows Vista 及更高版本的 Windows 上,还可以通过将 /volatile 参数添加到此命令激活和停用 DMA 验证而不用重启计算机。例如:

    
    
    1. verifier /volatile /flags 0x80 /adddriver MyDriver.sys

    此设置将立即生效,但在关闭或重启计算机时将丢失。有关详细信息,请参阅 使用易失性设置

    DMA 验证功能还包括在标准设置中。例如:

    
    
    1. verifier /standard /driver MyDriver.sys
  • 使用驱动程序验证程序管理器
    1. 启动驱动程序验证程序管理器。在“命令提示符”窗口中键入 Verifier
    2. 选择“创建自定义设置(供程序开发人员使用)”,然后单击“下一步”
    3. 选择“从一个完整的列表选择单个设置”
    4. 选择(选中)“DMA 验证”

    DMA 验证功能还包括在标准设置中。要使用此功能,请在驱动程序验证程序管理器中单击“创建标准设置”

如何在WDM中使用xp系统的DMA用来处理数据的更多相关文章

  1. 对 hiren bootcd 15.2 中的 XP 系统作了汉化, 同时支持中文输入法。提供下载

    对 hiren bootcd 15.2 中的 XP 系统作了汉化, 同时支持中文输入法.提供下载 对该PE 中的 XP 系统作了汉化, 由于一个 中文字库 就要 10M 多:加之原系统过于精简,对中文 ...

  2. 汉化 Hirens.BootCD 中的 XP 系统

    汉化 Hirens.BootCD 中的 XP 系统 1. 在中文版 XPSP3 镜像中提取所需的文件 原系统为没有作 server pack 的 Windows XP Professional ,在W ...

  3. 如何在VirtualBox虚拟机中安装XP系统? 转

    关闭VM (windows 7 )的方法, 使用 退出 保持状态 开启VM (windows 7 )的方法, 选择启动 ######Iissue 1 网络连接不上,可以重新初始化 网络连接. #### ...

  4. VirtualBox虚拟机中安装XP系统

    Windows XP是一款经典的操作系统,同时也是一款很老的操作系统,不过尽管如此,还是有一批用户在使用XP系统,所以发行一些软件的时候还是要测试在XP系统中能否运行,这时候我们就可以借助Virtua ...

  5. 如何在VMware中安装Linux系统

    这篇文章主要讲述如何在VMware12中安装RHEL6.9Linux操作系统 步骤一: 打开VMware软件,在主页中点击创建新的虚拟机或者点击左上角文件,在列表中点击新建虚拟机,如图: 步骤二: 点 ...

  6. 如何在linux中搭建JEECMS系统

    本人正在进行jeecms二次开发,但因win7系统中的Tomcat无法使用,就想起在linux下安装,但去jeecms的官方网站,没有给出在linux下安装的方法,确实苦恼,经过一天的研究,终于大功告 ...

  7. 如何在Virtualbox中对Ubuntu系统根分区扩容

    转载:             参见博客: https://blog.csdn.net/LEON1741/article/details/56494797 前在Virtualbox中安装了一个Ubun ...

  8. 如何在VMwareWorkstation中安装Ubuntu系统

    文章更新于:2020-03-17 注:如果安装之后重启停留在Write through,则关闭客户机,将 ISO 镜像换为物理光驱,或取消勾选开机连接.再次开机即可正常进入系统. 文章目录 一.安装环 ...

  9. VirtualBox安装及使用说明和虚拟机安装XP系统图文教程

    virtualbox是一款开源的虚拟机软件,它能够支持多种操作系统的安装如:Solaris.Windows.DOS.Linux.OS/2 Warp.BSD等系统作为client操作系统,而且最新版本号 ...

随机推荐

  1. .NET 异步多线程,Thread,ThreadPool,Task,Parallel,异常处理,线程取消

    今天记录一下异步多线程的进阶历史,以及简单的使用方法 主要还是以Task,Parallel为主,毕竟用的比较多的现在就是这些了,再往前去的,除非是老项目,不然真的应该是挺少了,大概有个概念,就当了解一 ...

  2. XML系列之--Linq操作带属性的XML(四)

    关于XML,之前解析过电文收发方面的,就是所谓的带表头.前缀(命名空间)SOAP格式.这次需求是解析一个xml的模板(xls内容),然后填充数据,最后保存.需要时可转换xls.pdf等文件.关于这种带 ...

  3. GitHub For Beginners: Commit, Push And Go

    In Part 1 of this two-part GitHub tutorial, we examined the main uses for GitHub and bega5n the proc ...

  4. [HTTP] PHP 实现 HTTP Server 原理

    单进程服务器简陋版: <?php /** * Single http server. * * Access http://127.0.0.1:8081 * * @license Apache-2 ...

  5. JS声明变量的写法

    学习JS时候,声明变量是必须的,(虽然在没有声明变量的情况下,对某一变量赋值后, js自动认为已进行声明,但为了严谨,建议还是要进行声明)声明方式有传统的 var a: var b: var c: 也 ...

  6. 玩转spring boot——简单登录认证

    前言 在一个web项目中,某些页面是可以匿名访问的,但有些页面则不能.spring mvc提供了HandlerInterceptor接口来应对,只需要重写preHandle方法便可以实现此功能.那么使 ...

  7. Java多线程基础(二)

    信号量Semaphore,类似于锁的功能,用于多线程中对一组资源的控制. acquire方法用于尝试获取一个资源,未获取前将一直等待.release用于释放一个资源,release的前提是已经获得了一 ...

  8. Python中Template使用的一个小技巧

    Python中Template是string中的一个类,可以将字符串的格式固定下来,重复利用. from string import Template s = Template("there ...

  9. docker dead but pid file exists

    CentOS 6安装docker 报docker dead but pid file exists 执行 yum install epel-release yum install docker-io ...

  10. CentOS 7 安装Java 1.8

    携程的Apollo配置中心服务端[https://github.com/ctripcorp/apollo/wiki]推荐的Java版本是:1.8+, 本文介绍如何在CentOS上安装java 1.8. ...