流Mini驱动开发(译自Microsoft DDK)

本文详细介绍了Stream Class和Minidriver之间的接口,包括Stream请求块SRB的使用、Minidriver初始化过程以及处理流请求的方法。内容涵盖Class Driver如何调用Minidriver的回调函数、SRB的数据结构以及流的初始化和同步机制。通过对硬件中断、请求取消和超时处理的讲解,揭示了Minidriver在驱动程序中的核心作用。
摘要由CSDN通过智能技术生成
本节详细讨论了已经过时的Stream.sys Class Driver。随着Microsoft Windows XP的正式发布,Microsoft建议硬件制造商考虑使用下一代Class模型——AVStream——来开发新的,非音频多媒体驱动程序。相关细节可参看《AVStream Overview》一章。Microsoft现在只对Stream.sys提供基本的支持。如果你要开发一个音频Minidriver,请参看《Audio Miniport Drivers》一章。
很多种设备都通过提供流式Minidriver来得到(操作系统的)支持。尤其是视频捕捉设备,譬如数码相机和DVD播放机,它们都是通过提供流式Minidriver来获得支持的,类似的还有外部音频设备。更多介绍可参考《Video Capture Minidriver Design Guide》和《Vendor-Supplied DVD Drivers》。
流Minidriver支持内核流。在此我假定本文的读者已经熟悉了内核流的相关基本概念。如果你不明白,请先阅读《Kernel Streaming Overview》
设计Stream Class Driver的目的,就是通过处理许多和操作系统进行交互的细节,来使流式设备驱动的开发更加简单。
Minidriver让Stream Class Driver代表它处理同步问题。举个例子,Stream Class Driver可以为Minidriver随意地串行化I/O请求。通过让Class Driver为它处理同步问题,Minidriver可以做到多处理器平台安全,但是代码却是不可重入的。这样很适合后端(low-end)到中端(medium-end)的硬件。
Class Driver会自动对文件操作进行同步。例如,通过互斥体(Mutex)、信号量(Semaphores)或者事件(Event),打开流和打开设备的操作可以被正确地串行化,无需Minidriver的参与。
Class Driver从Minidriver中抽象了内核流的具体实现细节。
Class Driver处理所有和PnP管理器之间的交互动作。例如:
Class Driver代表Minidriver创建功能性设备对象(Functional device object)。
Class Driver管理资源设置(如翻译端口地址,翻译并映射内存范围,连接中断)
Class Driver处理PnP IRP包。比如IRP_MN_START_DEVICE, or IRP_MN_STOP_DEVICE。
所有的低级缓冲区管理也是由Class Driver完成的。
如果必要的话,分配DMA适配器对象。
映射缓冲区,并为DMA创建scatter/gather列表。
为DMA和PIO正确锁定并回写(Locking and flushing)缓冲区
所有的IO控制码的正确性验证也是由Class Driver完成的。
Class Driver通过看门狗定时器为所有的请求打上时间戳。
Minidriver自己并不创建设备对象,它在必要的时候可以分享Class Driver的设备对象。这样可以节约对系统资源占用。
每个适配器只创建一个设备对象。而适配器所支持的Mulitiple SubDevice(称为流,Stream)则用WDM Streaming Pins来描述。
一、Class Driver Minidriver 的定义
Class Driver是由微软提供的一种中间驱动(或称媒介驱动),用来在硬件厂商提供的Minidriver和操作系统之间提供一个简单的接口。Minidriver是一个硬件相关的DLL,它通过函数调用的方式,使用微软提供的Class Driver来完成大部分动作,它只提供和设备紧密相关的控制。
在WDM模型中,Minidriver向Class Driver注册所有和它相关联的硬件适配器(Hardware Adapter),然后Class Driver会创建一个文件对象(File Object)来描述向它注册的每个适配器。Minidriver使用Class Driver的设备对象(Device Object)来进行系统调用。用户态的客户代码可通过WDM流(WDM Streaming)访问Class Driver。
Class Driver和Minidriver之间的交互包括:
·   Minidriver并不创建它自己的设备对象(Device Object),而是在必要的时候共享Class Driver的设备对象,这样可以节约系统资源。
·  每个适配器(Adapter)只能创建一个设备对象。而适配器所支持的Mulitiple SubDevice(称为流,Stream)则用WDM Streaming Pins来描述。
 

二、Stream Class Minidriver之间的接口

流类接口(Stream Class Interface)主要由介于Class DriverMinidriver之间的一系列的函数调用组成。Class Driver对请求的流程(Request Flow)进行控制,当有必要对适配器硬件进行存取时,它就调用适配器的MinidriverClass Driver还负责对多处理器和中断同步作出响应。当Class DriverMinidriver都初始化完毕之后,Minidriver将处于一个被动的地位,它只能被Class Driver所调用,而绝大多数的调用都是非常低级的服务请求。

Minidriver来说,对命令和信息(Commands and Information)进行控制的最基本的机制就是流请求块(Streaming Request Block)。每个Minidriver都有一系列的SRB来对其某个特定的功能进行访问,而且一般说来,设备所支持的每种数据流都有相应的SRB与之对应。这些信息(SRB)通过操作系统控制的DMA缓冲区(它是一个环形队列)传递给设备。

