windows驱动开发-WDM框架(一)

在前面的文章中解释过,NT5.0之后windows确定了新的架构Windows Driver Model (WDM),在Vista之后又推出了Windows Driver Framework(WDF),这两个都属于驱动程序框架,那么它们的之间的关系是怎样的?

WDF是对WDM进行的封装,是为更快、更简单的进行驱动开发进行的二次封装,故WDM里面的所有概念对于WDF都是适用的,所以理解内核架构可以学习WDM,开发驱动程序则使用WDF框架。

驱动程序类型

有三种类型的 WDM 驱动程序:总线驱动程序、功能驱动程序和过滤驱动程序。

总线驱动程序是用于控制单个 I/O 总线设备,提供总线功能,检测并报告连接到总线的子设备;
功能驱动程序用于控制单个设备,提供每种设备中具体某个设备的功能控制;
过滤驱动程序用于过滤设备、或者总线的 I/O 请求;

驱动程序开发人员必须了解不同类型的 WDM 驱动程序并知道自己正在编写哪种类型的驱动程序,这一点非常重要, 例如,驱动程序是否处理每个PNP的IRP以及如何处理此类 IRP 取决于所编写的驱动程序的类型。

过滤驱动英文描述为Filter Driver,这个翻译并不准确,但是非常形象,它一般用于对功能驱动或者总线驱动的I/O请求进行处理,这个过程就像“过滤”一样。

在后续的内核源代码和驱动分析解读中,我们可以看到为什么会有驱动程序类型的划分以及它们是为什么这么划分的。

内核组件和功能

内核组件是概念性而非实体,例如I/O管理器,并不是有一个IoManager.dll的动态库,而是将内核代码中关于I/O管理的部分代码抽象出来,称为I/O管理器。下面是一些开发中涉及的内核组件:

对象管理器: 用于管理所有的内核对象,它负责管理对象的创建和销毁、保留对象命名空间数据库以跟踪对象信息、跟踪分配给每个进程的资源、跟踪特定对象的访问权限以提供安全性、管理对象的生存期,并确定何时自动销毁对象以回收资源空间;

内存管理器:管理操作系统的物理内存。 此内存主要以随机访问内存的形式 (RAM) 。

内存管理器负责以虚拟和动态方式管理内存的分配和解除分配、支持内存映射文件、共享内存和写入时复制;

线程管理器: 它主要处理进程中的所有线程的执行。 无论有一个处理器还是多个处理器,都必须在进行驱动程序编程时非常小心,以确保进程的所有线程都被设计为无论处理线程的顺序如何,驱动程序都将正常运行。

如果来自不同进程的线程尝试同时使用同一资源,则可能会出现问题。 Windows 提供了几种技术来避免此问题。 确保不同进程中的线程不触及同一资源的技术称为“同步” 。

注意:由于线程调度器位于DPC链表的最底层,故驱动程序很可以中断线程调度器,所有某些情况下,驱动程序本身也是线程调度器的一部分。

I/O管理器: 计算机由各种设备组成,这些设备提供输入和输出 (外部世界的 I/O) 。 设备驱动程序提供设备和操作系统之间的软件连接。 I/O 管理器管理应用程序和设备驱动程序提供的接口之间的通信。 由于设备的运行速度可能与操作系统不匹配,因此操作系统和设备驱动程序之间的通信主要通过 I/O 请求数据包 (IRP) 完成。 这些数据包类似于网络数据包或 Windows 消息数据包。 它们从操作系统传递到特定驱动程序,以及从一个驱动程序传递到另一个驱动程序。

I/O 系统提供称为堆栈的分层驱动程序模型,这和编程语言中的堆栈是不一样的驱动程序的堆栈看起来如下:

图中的1为总线驱动、2是总线驱动的过滤驱动、3称之为功能驱动的下沿过滤驱动、4则是功能驱动、5为功能驱动的上沿驱动。

