驱动开发基础知识

news2024/11/26 10:29:18

文章目录

    • `记录驱动开发前的知识储备工作`
  • 一、驱动开发环境搭建
  • 二、驱动开发框架(重点:WDF框架)
    • 1、前世今生
      • (1)Vista简介
      • (2)发展历史
    • 2、基于框架的驱动程序的 WDM
      • (1)驱动程序类型
      • (2)驱动程序堆栈
      • (3)设备堆栈
      • (4)I/O请求数据包
    • 3、 WDF的优势
  • 三、完整的驱动签名流程(Win10)
  • 四、Windows的GUID
  • 五、总结

记录驱动开发前的知识储备工作

一、驱动开发环境搭建

参考我这篇:WIN10 驱动开发环境从0搭建

二、驱动开发框架(重点:WDF框架)

1、前世今生

(1)Vista简介

Windows Vista是微软公司2006年11月30日正式发布的操作系统,2017年4月11日,微软正式终止对Windows Vista的一切支持。

(2)发展历史

最早使用——>VXD (已经废弃)
Vista支持——>WDM
Vista及其以后——>WDF: 意为Windows Driver Foundation,此模型比WDM更先进、合理,将WDF中关于电源、PnP等一些复杂的细节由微软实现,所以在此模型上开发驱动会比以前要简单。

2、基于框架的驱动程序的 WDM

(1)驱动程序类型

  • 总线驱动程序:
    总线驱动程序检测插入到父级总线中的子设备,并报告这些子设备的特征,从而支持 I/O 总线;
  • 功能驱动程序:功能驱动程序控制设备总线的I/O 操作;
  • 筛选器驱动程序:筛选器驱动程序接收、审查并可能修改在用户应用程序驱动程序之间或在各驱动程序之间传输的数据。

(2)驱动程序堆栈

在 Windows 操作系统中,WDM 驱动程序按名为驱动程序堆栈 的垂直调用序列分层。在 I/O 请求已通过操作系统的 I/O 管理器之后,堆栈中位于最顶层的驱动程序通常会从用户应用程序接收这些请求。较低层的驱动程序通常与计算机硬件通信。
简单的驱动程序堆栈包括位于堆栈底部的总线驱动程序,该驱动程序用于处理总线特定的 I/O 操作,并枚举与总线相连的子设备。总线驱动程序上方通常有一个或多个设备特定的功能驱动程序。这些功能驱动程序处理与总线相连的设备的 I/O 操作。筛选器驱动程序可位于功能驱动程序上方,也可以位于总线驱动程序和功能驱动程序之间。正在运行的系统具有多个驱动程序堆栈,可支持不同类型的设备。

(3)设备堆栈

每个驱动程序堆栈都支持一个或多个设备堆栈。设备堆栈是一组根据 WDM 定义的 DEVICE_OBJECT 结构创建的设备对象。
每个设备堆栈都表示一台设备。每个驱动程序为其每台设备创建一个设备对象,并将每个设备对象附加到设备堆栈。当插入和拔出设备以及每当重新引导系统时,将创建和删除设备堆栈。
总线驱动程序在检测到已插入或拔出子设备时会通知即插即用 (PnP) 管理器。作为响应,PnP 管理器要求总线驱动程序为连接到父设备(即总线)的每台子设备创建一个物理设备对象 (PDO)。PDO 随即成为设备堆栈的底部。
接下来,PnP 管理器加载功能驱动程序和筛选器驱动程序以便支持每台设备(如果尚未加载这些驱动程序),然后 PnP 管理器会调用这些驱动程序,使每个驱动程序都可以创建一个设备对象并将该设备对象添加到设备堆栈的顶层。功能驱动程序创建函数设备对象 (FDO),筛选器驱动程序创建筛选器设备对象(筛选器 DO)。
I/O 管理器将 I/O 请求发送到设备的驱动程序时,它会将该请求传递到创建设备堆栈中的顶层设备对象的驱动程序。

(4)I/O请求数据包

