windows驱动开发-DMA技术(一)

DMA(Direct Memory Access)是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依于 CPU 的大量中断负载,否则CPU 需要从设备缓存中把每一页的数据复制到缓存中,然后把它们再次写入到新的地方,在这个过程中中,CPU 需要一直控制这个过程。 DMA 则是由DMA控制器直接将数据从一个地址空间复制到另外一个地址空间。

由于现在电脑基本上统一了内部总线,所以所有的DMA都是PCI总线来进行的,故了解了PCI总线是如何处理DMA的,那也就了解了DMA是如何进行的。

如果调试过PCI总线,那么会发现,DMA是以一个内存页面为单位进行的,每次DMA传输的总是内存页面的整数倍,PCI会先将windows的内存地址写入到DMA控制器,然后向寄存器写入数据来启动DMA传输,但是,这一切操作已经被windows封装起来了,在windows中,我们会直接分配适配器对象,使用适配器来操作DMA。

适配器对象

任何使用直接 I/O 和 DMA 的驱动程序都必须创建适配器对象。 适配器对象表示 DMA 控制器通道或端口,或总线-主设备。

两种最低级别驱动程序必须使用适配器对象:

  • 使用系统 DMA 控制器的设备驱动程序。 此类设备称为 从属设备 ,称为“使用系统 (或 从属) DMA”。
  • 用作总线-主适配器的设备驱动程序。 此类设备与系统仲裁以使用 I/O 总线,因此使用总线主 DMA。

驱动程序通常位于设备扩展中,为指向适配器对象的指针提供存储。

为了执行 DMA 传输,使用这些 DMA 方法的设备驱动程序通常具有AdapterControl 例程,并调用系统提供的用于操作适配器对象的支持例程。 不需要 AdapterControl 例程的 (驱动程序包括 那些使用Scatter/Gather DMA 的驱动程序,以及那些使用 common-buffer、bus-master DMA.)就是使用总线主DMA的驱动。

作为设备启动操作的一部分,处理 DMA 操作的驱动程序调用 I/O 管理器,后者又调用特定于平台的 HAL 来创建一组适配器对象。 在任何 Windows 平台上,适配器对象集通常包括以下对象的适配器对象:

  • 从属设备连接到的每个系统 DMA 控制器通道或端口。
  • 计算机中的每个总线主 DMA 设备。
获取/释放适配器

在设备启动时,使用系统或总线主 DMA 的驱动程序会调用 IoGetDmaAdapter 来获取指向适配器对象的指针,并确定每个传输操作可用的映射寄存器的最大数目。 当驱动程序调用 IoGetDmaAdapter 时,I/O 管理器反过来会调用 HAL 以获取特定于平台的必要信息。

驱动程序必须在调用 IoGetDmaAdapter 时,在系统定义的DEVICE_DESCRIPTION结构中提供某些信息。 驱动程序必须使用 RtlZeroMemory 初始化 DEVICE_DESCRIPTION 结构,并在其中设置值。

所需数据包括有关驱动程序设备功能的信息,例如设备是否为总线主机、设备是否具有散点/收集功能,以及设备一次可以传输多少字节的数据, (MaximumLength) 。

所需的设备说明数据还包括特定于平台的信息,例如总线主设备驱动程序控制的特定于平台和系统分配的总线编号。 驱动程序可以通过调用 IoGetDeviceProperty 来获取此信息。

DEVICE_DESCRIPTION结构包括一些可能与某些 DMA 设备或驱动程序无关的字段。 例如,WDM 驱动程序中不使用 BusNumber 字段。 每个驱动程序应为相关结构成员提供值,并应将所有其他成员的值设置为零。

当请求必须分解为两个或更多个 DMA 操作时,除非设备能够等待系统 DMA 控制器重新编程,否则从属设备的驱动程序不应在 ScatterGather 字段中传递 TRUE。

IoGetDmaAdapter 返回指向适配器对象的指针和特定于平台或特定于设备的值,该值指示适配器对象可用于每个 DMA 传输操作的映射寄存器数。

返回的适配器对象包含三个可供驱动程序访问的字段:

  • 版本号 (版本)
  • 大小 (大小)
  • 指向 DmaOperations(DMA_OPERATIONS) 结构的指针

