内核模式驱动程序的结构

内核模式驱动程序与传统的应用程序有非常大的不同,总的来说,驱动程序收集了被操作系统软件(通常是I/O管理器)调用的各种例程,只有当I/O管理器调用它们的时候它们才会执行。

  I/O管理器可能在下列状态下调用驱动程序的例程:

1. 当驱动程序加载的时候。

2. 当驱动程序被卸载或者系统被关闭的时候。

3. 当设备被插入或者移除的时候。

4. 当用户程序发出I/O系统服务的调用的时候。

5. 当一个分享的硬件资源变的可以被驱动程序使用的时候。

6. 在设备操作过程的任何时候。

以下将简要的介绍组成内核模式驱动程序的各中例程,具体的介绍会分布到以后各个章节。

驱动程序初始化和清除例程

  当一个驱动程序加载到系统的时候,各种各样的任务必须被执行,同样的,在驱动程序被卸载之前,必须被清除。这儿有几个例程去完成这些操作:

DriverEntry例程

  当驱动程序第一次加载的时候I/O管理器调用这个例程,可能在系统引导的时候,也可能在任何时候被动态加载。DriverEntry例程执行第一次的初始化任务,如宣布其它例程的地址,定位它所控制的硬件,分配或者确认硬件资源的用法(端口,中断,DMA),为发现的每个硬件设备提供一个名字,方便给操作系统使用。对于分享即插即用的WDM驱动程序,这个硬件分配的步骤被延迟到AddDevice例程之后。

REINITIALIZE例程

  一些驱动程序不能在DriverEntry例程中完成所有的初始化任务。如果驱动程序依赖另一个驱动程序的加载,或者驱动程序需要更多的操作系统资源的支持,而这些后来添加的资源是在DriverEntry例程执行之后添加的,这些驱动程序可能请求初始化延迟通过增加一个REINITIALIZE例程。

UNLOAD例程

  在驱动程序被动态的卸载的时候,I/O管理器会调用UNLOAD例程。它可能执行和DriverEntry例程相反的过程,包括移除所有它所控制的设备的设备名。对于WDM驱动程序,设备的资源包括名字的移除工作在RemoveDevice例程中进行。

SHUTDOWN例程

  奇怪的是,在系统关闭的时候UNLOAD例程不会被调用。因为这时完全的清除是不需要的,所以系统调用一个SHUTDOWN例程去给驱动程序一个将设备放置于静止状态的机会。

BUGCHECK CALLBACK例程

  如果驱动程序需要在系统出现故障的时候个到控制,就可以提供一个BUGCHECK CALLBACK例程。系统内核在有秩序的崩溃过程中调用这个例程。

I/O系统服务派遣例程

  当I/O管理器收到用户的应用程序的I/O请求,请求的类型(读,写等)被转换成为一个函数代码,I/O管理器确定适当的驱动程序去处理这个请求,然后调用其中一个派遣例程。这个例程检查请求,如果通过,它请求I/O管理器将请求的设备操作排到设备操作队列中,然后函数返回I/O管理器,标记请求被挂起。

OPENCLOSE操作

  所有的驱动程序必须有一个CreateDispatch例程,它是用来处理WIN32CreateFile请求,同样的,必须有一个CloseDispatch例程,它是用来处理WIN32CloseHandle请求。

设备操作

  一个设备驱动程序可能有单独的处理数据传输或者控制操作的派遣例程,WIN32的函数ReadFileWriteFileDeviceIoControl会产生I/O管理器对派遣例程的调用。再次,一个驱动程序仅仅需要提供这些它支持的操作的例程。如果用户发出一个它的设备的驱动程序不支持的I/O请求,用户程序将收到一个请求函数不支持的错误。

数据传输例程

  因为设备的性质不同,设备操作会包含一些不同的驱动程序例程:

START I/O例程

  I/O管理器在每次设备将要开始数据传输之前调用驱动程序的START I/O例程。I/O管理器在每次I/O执行结束且另一个I/O请求在队列里等待的时候发出对START I/O例程的请求,或者说,I/O管理器发出请求使所有的I/O请求连续起来。使设备复位的操作只能在以前的操作完成之后。复杂的可以同时处理多个请求的设备可以不选择这种串行处理的方法。

  驱动程序提供的START I/O例程分配要处理I/O请求的资源和设置设备运行。