I/O 管理器通过创建 I/O 请求数据包 (IRP),将应用程序的 I/O 请求发送到驱动程序。IRP 可包含执行 I/O 操作(如读/写操作)的请求或执行 I/O 控制 (IOCTL) 操作(如返回状态)的请求。此外,PnP 管理器还会创建表示驱动程序必须执行的 PnP和电源管理操作的 IRP,并将这些 IRP 发送到驱动程序。
I/O 管理器通常在用户应用程序请求读取或写入操作时创建读取或写入 IRP。I/O 管理器将 IRP 传递到位于驱动程序堆栈顶层的驱动程序,该驱动程序或者为该请求提供服务,或者将该请求传递到下一层驱动程序。某些请求会传输到堆栈底部,而某些请求则完全由较高层的驱动程序处理。
每当驱动程序接收 IRP 时,该程序还会接收一个指向某个设备对象的指针,该设备对象表示必须处理该操作的设备。因此,驱动程序堆栈中的驱动程序使用设备对象确定应将特定请求传输到插入的哪个设备。
基于框架的驱动程序通常不会直接访问 IRP。内核模式驱动程序框架将表示读取、写入和设备 I/O 控制操作的 WDM IRP 转换为驱动程序在 I/O 队列中接收的框架请求对象。框架在内部处理 PnP 和电源管理 IRP,并使用事件回调函数向驱动程序发送 PnP 和电源事件通知。

3、 WDF的优势

以WDM为基础进行建模和封装,降低开发难度,改动如下:

  1. WDF面向对象;
  2. 内核模式和用户模式的驱动程序,都采用WDF的基类,内核模式派生的对象是“KMDF”框架,用户模式派生的对象是“UMDF”;
  3. WDF将即插即用和电源管理封装在对象内,成了缺省(默认)行为;
  4. WDM驱动程序中,一方面要处理硬件,另一方面要处理驱动程序操作系统内核的交互。现在WDF则将驱动程序与操作系统内核之间进行了分离,驱动程序与操作系统交互工作交给框架内封装的方法(函数)完成;
  5. 两种模式的驱动程序(KMDF、UMDF)都使用同一环境进行构建,这一环境称为WDK:(Windows Driver Kit)集成驱动程序开发系统;
  6. 效率不变。

三、完整的驱动签名流程(Win10)

  1. 证书选择:
    (1)购买一个EV代码签名的证书;
    (2)网上随便下载一个;

  2. 数字签名工具下载:下载地址
    在这里插入图片描述

  3. 导入证书
    在这里插入图片描述

  4. 设置规则:签哪个证书

  5. 添加规则
    在这里插入图片描述

四、Windows的GUID

全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符,用于唯一标识一个任意计算机。GUID 的总数达到了2128(3.4×1038)个,所以随机生成两个相同GUID的可能性非常小,但并不为0。所以,用于生成GUID的算法通常都加入了非随机的参数(如时间),以保证这种重复的情况不会发生。

  • 程序:
#include <objbase.h>
#include <stdio.h>
//--生成GUID
const char* newGUID()
{
	static char buf[64] = {0};
	GUID guid;
if (S_OK == ::CoCreateGuid(&guid))
{
	_snprintf(buf, sizeof(buf)
	, "{%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}"
	, guid.Data1
	, guid.Data2
	, guid.Data3
	, guid.Data4[0], guid.Data4[1]
	, guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5]
	, guid.Data4[6], guid.Data4[7]
);
}
	return (const char*)buf;
}
int main(int argc, char* argv[])
{
	//--COM
	CoInitialize(NULL);
	printf(newGUID());
	printf("\n");
	//--COM
	CoUninitialize();
	return 0;
}

五、总结

  1. WinDGB是唯一内核驱动调试器,但不必须;
  2. WDF比WDM好;
  3. 编译出来的sys文件是PE(可移植可执行)文件格式;
  4. 驱动开发需要为每个函数指定分页内存/非分页内存,分页内存仅低中断级别的例程可以访问的,而非分页内存则是各个中断级别的例程都可以使用的;
  5. 关注warnning;
  6. 关注回调函数;
  7. 进行必要的失败处理;
  8. INF文件中的信息来确定哪个为函数驱动程序、哪个为筛选器驱动程序。安装后,PnP管理器通过注册表确定设备的驱动程序。

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

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

相关文章

