驱动SYS开发总结

            1.驱动简介

            1.1.驱动是什么
            计算机的外部设备需要和计算机进行数据交换,生产外部设备的厂家如何使计算机和自己的设备交换数据呢,就是通过驱动程序,从设备中读入到计算机中,早期的Win3.1,Win9x设备驱动是vxd,Win
            NT是kdm, Win2k 统一发展成wdm模式。

            1.2.sys文件
            sys文件是驱动程序的可执行代码,其扩展名为.sys,驱动程序安装后保存在windows/system32/drivers目录中。

            对于PnP设备,在设备插入后,sys文件会被windows装载到内存中,系统线程调用sys中的函数来和设备进行通信。

            1.3.inf文件
            inf文件是安装设备驱动程序时必须使用的文件,其扩展名为 .inf,驱动程序安装后保存在windows/inf目录中。

            系统使用一个扩展名为INF的文本文件来控制与安装驱动程序相关的大部分活动。INF文件应该由驱动程序开发人员随驱动程序一起提供。通过INF文件可以告诉操作系统哪一个文件需要复制到用户硬盘上,应该增加或修改哪一个注册表项,如此等等。


            inf中提供产品设备的产品id,以及对应的sys文件名,驱动class名,class guid,

            1.4.usb-client driver
            HOST 与DEVICE, ENDPOINT与PIPE

            我们进行的USB驱动开发大多数是usb-client
            driver,系统厂商大多数都已经把USB类驱动做好,我们则是在类驱动之上开发针对自己设备的驱动,习惯上称做usb-client
            driver,其在整个软件构架中地位如下:
            UHCD--USBD--USB CLIENT DRIVER--DLL OR APP

            usb-client driver仍然遵守WDM模型,是WDM驱动。因为要支持PnP,所以要很小心的处理自己的资源以及IRP,
            随时准备处理拔出或者插入设备的情况; 电源处理不当也会使系统无法唤醒。

            需要了解的知识:wdm,usbdi,our usedevice,
            wdm:
            目标: a, 能提供接口函数,
            b, 能实现pnp,电源消息处理,wmi,i/o等处理,
            usbdi:
            urb,irp,等时,中断,控制,批传输的概念
            our usedevice:
            我们的usb设备的传输类型,设备的能力。

 

            2.WDM机制
            WINDOWS 9X 及以前版本VXD,WIN NT 使用KDM机制,WIN2000后的驱动程序都使用WDM机制。

            2.1.WDM驱动的分层机制
            WDM驱动的分层图:

            2.2.PDO以及IRP机制
            一种设备使用相同的驱动程序,每层驱动程序装载后,有一个驱动对象(driver object)。

            在驱动对象中,有设备链,一个节点是一个设备对象(device object), 称为pdo,对应一个设备,用设备链实现多个设备支持。

            系统使用irp(i/o request
            package)和设备进行通信,调用驱动程序函数时候,会传递需要操作的的设备对象pdo,以及进行通信使用的irp。

            2.3.WDM驱动程序code构成
            1, 函数构成:
            基本函数:driverentry,adddevice,unload
            入口函数driverentry必须使用driverentry命名,并向系统注册 其他函数名。
            i/o控制函数:startio,oninterrupt,dpcforisr,adaptercontrol。
            分发函数:Dispatchpnp,Dispatchpower,Dispatchwmi,dispatchread,
            dispatchwrite。
            其它见到的函数:deviceioctl,Dispatchcreate,Dispatchclose。

            这些函数除了driverentry外,其它的都可以可以自己命名,由 driverentry向系统注册。

            2,必要性说明:
            必须函数:
            基本函数:driverentry,adddevice,
            分发函数:Dispatchpnp,Dispatchpower, Dispatchwmi,
            可选函数:
            处理请求队列需要的函数:i/o控制例程:startio,
            如果设备需要产生中断:i/o控制例程:oninterrupt,dpcforisr,
            DMA操作需要的函数:i/o控制函数:adaptercontrol,
            分发函数:dispatchread,dispatchwrite,

            2.4.必需的处理
            基本函数:driverentry,adddevice,
            分发函数:Dispatchpnp,Dispatchpower, Dispatchwmi,


            在driverentry中必须完成所需要的其他函数的注册,使得系统可以调用这些函数与设备进行通信。

            在有新的设备插入时系统会调用adddevice,由驱动程序自己调用IoCreateDevice创建设备对象,并attach到设备堆栈中,并初始化设备对象的Flag成员。


            Dispatchpnp,处理PnP管理器的发出的主功能码为IRP_MJ_PNP 的i/o请求,实现设备对即插即用的支持。

            Dispatchpower,处理电源管理器发出的主功能码为IRP_MJ_PNP 的i/o请求,实现设备对电源管理的支持。

            Dispatchwmi,处理WMI管理器发出的主功能码为IRP_MJ_SYSTEM_CONTROL
            的i/o请求,实现设备对WMI(WINDOWS management instrumentation)的支持,作用是可以监控设备性能。

            详细资料,可以查阅ddk,D_P2003-050_MBCUSB2_TRN_WDMSTRUCT_CN.ppt

 

            3.USB类驱动接口


            3.1.USB类驱动和URB
            在这个UHCD--USBD--USB CLIENT DRIVER--DLL OR APP结构中,
            usbd将usb端口芯片驱动uhcd进行了包装,提供更便利的功能,使得其它设备驱动程序可以简单的利用这些功能。

            usbd提供的函数就称为usbdi(usbd interface),主要利用 urb(usb request block),
            将urb放入irp(可以自己分配irp)中传递给usbd,由usbd完成 usb设备的相关操作。

            3.2.URB详细
            请阅读DDK帮助。

            3.3.常用函数
            UsbBuildVendorRequest,UsbBuildGetDescriptorRequest,
            UsbBuildSelectConfigurationRequest,USBD_ParseConfigurationDescriptorEx,
            USBD_CreateConfigurationRequestEx,USBD_ParseDescriptors

 

            4.我们的设备


            我们的设备有一个控制管道,两个bulk读写管道(自己的命令都通过读写来完成),支持usb2.0, 支持标准usb请求。

 

            5.SYS开发


            5.1.安装配置开发环境
            1、确定你已经安装了Visual C++,
            2、安装2000 DDK,安装2000 DDK成功后,在“开始”->“程序”里应该有“Development
            Kits”->“Windows 2000 DDK”的项目。(注意一定要先安装好VC,然后才安装DDK,这个顺序决不能颠倒!!)

            DDKROOT环境变量设置为Windows 2000
            DDK的基目录,如果不是的话,必须进行手工配置。请在控制面板“系统”属性的“高级”标签环境变量编辑器中设置好这个环境变量。例:DDK的安装路径为:E:WINDDK3790
            则新建用户环境变量变量名为: DDK ROOT 变量值为: E:WINDDK3790

            5.2.制作inf文件
            系统使用一个扩展名为INF的文本文件来控制与安装驱动程序相关的大部分活动。INF文件应该由驱动程序开发人员随驱动程序一起提供。通过INF文件可以告诉操作系统哪一个文件需要复制到用户硬盘上,应该增加或修改哪一个注册表项,如此等等。


            INF文件包含一些名字由方括号括起来的段,大部分段都含有一系列keyword = value形式的指令。例如:[Version]
            Signature="$CHICAGO$" Class=UUSBD
            ClassGUID=B51CA6BA-E750-4dff-9CDE-6AA963B17052{} provider=%LEADING%
            DriverVer=08/27/2001,0.1.0.1

            inf制作详细参看,D_P2003-050_MBCUSB2_TRN_INFSTRUCT_CN.ppt

            5.3.编写以及编译驱动
            1 、makefile 文件,2 、Sources文件

            makefile的内容是:
            # # DO NOT EDIT THIS FILE!!! Edit .sources. If you want to add a new
            source # file to this component. This file merely indirects to the
            real make file # that is shared by all the driver components of the
            Windows NT DDK # !INCLUDE $(NTMAKEENV)makefile.def

            Sources:
            TARGETNAME=HelloWDM TARGETTYPE=DRIVER DRIVERTYPE=WDM TARGETPATH=OBJ
            ? INCLUDES=$(BASEDIR)inc; $(BASEDIR)incddk;
            TARGETLIBS=$(BASEDIR)lib*freeusbd.lib? SOURCES=HelloWDM.cpp
            这个文件指定了生成的驱动程序目标名、存放obj文件的位置、lib文件的位置、被编译的源文件对象
            值得注意的是,“=”前后不能有空格,否则编译的时候会出错。

            编译:
            从开始菜单里选择编译环境 如:Windows 2000 Checked Build Environment.exe
            它从配置文件sources中读出待编译的程序的配置,包括源文件、目标文件等,
            从环境变量include中得到引用文件的地址,然后调用编译链接器进行实际的编译链接工作。 编译所产生的日志文件: Build.log
            链接中执行的命令行 Build.wrn 链接中遇到的警告 Build.err 链接中遇到的错误

            5.4.驱动的安装调试
            Win2000以上都使用*.inf文件来控制与安装驱动程序相关的大部分活动。Inf文件由驱动开发人员随驱动程序一起提供。控制面板->添加新硬件,从硬件列表中选择其他设备,并单击从软盘安装,再单击浏览,找到*.inf所在文件夹后,确定。接下来点下一步就ok了。安装之后,该驱动将出现在设备管理其中。


            调试手法:
            dbgprint(),
            systemdump,
            assert(),
            windbg跟踪,可以设置硬断点(插入dbgbreakpoint()函数)以及软断点(在运行到硬断点后,在windbg程序中打开源文件,设置软断点)


            详细资料,查阅D_P2003-050_MBCUSB2_TRN_WDMDEVELOP1_CN.ppt,
            D_P2003-050_MBCUSB2_TRN_WDMDEVELOP2_CN.ppt,机械工业出版社,《windows2000设备驱动程序设计指南》附录A驱动程序调试环境,附录B故障检验码

 


            6.经验、教训总结


            6.1.仔细check你的代码
            驱动程序运行在kernelmodel下,与应用程序截然不同,你的代码如果出现任何问题,那么你看到的将是蓝色的系统崩溃屏幕,或者系统直接重新启动,


            6.2.调试机的必要性
            由于代码不可避免的会存在错误,所以,拥有调试机是必要的,否则你的大部分时间会浪费在等待计算机shutdown和reset上,工作的进展会如同蜗牛在爬行。


            请注意你的dbug信息,尤其是dbgbreakpoint,如果你的机器不是处于调试模式下,断点将会挂起你的系统,黑屏,不能再进行任何操作,也看不到任何显示。


            6.3.谨慎和认真
            小心的处理每一个irp,以及你的任何资源,最好有一个可以确定它们被正确无误的处理和使用的手段,比如增加标志性的调试信息,使用计数等。否则你将花费很多很多的的时间去发现这些细微而致命的错误。


 

你可能感兴趣的:(驱动SYS开发总结)