DMA_OPERATIONS 结构包含指向驱动程序在其设备上执行 DMA 操作时必须使用的函数的指针表, 函数只能通过此数据结构中的指针访问,驱动程序无法直接按名称调用它们。 (请注意,这些例程替换以前版本的 Windows NT 中支持的 HalXxx 例程。为了确保旧驱动程序的兼容性,Wdm.h 和 Ntddk.h 头文件提供具有过时名称的宏,但新驱动程序应始终通过 data structure.)

映射寄存器的数量可能因设备以及平台而异。 通常,HAL 根据以下条件分配多个映射寄存器:

如果可能,HAL 将返回一个值,该值比传输 MaximumLength 字节所需的映射寄存器数多一个,如驱动程序对 IoGetDmaAdapter 的调用中所述。

否则,HAL 将返回一个较小的值,该值对于特定平台来说尽可能大。

换句话说,HAL 通常为每个驱动程序提供足够的映射寄存器,以最大化其设备的 DMA 吞吐量,但 HAL 在某些 Windows 平台上可以返回较小的值。 无法保证驱动程序将获取它请求的映射寄存器数,因此驱动程序应始终检查返回的值。

任何 DMA 设备驱动程序都必须为 IoGetDmaAdapter 返回的适配器对象指针和 NumberOfMapRegisters 值提供存储。 此指针是指向系统提供的用于 DMA 的支持例程的必需参数。 由于其中许多支持例程必须在 IRQL = DISPATCH_LEVEL调用,因此驱动程序分配的存储必须是驻留的。 大多数 DMA 驱动程序在 设备扩展中提供必要的存储。 但是,如果驱动程序也使用控制器对象或驱动程序分配的非分页池,则存储可以位于 控制器 扩展中。

驱动程序完成所有 DMA 操作后,会调用 PutDmaAdapter 以释放适配器对象。

AdaptControl例程要求

AdapterControl 例程必须至少执行以下操作:

1. 保存输入 MapRegisterBase 值以及驱动程序为当前 IRP 执行一个或多个 DMA 传输操作所需的任何其他上下文信息。 每个 DMA 传输操作完成后,驱动程序必须将 MapRegisterBase 值传递给 FlushAdapterBuffers 。

2. 返回相应的 IO_ALLOCATION_ACTION 值:

  • 如果设备是从属设备,则为 KeepObject,因此驱动程序使用系统 DMA。
  • 如果设备是总线主机,则 DeallocateObjectKeepRegisters,因此驱动程序使用基于数据包的总线主 DMA。

根据驱动程序的设计,其 AdapterControl 例程也可以在返回控制权之前执行以下操作:

  • 1. 确定传输在其设备上的起始位置;
  • 2. 根据由于传输的开始位置而对其设备的任何限制,计算可能的传输大小;一般情况下,调用 AllocateAdapterChannel 的例程负责确定是否必须将转移请求拆分为部分传输,因为针对每个 DMA 传输操作可用的 NumberOfMapRegisters 存在任何特定于平台的限制;
  • 3. 设置有关设备 (或控制器) 扩展中的每个传输请求的任何驱动程序维护的状态;例如,AdapterControl 例程可能会使用 CustomTimerDpc 例程的入口点调用 KeSetTimer,该例程超时驱动程序的 DMA 传输操作;
  • 4. 使用在 Irp-> MdlAddress传递的 MDL 指针调用 MmGetMdlVirtualAddress,以获取传输开始的索引,适合传递给 MapTransfer;
  • 5. 调用 MapTransfer 以设置系统 DMA 控制器或获取总线-主设备的物理到逻辑地址映射。
  • 6. 使用通过调用 KeSynchronizeExecution 调用的 SynchCritSection 例程对驱动程序的设备进行编程,以便执行传输操作。 

如果传输请求要求驱动程序执行一系列部分传输操作以满足当前 IRP,则驱动程序的 DpcForIsr 或 CustomDpc 例程通常负责对设备进行重新编程,以便执行后续传输操作。 每个传入传输 IRP 仅调用 一次 AdapterControl 例程。

完成当前传输 IRP 的驱动程序例程(通常是 DpcForIsr 或 CustomDpc 例程)也负责通过分别调用 FreeAdapterChannel 或 FreeMapRegisters 来释放系统 DMA 控制器或总线-主适配器。 此驱动程序例程应在完成其最后一次部分传输操作时尽快发出相应的调用,以便从属 DMA 设备的驱动程序可以分配系统 DMA 控制器,或者总线-主驱动程序可以立即开始处理下一个传输 IRP。