在windows设备栈中,每个驱动只能看到自己的上级驱动和下级驱动,故每个驱动都可以自己是过滤驱动,认为上面的是功能驱动,下面的是总线驱动!这一点是通过前向指针和后向指针来实现的!

驱动程序必须及时发送和接收 IRP 才能使整个堆栈高效运行,这一点非常重要。 如果驱动程序是堆栈的一部分,并且未正确接收、处理和传递信息,则驱动程序可能会导致系统崩溃。

I/O 管理器有两个子组件:即插即用管理器和电源管理器。

PNP管理器: 即插即用 (PnP) 是硬件技术和软件技术的组合,使电脑能够在将设备添加到系统时识别。 使用 PnP 时,系统配置可以在用户很少或无需输入的情况下进行更改。 例如,插入 U 盘时,Windows 可以检测 U 盘并自动将其添加到文件系统。 但是,若要执行此操作,硬件必须遵循某些要求,驱动程序也必须遵循。

PNP总线会管理所有支持PNP的总线,但它建立在非PNP总线的基础之上,例如,PCI总线上的USB或者1394总线分别支持PNP,但是PCI线没办法支持PNP。
电源管理器:Windows 使用电源管理技术来降低电脑(尤其是电池供电的笔记本电脑)的功耗。 例如,Windows 计算机可以处于睡眠或休眠状态。 计算机设备的复杂电源管理系统已经发展,因此,当计算机开始关闭或降低功耗时,连接的设备也可以以适当的方式关闭,以便不会丢失任何数据。 但这些设备需要一个警告,指示电源状态正在更改,它们可能还需要成为通信循环的一部分,该循环告诉控制设备等待,直到它们可以正确关闭。

Windows 内核模式电源管理器管理所有支持电源状态更改的电源状态的有序更改。 这通常通过控制其他设备的复杂设备堆栈来完成。 每个控制设备称为 节点 ,并且必须有一个驱动程序,该驱动程序可以通过设备堆栈上下处理电源状态更改的通信。

如果要编写可能受电源状态更改影响的驱动程序,则必须能够在驱动程序代码中处理以下类型的信息:

  • 系统活动级别;
  • 系统电池电量;
  • 当前要关闭、睡眠或休眠的请求。
  • 用户操作,例如按下电源按钮。
  • 控制面板设置,例如以 10% 的电池电量自动关闭。

电源管理器与策略管理结合使用来处理系统和设备的电源管理,并协调电源事件,生成、处理、完成电源管理相关的IRP;电源管理器收集更改电源状态的请求,确定设备必须更改其电源状态的顺序,然后发送相应的 IRP 以告知相应的驱动程序 (这些更改反过来可能会告知子设备进行更改) ; 策略管理器监视系统中的活动,并将用户状态、应用程序状态和设备驱动程序状态集成到电源策略中。

驱动程序例程

每个内核模式驱动程序都是围绕一组系统定义的标准驱动程序例程构造的。 内核模式驱动程序通过调用系统提供的驱动程序支持例程处理在这些标准例程中 I/O 请求数据包。

在这里,例程和回调函数等同,不过由于驱动基本是按照微软提供的例子来编写的,所以也会被称为例程,驱动程序本身是一个DLL,但是和常规DLL不一样的是,它只对外到处一个接口。

所有驱动程序,无论它们在附加驱动程序链中的级别如何,都必须具有一组基本的标准例程才能处理 IRP。 驱动程序是否必须实现其他标准例程取决于驱动程序是控制物理设备还是分层在物理设备驱动程序上,以及基础物理设备的性质。 控制物理设备的最低级别驱动程序比更高级别的驱动程序具有更多的所需例程,后者通常将 IRP 传递给较低级别的驱动程序进行处理。

标准驱动程序例程可以分为两组:每个内核模式驱动程序必须实现和可选实现,具体取决于驱动程序类型和它在设备堆栈中的位置。

下面是必须实现的例程