linux(1.nginx基础 2.使用Nginx负载均衡及动静分离)

一.nginx基础 目录 1. Nginx使用场景2. Nginx中的进程 2.1 Nginx中的多进程模型2.2 多进程模式的优点&#xff1a;2.3 缓存3. Ngnix的负载均衡策略 3.1 轮询法3.2 加权轮询3.3 原地址哈希3.4 最小连接数法3.5 Fair3.6 url_hash3. Nginx配置文件4. Nginxtomcat 集群示例 4.1 下…

c++学习-STL常用函数

第八部分-STL常用函数 5.1 常用遍历算法 5.1.1 for_each 5.1.2 transform 5.2 常用查找算法 5.2.1 find 5.2.2 find_if 5.2.3 adjacent_find 面试题中如果出现查找相邻重复元素&#xff0c;记得用stl中的adjacent_find算法 5.2.4 binary_search 5.2.5 count 5.2.6 count_if 5.…

【双十一特辑】爱心代码(程序员的浪漫)-李峋

前言 最近《点燃我温暖你》中李峋的爱心代码超级火&#xff0c;看着特别心动&#xff0c;这不&#xff0c;光棍节快到了&#xff0c;给兄弟们教学一波爱心代码&#xff0c;赶在双十一前表白&#xff0c;让这个双十一不在是孤单一个人&#xff01;目录 前言 C语言简易爱心代码…

final 关键字 —— 限制继承、限制虚函数重写

final 关键字有两个作用&#xff0c;一个是限制继承&#xff0c;一个是限制重写。 目录 1、限制继承 (1) 基类的构造函数设为私有 (2) 基类类名后面加上 final 关键字修饰 2、限制虚函数重写 1、限制继承 限制继承有两种方式&#xff0c;一种是将基类的构造函数设为私有&am…

谷粒商城-基础篇(详细流程梳理+代码)

文章目录前言一、项目环境搭建1.1、安装virtualbox以及vagrant1.2、Docker安装MySQL与Redis1.3、前后端开发工具统一配置1.4、Git工具安装与配置1.5、Gitee创建仓库与IDEA导入1.6、构建微服务模块1.7、编写.gitignore文件&#xff08;忽略上传gitee文件配置&#xff09;1.8、数…

【云原生之K8s】 K8s资源控制及探针检查

文章目录一、资源限制1.资源限制的使用2.request资源&#xff08;请求&#xff09;和limit资源&#xff08;约束&#xff09;3.Pod和容器的资源请求和限制4.官方文档示例5.资源限制实操5.1 编写yaml资源配置清单5.2 释放内存&#xff08;node节点&#xff0c;以node1为例&#…

昨晚,我用python帮学妹P证件照自拍,然后发现。。。

人生苦短&#xff0c;我用Python前因后果先上效果准备工作证件照尺寸调整证件照背景调整各种背景颜色图片完整代码结尾最后前因后果 事情是这样的 晚上我正在聚精会神写代码&#xff08;打游戏~&#xff09; 突然&#xff0c;收到学妹给我发来的消息 还有一张自拍照 而且是…

基于stm32单片机的超声波测距显示倒车雷达提醒报警系统Proteus仿真

资料编号&#xff1a;145 下面是相关功能视频演示&#xff1a; 145-基于stm32单片机的超声波测距显示倒车雷达提醒报警系统Proteus仿真&#xff08;源码原理图仿真论文&#xff09;设计内容 本次嵌入式课程设计综合实验的内容为倒车测距系统。以proteus keilU5为模拟硬件基础…

Android studio中控件TextView学习

1、TextView 基础属性 layout_ width; 组件的宽度layout. _height: 组件的高度id: 为TextView设置- -个组件idtext; 设置显示的文本内容textColor: 设置字体颜色textStyle: 设置字体风格&#xff0c;三个可选值: n normal(无效果)&#xff0c;bold(加粗)&#xff0c; italic(斜…

Springboot @Async 失效的坑

异步应用场景 为了提高接口的响应性能&#xff0c;当业务非常复杂的情况下&#xff0c;可以将一部分跟业务关联性不是特别强的逻辑进行异步处理。如日志记录、短信发送、增加积分等。通常而言会将此类业务逻辑通过异步的方式进行处理&#xff0c;从而加快接口的响应速度&#…

