虚拟设备驱动程序的设计与实现 陈国友 由于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的基本原理和设计方法,并结合开发工具vtoolsd给出了一个为可视电话音频卡配套的虚拟设备驱动程序vxd的设计实例。 1.windows 9x的虚拟环境 windows 9x作为一个完整的32位多任务操作系统,它不像window 3.x那样依赖于ms-dos,但为了保证软件的兼容性,windows 9x除了支持win16应用程序和win32应用程序之外,还得支持ms-dos应用程序的运行。windows 9x是通过虚拟机vm(virtual machine)环境来确保其兼容和多任务特性的。 所谓windows虚拟机(通常简称为windows vm)就是指执行应用程序的虚拟环境,它包括ms-dos vm和system vm两种虚拟机环境。在每一个ms-dos vm中都只运行一个ms-dos进程,而system vm能为所有的windows应用程序和动态链接库dll(dynamic link libraries)提供运行环境。每个虚拟机都有独立的地址空间、寄存器状态、堆栈、局部描述符表、中断表状态和执行优先权。虽然win16、win32应用程序都运行在system vm环境下,但win16应用程序共享同一地址空间,而win32应用程序却有自己独立的地址空间。 在编写应用程序时,编程人员经常忽略虚拟环境和实环境之间的差异,一般认为虚拟环境也就是实环境。但是,在编写虚拟设备驱动程序vxd时却不能这样做,因为vxd的工作是向应用程序代码提供一个与硬件接口的环境,为每一个客户虚拟机管理虚设备的状态,透明地仲裁多个应用程序,同时对底层硬件进行访问。这就是所谓虚拟化的概念。 vxd在虚拟机管理器vmm(virtual machine manager)的监控下运行,而vmm实际上是一个特殊的vxd。vmm执行与系统资源有关的工作,提供虚拟机环境(能产生、调度、卸载vm)、负责调度多线程占先时间片及管理虚拟内存等工作。vxd与vmm运行在其他任何虚拟机之外,vxd事实上就是实现虚拟机的软件的一部分。 与大多数操作系统一样,windows也是采用层次式体系结构。vmm和vxds构成了win 95的ring0级的系统核心(应用程序运行在ring3级,ring1、ring2级未被使用),具有系统的最高优先权。windows还提供一些以"drv"为后缀名的驱动程序,主要是指串行口的通信程序和并行口的打印机程序。这些程序与vxd不同,它们是运行在ring3级上的。图1可以使你更好地理解windows的虚拟环境。 图 2.深入理解vmm和vxd 如前所述,vxd是virtual device driver的缩写,但有人将它理解为虚拟任何驱动程序。实际上,vxd并非仅指那些虚拟化的某一具体硬件的设备驱动程序。比如某些vxd能够虚拟化设备,而某些vxd作为设备驱动程序却并不虚拟化设备,还有些vxd与设备并没有什么关系,它仅向其他的vxd或是应用程序提供服务。 vxd可以随vmm一起静态加载,也可以根据需要动态加载或卸载。正是由于vxd与vmm之间的紧密协作,才使得vxd具有了应用程序所不具备的能力,诸如可以不受限制地访问硬件设备、任意查看操作系统数据结构(如描述符表、页表等)、访问任何内存区域、捕获软件中断、捕获i/o端口操作和内存访问等,甚至还可以截取硬件中断。 尽管vxd使用32位平面存储模式(flat memory model),但它的代码和数据仍使用分段管理,段有六种类型,即实模式初始化、保护模式初始化、可分页、不可分页、静态和只调试(debug only),每种类型又有代码段和数据段之分,所以vxd共有12个段。实模式代码段和数据段为16位(分段模式),其他段则是32位(平面模式)。“实模式初始化”段包含了在windows初始化过程的最初阶段vmm变为保护模式之前要执行的代码。静态加载的vxd此时可以查看windows启动前的实模式环境,决定是否继续加载,并通知vmm。加载完毕后,vmm进入保护模式并执行保护模式初始化代码,同样将执行结果再通知vmm。初始化完成后,“实模式初始化”段和“保护模式初始化”段即被遗弃。vxd的大部分代码都在其他的某一段中,“可分页”段允许虚拟存储管理器(virtual memory manager)进行分页管理,大多数的vxd代码都应当在“可分页”段。“不可分页”段的内容主要包括:vxd的主入口点、硬件中断处理函数、所访问的数据以及能被另一个vxd中断处理函数调用的异步服务。“静态”段仅用于可以动态加载的vxd,当vxd卸载后,静态代码段和数据段都保留在内存中。“只调试”段只是vmm在soft-ice for win 95等调试环境下才将其载入。 vmm是通过vxd的设备描述符块ddb(device descriptor block)来识别的。ddb向vmm提供了vxd的主入口点,还向应用程序和其他的vxd提供了入口点。vmm利用这个主入口点将vm及windows自身的状态通知给vxd,然后vxd通过相应的工作来响应这些事件。由于vxd不仅仅服务于一个物理设备(比如多个串口)或仅与一个vm发生联系,所以vxd需要产生自己支持的数据结构(supporting data structures)来保存每一个设备、每一个vm的配置和状态信息。vxd用一个或多个设备上下文结构来保存设备信息,如i/o端口基地址、中断向量等,vxd将自己的每个vm的状态信息保存在vmm的vm控制块中。 vmm提供的服务包括:事件服务、内存管理服务、兼容执行和保护模式执行的服务、登录表服务、调度程序服务、同步服务、调试服务、i/o捕获服务、处理错误和中断服务、vm中断和回调服务、配置管理程序服务以及其他杂项服务。 以上内容仅涉及到vxd设计的一小部分,作为vxd的开发人员必须掌握更多的知识。首先是操作系统的知识,如地址空间、执行上下文、资源加锁、进程间通信和异步事件处理等方面的知识;其次,对intel处理器应有较深入的理解,包括寄存器、机器指令集、保护机制、分页机制,以及虚拟8086模式;最后,还必须熟悉vmm提供的各类服务和接口,熟悉windows其他的系统vxd。 3.开发工具vtoolsd简介 vtoolsd是专门用于开发vxd程序的一种工具软件,它包括vxd框架代码生成器quickvxd、c运行库、vmm/vxd服务库、vxd的c++类库、vxdload和vxdview等实用工具以及大量的c、c++例程。由vc++、bc++的32位编译器编译生成的vxd程序可以脱离vtoolsd环境运行。 利用quickvxd可以方便、快捷地生成vxd的框架,即生成后缀名为h、cpp和mak的三个文件。源文件包含了运行vxd的基本组件,其中包含控制消息处理、api入口点、以及vxd服务等函数框架,并且还定义了标志,设置了编译参数,声明了类,然后在c++环境下,向生成的各个处理函数体内添加自己的代码,最后使用编译器nmake生成标准的vxd程序。 由于vxd运行在ring0级,所以调试程序相当困难。我使用的调试工具是soft-ice for win 95。