Windows驱动程序设计入门.ppt

上传人:za****8 文档编号:12668277 上传时间:2020-05-13 格式:PPT 页数:49 大小:569KB
返回 下载 相关 举报
Windows驱动程序设计入门.ppt_第1页
第1页 / 共49页
Windows驱动程序设计入门.ppt_第2页
第2页 / 共49页
Windows驱动程序设计入门.ppt_第3页
第3页 / 共49页
点击查看更多>>
资源描述
Windows驱动程序设计入门,2,Windows的虚拟内存管理,3,Windows的虚拟内存管理,Windows的虚拟内存管理机制为应用程序和驱动程序提供了两种服务:使每个进程都拥有自己独立的内存地址空间;对于32位Windows而言,每个任务可寻址的内存地址空间都为0 x000000000 xFFFFFFFF(232,4GB)当物理内存不够4GB时,虚拟内存管理模块会用磁盘空间模拟内存空间,并且该模拟过程对应用程序是透明的。,4,用户地址空间与内核地址空间,Windows将每个进程的4GB的独立地址空间又划分为用户地址空间(0 x000000000 x7FFFFFFF)和内核地址空间(0 x800000000 xFFFFFFFF)两部分。操作系统内核代码和数据存放在内核地址空间;每个进程自己私有的代码和数据存放在用户地址空间虽然Windows的内核代码和数据被映射到了每个进程的地址空间中(所有进程看到的内容是相同的),但在实际的物理内存中,只有内核代码和数据的一份拷贝。,5,用户地址空间与内核地址空间,6,用户模式与内核模式,为了更好地保护系统,Windwos规定了两种处理器工作模式:用户模式和内核模式。工作在用户模式的程序只能使用CPU支持指令集的一个子集,只能访问用户空间中的内存,并且不能直接访问硬件。工作在内核模式的程序不受任何限制,可以使用CPU支持的任意指令,可以访问任意的内存空间,可以直接访问硬件。所有的Windows应用程序都工作于用户模式,Windows内核程序都工作于内核模式。也可以认为:位于用户空间的代码都工作于用户模式,位于内核空间的代码都工作于内核模式。应用程序只能通过Windows规定的一些API访问内核模式的代码和数据。,7,Windows系统结构,8,什么是Windows驱动程序?,Windows驱动程序是一种位于内核地址空间并且工作于内核模式的一种特殊的程序类型(.sys文件)。驱动程序是操作系统信任的一个内核扩展模块。驱动程序和操作系统之间遵循的是容器与插件模型。OS负责管理Driver的生命周期;Driver是一种被动的软件模块。驱动程序类似于DLL程序,它是一个回调函数(子程序)的集合体,这些函数由OS在适当的时候调用驱动程序也可以通过Windows内核API获得OS的一些服务。,9,编驱动程序用什么编程语言?,C语言C+语言1的情况下会用到汇编语言目前还不能用其它高级语言编写驱动程序。,10,编驱动程序用什么开发工具?,WDK(WindowsDriverKit)(可以到微软网站上免费下载)DriverStudio(CompuwareNuMega公司的产品)DDKWinDriverDDK,11,WDK中包含什么?,与Windows内核API函数相关的头文件(如ddk.h,wdm.h等)与Windows内核API函数相关的导入库(wdm.lib等)内核专用C运行时间库的头文件和导入库关于驱动程序编程模型和内核API函数的帮助文档C+编译器和链接器,综合创建工具内核调试工具、分析工具,12,内核模式下我们能调用哪些函数?,Windows内核输出的内核API函数;WDK提供的运行时间库其它驱动程序提供的服务,13,内核模式下我们不能调用哪些函数?,Windows的用户模式API函数;ISO规定的C/C+标准函数库,14,最简单的NT式驱动程序,extern“C”#includeexternCNTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath)NTSTATUSstatus=STATUS_UNSUCCESSFUL;/*KdPrint将输入字符串发送到一个特殊内存区,利用DbgView工具可以观察该内存区的内容*/KdPrint(HelloWorld!);returnstatus;,15,关于最简单驱动的问题,第一个extern“C”的作用是什么?第二个extern“C”的作用是什么?typedeflongNTSTATUS;#defineIN#ifdefDBG#defineKdPrint(a)DbgPrint#a#else#defineKdPrint(a)#endif,16,驱动程序的入口函数,NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath)returnstatus;,参数DriverObject表示指向驱动对象的指针;参数RegistryPath表示该驱动所对应的注册表服务键的子目录返回值表示初始化是否成功,17,DDK中一个驱动型工程的组成,MAKEFILE文件,一般不作改动Sources文件:(1)指示了整个工程由哪些源程序和资源文件构成;(2)包含了主要的编译参数,指导编译器和链接器的工作。.cpp文件和.h文件如何build驱动工程?用DDK中的build工具。build工具会根据MAKEFILE文件和Sources文件以及相关环境变量的指示编译并链接工程中的.cpp文件和.h文件,18,如何安装NT型驱动程序?,方法1:在注册表HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices下增加一个新的项目。可以将该服务指定为开机自启动,也可以指定为按需启动。如果是按需启动,则可以用netstart命令启动,用netstop命令停止。方法2:编写另外的用户模式程序利用SCM函数按需启动。方法3:在调试阶段可以利用第三方的工具如:DriverMoniter和IntallDriver随时安装和卸载。,19,如何调试驱动程序?,方法1:打印调试信息。即用DbgPrint函数打印调试信息,然后在驱动运行时用Dbgview等工具观察这些信息。方法2:分析内存转储(dump)文件。方法3:使用WinDbg、SoftICE等高级调试工具。,20,用WinDbg+VMWare进行双机调试,Step1:安装WinDbg和VMWare,并在VMWare中安装好WindowsXP。Step2:设置好WMWare的虚拟串口Step3:将虚拟机中的WindowsXP设置为调试运行模式。(修改boot.ini文件)Step4:以调试方式启动虚拟机中的WindowsXPStep5:启动WinDbgStep6:设置WinDbg的Symbol文件路径,设置C源程序路径。Step7:设置断点,监视变量,21,HelloWorld版的WDM驱动程序,extern“C”#include“wdm.h”externCNTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath)NTSTATUSstatus=STATUS_DEVICE_CONFIGURATION_ERROR;KdPrint(HellowWorld!);returnstatus;,22,如何安装WDM驱动程序?,必须编写一个安装指示文件(.inf)指导Windows将驱动程序安装到指定位置(一般安装在windowssystem32drivers子目录下),并在注册表中进行登记。对于即插即用类设备的驱动,操作系统会自动发现该设备并调用“添加新硬件”程序向用户询问相应的inf文件的位置。对于非即插即用类设备的驱动,用户必须自己手动调用“添加新硬件”程序,并通过告诉该程序inf文件的位置。,23,inf文件主要包含了哪些内容?,设备类型、设备型号、厂商信息、程序版本号。对操作系统版本和CPU类型的要求源文件(.sys文件)的文件名和所在位置安装目标子目录在注册表中添加哪些内容硬件配置信息安全配置信息,24,驱动对象(DriverObject),在操作系统首次装载一个驱动程序之后,它会创建一个数据结构用来记录该驱动,该数据结构我们称为驱动对象(DriverObject)。驱动对象记录与驱动程序本身相关的信息,它主要包含了除了DriverEntry之外的其它驱动程序入口函数的入口地址。(驱动程序是一种具有多个入口函数的程序)驱动对象是由操作系统创建,然后作为DriverEntry的第一个参数传递给你的程序。在获得驱动对象的指针之后,你的程序需要对其中的一些字段进行初始化。,25,驱动对象(DriverObject),驱动对象在DDK的头文件(ntddk.h)中按如下方式定义:。,typedefstruct_DRIVER_OBJECTCSHORTType;CSHORTSize;DRIVER_OBJECT,*PDRIVER_OBJECT;,由上面的定义可以看成,驱动对象不同于C+中的Class,它只是一个Struct。,26,27,驱动对象的一些关键字段(一),DriverStartIo(PDRIVER_STARTIO):指向StartIO入口函数的指针.DriverUnload(PDRIVER_UNLOAD):指向DriverUnload入口函数的指针。在驱动程序被从内存中卸载时,DriverUnload入口函数会被操作系统调用,你应该在该函数内部做一些与DriverEntry向对应的资源清除工作。MajorFunction(一个数组,数组中每一元素又是一个指向函数的指针PDRIVER_DISPATCH):数组中每一个指针指向一个入口函数。在接收到不同的请求包(IRP)时,OS会调用不同的入口函数。,28,驱动对象的一些关键字段(二),DeviceObject(PDEVICE_OBJECT):指向一个链表的指针,该链表中每一个节点都存储了一个FDO对象。每一个FDO都代表一个由该驱动维护的硬件设备实例。在WDM模型中,该链表由OS自动维护。DriverExtension(PDRIVER_EXTENSION):指向另外一个结构体,该结构体中唯一有用的字段为AddDevice。AddDevice字段指向一个入口函数。在操作系统发现一个新的设备实例时,它会自动调用AddDevice函数,你应该在该函数中做一些与设备实例相关的初始化工作。,29,DriverEntry函数的主要工作,在操作系统创建的驱动对象中填写其它入口函数的地址,使得操作系统在必要的时候能够找到这些入口函数并调用它们。创建一个或多个设备对象,并将这些对象挂接在驱动对象所指示的链表上。(只针对NT型驱动)与该设备相关的其他初始化工作,VOID(*PDRIVER_UNLOAD)(INPDRIVER_OBJECTDriverObject);VOID(*PDRIVER_STARTIO)(INPDEVICE_OBJECTDeviceObject,INPIRPIrp);NTSTATUS(*PDRIVER_DISPATCH)(INPDEVICE_OBJECTDeviceObject,INPIRPIrp);NTSTATUS(*PDRIVER_ADD_DEVICE)(INPDRIVER_OBJECTDriverObject,INPDEVICE_OBJECTPhysicalDeviceObject);,30,DriverUnload函数的主要工作,删除以链表形式挂接在驱动对象上的一个或多个设备对象。(只针对NT型驱动)进行与DriverEntry函数中相对应的反初始化工作。例如如果在DriverEntry函数中申请了堆内存,那么在DriverUnload函数中应该释放该堆内存。,VOIDDriverUnload(PDRIVER_OBJECTDriverObject)RtlFreeUnicodeString(,31,第二简单的驱动程序,extern“C”#includeVOIDHelloDDKUnload(INPDRIVER_OBJECTpDriverObject);NTSTATUSHelloDDKDispatchRoutine(INPDEVICE_OBJECTpDevObj,INPIRPpIrp);externCNTSTATUSDriverEntry(INPDRIVER_OBJECTpDriverObject,INPUNICODE_STRINGpRegistryPath)NTSTATUSstatus=STATUS_SUCCESS;KdPrint(EnterDriverEntryn);KdPrint(RegistryPath:%wZn,pRegistryPath);pDriverObject-DriverUnload=HelloDDKUnload;pDriverObject-MajorFunctionIRP_MJ_CREATE=HelloDDKDispatchRoutine;pDriverObject-MajorFunctionIRP_MJ_CLOSE=HelloDDKDispatchRoutine;pDriverObject-MajorFunctionIRP_MJ_WRITE=HelloDDKDispatchRoutine;pDriverObject-MajorFunctionIRP_MJ_READ=HelloDDKDispatchRoutine;KdPrint(LeaveDriverEntryn);returnstatus;,32,第二简单的驱动程序(续),VOIDHelloDDKUnload(INPDRIVER_OBJECTpDriverObject)KdPrint(EnterDriverUnloadn);KdPrint(LeaveDriverUnloadn);NTSTATUSHelloDDKDispatchRoutine(INPDEVICE_OBJECTpDevObj,INPIRPpIrp)NTSTATUSstatus=STATUS_SUCCESS;KdPrint(EnterHelloDDKDispatchRoutinen);KdPrint(LeaveHelloDDKDispatchRoutinen);returnstatus;,33,设备对象(DeviceObject),针对每一个硬件设备,Windows都需要用一个数据结构来记录它的相关信息,这个数据结构就叫做设备对象(DevcieObject)。因为一个驱动程序可以同时管理多个同类型的硬件设备,因此一个驱动对象可以对应多个设备对象。对应同一个驱动对象的多个设备对象构成一个链表挂接在驱动对象的DeviceObject字段上。设备对象由驱动程序负责创建和初始化,由操作系统负责保存和管理。设备对象可以有名字,其他驱动程序或应用程序可以通过该名字找到该设备对象。,34,TheDeviceObject,35,设备对象的一些关键字段(一),DriverObject(PDRIVER_OBJECT):指向与该设备对象相对应的驱动对象的指针。NextDevice(PDEVICE_OBJECT):指向下一个设备对象的指针,利用该字段与同一个驱动对象对应的多个设备对象就可以构成一个单链表,该链表最后挂接在驱动对象的DeviceObject字段上。,36,设备对象的一些关键字段(二),Flags(ULONG):保存了一些标志位,这些标志位指示了该设备的一些工作方式。,37,设备对象的一些关键字段(三),Characteristics(ULONG):另外一组标志位集合。DeviceExtension(PVOID):指向一个扩展内存区,该内存区的大小和使用方式由程序员规定。一般在该区域存放一个自定义的结构体,用于存储硬件设备特有的信息。今后称该结构体为设备扩展对象。该扩展内存区由操作系统负责创建并维护。DeviceType(DEVICE_TYPE):一个枚举型变量,指明该设备的类型(FILE_DEVICE_UNKNOWN)AlignmentRequirement(ULONG):指定该设备使用内存时的对齐方式(FILE_BYTE_ALIGNMENT、FILE_WORD_ALIGNMENTFILE_512_BYTE_ALIGNMENT),38,如何创建设备对象,利用内核API函数IoCreateDevice创建设备对象。OS负责申请并管理设备对象所需内存,并对其中的一些字段按照输入参数做了初始化,最后将其挂接在设备对象链表上。,NTSTATUSIoCreateDevice(INPDRIVER_OBJECTDriverObject,/设备对象所对应的驱动对象INULONGDeviceExtensionSize,/设备扩展区的大小INPUNICODE_STRINGDeviceNameOPTIONAL,/设备对象名称INDEVICE_TYPEDeviceType,/设备类型INULONGDeviceCharacteristics,/设备对象特征INBOOLEANExclusive,/一般设为FALSEOUTPDEVICE_OBJECT*DeviceObject/由操作系统创建的设备对象/的起始地址利用该参数返回);,39,如何删除设备对象,在WDM驱动中,如果接收到IRP_MN_REMOVE_DEVICE消息,则应删除设备对象;在NT式驱动中,在DriverUnload函数中删除设备对象。在创建设备对象之后如果出错也应该及时删除对象。通过调用内核API函数IoDeleteDevice删除设备对象,NTSTATUSstatus=IoCreateDevice(.);if(!NT_SUCCESS(status)returnstatus;.if()IoDeleteDevice(pdo);returnstatus;,40,设备对象的命名,Windows系统中有一个称为“对象管理器”的执行模块复杂集中管理系统中所有的内核对象,其中包括驱动对象和设备对象。对象管理器给大多数内核对象都起了名字,并把这些名字组织为具有树形结构的命名空间。设备对象一般都位于该命名空间的Device子目录下其他内核模块和驱动程序都可以通过设备的名字获得该设备对象的指针(利用IoGetDeviceObjectPointer),并通过该指针向驱动对象发送IRP。用户模式的应用程序对Device子目录没有访问权,41,设备对象的命名(续),为了给自己的设备对象命名,必须将名字存放在一个UNCODE_STRING型的字符串中,并将其作为IoCreateDevice的第3个参数传入。,UNICODE_STRINGdevname;RtlInitUnicodeString(,42,设备对象名与符号链接,因为应用程序只能访问Windows内核对象空间中的“?”子目录,而对对Device子目录没有访问权限,因此必须在“?”子目录中创建一个符号链接,将其指向Device子目录中的名字。符号链接就类似于Windows文件系统中的快捷方式创建符号链接的方法是调用IoCreateSymbolicLink,43,设备对象名与符号链接(续),UNICODE_STRINGdevname;UNICODE_STRINGlinkname;RtlInitUnicodeString(,44,应用程序如何通过设备名打开设备,在用户模式下“?”子目录叫做“.”子目录,因此通过“.”子目录下的符号链接名就可以找到设备对象,并打开指向设备对象的句柄。,hDevice=CreateFile(.Simple1,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);ReadFile(hDevice,lpBuffer,.);WriteFile(hDevice,lpBuffer,.);.,45,创建完设备对象后还需做什么,设置设备扩展对象的内容设置设备对象的flags字段设定该设备的工作方式。,fdo-AlignmentRequirement=.fdo-Flags=DO_BUFFERED_IODO_POWER_PAGABLE;,创建设备对象栈(可选)等所有准备工作做完之后一定要清除flags字段的DO_DEVICE_INITIALIZING标志告诉OS可以接收IRP了,fdo-Flags,46,第三个例子程序,47,基于I/O请求包(IRP)的工作方式,48,应用程序与驱动程序的通信,Windows应用程序与WDM通信的一般过程是:应用程序先用CreateFile函数打开设备,然后用ReadFile从WDM中读取数据,用WriteFile函数向WDM写数据,用DeviceIoControl函数向WDM发送自定义的控制信息,最后用CloseHandle函数关闭设备。对于异步IO请求还可以用CancelIo函数取消。这些函数调用使得IO管理器产生相应的IRP发送给驱动程序,49,第四个例子程序,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!