学习windows驱动(回顾1)

来源:互联网 发布:西门子200plc编程电缆 编辑:程序博客网 时间:2024/05/17 03:21

温故而知新。

到现在为止,我们来回想一下已经接触了哪些windows驱动的知识点。
首先,windows驱动是什么?
驱动是一个软件,负责承上启下,
承上就是与用户程序打交道,提供接口给用户使用;
启下就是跟系统内核和硬件打交道,负责读写操作硬件。
那么,驱动是怎么实现的?
需要掌握哪些概念和知识呢?
万丈高楼平地起,
说明基础是很重要的,
因此,我们首先得从基础开始。

在windows系统环境下,驱动的开发依赖于windows系统环境提供的手段。

windows系统内核提供了接口供程序员开发驱动。
windows驱动开发是一种windows系统开发,
驱动可以算是内核的一部分。

因此对windows内核就要有一定的了解。
同时,现在流行的windows驱动开发是使用WDF来开发。

因此要熟练WDF框架开发驱动。

WDF是一种驱动开发框架,它使得程序员开发驱动更容易了,
在WDF框架里,程序员根据自己的需要填写自己的代码就可以实现驱动。

WDF里使用了对象的概念,WDF对象成员包括:驱动对象、设备对象、内存对象、队列对象、IO请求对象、文件对象等。

程序是看不到WDF对象的,可以通过句柄获得对象的操作。
句柄是一个指针,因为程序员没法接触真正的对象,可以通过句柄来代替对象。

每个对象都有个引用计数,用于管理对象的生命周期,当引用计数为0时,对象就会被释放销毁。

设备上下文空间,是设备对象的一个扩展,设备上下文空间是用户定义的数据结构,在创建设备对象时,就开辟了这个上下文空间,到时用户可以操作上下文空间来管理自己驱动关键变量。

WDF编程接口类似(Property/Method/Event)接口模型。
事件对于WDF驱动来说非常重要,WDF驱动,除了入口函数DriverEntry,其它的都无外乎事件处理函数,以及事件处理函数调用的子函数。
事件函数实际上就是回调函数,一般把它叫做“事件回调”。

使用WDF来开发驱动,就要学习使用WDF提供的DDI接口,
WDF提供的DDI接口形如“WdfXXX()”。

使用WDF不仅要了解熟悉框架逻辑,还要了解DDI接口。

这些都是基础,这些需要在开发使用中一点一点慢慢练习掌握。

WDF的对象是具体的对象,有父子对象,父对象与子对象关系有规定,不可以随意组合的。

对象是一种会被哄抢的资源,因此需要为它设置同步机制。
框架对象内部包含了同步锁机制。

可以通过WdfObjectAcquireLock 和WdfObjectReleaseLock实现手动同步。一般方便起见,使用自动同步机制。

采用自动同步,先是确定同步范围,有两种可选同步范围:
设备同步(WdfSynchronizationScopeDevice)、队列同步(WdfSynckronizationScopeQueue)。

当选择设备同步时,设备上的队列和文件对象,同时只能有一个对象的一个事件回调被执行;当选择队列同步,在同一时刻,每个队列只有一个事件回调被执行。如果不选同步范围,就是不同步(WdfSynchronizationScopeNone),这种情况下,同一时刻可以有任意个事件回调被执行。
自动同步的原理是:
设备同步,所有下属队列或文件对象的事件回调执行前,必须申请设备对象同步锁;队列同步,队列中事件执行前,必须申请此队列对象的同步锁。如果不选同步范围,就不必申请同步锁。

采用自动同步,其次是设定运行级别,运行级别决定事件回调最高可在哪个中断级别(IRQL)上执行。可选的值有PASSIVE_LEVEL(WdfExecutionLevelPassive)和更高级别DISPATCH_LEVEL(WdfExecutionLevelDispatch)。通过WdfExecutionLevelDispatch设置子设备从父设备继承这个属性,这个属性对应结构体WDF_OBJECT_ATTRIBUTES的ExecutionLevel变量。
对于设备对象的PNP/Power事件回调,驱动总是实施同步调用。

驱动对象是框架中第一个被创建的对象,最后一个被删除的对象。
当驱动对象不存在了以后,其它子对象也就不存在了。
当获得驱动对象,就可以遍历获得它的所有子对象。
可以通过WdfGetDriver函数获得驱动对象句柄。
PNP类驱动,驱动对象负责注册EvtDriverDeviceAdd事件回调,这个事件回调相当于WDM中的AddDevice函数,用于建立设备栈。

非PNP类驱动,一般通过驱动对象注册EvtDriverUnload事件回调,相当于WDM里的DriverUnload函数,保存在驱动对象里的系统资源一般借助EvtDriverUnload事件回调释放。资源泄露在内核里是非常严重的错误。
可以为驱动初始化一个事件跟踪(WPP机制)。

在驱动入口DriverEntry函数里创建驱动对象。
根据驱动类型,DriverEntry入口函数有不同写法:设备驱动、过滤驱动和纯软件驱动。纯软件驱动是不与任何硬件打交道,在一个内核里提供接口服务的软件模块。

设备驱动一定要注册EvtDriverAdd事件回调;过滤驱动根据类型,如果过滤设备栈属于某个物理设备,也应注册EvtDriverDeviceAdd事件回调;否则,驱动加载后,将不起作用。

纯软件驱动不可以注册EvtDriverDeviceAdd事件回调;过滤驱动根据类型,如果过滤的设备栈不属于物理设备(如文件驱动设备栈),则也不可注册此事件回调;否则,返回无效参数错误。

0 0