视频微端口驱动程序.docx
《视频微端口驱动程序.docx》由会员分享,可在线阅读,更多相关《视频微端口驱动程序.docx(27页珍藏版)》请在冰豆网上搜索。
视频微端口驱动程序
WindowsNT/Windows2000视频微端口驱动程序(VideoMiniportDriver)是特定适配器的、内核模式的驱动程序。
每一种可在WindowsNT/Windows2000中应用的图形卡都必须有视频微端口驱动程序和显示驱动程序。
视频小驱动程序将它自身链接到视频端口驱动程序上,视频端口驱动程序是一个系统提供的内核模式的动态链接库(DLL)。
视频端口驱动程序的VideoPortXxx函数调用微端口驱动程序来与系统及它的硬件进行通信。
Windows2000微端口驱动程序必须以即插即用(PnP:
PlugandPlay)的驱动程序来实现。
Windows2000视频端口驱动程序同时继承性地支持WindowsNT4.0驱动程序。
本章提供了视频微端口驱动程序实现及编写的详细资料,描述了微端口驱动程序与显示驱动程序以及视频端口驱动程序的交互操作。
对所有视频端口和微端口驱动程序的函数参考可以在图形驱动程序参考的在线DDK中查到。
显示驱动程序将主要在第一章显示介绍及第二章显示驱动程序中讨论。
6.1视频微端口头文件、示例代码及参考
WindowsNT/Windows2000视频微端口驱动程序包括下列头文件:
文件内容
dderror.h
由微端口驱动程序返回给视频端口驱动程序的win32状态常量,也可以返回到与微端口驱动程序对应的内核模式显示驱动程序
devioctl.h
用于定义I/O控制代码的宏及常量
miniport.h
视频微端口和SCSI微端口驱动程序所需的基本类型、常量和结构
ntddvdeo.h
系统定义的I/O控制(IOCTLs)以及相应的结构等,可以按视频请求包VRPs传送到视频微端口驱动程序。
tvout.h
用于实现TV连接以及拷贝保护支持的VIDEOPARAMETERS结构以及此结构中使用的常量
video.h
VideoPortXxx和SvgaHwIoPortXxx视频端口函数声明。
视频专用的结构如VIDEO_REQUEST_PACKET以及HwVidXxx视频微端口函数原型
videoagp.h
AGP专用的结构,AgpXxx微端口驱动程序函数原型。
以及支持视频微端口驱动程序的实现图形端口(AGP:
AcceleratedGraphicsPort)加速所需的VideoPortXxx函数声明
这些头文件与Windows2000DDK一起发布。
需要包含在这些头文件中的函数、结构、系统定义的I/O控制代码、常量的更详细信息,可参考在线DDK中图形驱动程序参考部分的内容。
Windows2000DDK同样提供好几个视频微端口驱动程序工作的实例代码,其内容放在video\miniport目录下。
3dlabs微端口驱动程序实例实现了广泛的功能;s3virge微端口驱动程序实例则实现了VPE;mirror实例则包含该驱动程序专用的微端口驱动程序实现。
6.2在图形体系结构中的视频微端口驱动程序
图6-1显示了WindowsNT/Windows2000图形子系统中的视频微端口驱动程序。
插入图6-1WindowsNT/Windows2000图形体系结构
每一个视频微端口驱动程序提供硬件级的显示驱动程序支持,显示驱动程序调用图形引擎函数EngDeviceIocontrol请求下面的视频微端口驱动程序支持,并依次调用一个I/O系统服务以通过视频端口驱动程序向微端口驱动程序发送请求。
在大多数情况下,显示驱动程序完成对用户可见的时间关键的操作,而其下层的微端口驱动程序则提供对非经常性请求操作的支持,或者提供对不能被中断或设备环境转换到另外一个进程所剥夺的真正的时间关键性操作的支持。
显示驱动程序不能支持设备中断,只有微端口驱动程序可以建立起设备内存并将它映射到显示驱动程序的虚拟地址空间。
视频端口驱动程序是系统提供的用于支持视频微端口的驱动程序模块,并充当显示驱动程序与视频微端口驱动程序之间的中介。
要获得更多的WindowsNT/Windows2000的显示驱动程序的信息,参考第一章显示介绍及第二章显示驱动程序中的内容。
6.2.1视频微端口驱动程序特定平台的详细内容
在基于x86的WindowsNT/Windows2000平台,有两种视频微端口驱动程序:
非VGA兼容微端口驱动程序和VGA兼容微端口驱动程序。
6.2.1.1非VGA兼容、基于x86的微端口驱动程序
许多微端口驱动程序是非VGA兼容的并因此非常容易实现。
非VGA兼容的视频微端口驱动程序依赖于系统提供的VGA微端口驱动程序(vga.sys)或另外一个当前装载的VGA兼容的SVGA微端口驱动程序。
这些微端口驱动程序的设置是在registry注册文件中将vgacompatible设置为零(FALSE)并且具有以下特征:
■它对全屏的、基于X86机器的MS-DOS应用程序不支持。
但是,它是随着系统提供VGA(或者可能是VGA兼容的SVGA)微端口驱动程序的装载来提供对全屏的MS-DOS应用程序的支持。
■在大多数情况下,它是对没有VGA兼容模式适配器而编写的或者是为独立工作于VGA的加速器而编写的。
6.2.1.2VGA兼容的基于x86的微端口驱动程序
VGA兼容的微端口驱动程序主要包括以下特点:
■它基于系统提供的VGA微端口驱动程序,可以修改一定的代码来支持特定适配器的特性。
系统提供的VGA显示驱动程序利用VGA兼容的微端口驱动程序支持,这样VGA兼容的适配器的微端口驱动程序开发者就不需要再编写新的显示驱动程序。
■它提供全屏MS-DOS应用程序的支持可以直接对适配器寄存器进行I/O操作。
它同时作为一个视频检验器以防止这些应用程序发布任何使系统中止的指令序列。
许多SVGA适配器的微端口驱动程序也归入此类。
但是对非SGVA适配器的任何新的微端口驱动程序可以根据驱动程序设计者的判断来提供VGA兼容支持。
VGA兼容的微端口驱动程序可以由在注册表中的vgacompatible设置成为1(TRUE)来配置。
6.3视频微端口驱动程序接口
接下来的部分枚举了构成视频微端口驱动程序接口的函数,一些函数是必需的,其他的函数有的是有条件的,有的是可选择的。
而它们在微端口驱动程序中的包含则取决于适配器的特性和驱动程序的开发者。
除了DriverEntry函数,本文档建议对每一个必需的标准的微端口驱动程序都用假名。
换句话说,即给出的每一个标准的微端口驱动程序除DriverEntry之外都可以由微端口驱动程序的开发者任意选择。
6.3.1必需的微端口驱动程序函数
以下系统定义的函数必须在每一个视频微端口驱动程序中实现。
除了DriverEntry函数,所有其他的微端口驱动程序都是按字母顺序排列的。
必需的函数描述
DriverEntry
初始化视频微端口驱动程序
HwVidFindAdapter
获取设备可枚举的总线的范围,如果可能,确定设备的类型。
HwVidGetPowerState
查询设备是否可以支持需要的电源状态
HwVidGetVideoChildDescriptor
枚举附加于特定设备的子设备
HwVidInitialize
执行以前的对于相应的显示驱动程序的适配器的初始化。
该函数调用是作为打开适配器的请求的响应。
HwVidSetPowerState
设置特定设备的电源状态
HwVidStatrtIO
开始处理进入的VRP
6.3.2一定条件下必需的视频微端口驱动程序函数
下面的系统定义的函数是在一定条件必需的视频微端口驱动程序函数。
依赖于给定的适配器的特征及驱动程序的设备。
它们同样按字母顺序排列:
一定条件下必须的函数描述
HwVidInterrupt
处理适配器产生的中断,如果微端口驱动程序的适配器产生中断则该函数是必需的。
HwVidResetHw
重新设置适配器到字符模式,这样HAL可以在系统被控制宕机或崩溃时显示系统的关闭信息,或者在软启动时显示初始化信息。
如果适配器的寄存器不能自动设定为INT10复位,该函数是必需的。
HwVidSynchronizeExecutionCallback
同步存取由HwVidInterrupt中断所共享的数据。
允许关键部分的代码以更高的软件或硬件优先级别运行(IRQL,具有设备或系统中断屏蔽)。
如果与HwVidInterrupt小驱动程序函数共享,则它是必需的。
6.3.3可选的视频微端口驱动程序
下面的系统定义的函数可以在视频微端口驱动程序中选择性地实现,函数以字母顺序排列。
可选函数描述
HwVidLegacyResources
返回一个特殊设备的继承资源
HwVidQueryDeviceCallback和/或
HwVidQueryNamedValueCallback
处理存储在寄存器中的配置信息。
该函数在小驱动程序的HwvidFindAdpter函数利用I/O总线类型专用的配置信息或驱动程序提供的默认值时是可选的。
HwVidQueryInterface
返回一个微端口驱动程序实现的函数接口,该函数接口可以由子设备来调用
HwVidTimer
由视频微端口驱动程序大约隔一秒钟周期性调用一次
SvgaHwIoPortXxx函数
由基于x86的全屏的MS-DOS应用程序校验存取I/O端口的有效性,这些函数是对VGA兼容的SVGA微端口驱动程序。
可以参考VGA兼容的微端口的SvgaHwIoPortXxx获取更多的信息。
6.4视频微端口驱动程序初始化
视频微端口驱动程序初始化发生在NT内核、HAL及核心驱动程序如PCI总线驱动等装载及初始化之后。
基本的系统初始化发生顺序如下:
■NT内核及HAL加载并初始化。
■内核驱动程序如PCI总线驱动程序加载并初始化。
■PCI总线驱动程序从每个子PCI的配置空间获得PCI资源信息及设备ID、供应商ID,并将这些信息报告给系统。
■如果PnP管理识别出设备或供应商的ID,I/O管理器将从已知的位置加载相应的视频微端口驱动程序和视频端口驱动程序。
如果PnP管理器不能识别出这些ID,则它给用户提示加载微端口驱动程序的位置。
■I/O管理器用两个系统提供的指针调用微端口驱动程序的DriverEntry例程。
DriverEntry用驱动程序特定及适配器专用的值分配并初始化一个VIDEO_HWINITIALIZATION_DATA结构,包括指向微端口驱动程序其他条目的指针。
DriverEntry也必须声明其他继承资源,这些资源没有被列入设备PCI配置空间但是由设备进行解码。
可参考声明遗资源部分获得更详细信息。
■微端口驱动程序的DriverEntry函数调用VideoPortInitalize函数。
VideoPortInitialize执行微端口驱动程序初始化方面的工作,这是对所有的微端口驱动程序者非常一般性的工作。
例如,对非即插即用的驱动程序,VideoPortInitialize验证微端口驱动程序初始化的VIDEO_HW_INITIALIZATION的结构,初始化一些系统产生的设备对象的公有成员,并对这些设备对象及扩展对象分配内存,收集并存储相关的扩展设备的信息。
可以参见视频微端口驱动程序扩展部分获得更详细的信息。
对即插即用的驱动程序来说,设备的对象相关动作则发生在以后的时间里。
■如果VideoPortInitialize返回,DriverEntry将其返回值再传播给VideoPortInitialize调用者。
微端口驱动程序开发者应当对VideoPortInitialize的返回值不作任何的假设。
在这一点上来说,系统已经装载并且初始化了视频微端口驱动程序。
下一步就是PnP管理器启动设备,可参考启动视频微端口驱动程序部分了解详细内容。
6.4.1启动视频微端口驱动程序
PnP管理器向视频端口驱动程序发送IRP消息请求启动图形适配器,视频端口驱动程序分派HwVidFindAdapter例程对IRP响应,HwVidFindAdapter的详细任务的讨论将在本部分的后面内容中叙述到。
■6.4.1.1建立视频适配器存取区间
■6.4.1.2设置注册表中的硬件信息
■6.4.1.3改变适配器中的状态
6.4.1.1建立视频适配器存取区间
一个VIDEO_ACCESS_RANGE类型的元素数组描述一个视频适配器解码内存和/或I/O端口的一个或多个区间,在这个数组中的每个存取区间元素都包含总线相关的物理地址值。
微端口驱动程序例程HwVidFindAdapter例程必须声明所有的PCI内存及端口或者适配器可以响应的所有区间的端口。
依赖于适配器及在VIDEO_PORT_CONFIG_INFO中的AdapterInterfaceType值,HwVidFindAdapter可以调用下面VideoPortXxx函数以得到必要的总线相关的配置数据:
■VideoPortGetAccessRanges
■VideoPortGetBufData
■VideoPortGetDeviceData
■VideoPortGetRegistryParameters
■VideoPortVerifyAccessRanges
如果HwVidFindAdapter不能通过调用VideoPortGetBusData或VideoPortGetAccessRanges函数,或者利用VideoPortGetDeviceData或VideoPortGetRegistryParameters函数从寄存器中得到总线相关的可存取区间的相关信息,微端口驱动程序应当有一套总线相关的存取区间的默认值。
小驱动程序试图与适配器通信之前,HwVidFindAdapter函数应当映射每一个声明的总线相关的物理地址区到用VideoPortGetDeviceBase函数得到的内核模式的地址空间的区间。
HAL能够将总线相关的存取区间值重新映射到系统地址的逻辑地址区间,尤其是在多条总线的机器中。
利用映射的逻辑区间地址,驱动程序可以调用VideoPortReadXxx和VideoPortWriteXxx函数以读或写到一个适配器,这些内核模式的地址也可以被传递到VideoPortCompareMemory,VedeoPortMoveMemory,VideoPortZeroDeviceMemory和/或VideoPortZeroMemory。
对一个被映射的I/O空间中的区间来说,微端口驱动程序调用VideoPortReadPortXxx和VideoPortWriterPortXxx函数。
对一个在内存中映射的区间来说,微端口驱动程序调用VideoPortReadRegisterXxx及VideoPortWriterRegisterXxx函数。
HwVidFindAdapter函数应当总是在调用VideoPortGetDeviceBase函数之前成功调用VideoPortVerityAccessRanges或者VideoPortGetAccessRanges。
■任何对VideoPortVerifyAccessRanges或VideoPortGetAccessRanges的成功调用将建立起一个微端口驱动程序的声明,即声明特定总线的视频内存和寄存器地址或适配器在注册表中的I/O端口。
非常值得注意的是接下来对VideoPortVerityAccessRanges或VideoPortGetAccessRanges的任何顺序的调用都会导致驱动程序以前声明的资源被删除或者传送给最近调用函数的值所代替。
因此,如果驱动程序单独调用函数声明区间,它必须传递到所有区间的数组,包括那些已经声明的区间。
■HwVidFindAdapter可以从适配器要求一小部分的存取区间,利用这一小部分区间来决定该适配器是否是微端口驱动程序支持的,并且利用另外一个函数调用VideoPortGetAccessRanges或者VideoPortVerityAccessRanges要求一个全部的对适配器支持的存取区间。
同样的,对某专用的适配器的这些VideoPort…AccessRanges例程的成功调用,都会导致调用者以前在注册表中声明的信息覆盖。
■声明其他类型的硬件资源,如中断向量,一个微端口驱动程序应当在VIDEO_PORT_CONFIG_INFO中设置合适的值并调用VideoPortVerityAccessRanges或它应当调用VideoPortGetAccessRanges函数。
■对VideoPortGetAccessRanges或VideoPortVerifyAccessRanges的成功调用保证了微端口驱动程序不去使用已经由另外一个驱动程序使用的寄存器或设备内存地址。
■在寄存器中声明适配器的总线相关硬件资源,防止后来加载的驱动程序企图利用其他适配器的同一存取区间(即其他硬件地址)。
它同样防止按顺序装载的驱动程序更改视频适配器的初始状态。
硬件解码的微端口驱动程序继承资源时必须通过它的DriverEntry例程来声明,或者,如果实现,则必须通过HwVidLegacyResources例程,继承资源是那些没有列入设备的PCI配置空间但由设备解码的资源。
可以参考声明继承资源部分获得详细内容。
在微端口驱动程序装载之后,它的HwVidInitialize函数便已经运行,微端口驱动程序的HwVidStartIO函数调用,以映射那些微端口驱动程序对显示驱动程序可见的视频内存存取区间。
6.4.1.2在注册表中设置硬件信息
HwVidFindAdapter可以调用VideoPortGetRegistryParameters及VideoPortSetRegistryParameters函数来获得并设置注册表中的配置信息。
例如,HwVidFindAdapter可以调用VideoPortsSetRegistryParameters来设置下一次启动时非易失性的注册表配置信息。
也可以调用VideoPortGetRegistryParameters来获得由一个安装程序写入到注册表中特定适配器的、总线相关的配置参数。
推荐使用通过微端口驱动程序设置注册表中的一定的硬件信息,来向用户显示有用的信息或在调试时显示信息。
微端口驱动程序可以设置芯片类型、DAC类型、适配器内存大小、鉴别适配器的字符串等,这些信息都是通过控制面板(ControlPanel)的显示小应用程序来显示的。
驱动程序通过调用VideoPortSetRegistryParameters函数来设置这些信息,而且通常是驱动程序在它的HwVidFindAdapter例程中调用。
下表描述了驱动程序可以注册并提供的VideoPortSetRegistryParameters中ValueName和ValueData参数的详细信息:
条目信息ValueNameValueData
Chiptype
HardwareInformation.ChipType
包含芯片名称的以NULL结尾的字符串
DACtype
HardwareInformation.DacType
包含DAC名称或ID的以NULL结尾的字符串
MemorySize
HardwareInformation.MemorySize
包含ULONG,以MB为单位,适配器上视频内存的总量
AdapterID
HardwareInformaiton.AdapterString
包含适配器名称的以NULL结尾的字符串
BIOS
HardwareInformation.BiosString
包含BIOS信息的以NULL结尾的字符串
6.4.1.3改变适配器的状态
微端口驱动程序在调用HwVidInitialize例程之前不能永久性改变适配器的状态。
微端口驱动程序例程在HwVidInitalize函数之前调用,如HwVidFindAdapter函数,它不能改变任何不需要的视频适配器的状态并且不能永久性改变任何视频适配器的状态。
当HwVidFindAdapter运行时,HAL已经控制了视频适配器,因此它可以在系统启动的早期阶段将信息写到屏幕上。
如果HwVidFindAdapter试图签别适配器是否影响适配器状态,这一例程应当立即恢复原先的状态信息。
因此一经HwVidFindAdapter返回,HAL就可以继续显示启动的消息。
例如,HwVidFindAdapter应当推迟决定一个适配器的DAC类型到HwVidInitalize函数,由于做这一决定并不会影响微端口驱动程序是否已经被装载,但是永久性地改变了适配器的状态。
6.4.2声明继承资源
视频微端口驱动程序必须在驱动程序初始化过程中在VIDEO_HW_INITIALIZATION_DATA结构中声明并报告所有的继承资源。
继承资源是那些没有列在PCI配置空间但由设备解码的资源。
WindowsNT/Windows2000遇到那些没有在本部分以提纲形式列出的未报告的继承资源时,将禁止电源管理及停靠功能。
微端口驱动程序必须在报告继承资源时做如下事情:
■如果对设备列出的继承资源在编译时可知,则将填充VIDEO_HW_INITIALIZATION_DATA结构中的两上字段,它是在DriverEntry例程中创建和初始化的。
结构成员定义
HwLegacyResourceList
指向一个VIDEO_ACCESS_RANGE结构,每一个结构描述了视频驱动程序未列入PCI配置空间的设备I/O端口或者内存区间。
HwLegacyResourceCount
HwLegacyResourceList指向的数组所包含的元素个数
■如果列出的设备的继承资源在编译时是未知的,则实现一个HwVidLegacyResources函数,初始化VIDEO_HW_INITIALIZATIONH_DATA结构的GetLegacyResources成员并指向该函数。
例如,一个支持具有不同继承资源设置的两个设备微端口驱动程序可以实现HwVidLegacyResources以在运行时报告继承资源。
小视频端口驱动程序实现HwVidLegacyResources函数时,视频端口驱动程序将忽略VIDEO_HW_INITIALIZATION_DATA结构的HwLegacyResourceList及HwLegacyResourceCount成员。
■根据微端口驱动程序的定义,对每一个VIDEO_ACCES_RANGE结构填充其RangePassive字段值。
设置RangePassive为VIDEO_RANGE_PASSIVE_DECODE意味着该区由硬件进行解码,但是显示及视频微端口驱动程序将永不会接触到它。
设置RangePassive为VIDEO_RANGE_10_BIT_DECODE意指设备对该区的端口地址进行10位解码。
同样,驱动程序应当包括一种由硬件解码的但没有被PCI声明的资源。
驱动程序中声明的较小的继承资源的代码也许看起来如下边代码所示:
//RangeStartRa