例程名称具体功能备注
DriverEntry初始化驱动程序及其驱动程序对象驱动入口
AddDevice初始化设备并创建设备对象设备新增
Dispatch对I/O请求的处理
Unload驱动卸载

驱动卸载

下面是可选实现的例程

例程名称具体功能
Reinitialize初始化失败后用于重新初始化的例程
StartIo开始处理I/O请求
Interrupt中断例程
DeferredProcedureCallsDPC过程
SynchCritSection同步对驱动程序数据的访问
AdapterControlDMA适配器控制
IoCompletionI/O完成例程
CancelIO取消I/O请求
CustomTimerDpc定时器DPC

如何判断需要实现哪些例程?这取决于具体的需求,例如,在1394设备中,我们需要考虑DMA的问题,如果在虚拟设备中,是不需要考虑硬件中断的问题的。所以我们先谈论必须实现的例程,然后在后续的案例分析中,再讨论每中驱动需要实现的可选例程。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux--基础IO(上)

目录 1. 文件的边角知识 1.1 文件是什么? 1.2 文件是怎么打开的? 1.3 进程与文件 进程与文件的关系 2. 重温c语言文件接口 2.1 打开文件的方式 2.2 读写文件接口的重温 2.2.1 写文件 2.2.2 读文件 3. 系统文件I/O 3.1 系统接口 3.2 系…

OpenVINO安装教程 npm版

从 npm Registry安装 OpenVINO™ 工具套件的英特尔发行版 请注意: 仅提供 JavaScript API 专用于所有主要操作系统的用户:Windows、Linux 和 macOS (所有 x86_64 / ARM64 架构) macOS 仅支持 CPU 推理 系统要求软件要求 Window…

Python --- 在python中安装NumPy,SciPy,Matplotlib以及scikit-learn(Windows平台)

在python中安装NumPy,SciPy,Matplotlib以及scikit-learn(Windows平台) 本文是针对(像我一样的)python新用户所写的,刚刚在电脑上装好python之后,所需的一些常见/常用的python第三方库/软件包的快速安装指引。包括了这些常用安装包…

【AI自媒体制作】【AI工具】天工AI

链接:天工AI 目前chatgpt3.5已经免费,很多AI平台都可以进行一定层度的白嫖,对于个人开发者是一件好事,有些会员就没必要充值了。 天工AI是比较常见的AI工具了,可以识别图片、智能问答、生成图片等。当然对于一个程序员…

【Linux】git

大家好,我是苏貝,本篇博客带大家了解Linux的编译器-gcc/g,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 1.安装git2.在gitee上创建仓库3.首次配置4.下载仓库到本地5.三板斧6.git log7.gi…

【数据结构】二叉爆炸

【数据结构】二叉爆炸 按照惯例整点抽象的,贴上这篇博客的名字由来: 言归正传,本篇博客介绍二叉树的构造方式、前中后序遍历、层序遍历以及代码随想录中二叉树章节的相关题目: 代码随想录 (programmercarl.com) 一、啥是二叉树 …

HDMI to TYPE-C芯片|HDMI2.0转TYPE-C转接器方案|CS5802设计方案|ASL CS5802

CS5802输入端可以是1080P、4K30、4K60HZ这三种规格,输出的接口可以是TYPE-C信号接口,或者是TYPE-C信号接口,输入端HDMI由4路信号组成,支持1.62Gbps、2.7Gbps、5.4Gbps链路速率。内置可选SSC功能可降低EMI的干扰状况。 ASL CS5802芯片概述: 符合HDMI规范…

04节-51单片机-数码管模块

1.静态数码管显示 LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件 下图展示了数码管的线路连接 数码管的连接方式分为,公共端,共阴极和共阳极连接: 多个数码管共用引…

IMUGNSS 误差状态卡尔曼滤波器(ESKF)的离散时间的ESKF 运动方程与运动过程