IRP_MN_START_DEVICE 请求的驱动程序调度例程必须为 AdapterControl 例程执行以下操作:

  • 通过填写 DEVICE_DESCRIPTION结构并 调用 IoGetDmaAdapter,为设备的 DMA 功能设置适配器对象。
  • 保存 IoGetDmaAdapter 返回的适配器对象指针和 NumberOfMapRegisters。
  • IoGetDmaAdapter 返回的平台特定最大 NumberOfMapRegisters 或驱动程序设备的传输功能(以限制性更强者为准)确定驱动程序是否必须拆分给定的传输请求并在其设备上执行多个 DMA 操作来满足该 IRP。

返回的适配器对象指针、驱动程序的 AdapterControl 例程的入口点、表示当前 IRP 的目标设备的 DeviceObject 指针、指向已为 AdapterControl 例程设置的区域的上下文指针,以及 NumberOfMapRegisters 值(可能小于较小传输请求的最大可能数目)必须在调用中传递给 AllocateAdapterChannel。 通常,驱动程序的 StartIo (或可能是 ControllerControl) 例程在调用 AllocateAdapterChannel 之前在 Context 处设置区域。

在系统中,可能以两种不同的方式使用DMA,基于数据包的系统DMA、基于公用缓冲区的系统DMA。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/6025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jenkins 部署springboot 项目

文章目录 持续集成指定tag发布 基于Jenkins拉取GitLab的SpringBoot代码进行构建发布到测试环境实现持续集成 基于Jenkins拉取GitLab指定发行版本的SpringBoot代码进行构建发布到生产环境实现CD实现持续部署 持续集成 为了让程序代码可以自动推送到测试环境基于Docker服务运行…

PostgreSQL日期和时间相关函数

PostgreSQL日期和时间相关函数 时间类型获取当前时间时间加减格式转换相关函数 示例: --- 提取7天前的日期 SELECT (current_date - interval 7 day)::date as start_date-- 明天的日期 SELECT (current_date interval 1 day)::date as end_date-- 当年的第一天 SELECT DATE_…

【Transformer系列(4)】基于vision transformer(ViT)实现猫狗二分类项目实战

文章目录 一、vision transformer(ViT)结构解释二、Patch Embedding部分2.1 图像Patch化2.2 cls token2.3 位置编码(positional embedding) 三、Transformer Encoder部分(1) Multi-head Self-Attention(2) encoder block 四、head…

uni-app(优医咨询)项目实战 - 第2天

学习目标: 掌握WXML获取节点信息的用法 知道如何修改 uni-ui 扩展组件的样式 掌握 uniForm 表单验证的使用方法 能够在 uni-app 中使用自定义字体图标 一、uni-app 基础知识 uni-app 是组合了 Vue 和微信小程序的相关技术知识,要求大家同时俱备 Vue 和原生小程序的开发基础。…

Python中的else魔法:不止是if

写在前面 提到else,肯定会对应一个if。虽然在许多编程语言中这都是正确的,但 Python 却不是。Python 的else语句有着更广泛的用途。从循环语句后的else到try-except块后的else…,本文将探讨else语句鲜为人知的功能。 1. if-else else 可以与 if 一起使用,这也是最常用的…

程序包的实例和删除

目录 程序包的实例 我们创建一个程序包,内容包含上一章所创建的存储过程和函数 程序包的删除 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 程序包的实例 下面就通过具体范例来演示程序包的使用。 我们…

pyqt 按钮常用格式Qss设置

pyqt 按钮常用格式Qss设置 QSS介绍按钮常用的QSS设置效果代码 QSS介绍 Qt Style Sheets (QSS) 是 Qt 框架中用于定制应用程序界面样式的一种语言。它类似于网页开发中的 CSS(Cascading Style Sheets),但专门为 Qt 应用程序设计。使用 QSS&am…

高可用系列三:事务

都成功或者都失败是事务目标,实际中往往会采用最终一致、最大努力一致和不一致时人工介入策略。 评估事务,通常会根据业务特点,考虑对于事务相关业务之间所需的时效性、依赖联系因素,框定事务可用方案,并结合事务实现…

【论文阅读笔记】Frequency Perception Network for Camouflaged Object Detection