【HMS Core】集成多种HMS Core服务,让APP成为旅行小助手

1 介绍 Duration: 5:00 总览 旅行者能够使用该应用在华为地图上搜索附近名胜景点、游玩去处或是附近ATM、餐馆和医院等。 服务场景描述 Tourism应用通过集成机器学习服务的地标识别能力&#xff0c;能够提供旅行过程所有必要的信息&#xff0c;还可以识别图片中的地标建筑。…

[Python]字符串常用操作与方法

前言 系列文章目录 [Python]目录 文章目录前言1. 字符串的常用操作1.1 格式化输出1.1.1 %1.1.1.1 语法1.1.1.2 字符串格式操作符(%)的格式化符号%c&#xff1a;以字符的形式格式化输出整数或长度为1的字符串%r&#xff1a;将数据格式化为供解释器读取的形式%s&#xff1a;将数据…

一文带你精通Git

一文带你精通git回顾git对象树对象提交对象重新认识git 基本命令git 高层命令分支&#xff08;特别重要&#xff09;分支冲突&分支合并git 存储git 后悔药远程分支和团队协作远程仓库冲突回顾 博主之前直接已经写过了git的相关基础博客了,老铁可以自行去查看。本篇文章的目…

【分割链表】

目录&#xff1a;前言一、题目描述二、算法思想&#xff08;一&#xff09;值交换1、题目解析2、代码实现&#xff08;二&#xff09;重构链表1、题目解析2、代码实现总结前言 大家好&#xff0c;今天我们来了解一下leetcode中比较简单的单链表问题。 一、题目描述 题目描述如…

MySQL事务隔离级别

MySQL的四种隔离级别 读未提交读提交可重复读串行化 隔离级别可以通过MySQL的视图来实现。 读未提交 读未提交是一个事务仅修改了数据但还未提交时&#xff0c;本次修改可以便可被其他事务查询到变更后的值。读未提交隔离级别下&#xff0c;其他事务进行查询时&#xff0c;直…

新手小白学JAVA 日期类Date SimpleDateFormat Calendar

Date日期类 类 Date 表示一个特定的瞬间&#xff0c;精确到毫秒 1.1 Date的构造函数 Date() 分配一个 Date 对象&#xff0c;以表示分配它的时间&#xff08;精确到毫秒&#xff09; Date(long date) 分配一个 Date 对象&#xff0c;表示自从标准基准时间起指定时间的毫秒数 标…

【Java实验五】继承与多态

一、实验一 对于父类的含参构造方法&#xff0c;子类必须通过super调用&#xff0c;重写父类的构造方法 设计一个应用程序要求&#xff1a; 设计一个表示二维平面上点的类Point&#xff0c;包含有表示坐标位置的protected类型的成员变量x和y&#xff0c;获取和设置x和y值的publ…

SpringBoot项目的创建(三):手动创建一个Maven工程,然后引入SpringBoot所需的dependency来完成 (不需联网,但复杂)

SpringBoot项目的创建1.配置Maven环境。2.创建一个新的maven项目3.创建出来的目录结构4 继承springboot父项目5.添加Spring Boot Maven插件6.添加spring和web模块的依赖7.创建入口类8.添加代码测试1.配置Maven环境。 在以maven方式创建Spring Boot项目之前&#xff0c;需要先确…

交换网络基础

交换网络基础网络基础交换机的转发行为数据帧分类交换机MAC地址表ping包来回过程VLAN概念&#xff1a;VLAN接口类型ICMP返回值网络基础 路由器&#xff1a;基于3层路由表转发交换机&#xff1a;基于2层MAC地址表转发&#xff0c;数据帧转发 交换机的转发行为 泛洪&#xff1…

Buffer Pool Size of Total RAM No data

1.问题描述 1)问题现象 通过prometheus监控mysql实例和服务器&#xff0c;使用grafana做可视化展示&#xff0c;grafana 中添加 7362 号dashboard 作为mysql看板&#xff0c;添加 11074 号dashboard 作为主机看板。但是添加后查看 MySQL Overview 看板发现 Buffer Pool Size …