IMU&GNSS 误差状态卡尔曼滤波器(ESKF)的离散时间的ESKF 运动方程与运动过程 离散时间的ESKF 运动方程ESKF的运动过程 离散时间的ESKF 运动方程 名义状态变量的离散时间运动方程可以写为:(不用考虑噪声,噪声在误差…

701强连通分量(python)

看见题目知道时间复杂度不超过(mlogm)。 这题用强连通分量 Tarjan 算法,强联通:对于任意两个点u和v,u可以到达v,v也可以到达u。这题需要考虑有重边,自环,同样别忘记可能会有两个点u…

[阅读笔记20][BTX]Branch-Train-MiX: Mixing Expert LLMs into a Mixture-of-Experts LLM

这篇论文是meta在24年3月发表的,它提出的BTX结构融合了BTM和MoE的优点,既能保证各专家模型训练时的高度并行,又是一个统一的单个模型,可以进一步微调。 这篇论文研究了以高效方法训练LLM使其获得各领域专家的能力,例如…

idea项目启动异常:Command line is too long.

项目场景: 提示:这里简述项目相关背景: idea中启动项目报错: 解决方案 在idea 的运行配置中,修改enviroment下的shorten command line 为jar manifest 注: 有时shorten command line 可能不是默认存在的…

Linux实验一:NAT、桥接方式的验证

实验名称:在虚拟机中安装RHEL7,验证NAT、桥接上网方式 实验结果: 创建虚拟机 NAT模式 自动获取IP 手动配置IP 桥接模式 自动获取IP 手动配置IP 总结和分析:

我与C++的爱恋:类和对象(四)

​ ​ 🔥个人主页:guoguoqiang. 🔥专栏:我与C的爱恋 ​ 朋友们大家好!本篇是类和对象的最后一个部分。 一、static成员 声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之…

[阅读笔记29][AgentStudio]A Toolkit for Building General Virtual Agents

这篇论文是24年3月提交的,提出了一个用于agent开发的全流程工具包。 作者提到目前agent开发主要有两个阻碍,一个是缺乏软件基础,另一个是缺乏在真实世界场景中进行评估。针对这两个阻碍,作者涉及了一个开发工具包,包括…

使用立创EDA打开JSON格式的PCB及原理图

一、将PCB和原理图放同一文件夹 并打包成.zip文件 二、打开嘉立创EDA并导入.zip文件 文件 -> 导入 -> 嘉立创EDA标准版/专业版 三、选择.zip文件并选择 “导入文件并提取库” 四、自定义工程路径 完成导入并转换为.eprj文件 五、视频教学 bilibili_使用立创EDA打开JSO…

NLP预训练模型-GPT-3

ChatGPT GPT-3是OpenAI开发的一个自然语言处理(NLP)预训练模型。GPT代表“生成式预训练变换器”(Generative Pretrained Transformer)。GPT-3是GPT系列的第三代模型,是一种采用了深度学习技术的强大语言模型&#xff…

驱动开发-windows驱动设计目标

驱动程序和应用程序不一样的,由于其直接运行于windows r0级,故对于开发有更多和更严格的标准,一般会有以下一些常见的设计目标: 安全性、可移植性、可配置性、 可被中断、多处理器安全、可重用 IRP、 支持异步 I/O这些是基本目标。 1. 安全…

【Numpy】对于 Numpy 中 Axis 的理解

文章目录 前言理解轴的两个角度在维度变化方向上计算降维 示例剖析写在最后 前言 Numpy 是 Python 中一个常用科学计算库,常用来表示向量、矩阵以及多维度数组。在 Numpy 中多对某一个维度(轴)进行相应的操作,这一点经常出错。今…

再论图像变化和频率的关系。

我之前是做了一些探讨,但是没说清楚,现在再看这个问题。 我先提出这个问题。 以以为点列为例,先写成傅里叶级数的形式,不过这里不是三角函数形式,而是指数形式,是一样的。 对f(n)求导,就可以观…