中断服务例程(ISR)

  内核模式的中断派遣器在设备产生一个中断的时候调用驱动程序的中断服务例程。ISR负责完善硬件中断服务。当ISR返回以后,中断应当被解除。

  像以前描述的一样,只有少部分的服务在ISR中执行。时间相关的请求才必须中断例程直接服务中断,否则,在ISR中应该调度DPCISR剩下的工作就可以在IRQL低于DIRQL的级别下完成。

DPC例程

  一个驱动程序可以提供零个或者多个DPC例程去完成设备操作例程,可能包括释放系统资源(DMA页描述符),汇报错误状态,完成I/O请求,开始下一个设备操作等。

  如果只有一个DPC被请求去完成中断服务程序,I/O管理器提供一个简单的DpcForIsr例程。一些设备可能希望驱动程序为不同的目的提供多的DPC例程,可能是两个不同DPC,一个完成读操作,另一个完成写操作,这样的处理是非常方便的。DPC例程可以在IRQLDISPATCH_LEVEL的水平下工作。

资源同步回调

  回想WIN2000的设计目标,所有的内核模式代码(包括驱动程序)必须是可重入的,驱动程序代码必须考虑在一个或者多个处理器平台上的用户程序的多个线程同时请求I/O的情况,这个可重入的驱动程序代码必须安全的和正确的处理这些请求。

  I/O管理器提供了几个处理这种同时请求分享资源和服务的方法,这些同步的例程操作与其它的提供给WIN32程序的例程序不同的。WIN32模式下如果一个程序的一个资源是不可以利用的,那他一定是正在被其它程序使用着,系统将阻塞这个后来请求资源的程序执行。但是在内核模式下,系统是不会去阻塞这个武断的程序。

  在内核模式代码间同步的技术是提供一个专门用来同步指定的资源的回调例程的地址。当一个驱动器需要访问共享的资源,它在I/O管理器的协助下排队请求资源,当资源变的可利用的时候,I/O管理器调用与请求相关联的驱动程序支持的回调函数。当然,这就意味着多个对资源的请求是连续的,在任何时间,只有一个线程的上下文环境拥有那些竟争的资源。

  I/O管理器支持三种资源同步回调函数:

ControllerControl例程

  一些控制器()支持多个功能(或者设备),这些功能(或者设备)可能共享一个控制器的寄存器。这种情况下,在同一时刻只允许一个功能(或者设备)使用这个寄存器是必要的。通常,START I/O例程请求单一的控制器所有权,当同意的时候,ControllerControl回调例程执行,当I/O完成的时候,通常由DpcForIsr例程释放资源。

AdapterControl例程

  另一个必须被一个设备传递到另一个设备的共享资源是DMA硬件,在DMA执行之前,设备请求独一无二的DMA信道的拥有权,当申请到拥有权时,AdapterControl例程执行,否则,等待。

SynchCritSection例程

  中断服务程序在DIRQL的特权级运行,而其它的驱动程序代码在DISPATCH_LEVEL特权级或者更低运行,如果这些特权级低的代码需要使用被ISR使用的资源时,这些操作必须在SynchCritSection例程中执行,在这个范围内的资源包括所有的设备控制寄存器,和与中断服务例程共享其它的上下文环境和状态信息。

  SynchCritSection例程的操作和其它的同步技术不同,一旦回调产生,IRQL水平马上升到DIRQL水平。这样低的IRQL水平的暂时工作在硬件DIRQL水平,避免被中断服务程序中断。当SynchCritSection例程完成后,IRQL就回到原来的水平。

其它的例程

  除了以上所讲的例程外,驱动程序还可能包含以下的例程:

1. Timer例程:       一些驱动程序可能需要跟踪时间,可以使用I/O Timer或者CustomTimerDpc来实现这个功能。

2. I/O Completion例程: 在分层的驱动程序中,当发送到低层的请求完成时,高层的驱动程序想要被通知到。高层的驱动程序就需要一个I/O Completion例程来搞定这件事。

3. Cancel I/O例程:    驱动程序必须考虑请求可能被取消的情况。这种操作可能在一个长的设备操作的时候,或者因为一个不可预知的设备错误导致驱动程序长时间的等待时,驱动程序应该提供一个Cancel I/O例程。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值