WDM驱动程序设计之基础知识篇
(作者:苏金国2000年11月09日 13:26)
WDM(Win32 Driver Model),即Win32驱动程序模型,是Microsoft力推的全新驱动程序模式,旨在通过提供一种灵活的方式来简化驱动程序的开发,在实现对新硬件支持的基础上减少并降低所必须开发的驱动程序的数量和复杂性。
除了通用的平台服务和扩展外,WDM还实现了一个模块化的、分层次类型的微型驱动程序结构(见图1)。类型驱动程序实现了支持通用总线、协议或设备类所需的功能性接口。类型驱动程序的一般特性是为逻辑设备的命令设置、协议和代码重用所需的总线接口实现标准化提供必要的条件。WDM对标准类接口的支持减少了Windows 95和Windows NT所需的设备驱动程序的数量和复杂性。Windows 2000也引入了WDM驱动程序构架。虽然WDM目前实际应用还不多,但是相信在不久的将来,在Windows平台上,WDM将成为21世纪主流的驱动模式。
(1)Windows 操作系统
Windows 98不像Windows 2000那样非常有规律的处理I/O操作(见图2)。应用程序调用Win32 API,而且仅当读硬盘文件、通信端口和有WDM驱动程序的设备时才调用相应的 Win32 API,对其它设备必须使用特定的机制。全部Windows 2000的内核模式I/O操作都使用一个共同的数据结构(IRP),Windows 98不具备这一特点,应用程序请求更达不到内核模式。不过,当谈到WDM驱动程序的时候,Windows 98内部的体系结构与Windows 2000是非常相似的。系统模块(NTKERN.VxD)包括大量Windows NT内核支持函数,它完成请求包IRPs的创建,把它们发送给WDM驱动程序,从这一点考虑,两个环境之间不存在差异。
图1 WDM中设备对象和驱动程序的分层(2)WDM特性
模块化的WDM体系结构中灵活统一的接口,使操作系统可以动态地配置不同的驱动程序模块来支持特定的设备。一个典型的驱动程序堆栈由通用设备、协议及特定协议和特定总线的微型驱动程序联接的总线类驱动程序构成。动态构造WDM驱动程序堆栈是实现即插即用设备支持的关键。
WDM服务使实现一个用于Windows NT和Windows 95快速反应的模型成为可能。WDM提供了多个执行优先级,包括核心态和非核心态线程、IRQ级别和被延缓的程序调用(DPC)。所有的WDM类和微型驱动程序都作为核心态(第0层)的特权级线程(不会被CPU调度程序中断)执行。32个IRQ级可以被用于区分硬件中断服务的优先级。对于每个中断,DPC被排入队列等到被启用中断的IRQ服务例程完成后再执行。DPCs通过有效的减少中断被禁止的时间,使系统对中断的响应获得了很大的提高。对于使用多处理器的基于x86的PC系统,在WindowsNT下对中断的支持是以Intel的多处理器规范1.4版本为基础的。
对于流媒体应用程序,WDM在核心态提供了快速反应的接口来处理I/O流。WDM的流接口是通过标准的WDM类接口提供出的。
图2 Windows 98体系结构(3)WDM工作原理
WDM支持USB、IEEE 1394、ACPI等全新的硬件标准。而且以往在两个平台上同时运行时需要编写两个截然不同的驱动程序,现在只需要编写一个WDM驱动程序就可以了。WDM驱动程序也是分层的,即不同层上的驱动程序有着不同的优先级,而Windows 9x下的VxD则没有此结构。另外,WDM还引入了功能设备对象FDO(Functional Device Object)与物理设备对象PDO(Physical Device Object)两个新类来描述硬件,一个PDO对应一个真实硬件。
另外值得注意的是,一个硬件只允许有一个PDO,却可以拥有多个FDO,在驱动程序中直接操作的不是硬件而是相应的PDO与FDO。在Ring-3与Ring-0通讯方面,系统为每一个用户请求打包形成一个IRP结构,将其发送至驱动程序,并通过识别IRP中的PDO来区别是发送给哪一个设备的。另外,在驱动程序的加载方面,WDM不通过驱动程序名称识别,而是通过一个128位的GUID来实现驱动程序的识别。
(4)WDM与其它驱动程序的比较
写WDM和其它模式驱动程序基本上是相同的,代码中的主要区别在于如何创建设备。在WDM驱动程序中,即插即用(PnP)管理器告知何时向系统添加一个设备,或者从系统删除设备。PnP管理器使用安装的INF文件查找新设备的正确驱动程序;而其它模式驱动程序必须发现它自己的设备,使用专门的安装程序安装。
另外在细节上也存在很多区别,其它模式驱动程序参数一般由注册表提供,在DriverEntry里调用读注册表的函数,然后根据注册表再调用CreateDevice,但是WDM一般不是这样,这是由于Windows 2000下支持PnP,在加载的时候会发PnP消息给Driver,所以一般不需要在DriverEntry里调用CreateDevice,而是在AddDevice里创建,或者在PnP消息里创建。一般在DriverEntry里创建的是一个与设备或者对象毫无关系的虚拟设备,用于管理与Win32的通讯。如果不想对该设备做什么特别的处理,或者设备不复杂,AddDevice可以简单返回Nt_Success,不用调用CreateDevice。另外整个设备驱动树也发生了改变,从而使安装程序发生了很大的改变。