1 Windows95驱动程序原理
Windows 95 时期 Windows95终结了DOS实模式的历史,是真正独立的32位操作系统。Win95使用数种不同的驱动驱动程序模型。在操作系统中,程序必须通过系统内核上的驱动来控制硬件,而这些驱动必须完全符合操作系统对驱动加载、连接、读写的规定,并且使用相关系统API(Application Programming Interface)函数来控制。Windows 95的驱动程序类型以VXD为中心VXD又称虚拟设备驱动。它不仅适用于硬件设备,还能虚拟出不存在的"软件设备",如虚拟光驱。 所有运行Windows的程序都分为两个保护级:Ring0和Ring3。系统进程运行于Ring0级,这个保护级的程序拥有完全的系统控制权限,可对所有的系统资源进行访问与管理;普通应用程序运行与Ring3级,不允许对系统资源进行直接访问且很多操作系统也受到限制,如果程序强行访问的话,Windows就会给出出错提示并强制结束——我们会经常看到某些程序运行中出现"常规保护错误"等错误提示,也就是这个原因。 所有的Ring3级程序在Windows下都受到80×86保护模式的严格"监视",使应用程序无法进行的操作,不过,VXD能使应用程序具有扩展操作系统的能力,开发人员通过让运行于Ring3级的普通程序加载具有Ring0级的VXD,从而实现底层控制。不幸的是,着名的"CIH"病毒就是利用了VXD技术才可以破坏主板BIOS。
WDM 模型 WDM模型采用分层结构,首先是由模型来描述设备驱动程序的标准结构;其次微软为常见类型的设备提供一系列的总线驱动程序和类型驱动程序。模型描述驱动程序如何安装和启动,类驱动则具有为许多标准类型设备所需的基本功能。标准的WDM驱动应该包含1个总线驱动和1个功能驱动。 总线驱动:总线驱动已经包含在Windows中,不必另行安装。总线包括PCI、AGP、并口、串口、IEEE1394接口等。总线驱动主要负责管理总线设备,例如当我们在PCI插槽上插入新硬件,开启电脑并进入系统后总线驱动开始工作——发现新硬件,并提示用户安装驱动程序。不仅如此,总线驱动还会实时向操作系统总线设备状态,检测总线上有什么类型的设备,这就是家喻户晓的"即插即用"。总线设备还负责设备的电源管理(ACPI),比如Windows的休眠功能。当我们通过控制面板选择不同电源管理模式时,电源管理器就会通过系统发出的电源命令向总线驱动发出改变电源状态的请求,总线驱动会响应这些请求并设置相应设备的电源状态。 功能驱动:这就是常说的驱动程序,由类驱动程序和Mini驱动程序组成。其中,类驱动用来处理常规系统事务,如电源管理和即插即用,这都是由微软定义好的,程序开发者只需要编写Mini驱动即可。功能驱动一般由设备生产厂商提供,用以实现硬件设备的具体功能。例如NVIDIA系列显卡只有在"雷管"驱动的支持下才能使用抗锯齿和各项异性过虑。 过虑驱动:过虑驱动程序位于其他的驱动程序层之间,提供一些附加功能但不影响其他驱动程序,例如不少品牌电脑宣传的一键上网功能是通过键盘过虑驱动和应用程序来实现的。
Windows95视频采集卡设备驱动程序包括虚拟设备驱动程序和可安装设备驱动程序两部分,一般可以采用Microsoft Windows95 DDK(Device Driver Kit)进行原形、输入库以及一些样例代码,但是未提供编程所需要的编译、汇编和连接程序。采用Visual C++ 5.0、Visual C++ 1.5以及MASM 6.0进行程序设计。设备驱动程序设计的好坏与采集卡的功能、性能、 兼容性及稳定性密切相关。为保证驱动程序的质量,应当严格遵照Windows95 DDK的文档进行程序设计。
2 虚拟设备驱动程序设计
在视频采集卡的驱动程序中,虚拟设备驱动程序CAPTURE.VXD负责参与系统即插即用配置过程,管理视频采集卡的硬件设备,并向运行在权限级3的上层程序提供调用接口:一是将分配的资源返回,如内存选择子、I/O地址、中断号等,使得上层驱动程序可以使用这资源来操纵采集卡硬件设备;二是完成一些在权限级3所不能进行的操作,如分配DMA缓冲区、查看内存映射页表等。虚拟机管理器和虚拟设备驱动程序运行在一个单一的32位平板模式址空间中,权限级为0。系统建立两个基地址为0、界限为4GB的全局描述符选择子分别用于代码段和数据段,程序不应当直接修改段寄存器、内存描述符表、中断描述符表。
2.1 设备声明
虚拟设备驱动程序必须包含一个声明,它一般位于程序的前部,声明中包括虚拟设备驱动程序的名称、版本号、调用接口等一些重要信息。
设备名称定义了虚拟设备驱动程序的名称。设备控制过程接受来虚拟机管理器的消息,并根据不同消息进行不同的操作。设备标识符是一个16位整数,它是该程序在系统中的标识。初始化次确定虚拟设备驱动程序的装载顺序,首先装入初始化次序值较小的虚拟设备驱动程序。V86 API接口用于接受来自虚拟8086模式程序的调用。PM API接口接受来自16位保护模式程序的调用。
2.2 设备控制过程
由于Windows对系统底层操作采取了屏蔽的策略,因而对用户而言,系统变得更为安全,但这却给众多的硬件或者系统软件开发人员带来了不小的困难,因为只要应用中涉及到底层的操作,开发人员就不得不深入到Windows的内核去编写属于系统级的虚拟设备驱动程序。Win 98与Win 95设备驱动程序的机理不尽相同,Win 98不仅支持与Windows NT 5.0兼容的WDM(Win32 Driver Mode)模式驱动程序,而且还支持与Win 95兼容的虚拟设备驱动程序VxD(Virtual Device Driver)。下面介绍了基于Windows 9x平台的虚拟环境、虚拟设备驱动程序VxD的基本原理和设计方法,下面为可视电话音频卡配套的虚拟设备驱动程序VxD的设计实例:
BeginProc WBD848_Control
Control_Dispatch Sys_Dynamic_Device_Init,WBD848_Dyn_Device_Init
Control_Dispatch Sys_Dynamic_Device_Exit,WBD848_Dyn_Device_Exit
Control_Dispatch PnP_New_DevNode,WBD848_PnP_New_DevNode
Control_Dispatch W32_DEDVICEIOCONTROL,WBD848_W32_DeviceIOControl
Clc
Ret
EndProc WBD848_Control
与视频采集卡即插即用配置过程相关的消息是PnP_New_DevNode。系统首先检测视频采集卡硬件存在,然后根据PCI接口板厂商和器件标识在注册表中找到对应的虚拟设备驱动程序并装入内存,随后系统向该虚拟设备驱动程序发送PnP_New_DevNode消息。因为视频采集卡属于多媒体设备,设备驱动程序的装入应由MMDEVLDR.VXD完成,所以虚拟设备驱动程序在处理PnP_New_DevNode消息时,调用MMDEVLDR.VXD的服务MMDEVLDR_Register_Device_Driver注册了回调函数PnP_Config_Handler,系统根据采集卡PCI配置空间为其分配资源后将调用此回调函数。在PnP_Config_Handler中可以使用CM_Get_Alloc_Log_Conf服务获得系统为采集卡分配的资源。处理系统控制消息PnP_New_DevNode的例程如下:
BeginProc WBD848_PnP_New_DevNode
Mov eax,ebx ;虚拟机句柄
Mov ebx, offset32 PnP_Config_Handler;即插却用处理例程
VxDCall MMDEVLDR_Register_Device _Driver
Mov eax,CR_SUCCESS
Stc
Ret
EndProc WBD848_PnP_New_DevNode
在回调函数PnP_Config_Handler中获得的资源包括内存、I/O、中断和DMA四种。PCI总线视频采集卡主要使用内存和中断资源,它包括一个内存窗口作为内存映射I/O和一个中断IRQ号。虚拟设备驱动程序应用使用_MapPhysToLonear服务将内存窗口物理地址映射到线性地址空间中,并使用_Allocate_GDT_Selector服务分配内存选择字,以便16位应用程序访问该内存区域。
2.3 应用程序接口
虚拟设备驱动程序为虚拟8086模式、16位及32位保护模式应用程序分别提供应用程序编程接口,使运行在权限级3上的应用程序可以访问虚拟设备驱动程序。前两种接口在设备声明时定义,应用程序通过中断调用INT28H AX=1648H获得虚拟设备驱动程序的入口地址。32位接口通过W32_DEVICEIOCONTROL系统信息消息实现,应用程序则使用系统API函数DeviceIoControl对虚拟设备驱动程序进行调用。
当16位应用程序对入口地址发出远调用后,虚拟机管理顺将应用程序的寄存器内容保存在Client_Reg_Struc结构中,并将指向该结构的指针赋予EBP寄存器,然后调用相应的虚拟设备驱动程序。虚拟设备驱动程序必须访问Client_Reg_Struc结构中的数据以获得应用程序的调用参数。一般利用AX寄存器传递功能号,利用其它寄存器传递参数,执行结果通过Client_Reg_Struc结构返回。16位保护模式应用程序使用选择子——偏移量地址模型,而虚拟设备驱动程序使用32位平板式地址模型,如果参数是以指针的形式传递给虚拟设备驱动程序,需要使用宏Client_Ptr_Flat进行转换。
本采集卡中虚拟设备驱动程序提供的主要功能是:(1)使应用程序获得系统为采集卡分配的资源,如内存映射、I/O地址和中断IRQ号,以便操纵采集卡;(2)提供有关内存页表的信息,以便进行DMA操作。16位应用程序接口的部分代码如下:
;******** Copy Page Table ********
Client_Ptr_Flat eax,ES,BX ;es:bx指向页表缓冲区
Client_Ptr_Flat ebx,DI,SI ;di:si指向DMA缓冲区
Shr ebx,12 ;起始页号
Movz ecx,[ebp].Client_CX ;cx为需要拷贝的页表项个数
VMMcall _CopyPageTable <ebx,ecx,eax,0>
Mov [ebp].Client_EAX,eax ;ax返回执行结果
Ret
;********** Get Resource **********
movzx eax, _g_wSelector ;存储器映射I/O地址选择子
mov [ebp].Client_EAX,eaz
movzx eax,_g_wIRQ
mov [ebp].Client_EBX,eax
ret
32位应用程序接口的功能与16位接口十分相似,只是将存储器映射I/O地址以32位线性地址的方式返回,以适应32位平板模式的寻址要求。另外32位接口不返回中断IRQ号,因为32位应用程序中不进行有关中断的操作。
3 可安装设备驱动程序
3.1 Video For Window编程模型
视频采集卡可安装设备驱动程序采用Video For Window程序模型,它从各种各样的视频采集卡抽象出一个统一的逻辑结构,以便上层程序调用。上层程序主要是指由AVICap32.dll等系统动态链接库构成的视频采集引擎。视频采集引擎负责显示视频数据、分配数据缓冲区、操纵系统调色板、存储AVI文件等工作,它们将应用程序的调用翻译成低级消息发送给可安装设备驱动程序。可安装设备驱动程序在消息的控制下,操纵采集卡硬件设备,完成视频数据的采集。Video For Window驱动程序逻辑结构如图2所示。
Video For Window驱动程序模型包括视频源、帧存储器、显示设备、CPU和四个视频数据通道。帧存储器只具有逻辑上意义,可能在采集卡上或位于主机内存中或者根本上不存在。它在图2中只表明处于该闰置的应当是已经解码完整的视频数据。四个视频数据逻辑通道的功能如下:
External In代表视频信号由模拟向数字的转换过程,包括采样量化、解码等工作。该通道负责视频信号的选择(摄像机、录像机、调谐器等),视频信号制式选择(NTSC、PAL、SECAM等),亮度、对比度、色调的调节等工作。
Video In 代表视频数据由帧存储器向系统缓冲区的传输过程。该通道负责视频图像数据的传输工作,如设定图像大小、彩色格式,确定图像帧的同步定时等。
External Out 代表视频数据向显示设备的直接传输过程。该通道负责视频图像的实时显示工作,如确定显示窗数据格式,进行显示窗口的剪裁等。
Video Out 代表视频数据由系统缓冲区向帧存储器的反向传输过程。该通道负责视频数据的回放,具有视频解压缩功能的休集卡可能需要这种反向的传输,以便对压缩数据进行解码。
3.2 数据传输
驱动程序将采集到的数据传送到上层程序时使用VIDEOHDR结构,该结构包含了数据缓冲区、数据长度、时间戳等信息,定义如下:
typedef struct {
LPSTR lpData; //address of video buffer
DWORD dwBufferLength; //size,in bytes,of the data buffer
DWORD dwBufferLength; //size,in bytes,of the data buffer
DWORD dwBytesUsed;
DWORD dwTimeCeptured;
DWORD dwUser; //user-specific data
DWORD dwFlags;
DWORD dwReserved[4];//reserved;do not use }VIDEOHDR;
LpData 视频数据缓冲区指针,由采集引擎填写;
dwBufferLength 视频数据缓冲区长度,由采集引擎填写;
dwBytesUsed 缓冲区中图像数据的实际长度,由驱动程序填写;
dwTimeCaptured 时间戳,从采集帧起以ms为单位记录,用于视频数据的同步,由驱动程序填写;
dwFlage 标志,驱动程序应当填写VHDR_DONE以表示采集完成,如果此帧为关键帧还可以同时使用VHDR_KEYFRAME标志。
缓冲区通常由视频采集引擎分配,并钭VIDEOHOR结构指针以消息参数形式发送给驱动程序。当进行单帧采集时,驱动程序每收到一个DVM_FRAME消息便采集一帧图像,驱动程序从DVM_FRAME消息返回时将VIDEOHDR结构返回给采集引擎。
序列图像的采集比较复杂,驱动程序与采集引擎间以缓冲区队列的形式进行数据交换,确保了连续的实时采集。采集引擎使用DVM_ADDBUFFER消息将空数据缓冲区不断地加到缓冲区队列的队尾。同时,驱动程序将空数据缓冲区从队列的队首取出,并进行视频采集。驱动程序将填充视频数据的缓冲区通过回调函数返回给采集引擎,由它进行显示、存盘等操作。添加缓冲区和取出缓冲区是两个相对独立的异步操作。采集引擎是缓冲区的生产者,它可以在系统空闲时分配若干个缓冲区并加入队尾。驱动程序是缓冲区的消费者,在采集卡硬件中断的驱动下它不断取出空缓冲区,并将用过的缓冲区返还给采集引擎。
3.3 视频实时显示
视频图像实时显示功能又称为Overlay,它将视频图像以窗口方式在计算机屏幕上实时显示,显示的画面具有良好的视觉效果,显示窗口与Windows95的图形具有良好的视觉效果,显示窗口号Windows95的图形界面配合默契。要实现这些功能,首先采集卡必须具有将数据直接传输至显示卡的硬件设备,因为实时显示数据传输量巨大,主机CPU是不可能承担这样的任务的;其次要求软硬件设备默契配合。
DirectDraw是一种软件接口标准,提供了对显示设备的直接访问。它将显示画面分成表面(Surface),每种表面具有不同的属性,如尺寸大小、彩色格式等。整个屏幕对应的表面称为主表面,程序可以在显存或内存中建立其它表面,并在这些表面中绘制图形,然后通过某种操作这些表面的内容显示在主表面上,这些操作是高效率的,程序可以从中获得很高的性能。Overlay表面具有特殊的性质,它位于显存,并且可以覆盖显示在主表面的任何位置。
当驱动程序的External Out通道收到DVM_STREAM_INIT消息时,开始视频实时显示。首先启动DirectDraw接口,创建主表面和Overlay表面,并记录有关Overlay表面的信息,如尺寸、数据格式、内存地址等,同时为Overlay表面选择一个颜色作为色键,通常是洋红色。然后根据Overlay表面的信息初始化硬件设备,使DMA设备将视频数据直接关入Overlay表面所在的显存中。当显示窗口移动或改变大小时,视频采集引擎会发送DVM_UPDATE消息通知驱动程序更新显示,驱动程序应当在视频窗口中填充色键的颜色,并移动Overlay表面使其与视频窗口对齐。因为可安装设备驱动程序是16位模块,而DirectDraw位于32位模块中,在采集卡驱动程序中不能直接调用DirectDraw接口,故意需借助Flat Thunk在16位与32位模块间建立联系。
本设备驱动程序朝阳区分利用PCI总线的带宽和Windows95系统资源,获得了较高的采集速率(384×288×24bits 25fps),实现了实时视频显示。
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。