1.论文介绍 Frequency Perception Network for Camouflaged Object Detection 基于频率感知网络的视频目标检测 2023年 ACM MM Paper Code 2.摘要 隐蔽目标检测(COD)的目的是准确地检测隐藏在周围环境中的目标。然而,现有的COD方法主要定位…

信息系统项目管理师0083:项目管理的重要性(6项目管理概论—6.2项目基本要素—6.2.2项目管理的重要性)

点击查看专栏目录 文章目录 6.2.2项目管理的重要性 6.2.2项目管理的重要性 项目管理就是将知识、技能、工具与技术应用于项目活动,以满足项目的要求。通过合理地应用并整合特定的项目管理过程,项目管理使组织能够有效并高效地开展项目。 有效的项目管理能…

Rust个人学习之Rust操作Mysql数据库

Rust 使用 mysql 的 crate 进行 mysql 的连接操作,特进行记录。 写在前面 如果想使用 mysql 需要在 CargoToml 文件中增加 mysql 的引用 [dependencies] chrono "0.4" mysql "*"连接数据库 数据库信息如下: 字段数据数据库地…

可靠的智能组网系统有哪些?

天联是一种可靠的智能组网解决方案,在现今复杂网络环境下具备明显的优势。本文将介绍天联组网以及其所带来的诸多优势。 天联组网的优势 天联组网具有以下优势,使其成为一种可靠的智能组网方案: 无网络限制:天联组网能够解决复杂…

Tire 字典树、前缀树

字典树(又称单词查找树或Trie树)是一种树形结构,它是哈希树的变种,通常用于统计、排序和保存大量的字符串(但不仅限于字符串)。字典树在搜索引擎系统中常用于文本词频统计。它的主要优点在于能够利用字符串…

每日一题(力扣213):打家劫舍2--dp+分治

与打家劫舍1不同的是它最后一个和第一个会相邻,事实上,从结果思考,最后只会有三种:1 第一家不被抢 最后一家被抢 2 第一家被抢 最后一家不被抢 3 第一和最后一家都不被抢 。那么,根据打家劫舍1中的算法 我们能算出在i…

excel办公系列-图表元素及其作用

Excel图表元素及其作用 Excel图表由各种元素组成,每个元素都有其特定的作用,可以帮助我们更清晰地传达数据信息。下面将介绍Excel图表中常见的一些元素及其作用,并附上相关截图。 原始数据 月份 网站访问量 (万次) 销售额 (万…

FIFO Generate IP核使用——Data Counts页详解

在Vivado IDE中,当看到一个用于设置数据计数选项的选项卡时,需要注意的是,尽管某些选项值可能因为当前的配置而显示为灰色(即不可选或已禁用),但IDE中显示的有效范围值实际上是你可以选择的真实值。即使某些…

opencv t函数

在OpenCV中&#xff0c;t函数通常用于转置矩阵&#xff08;Transpose&#xff09;。这意味着矩阵的行和列互换位置。 在C中&#xff0c;使用OpenCV库进行矩阵转置的代码如下所示&#xff1a; #include <opencv2/opencv.hpp> #include <iostream>int main() {// 创…

《十二》Qt各种对话框之FileDialog文件对话框及QMessageBox 消息对话框

QFileDialog 对话框 选择打开一个文件 若要打开一个文件&#xff0c;可调用静态函数 QFileDialog::getOpenFileName()&#xff0c;“打开一个文件”按钮的响应代码如下&#xff1a; void Dialog::on_btnOpen_clicked() { //选择单个文件QString curPathQDir::currentPath()…

基于React实现B站评论区

今天继续来学习一下React&#xff0c;使用React实现B站评论区&#xff0c;如下图&#xff1a; 在使用React开发类似B站评论区的功能时&#xff0c;我们需要考虑以下几个关键点来构建一个基本的评论系统&#xff1a; 1. 设计组件结构 首先&#xff0c;设计组件结构是关键。至少…

Unity Animation--动画剪辑

Unity Animation--动画剪辑 动画剪辑 动画剪辑是Unity动画系统的核心元素之一。Unity支持从外部来源导入动画&#xff0c;并提供创建动画剪辑的能力使用“动画”窗口在编辑器中从头开始。 外部来源的动画 从外部来源导入的动画剪辑可能包括&#xff1a; 人形动画 运动捕捉…