我们开发了一套通用的PCI设备驱动轨范,它可以完成一般PCI设备驱动所需的功能,可以作为其它PCI设备驱动开发的框架。
1 驱动轨范的模式和开发工具的选择
设备驱动轨范是指打点某个外围设备的一段代码。驱动轨范不会独登时存在,而是操作系统的一部门。经由过程设备驱动轨范,多个历程可以同时使用这些资本,从而可以实现多历程并走运行。不才文中,将挪用设备驱动轨范的PC机轨范称为用户轨范。
Windows 95和Windows NT采用的驱动轨范系统分歧,所以年夜年夜都情形下驱动轨范也不能通用。若是设备需要在Windows 9x/NT下使用,一般至少要设计Windows 9x和Windows NT两个驱动轨范版本。Windows 98 可以兼容Windows 95的驱动轨范,同时它又推出一个新的Win32 Drivers Mode(WDM)驱动类型。Windows 98中有些设备(如USB设备)的驱动轨范必需为WDM模式。这个新的类型现实是在Windows NT的驱动模子的基本上增添了即插即用等内容。WDM驱动也可以用在Windows 2000(先前叫Windows NT 5.0)中。从久远的角度看。此后开发人员只要开发WDM驱动就可以了,但从今朝的市场情形来看,Windows 95是无法抛却的,所以WDM在近一两年还无法替代其它类型的设备驱动。
ler_508.do" target="_blank">Intel 80386以上的微措置器有4个优先级别:0级、1级、2级和3级,一般操作系统运行于优先级0级上,而用户轨范运行在3级上,在对硬件操作上有一些限制(具体的限制在分歧的操作系统中是分歧的)。Windows 95撑持的驱动类型良多,但针对一般硬件设备而言,主若是VxD和打印机驱动两类。VxD指的是Virtual Device Drivers。VxD运行在Intel系统的0级上,可以执行特权级指令,对任何I/O设备有全数访谒权,所以年夜年夜都硬件驱动轨范都是VxD。VxD驱动凡是以。vxd为扩展名,放在WindowsSystem目录下,可以在Windows 95启动时装入,也可以在轨范运行时按照需要动态地载入。动态加载有助于节约系统内存和资本。但打印机驱动轨范不是VxD,它运行在3级上。同Windows 95近似,Windows NT的驱动也有可以运行在0级的内核模式(Kernel Mode)和运行在3极的用户模式(User Mode)之分。因为Windows NT禁止用户模式的轨范访谒I/O端口(Windows 95/98则许可用户轨范直接访谒I/O端口),直接节制物理设备的驱动轨范都是内核模式的。而我们设计的PCI通用驱动轨范要求对各类硬件资本访谒,所以应该选择工作在0级的驱动轨范模式。
开发设备驱动采用的首要开发工具是微软为设备开发者供给的软件包Device Driver Kit(DDK)。这个软件包搜罗有关设备开发的文档、编译需要的头文件和库文件、调试工具和轨范典型。在DDK中还界说了一些设备驱动可以挪用的系统底层处事,象DMA处事、间断处事、内存打点处事、可安装文件系统处事等等。这些都是编写设备驱动所必需的。但Windows 95的DDK因为首要使用汇编说话描述。开倡议来斗劲坚苦。是以,我们在Windows 95操作系统中同时采用了Numega公司的产物VtoolsD。VtoolsD是基于C/C++的,撑持Borland C++和Visual C++,使用和维护都较Windows 95 DDK轻易。
2 PCI驱动轨范的特点
在设计驱动轨范之前,首先要对欲节制的硬件设备进行详尽地剖析,更需要具体体味硬件设备的特征。硬件设备的特征会对驱动轨范设计发生重年夜的影响。需要体味的最首要的硬件特征搜罗:
(1)设备的总线结构
设备采用什么总线结构很是关头,因为分歧的总线类型(如ISA和PCI)在良多硬件工作机制上是分歧的,所以驱动轨范设计也分歧。
(2)寄放器
要体味设置的节制寄放器、数据寄放器和状况寄放器,以及这些寄放器工作的特征。
(3)设备错误和状况
要体味若何判定设备的状况和错误旌旗灯号,这些旌旗灯号要经由过程驱动轨范返回给用户。
(4)间断行为
要体味设备发生间断的前提和使用间断的数目。
(5)数据传输机制
最常见的数据传输机制是经由过程I/O端口(port),也就是经由过程CPU的IN/OUT指令进行数据读写。PC的另一种主要的传输机制是DMA,但PCI规范不搜罗隶属DMA的声名。
(6)设备内存
良多设备自身带有内存,PCI设备年夜多是采用映射的体例映射到PC系统的物理内存。有的设备还要经由过程驱动轨范设置设备的接口寄放器。
有关驱动轨范的加载和响应用户请求的内容,在DDK文档中有划定,所以设计设备驱动轨范首要的面临问题是若何进行硬件操作,这是按照设备的分歧而分歧的。而硬件驱动轨范的功能虽然千差万别,但根基功能就是完成设备的初始化、对端口的读写操作、间断的设置、响应和挪用以及对内存的直接读写。如前面所说,Windows 9x和Windows NT的操作系统模子分歧,但驱动轨范所要完成的工作却是不异的,所以下面以Windows 9x为主进行介绍,仅在需要的处所指出两个操作系统的分歧。下面从这几方面谈判解决这些问题的路子#e#下面从这几方面谈判解决这些问题的路子:
(1)设备初始化
PCI设备驱动轨范要实现识别PCI器件、寻址PCI器件的资本和对PCI器件间断的处事。PCI系统BIOS功能供给了BIOS的访谒与节制的具体特征,所有软件(设备驱动轨范、扩展ROM码)将经由过程尺度间断号1AH挪用BIOS功能访谒非凡部件。PCI BIOS规范有完整的有关PCI BIOS功能的描述[3]。
在PCI设备驱动轨范的初始化过程中,操作指定器件识别号(device_id)、厂商识别号(vendor_id)、检索号(index)搜索PCI器件,经由过程挪用PCI BIOS确认其存在,并确定其物理位置:总线号、器件号和功能号,这是该器件/功能在系统中的独一寻址标识表记标帜。操作总线号、器件号和功能号可以寻址该器件/功能的PCI设置装备摆设空间(configuration space)。
接下来,设备驱动就需要从设置装备摆设空间获得硬件的参数。PCI设备的良多参数,搜罗所用的间断号,端口地址的规模(I/O)体例、存储器的地址(存储器映射体例)等,都可以从PCI设置装备摆设空间的各基址所对应的寻址空间中获得。读写设置装备摆设空间可以挪用BIOS间断1AH,
也可以先向设置装备摆设空间地址寄放器(0CF8H)写入总线和设备号(在前面搜索PCI器件时获得的)和寄放器号,再对设置装备摆设空间数据寄放器(0CFCH)进行读写。对设备驱动来说,最主要的是获得基址寄放器(BADR),不能认为PCI器件资本老是设计设备时设置的初值,系统可能会按照硬件情形为PCI设备分配新的资本。我们所设计的PCI设备使用的基址1-3都是按I/O空间映射的,而基址4是按内存体例映射的。确定一个端口是按什么体例映射的,可以读对应端口的设置装备摆设寄放器(Configuration Register)。读出后,判定其0位,若是0位为数值0,暗示其是按内存体例设置的,否则为I/O体例设置的。内存体例和I/O体例的设置装备摆设寄放器的寄义参见文献[3]。若是要获得基址的巨细,可以向基址寄放器写入FFFFH,然后读基址寄放器,若是是内存体例,从第4位起头的0的数目暗示基址的巨细,若是是I/O体例,则从第2位起头的0的数目暗示基址的巨细。
在Windows NT下,查找PCI设备的工作是由HalGetBusData完成的,也可以使用前述的法子读取设置装备摆设寄放器,但DDK举荐使用HaiGetBusDataOffset函数。
(2)端口操作
在PC机上,I/O端口寻址空间和内存寻址空间是分歧的,所以措置体例也分歧。I/O空间是一个64K字节的寻址空间,它不象内存有实模式和呵护模式之分,在各类模式下寻址体例不异。在Windows 9x下,用户轨范可以直接使用I/O指令,而不必然非经由过程专门的驱动轨范来完成,所以若是软件对硬件的操作美全是经由过程I/O端口操作来完成的,甚至可以不用专门设计驱动轨范,直接由应用轨范来完成对硬件的节制。因为PCI总线是32位的总线尺度,在进行I/O操作时凡是要进行双字(DWORD)操作,而且以前年夜年夜都C/C++编译软件都没有供给双字的函数,所以需要机关双字操作读写函数inpd/outpd。
在Windows NT下,系统不许可处于优先级3级的用户轨范和用户模式驱动轨范直接使用I/O指令,若是使用了I/O指令将会导致特权指令意外(privileged instruction exception)。所以任何对I/O的操作都需要借助内核模式驱动来完成。具体的做法有两种:一是在驱动轨范中使用IoReportResourceUsage陈述资本占用,然后使用READ_PORT_XXX、WRITE_PORT_XXX函数读写,最后使用IoReportResourceUsage打消资本占用;另一种是驱动轨范改削NT的I/OPermissions Map (IOPM),以使系统许可用户轨范对指定的I/O端口进行操作,这时用户轨范采用凡是的I/O指令进行操作。后者的利益是速度快、用户轨范设计简单,但牺牲了移植性,轨范不能移植到非Intel的系统中,而且若是多个轨范同时读写统一端口轻易导致冲突。
(3)内存的读写
Windows工作在32位呵护模式下,呵护模式与实模式的根柢区别在于CPU寻址体例上的分歧,这也是Windows驱动轨范设计中需要着重解决的问题。Windows采用了分段、分页机制(图1),这样使应用轨范发生一种错觉,好象轨范中可以使用很是年夜的物理存储空间。这样做最年夜的益处就是一个轨范可以很轻易地在物理内存容量纷歧样的、设置装备摆设规模分歧很年夜的计较机上运行,编程人员使用虚拟存储器可以写出比任何现实设置装备摆设的物理存储器都年夜得多的轨范。