vxd驱动的开发.docx
- 文档编号:11916825
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:29
- 大小:141.58KB
vxd驱动的开发.docx
《vxd驱动的开发.docx》由会员分享,可在线阅读,更多相关《vxd驱动的开发.docx(29页珍藏版)》请在冰点文库上搜索。
vxd驱动的开发
摘要
第一章绪论
驱动程序实际上可以理解为是一系列控制硬件设备的函数。
在DOS系统中,一个驱动程序可能是一个连到应用程序.EXE中的一个模块或者是与应用程序分开的一个独立部分;在Widows系统中,封装驱动程序的方法是制作一个DLL或VxD。
在早期,由于我们一般涉及的与计算机相关的硬件设备都是标准设备,它们的驱动程序是由厂家或专门的程序开发人员提供并加以封装,用户只需了解与驱动程序相连的Windows应用程序接口(API),而无需知道其内部运行机制。
但是如果硬件是非标准设备,我们必须针对该特定硬件自己来设计Windows环境下的设备驱动程序。
我所面对的硬件是一块超声波探伤卡,它集成在一块PCI插卡上,桥接芯片采用了PCI2040,因为它可以和DSP无缝连接。
我要做的工作是首先利用主机通过并口启动模拟采样部分,当采样数据放大后进入A/D变换后存入储存器,在数据存储器中存满一帧时,硬件向主机发中断,主机响应中断后通过PCI2040芯片读出存放在数据存储器中的采样数据,然后进行后续处理并将结果显示于屏幕。
我编写的应用程序的软件平台是Window95/98,采样的工具是VisualC++6.0(简称VC++),因为它是一种面向对象的编程语言,具有良好的交换性,可以根据用户对界面上的控件或菜单操作作出相应的处理,而且它可以自动根据要求生成框架,我们要做的只是对空的函数框架进行填充。
由于应用程序运行在Ring3级,它不能对硬件进行直接访问,也不会响应硬件中断,必须通过驱动程序来响应中断以及访问硬件。
该硬件显然不是Windows标准组件,系统不会提供相应的VxD驱动程序,因此必须自己编写PCI2040的硬件安装信息文件和驱动程序。
值得一提的是在通过并口与硬件通信时理论上也得写VxD但是由于并口是Windows标准组件,Windows已经封装了一些常用的API函数(如_inp()和_outp()等函数),可以在应用程序中直接使用,而且像打印机等利用并口传输数据的硬件的驱动程序已经被认为不属于虚拟设备驱动程序了。
在本论文安排上首先介绍驱动程序的产生背景、实现原理和开发工具,然后介绍PCI总线及PCI2040芯片,最后说明我的驱动程序以及相应的应用程序。
第二章Windows环境下的驱动程序
在DOS操作系统时代,对于一个应用程序而言它总认为自己是唯一运行的程序,因此常常可以直接访问硬件,独占所有的系统内存以及系统运行时间,当然也就不需要设备驱动程序。
但是到了Windows时代,DOS应用程序并不是唯一运行的程序,系统中同时可能有若干个应用程序在运行,这就使得系统不可能让它随意的直接访问硬件,否则就会引起混乱导致系统崩溃。
为了解决这个问题,人们提出了将系统的资源虚拟化,让应用程序运行在一个虚拟的环境中的虚拟机(VM)上,而管理程序和驱动程序运行在实际机器上(Ring0级),由它们来处理针对硬件的操作。
2.1虚拟机(VM)
虚拟资源是由系统产生的假象,它是硬件(甚至是软件)资源的仿真,当系统虚拟了所有或者几乎所有的程序可以访问的资源时,它就创造了一个“虚拟机”(VM)。
概括起来,Windows的虚拟机完全透明地仿真了以下地资源和性能:
●可访问的内存空间;
●I/O操作;
●中断操作;
●外围设备(显示器、键盘等);
虚拟机的管理主要由虚拟机管理器(VMM)完成。
VMM利用系统的硬件创造了几个相互独立的虚拟机,每个虚拟机都有自己的虚拟环境,而且每个虚拟环境可能与物理环境根本不同。
让所有的Windows应用程序(Win16应用程序和Win32应用程序)运行在一个VM上,称为系统VM;而每一个DOS应用程序都分别运行在各自的一个VM上,这样便解决了DOS和Windows应用程序的兼容问题。
2.2处理器运行模式及各种程序优先级
为了创建和维护虚拟机,VMM开发了80386以及以后的兼容处理器的特殊性能。
这些处理器有三种运行模式:
实模式、保护模式和V86模式,它们决定了处理器所能寻址的地址空间,如何实现逻辑地址到物理地址的转换以及如何保护对内存和I/O端口的访问。
Windows95/98利用了其中的保护模式和V86模式两种模式,以下各项也是针对这两种模式而言。
Windows95/98执行环境支持四种不同的基本模式:
管理程序、Win32应用程序、Win16应用程序和DOS应用程序。
其中管理程序在Ring0级(最高级)中运行,能够访问和控制实际硬件环境,也就是说它们在真正的计算机上运行,而不是在虚拟机上运行,在所有构成Windows的组件中,只有VMM和VxD在管理环境中执行。
Windows应用程序在Ring3级(最低级)的保护模式上运行,它们不能直接访问硬件,一旦执行一个对硬件的操作就会引起一个异常事件,这时处理器切换到Ring0级,并且将控制权交给相应的控制器。
所有Windows应用程序分享一个系统虚拟机。
每个DOS应用程序运行在各自的V86虚拟机(类似于系统虚拟机)上,标注为Ring3级(最低级),它访问的硬件资源和中断也被隐藏和虚拟了。
2.3如何实现虚拟机
当在虚拟机中执行程序时,Windows必须能够捕获并透明的“代替”以下功能:
●对I/O端口查询
●对一个内存映射的外围设备查询。
●可能导致传送到虚拟机之外的操作,如一个异常时间或中断。
2.3.1捕获I/O操作
不论保护模式还是V86模式,操作系统都可以捕获输入和输出指令来防止应用程序直接访问I/O映射的设备。
Windows98/95使用I/O优先级(IOPL)和I/O允许映射(IOPM)(‘0’表示拒绝,‘1’表示允许)来控制VM访问I/O地址。
在保护模式中,每个代码段都有一个相关的优先级描述器,它存储在描述器列表中。
当在保护模式中执行一个I/O指令时,处理器将段的IOPL和当前代码段的优先级(CPL)比较,如果CPL
IOPL且IOPM=0,处理器才执行指令,否则产生一个异常事件。
在V86模式中,处理器只参照IOPM,与IOPL无关。
Windows和它的标准组件VxD可以捕获PC机上的所有标准I/O设备,由于我们使用的不是标准硬件,因此要自己编写VxD,流程也相似先向VMM申请捕获我们的硬件端口的服务,安装回调处理器,当VM访问该端口时产生异常进入我们的回调处理中,由我们自己编写的函数进行处理。
2.3.2捕获内存操作
Windows主要根据页错误机制实现对存储器映射设备访问的虚拟化。
要捕获对某个设备内存的访问,设备VxD会将页表中对应于为了内存的页标注为“不可用”。
当在虚拟环境中运行的程序试图访问这个页时,会产生一个错误。
VMM的异常处理器会调用已注册的设备VxD的页错误处理器进行相关处理。
2.3.3捕获中断和异常事件
Windows必须能够捕获一些具有优先级的指令,因为它们可能会绕过处理器的保护特性或干扰虚拟机的完整性。
如影响处理器中断标志指令(CLI,STI,POPF,IRET等),调入描述表的指令(LLDT,LGDT,LIDT等)。
解决的方法是在Ring3层上一旦执行一个有优先级的指令,就会引起一个异常事件。
这时处理器就会切换到Ring0层并将控制交给相应的控制器。
2.4各种驱动程序比较
●VxD
VxD是虚拟设备驱动程序,是系统用于对各种硬件资源识别,管理,维护运作的扩展。
VXD和VMM(虚拟机管理器)一起合作,维持着系统的运作。
VxD模式从WIN3X时代就开始了.一直到了WIN98还一直在MS的WIN系列操作系统中起主导作用。
VxD运作在INTEL系列CPU保护模式下的RING0,拥有对硬件的最高控制权。
●KMD
KMD是KernelModeDriver的缩写,它是WindowsNT下提出的管理,维护硬件运作的驱动程序模式。
该DRIVER运行于WindowsNT的KERNEL模式下(类似于RING0),但是,一个KMD的运作环境在不同的时候是根本不同的。
DRIVER收到设备请求时的运行环境很可能和设备请求实际操作的运行环境根本不同,因此在WindowsNT下DRIVER的运作也受到WindowsNT本身的许多限制。
●WDM
WDM是Win32DriverModel的简写,它可以和Windows2000兼容,乃微软力推的全新的驱动程序模式,它实际也可以理解为一个即插即用(PNP)的KMD。
但是由于Windows98对WDM的支持有限,而且WMD的代码很长,能用VxD时一般不采WDM,因此目前WDM的实际应用还不多,但随着Windows2000/NT的普及WDM必将成为主流的驱动程序模式。
2..3驱动程序的开发工具
●DDK
开发虚拟设备驱动程序(VxD)的常规方法是使用Microsoft出品的设备驱动程序开发工具包DDK(DeviceDeveloperKit)。
它有Windows98DDK和Windows2000DDK两个版本。
前者能够开发Windows95/98/Me/NT下的VxD、KMD和WDM驱动程序,后者可以开发Windows98/Me/NT/2000下的KMD和WDM驱动程序。
它要求设计者必须对Windows的体系结构、设备驱动程序的结构、虚拟机管理器(VMM)以及IntelCPU体系结构有深入的了解,而且需要保护模式的汇编语言编程经验。
因此,在实际中DDK一般不常被人使用,取而代之的是下面二种开发工具。
●VtoolsD
Vireo公司出色的VtoolsD由可视的VxD代码生成器QuickVxD、C运行库、VMM/VxD服务库、C++类库以及VxD的装入程序等组成。
利用QuickVxD生成的框架程序和经充分测试过的C运行库或C++类库可以绕过DDK用C或C++来编制驱动程序,这就大大地简化了开发的难度,提高了可靠性。
框架程序可以直接在VisualC++集成开发环境中用NMAKE编译为VxD。
由于利用VtoolsD主要针对Windows95/98驱动程序编程,写出的VxD程序相对比较简洁,而且它容易上手,因此我在实际编写VxD设备驱动时使用了该工具。
●WinDriver
WinDriver是美国KRFTech公司出品的用于编写驱动程序的另一种工具包。
它包括1个类似于QuickVxD的代码生成器WinDriverWizard、1个WinDriver发行包、2个公用程序。
与VToolsD一样,WinDriver工具包的优点在于可以使编程人员用C或C++语言来编写设备驱动程序,而不是将大量精力放在编写那些复杂的、难于调试的内核模式代码。
以上介绍的3种工具各有优点。
DDK功能强大,编程灵活,适用范围广,可应用于各类硬件驱动程序的编写,但对编程人员的要求较高,编程难度较大。
VToolsD主要工作环境是在Windows98/95下,它具有较强的开发能力和较高的开发效率,是编程人员常用的工具。
WinDriver的适用面比前二者窄,它主要针对ISA/PCI插卡,而对其他类硬件的技术支持较少,但它编写的程序可同时工作在Windows95/98/NT操作系统
第三章VxD虚拟设备驱动程序
VxD是虚拟设备驱动程序(VirtualXDriver)的缩写,中间的x表示某一类设备。
如VKD.VXD表示键盘的驱动程序,当然一个VxD并非一定对应一个硬件设备,有的VxD只是为其他的VxD或应用程序服务,有的VxD也可能只是对应一个不存在的硬件。
但是所有的VxD都有一个共同的特点,即“到任何地方做任何事情”。
它们可以访问内存地址,访问硬件端口,捕获其他程序对内存和端口的访问,甚至可以截获硬件中断,VxD模式从Windows3.1时代就开始了,一直到Windows95/98/ME它还一直在微软的操作系统中起主导作用。
3.1VxD的开发工具
在编写VxD时我采用了Vireo公司的VtoolsD工具,它由QuickVxD,DebugMonitor及INFEdit等组成。
QuickVxD工具(见图3-2)可以快速生成VxD的代码框架,开发者只需填写几个选项然后在生成的框架中再增加自己的代码,编程效率比较高而且程序比较简洁,QuickVxD的使用在下面将详细介绍。
DebugMonitor工具(见图3-1)具有两个功能,一个是用来观察VxD在debug状态下的输出流,另一个是可以强制执行和终止VxD的运行。
图3-1
INFEdit工具主要是用来编写安装硬件信息的.inf文件,当CMOS检测到新硬件时它会按照安装信息来安装硬件。
当然我们可以使用任何一种文本编辑器来编写安装文件,只要最后以inf作为后缀名就行了,但是由INF文件中的节是分层排列的且比较多,使得直接写很困难,如果使用INFEdit工具就比较简单,只需安照它的类目一一填写即可自动生成所需文件。
3.2VxD的创建
Windows支持静态安装和动态安装VxD。
静态安装是在Windows初始化时安装VxD并一直保存在Windows中,动态安装的VxD是在一个应用程序或其他VxD的控制下安装和卸载。
如果选择静态安装,由于我的应用程序并不是一直在执行,而VxD始终占用着一定的内存资源以及宝贵的中断口,这样导致了资源浪费。
因此我使用了动态安装,只有当应用程序运行时,通过CreatFile()函数动态打开VxD,申请内存资源,挂钩中断口,然后响应中断进行数据采集、处理和显示,当用户关闭应用程序时,它首先通过CloseHandle()关闭VxD,VxD在中止前释放所有先前它申请的资源。
在使用QuickVxD开发VxD只需在DynamicallyLoadable选项中打勾就行了(图3-1),其中DeviceName是指我们的VxD的设备名,每个VxD都有设备名这儿是指PCI2040芯
图3-2
片,DeviceID是用来标识设备,只有当该VxD需要提供对其他VxD的调用入口时才用,且不能任意取应该由Microsoft公司提供,一般情况直接用UNDEFINED_DEVICE_ID就行了,DeviceInitializationOrder确定Windows对VxD的安装顺序,比如你想要你的VxD先于VDD初始化就应该设置为VDD_INIT_ORDER-1,一般情况也使用默认值。
3.3VxD的事件通知
VMM提供了大量的消息与VxD进行通信,对于编程人员来讲要做的工作就是写消息处理程序。
消息数目总共将近40个(详见附录a),但是一般情况我们只使用其中的很少一部分,限于篇幅下面仅详细介绍PCI2040芯片的驱动程序用到的几个消息。
●SYS_DYNAMIC_DEVICE_INIT
通知可动态加载的VxD加载并初始化,在其中作一些初始化工作,如设备的初始化,挂钩中断口和安装硬件中断处理函数。
当该消息处理函数返回值为真时,表示初始化成功,否则初始化失败,系统将VxD从内存中移去。
●SYS_DYNAMIC_DEVICE_EXIT
通知可动态卸载的VxD从内存中移去,并且释放它先前申请的资源。
当处理函数返回值为真时表示VxD安全卸载,否则将阻止系统卸载VxD。
●PNP_NEW_DEVNODE
通知VxD设备结点已经装载了硬件,此时VxD可以去取配置管理器分给它的配置了。
●W32_DEVICEIOCONTROL
该消息主要用来进行Win32程序和VxD的通信,在第五章中有详细介绍。
在QuickVxd中提供了大部分VxD控制消息,我们只需在想要的消息上打勾就可以在生成的驱动程序框架中包含该消息。
Windows95ControlMessage是指Windows95支持的
图2-2
消息(图2-2),而ControlMessage是指Windows3.1和Windows95都支持的消息。
中。
3.4VxD访问硬件设备
计算机的硬件可以被定位于I/O空间和内存空间,这两种空间是完全独立的而且I/O地址空间比内存空间小的多,对于80386后的处理器而言前者只有64KB而后者有4GB。
映射到I/O地址空间的硬件设备只能通过专门的I/O指令如IN、OUT命令(C语言中为inp和outp)来访问。
映射到内存空间范围的硬件可以象访问内存一样进行访问,一般使用MOV、ADD、OR等指令(C语言中则通过指针来访问)。
在实际访问过程中VxD访问I/O映射硬件可以直接使用I/O指令访问,但对于内存映射硬件则复杂的多。
因为尽管VxD运行在Ring0级,但它所见的是平面内存,只能用线性地址,因此在每次访问一个硬件前必须先配置页表,保证设备的物理地址与一个线性地址相联系,而这个线性地址可以作为一个指针来由我们进行内存访问,就好像我们在直接对硬件操作一样。
由于我们的PCI插卡是动态配置的内存映射设备,它每次分配的物理地址可能会改变的,因此在进行地址转换时采用的也是动态转换。
3.5VxD处理硬件中断
在Windows环境下,将所有的IDT(中断描述符表)指向VMM的一个例程,由VMM来确定它是做为异常事件处理还是中断的结果被调用。
VMM自己只管理异常事件,所有的中断由VPICD(虚拟可编程中断处理器)处理。
如果一个VxD为中断进行了注册,VPICD就将这个中断交给它处理,否则VPICD将中断交给VM由它来处理。
VxD通过调用VPICD的服务VPICD_Virtualize_IRQ()来为硬件中断注册,并将会调例程的地址交给VPICD。
一旦VxD进行了注册,它就可以处理硬件中断。
2..3VxD的其它开发工具
●DDK
DDK(DeviceDeveloperKit)是专业软件开发人员常用的Microsoft公司出品的设备驱动程序开发工具包。
它有Windows98DDK和Windows2000DDK两个版本。
前者能够开发Windows95/98/Me/NT下的VxD、KMD和WDM驱动程序,后者可以开发Windows98/Me/NT/2000下的KMD和WDM驱动程序。
DDK虽然功能强大,但它要求设计者必须对Windows的体系结构、设备驱动程序的结构、虚拟机管理器(VMM)以及IntelCPU体系结构有深入的了解,而且需要保护模式的汇编语言编程经验,因此,在实际中DDK一般不常被人使用。
●WinDriver
WinDriver是美国KRFTech公司出品的用于编写驱动程序的另一种工具包。
它包括1个类似于QuickVxD的代码生成器WinDriverWizard、1个WinDriver发行包、2个公用程序。
与VToolsD一样,WinDriver工具包的优点在于可以使编程人员用C或C++语言来编写设备驱动程序,而不是将大量精力放在编写那些复杂的、难于调试的内核模式代码。
以上介绍的几种工具各有优点。
DDK功能强大,编程灵活,适用范围广,可应用于各类硬件驱动程序的编写,但对编程人员的要求较高,编程难度较大。
VToolsD主要工作环境是在Windows98/95下,它具有较强的开发能力和较高的开发效率,是编程人员常用的工具。
WinDriver的适用面比前二者窄,它主要针对ISA/PCI插卡,而对其他类硬件的技术支持较少,但它编写的程序可同时工作在Windows95/98/NT操作系统。
第四章PCI2040芯片驱动程序的开发
PCI(peripheralcomponentinterconnect)总线主要为Pentium微处理器的开发使用而设计的,它定义了32位数据总线,且可扩展为64位,使用33MHz时钟频率,最大数据传输率为132~264Mb/s,支持无限读写猝发操作,支持即插即用,支持并发工作方式,即多组外围设备可与CPU并发工作。
PCI总线以其优良性能和适应性已成为Pentium以上微机的主流总线。
要开发基于PCI接口的设备就需要选择PCI总线接口芯片,目前常用的有S5933,AN3042,PLX9030等,但是它们不便于和DSP连接。
4.1PCI2040控制芯片
TI公司推出的PCI2040PCI桥控制器(内部结构如图4-1)可以很方便的通过主机接口实现多达四片C54x或C6x系列DSP与PCI总线的连接。
同时它提供了两种数据传输方式:
HPI方式和GPBUS总线传输方式,其中GPBUS总线传输方式比较简单但是传输的速度有所限制,因此我们采用了HPI传输方式。
在HPI方式下,主机可以通过三个HPI寄存器实现对DSP片内DRAM的访问。
这三个寄存器分别是:
(1)HPI地址寄存器(HPIA):
由主机直接访问。
寄存器中保存了当前要访问的DSP片内存储器地址。
(2)HPI数据寄存器(HPID):
由主机对其直接访问。
如果当前操作是读,则将数据从HPIA当前所指向的存储器中读入该寄存器;如果当前操作是写,则将该寄存器内容写入HPIA当前所指向的存储器中。
当进行较大的数据块读写操作时,可以通过地址自增方式对HPID进行读写。
(3)HPI控制寄存器(HPIC):
被主机和C54x直接访问。
它映象在C54x数据存储器的地址002ch处,该寄存器中保存了HPI的控制和状态位。
在进行第一个数据或地址寄存器操作前必须先初始化HPIC的BOB位(若为零表示传输的第一个字节是高字节,否则表示传输的第一个字节是低字节)。
这是因为主机接口总是传送8位字节,而HPIC寄存器(通常是主机首先要寻址的寄存器)又是一个16位的寄存器,在主机这边就以相同内容的高字节与低字节来管理HPIC寄存器。
图4-1
PCI总线规范要求任何PCI设备必须提供256字节的配置空间,它用来实现无需用户干预的安装、配置和引导;完全的设备再定位,由与设备无关的软件进行系统地址映射。
PCI2040的配置空间如下:
图4-2
其中设备ID用以标识特定的设备,具体的代码由供应商来分配;供应商ID用以表明设备的制造者,这二者是识别PCI设备的唯一标识。
对于PCI2040来讲,当读Vendor-deviceID时,返回值为AC60104C。
4.3即插即用体系
即插即用(PnP)是微软公司为了使新硬件设备的安装和配置更加容易而采取的一种策略。
PnP设备能够自身识别,自动提出资源需求,并且可以在运行时接收资源分配,较新类型的扩展总线如PCI、EISE、PCMCIA等,其任一设备都定义为即插即用的,这些总线也都满足即插即用的要求。
配置管理器是即插即用体系结构的核心元件。
它由四个软件元件来工作:
●枚举器
●仲裁器
●设备安装器
●设备驱动器
其中,枚举器生成设备结点树并参与总线中的设备配置。
枚举过程发生在计算机开机时,枚举结束后设备结点树包含的信息有:
可用的系统资源、需要的设备驱动程序和资源的要求。
当用户将卡插上时,系统的枚举器将自动识别新设备然后查找所有的已知的.INF文件看是否有与设备ID号相匹配的,如果有则在新生成的注册表项内复制相应文件,否则提示用户插入一张安装盘。
设备信息安装文件(.INF)包含了驱动程序的名称,驱动程序应该复制到的目录,以及在驱动程序安装时必须生成和修改的注册表入口。
在编写INF文件时,我使用了VtoolsD开发包中的INFEditor工具,以下是我所编写的PCI2040安装信息文件。
[Version]
Signature=$CHICAGO$
Class=PCIBridge//设备类型为PCI桥设备
Provider=%String0%//供应商的名称
[ClassInstall]
[DestinationDirs]
DefaultDestDir=11//将驱动程序安装在C:
\Windows\System目录下
[
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- vxd 驱动 开发