一个SRB由一个命令码字段,以及与该命令码相关联的其他数据所组成。结构体HW_STREAM_REQUEST_BLOCK包含了和特定的SRB相关的所有信息。我们常常把这个结构体就简称为SRB,它体内还包含了一些作为对命令码的补充信息的其他参数。结构体HW_STREAM_REQUEST_BLOCK的定义如下:

typedef struct _HW_STREAM_REQUEST_BLOCK

{

ULONG                      SizeOfThisPacket;

SRB_COMMAND              Command;

NTSTATUS                   Status;

PHW_STREAM_OBJECT       StreamObject;

PVOID                        HwDeviceExtension;

PVOID                        SRBExtension;

 

union _CommandData

{

    PKSSTREAM_HEADER                                                  DataBufferArray;

    PHW_STREAM_DESCRIPTOR                                        StreamBuffer;

    KSSTATE                                                         StreamState;

    PSTREAM_PROPERTY_DESCRIPTOR                                             PropertyInfo;

    PKSDATAFORMAT                                              OpenFormat;

    struct _PORT_CONFIGURATION_INFORMATION *           ConfigInfo;

    HANDLE                                                       MasterClockHandle;

    DEVICE_POWER_STATE                                        DeviceState;

    PSTREAM_DATA_INTERSECT_INFO                             IntersectInfo;

} CommandData;

 

ULONG                                                       NumberOfBuffers;

ULONG                                                       TimeoutCounter;

ULONG                                                       TimeoutOriginal;

struct _HW_STREAM_REQUEST_BLOCK*                             NextSRB;

PIRP                                                         Irp;

ULONG                                                       Flags;

PVOID                                                       HwInstanceExtension;

 

union

{

    ULONG   NumberOfBytesToTransfer;

    ULONG   ActualBytesTransferred;

};

 

PKSSCATTER_GATHER        ScatterGatherBuffer

ULONG                       NumberOfPhysicalPages;

ULONG                       Reserved[2];

} HW_STREAM_REQUEST_BLOCK, *PHW_STREAM_REQUEST_BLOCK;

关于对以上其他参数的解释,参见DDK文档,这里不再赘述。

 

下图解释了流类(Stream Class)和Minidriver在初始化时所进行的交互动作。

·初始化适配器

所有的流式Minidriver函数并不一定非要和Minidriver的中断服务例程(Interrupt Service RoutineISR)同步,因而Minidriver的代码是不可重入的(Non-re-entrant,相应的概念叫做可重入代码,又叫做纯代码。关于可重入代码的概念,请参考西电版操作系统教材),亦即,当Minidriver正在执行一个线程的时候,不能再调用Minidriver内其他任何函数,包括中断服务例程在内。这种非可重入的特性即便在支持多处理器的Windows NT/2000系统下也是存在的,这样可以令Minidriver编写起来更加方便。为了达到这样的特性,流类驱动(Stream Class Driver)会在Minidriver体内任何例程被执行时,通过内核例程KeSynchronizeExecution屏蔽Streaming Minidriver的中断请求IRQ(和所有低优先级的IRQ)。如果想了解更多关于同步的信息,请参看MiniDriver同步一章。Streaming Minidriver可以在必要的时候调用WDM系统服务。但是,Minidriver自己并没有设备对象,他是利用ClassDriver的设备对象来完成系统调用的。绝大多数Minidriver是不需要进行WDM系统调用的,因为几乎所有必要的功能都已经被Class Driver所涵盖了,没有必要直接进行系统调用。

必须知道的是,当进行WDM系统服务调用时,所有的Minidriver的入口点都会在高于DISPATCH_LEVEL的中断优先级下被调用(注意不包括DISPATCH_LEVEL中断优先级)。但有一个例外,那就是StreamClassCallAtNewPriority例程,此函数允许在DISPATCH_LEVEL

PASSIVE_LEVEL中断优先级上进行系统服务调用,具体哪个优先级取决于调用时所指定的优先级别。如果要一劳永逸地修改这个对IRQL的调用限制,可以通过把HW_INITIALIZATION_DATA结构体中的BOOL型成员变量TurnOffSynchronization简单置为TRUE来实现

 

 

三、开始着手编写Stream Minidriver

设计Stream Class Driver的主要目标,就是处理两个工作,一是处理操作系统,操作系统包含了对复杂的对多处理器的支持,二就是对内核流进行支持。这样Minidriver只需要对它必须执行的,与设备相关的操作进行处理即可。Class DriverMinidriver分配内存空间,对Minidriver可能用到的NT内核资源进行登记,并(随意地)处理同步问题。

Class Driver通过一系列由Minidriver提供的回调函数和Minidriver进行通讯。大部分对流式Minidriver写的动作都发生在写这些回调函数的时候。

在本文中,我们所提到的每种由Minidriver提供的例程都命名为StrMin×××。根据下层硬件可能执行的不同功能的数目,Minidriver也许要为每个例程提供一到更多的版本。

一个典型的流驱动都会支持数种不同的数据流。例如,DVD播放器会产生音频和视频流。在内核流环境中,每个流都用一个pin来描述。(参见KS Filters, Pins and Node Topology for a description of pins)。

流类驱动会跟踪Minidriver上的每个pin,在Class Driver看来, pin的每种类型都是一个流。流,就好比Pin的类型,有可能会有多个实例。因为流可以接收

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值