内核模式驱动程序设计指南.doc_第1页
内核模式驱动程序设计指南.doc_第2页
内核模式驱动程序设计指南.doc_第3页
内核模式驱动程序设计指南.doc_第4页
内核模式驱动程序设计指南.doc_第5页
已阅读5页,还剩226页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 第三卷第三卷 内核模式驱动程序设计内核模式驱动程序设计指南指南 第一部分 一般内核模式 2 第一部分第一部分 一般内核模式一般内核模式 第 1 章 Windows 2000 和 WDM 驱动程序 第 2 章 分层的 I O IRP 和 I O 对象 第 3 章 系统定义的对象和对驱动程序的支持 第 4 章 驱动程序基本结构 第 5 章 DriverEntry 和 Reinitialize 例程 第 6 章 Dispatch 例程 第 7 章 StartIo 和队列管理例程 第 8 章 中断服务例程 第 9 章 DpcForIsr 例程和 CustomDpc 例程 第 10 章 SynchCritSection 例程 第 11 章 AdapterControl 和 ControllerControl 例程 第 12 章 Cancel 例程 第 13 章 IoCompletion 例程 第 14 章 IoTimer 和 CustomTimerDpc 例程 第 15 章 Unload 例程 第 16 章 常见的驱动程序设计问题 3 第第 1 1 章章 WindowsWindows 20002000 和和 WDMWDM 驱动程序驱动程序 本章叙述了什么是 Windows 2000 内核模式驱动程序 介绍了一些重要的驱动程序名词 并 总结了内核模式驱动程序的设计目标 解释为了满足这些设计目标 Windows 2000 和 WDM 的内核模式驱动程序如何不同于其他操作系统的驱动程序 本章内容组织如下 1 1Windows 2000 组件一览 1 2Windows 2000 中的驱动程序种类 1 3Windows 2000 和 WDM 驱动程序设计目标 1 3 1 移植性 1 3 2 可配置性 1 3 3 永远抢占优先和永远中断 1 3 4 多处理器安全 1 3 5 基于对象 1 3 6 带有可复用 IRP 的包驱动 I O 1 3 7 支持异步 I O 关于 Windows NT Windows 2000 操作系统环境的更多细节 可以参看 David Solomon 的 Inside Windows NT 微软出版社 1998 1 1 Windows 2000 组件一览组件一览 图 1 1 显示了 Microsoft Windows 2000 操作系统环境的主要组件 图 1 1 Windows 2000 组件一览 在 Windows 2000 操作系统环境中 一部分组件运行在用户模式下 其他的则运行在内核模 式下 文件系统 中间层和最低层驱动程序被显示在图的左下方 其中包含了内核模式 I O 管理器 如图 1 1 所示 Windows 2000 操作系统包括了许多内核模式组件 它们被精心地定义为功 能相互独立的组件 对内核模式驱动程序设计者来说 最感兴趣的就是内核 I O 管理 即 插即用管理 Plug and Play Manager 电源管理 Power Manager 硬件抽象层 Hardware Abstraction Layer HAL 配置管理 Configuration Manager 存储管 理 Memory Manager 运行支持 Executive Support 和过程结构 Process Structure 组件 对另一些设计者来说 感兴趣的其他组件可能包括对象管理 Object Manager 和安全引用监控器 Security Reference Monitor 即插即用 PnP 管理和电源管理是 Windows 2000 中的新组件 他们仅仅支持 Windows 2000 驱动程序和 WDM 驱动程序 有关 Windows 2000 和 WDM 驱动程序使用这些 Microsoft 操作系统新特性的更详细资料 请参见 Windows 2000 驱动程序开发参考 的第 1 卷 即 插即用 电源管理和安装设计指南 4 1 2 Windows 2000 中的驱动程序种类中的驱动程序种类 在 Windows 2000 操作系统中 有两个基本的驱动程序种类 用户模式驱动程序 例如 Win32 VDD 它是为 MS DOS 应用程序开发的专用设备 或另 一个被保护的子系统的驱动程序 用户模式驱动程序是与子系统细节相关的 我们不在这里讨论 更多 VDD 的细节 参 考在线 DDK 中的 Virtual Device Drivers 虚拟设备驱动程序 文档 针对逻辑 虚拟或物理设备的内核模式驱动程序 这些驱动程序作为 Windows NT 执行体部分来运行 Windows NT 是基础的 基于微内 核的操作系统 它支持一个或更多的保护子系统 一些 Windows 2000 内核驱动程序也是 WDM 驱动程序 它们符合 Windows 驱动程序模型 WDM 所有的 WDM 驱动程序是 PnP 驱动程序 并支持电源管理 WDM 驱动程序对 Microsoft Windows 98 和 Windows 2000 操作系统来说 是源代码兼容的 不是二进 制兼容的 在这里 术语 Windows 2000 驱动程序 通常指代任何运行于 Windows 2000 操作系统之 上的内核模式驱动程序 是 WDM 或不是 必要的时候 本书会特别指出哪些是 WDM 驱动 程序 哪些只是 Windows 2000 驱动程序 名词 早期驱动程序 指的是那些为 Windows NT 以前版本写的驱动程序 它们是不支持 PnP 的 像操作系统自己 内核模式驱动程序是依据仔细定义的需求功能集 作为单独的 模块化 的组件来实现的 所有的 Windows 2000 内核模式驱动程序 包括 WDM 驱动程序 都包含一组系统定义的标准 驱动程序例程和一些依赖于个别设备需求的内部例程 图 1 2 内核模式驱动程序类型 如图 1 2 所示 有三种基本类型的内核模式驱动程序 每一种都有稍微不同的结构和完全 不同的功能 1 最高层驱动程序 例如系统支持的 FAT NTFS 和 CDFS 文件系统驱动程序 FSD 最 高层驱动程序通常依赖于较低层的驱动程序支持 虽然特定的文件系统驱动程序可能 或不可能从一个或多个中间层驱动程序获得支持 但是每个文件系统驱动程序最终依赖一个或多个下层外围设备 可能是 PnP 硬件总线 驱动程序的支持 2 中间层驱动程序 例如虚拟磁盘 镜像 或指定设备类型的类驱动程序 中间层驱动 程序也需要较低层驱动程序的支持 PnP 功能驱动程序是中间层驱动程序 它们在一个 I O 总线上控制特定的外围设备 这个 I O 总线是由 PnP 硬件总线驱动程序来控制的 同样还有 PnP 过滤器驱动程序 PnP filter driver 它们在驱动程序栈 driver stack 内将它们自己插入到 PnP 功能驱动程序中去 以支持任何特定的外围设备 PnP 功能和过滤器驱动程序的子 集也是 WDM 功能和过滤器驱动程序 任何系统支持的向外输出一个系统定义的 WDM 类 微类接口的类驱动程序 实际上是一 个带有一个或多个链接的 WDM 微类驱动程序 有时称为 WDM 微驱动程序 的中间层驱 动程序 每一对相互链接的 WDM 类 微类 提供与 WDM 功能驱动程序或 WDM 软件 总 线驱动程序相同的功能 5 PnP 软件总线驱动程序表示一组子设备 较高层的类 功能和 或过滤器驱动程序能连 接它们自己到这些子设备上 PnP 软件总线驱动程序也是中间层驱动程序 例如 控 制多功能适配器的驱动程序是一个 PnP 软件总线驱动程序 这样的多功能适配器是用 于不同的设备的一个便携集合 根据便携设备的特性和它的驱动程序使用的接口 这 样的驱动程序也可能是 WDM 软件总线驱动程序 它似乎使得较高层驱动程序成为一个 PnP WDM 总线驱动程序 对于操作系统来说 驱动程序是以 PnP WDM 驱动程序的面目 出现的 它服务于它自己的适配器 将它自己插入底层 PnP 硬件总线驱动程序之上的 驱动程序堆栈中 3 最低层驱动程序 例如 PnP 硬件总线驱动程序 它控制一个 I O 总线 这个总线连了 一些外围设备在上面 最低层驱动程序不依赖于较低层驱动程序 而是控制物理外围 设备 例如总线 早期的 NT 设备驱动程序直接地控制物理外围设备 它们是最低层的驱动程序 同样的 驱动程序例如 SCSI HBA Host Bus Adapter 宿主总线适配器 驱动程序 PnP 硬件总线驱动程序是系统提供的 并且通常动态控制可配置的 I O 总线 这个驱 动程序通过与即插即用管理协作 为所有连到它所控制的 I O 总线上的子设备 配置 和重新配置系统硬件资源 例如设备存储的映射和 IRQ 对其 I O 总线来说 PnP 硬 件总线驱动程序包含了一部分 Windows NT 早期版本中由 HAL 组件提供的功能 Windows 2000 网络驱动程序也能被划分为上述的基本类型之一 例如 NT 服务器或转向器 是一个特定的文件系统驱动程序 传输堆栈中的任何驱动程序都是中间层驱动程序 物理 网卡 有时称为网络接口控制器或 NIC 驱动程序则是最低层设备驱动程序 当然 Windows 2000 为网络设备提供了明确的接口和支持 例如 NDIS Network Device Interface Specification 网络设备接口规范 库在网络传输堆栈的下界提供了 NIC 驱动 程序和中间层驱动程序 本书为文件系统和网络驱动程序设计者提供了一些有用的综述和背景信息 对于内核模式 设备和中间层驱动程序 以及包括 WDM 驱动程序的设计者来说 本书主要是一个设计指南 网络中间层和设备驱动程序的设计者也应该参考在线 DDK 中的 Network Driver Design Guide 和 Reference 文件系统驱动程序设计者和最高层网络驱动程序设计者应当参 考 IFS 工具包 1 3 Windows 2000 和和 WDM 驱动程序的设计目标驱动程序的设计目标 内核模式驱动程序与很多 Windows 2000 的设计目标相符合 特别是系统 I O 管理器部分 这些设计目标包括 平台之间的移植性 硬件和软件的可配置性 永远抢占优先和永远中断 多处理器平台上的多处理器安全 基于对象 带可重用 I O 请求包 IRP 的包驱动 I O 异步 I O 支持 后面的小节中将向所有的 Windows 2000 内核模式和 WDM 驱动程序设计者介绍这些系统设计 目标 6 1 3 1 1 3 1 移植性移植性 Windows 2000 输出两个系统提供的运行时库 它们包含了以 Rtl 为前缀的函数 内核模式 驱动程序可以使用相同的内核模式 RtlXxx 例程作为执行组件 但是不能调用用户模式 RtlXxx 例程 每个 NT 执行组件输出一组内核模式支持的例程 驱动程序和所有其他的内核模式组件可以 调用这些例程 如果支持例程的底层实现随着时间的推移发生了变化 它的调用者依然可 以保持不变 因为定义组件的接口没有发生变化 大多数 Windows 2000 组件完全是用 C 写成的 仅仅少部分的 HAL 和内核是用汇编语言写成 的 所以操作系统对于硬件平台来说是容易移植的 内核模式驱动程序应该也使用 C 来写 从而使得它能被系统兼容的 C 编译器重新编译 链接 并且运行在不同的 Windows 2000 平 台上 如果是一个 WDM 驱动程序 不用重新书写驱动程序部分的代码 也不用替换驱动程 序中的模块 就可以在 Windows 98 平台上运行 如果相同的特性不能保证被其他系统兼容的编译器所支持 驱动程序则不应该依赖于任何 特定系统兼容的 C 编译器或 C 支持库的特性 通常 驱动程序代码应该符合 ANSI C 标准 要避免使用任何这个标准中描述为 实现定义的 的部分 特别地 编写可移植的 Windows 2000 驱动程序 最好避免以下的情况 对数据类型的依赖 因为它可能随着平台的不同而在大小和表现形式上有所不同 调用任何保持状态的标准 C 运行时库函数 调用任何标准 C 运行时库函数 而操作系统已经提供了一个可以替换被调用函数的支 持例程 DDK 提供了一组包含文件 这些文件中定义了系统特定的数据类型和常数 驱动程序 以 及所有其他内核模式组件 可以使用它们来保证平台之间的可移植性 大多数驱动程序包 含了主 DDK 内核模式的包含文件之一 这些文件是 ntddk h 和 wdm h 这些主包含文件不 仅收录了系统提供的头文件 它们定义了基本的内核模式类型 而且 还收录了针对不同 处理器构架特定的头文件的合适选择 从而驱动程序能被使用相应的编译器指令编译 对于 WDM 驱动程序 DDK 提供了一组包含文件 它们输出 Windows 2000 内核模式支持例程 宏 常数以及类型的一个子集 WDM 驱动程序使用主 DDK 包含文件 wdm h 而不是 ntddk h 包含 wdm h 以及只使用它所输出的支持例程 宏 常数以及类型 使得 WDM 驱动程序可以 象在 Windows 2000 上一样在 Windows 98 上编译运行 如果驱动程序需要与平台有关的定义 最好是将这些定义用 ifdef 语句单独分割开 这样 就能使驱动程序针对合适的硬件平台被编译和连接 当然 使用 DDK 主头文件提供的支持 例程 宏 常数和类型 你几乎可以避免实现任何与平台有关的条件编译代码 某些驱动程序包含系统提供的其他头文件来确保 Windows 平台上的可移植性 特别是 SCSI NDIS 以及视频微端口驱动程序 关于这些类型的驱动程序的头文件的详细信息分 别参看第 3 部分 存储驱动程序 以及在线 DDK 中的 Graphics Driver Design Guide 图形驱动程序设计指南 和 Reference 参考 Network Driver Guide 网络驱动程序设计指南 和 Reference 参考 1 3 2 1 3 2 可配置性可配置性 因为 Windows NT Windows 2000 是一个可移植的操作系统 所以 设备及其驱动程序必须 是硬件可配置和软件可配置的 7 例如 在一个热插拔的 RAID 廉价磁盘冗余阵列 配置中 用户可以在运行的时候替换磁 盘 这样的设备被称为是硬件可配置的 它的驱动程序不能假定给定的磁盘设备会在某个 特定的位置固定 因此 为了保持可移植性 它的驱动程序一定不能包含硬编码的与机器 有关的值 这类磁盘设备的驱动程序可以在任何给定的机器上对一个或多个文件系统提供硬件级支持 当然这取决于用户如何对这些磁盘分区 另外 中间层驱动程序能为高层文件系统驱动程 序提供灾难恢复 镜像分区 带集 和 或卷集 支持 这样的机器通常具有充足的存储能 力 换句话说 同样的物理磁盘驱动程序能为一些机器提供对多种高层驱动程序的支持 而对其他的机器则不能 这样的磁盘驱动程序是软件可配置的 它们都是中间层和文件系 统驱动程序 并且它们最终依赖于底层设备和 或即插即用 PnP 硬件总线驱动程序 Windows NT 2000 HAL 组件被实现成一个动态连接库 它负责所有的硬件层 平台特定支 持 包括内核模式驱动程序在内 系统中的其他任何组件都需要它的支持 HAL 输出的例 程提供了平台硬件与包括所有驱动程序在内的系统软件组件之间的一个接口 这些例程隐 藏了平台特定的硬件细节 例如高速缓存 I O 总线 中断等等 系统支持的 PnP 硬件总线驱动程序 在 PnP 管理器的合作下对 HAL 组件提供了类似的功能 这就是说 PnP 管理器与每一个 PnP 硬件总线驱动程序合作 提供特定类型 I O 总线的平 台硬件和系统软件之间的接口 PnP 管理器创建一个设备树 它的节点代表系统中所有的设备 包括总线和连在总线上的 设备 对于每一个设备 PnP 管理器维护两个列表 一个是设备可以使用的硬件资源表 另一个是设备实际占用的硬件资源表 设备驱动程序辅助 PnP 管理器创建这些列表 这些 列表被保存在注册表中 一旦在系统中增添或删除设备 PnP 管理器有必要重新分配资源 并更新列表 1 3 3 1 3 3 永远抢占优先和永远中断永远抢占优先和永远中断 内核组件确定什么时候依照下列优先级调度标准之一来运行一段特定的代码 针对线程的内核定义的运行时优先级 系统中每一个线程都被分配了一个优先级属性 通常 系统中的大多数线程拥有可变 的优先级属性 它们是总是抢占优先的 并且当前在同一优先级上的线程被轮询调度 系统中的一些线程拥有实时优先属性 这些对时间要求苛刻的线程可以被拥有更高实 时优先级的线程抢占 直到它们释放控制 无论拥有什么优先级属性 系统中的任何线程在硬件和某种软件中断发生时被抢占 内核定义的中断请求级 IRQL 在给定平台上被赋予特定的中断向量 内核也区分硬件和软件中断的优先次序 使得一些内核模式代码可以在更高的 IRQL 上 运行 从而使得这些代码 包括大多数驱动程序 比系统中所有的线程拥有更高的优 先级 一段内核模式代码在特定的 IRQL 上执行 这个 IRQL 定义了它的硬件优先级 内核模 式代码是总是可中断的 一个带有更高 IRQL 值的中断可能在任何时候发生 从而导致 拥有更高 IRQL 的另一段内核模式代码被处理器立即执行 换句话说 当一段代码在给 定的 IRQL 上运行时 内核屏蔽微处理器上所有小于等于当前 IRQL 值的中断向量 通常 线程运行在 PASSIVW LEVEL IRQL 上 没有中断向量被屏蔽 软件中断被赋予相对较 低的 IRQL 值 APC LEVEL DISPATCH LEVEL 或针对内核调试 WAKE LEVEL 设备中断拥 有较高的 IRQL 值 内核则为系统关键的中断保留最高的 IRQL 值 例如系统时钟或总线错 8 误中断 一些系统支持例程运行在 IRQL PASSIVE LEVEL 原因有两个方面 一是因为一些内核模式 组件创建它们自己的线程 另一是因为一些支持例程被作为可分页代码实现 并且 或者访 问可分页数据 同样的 某种标准驱动程序例程通常运行于 IRQL PASSIVE LEVEL 然而 几个标准的驱动 程序例程要么运行于 IRQL DISPATCH LEVEL 要么运行于设备 IRQL 也称为 DIRQL 后 一种是针对最低层的驱动程序来说的 参看 内核模式驱动程序设计指南 的第 16 章中的 管理硬件优先级 可以得到关于 IRQL 的细节 通常 如果线程正在请求驱动程序的当前 I O 操作 则在这些线程的环境中 仅仅最高层 的驱动程序被调用 如果线程已经请求了它的当前 I O 操作 中间层或最低层驱动程序从 不假定它正在这些线程的环境中执行 由于性能的原因 避免环境交换 几乎没有驱动程序创建它们自己的线程 因此 当一 个标准的驱动程序例程被调用做某些工作时 驱动程序例程通常恰恰在当前线程环境中执 行 也就是说 它们在专用线程环境中执行 任何内核模式例程都运行在比 PASSIVE LEVEL 高的 IRQL 上 这些例程拥有比系统中所有线 程都高的优先级 驱动程序中的任何例程都是可中断的 运行在特定 IRQL 上的任何内核模 式例程一直保留处理器的控制权 除非例程运行时有更高的内核指定的 IRQL 发生 甚至一个最底层的驱动程序中断服务例程 ISR 也能被其他运行在较高 IRQL 上的例程中 断 例如 被另一个驱动程序的 ISR 中断 不像一些旧的 PC 操作系统中的驱动程序 Windows NT Windows 2000 驱动程序的 ISR 几乎不做任何驱动程序的 I O 处理 因为驱动 程序的 ISR 一直到它返回 也不必保留它正在其上运行的 CPU 的控制 相反 最低层的驱动程序必须在较低的 IRQL 上完成它的 I O 操作的大部分 而不是它的 ISR 的 DIRQL 为了获得好的系统整体性能 所有的运行在高级 IRQL 上的内核模式例程必 须迅速释放 CPU 的控制权 这样的例程不仅仅做它们在高级 IRQL 上必须作的 通常将一个 延迟过程调用 DPC 排队 以完成任何能在较低 IRQL DISPATCH LEVEL 上完成的操作 操作系统的可中断 可抢占优先的设计目标是最大化平均性能 任何驱动程序的 ISR 能被 运行在较高 IRQL 上的例程中断 并且任何线程都能被具有较高优先级的线程中断 虽然一 些线程拥有实时优先级属性 它们仍然能被具有更高优先级的线程抢占 然而 Windows NT Windows 2000 构架并没有提供一个真正的实时系统 如果想得到内核模式驱动程序中系统定义的标准例程的介绍 可以参看第 2 章 分层的 I O IRP 和 I O 对象 参看第 4 章 基本驱动程序结构 可以得到这些例程的概述 1 3 4 1 3 4 多处理器安全多处理器安全 在任何 Windows NT Windows 2000 多处理器平台中 需要满足下列条件 所有的 CPU 是相同的 并且它们要么都有协处理器 要么都没有 所有的 CPU 共享内存 并且一致地访问内存 在对称平台中 每一个 CPU 能访问内存 处理中断 访问 I O 控制寄存器 相对来 说 在不对称多处理器机器中 一个 CPU 可能为一组从属 CPU 处理所有中断 Windows NT Windows 2000 被设计成一律运行在单一或对称多处理器平台上 内核模式的 Windows 2000 和 WDM 驱动程序应该被同样的设计 为了能在对称多处理器 SMP 平台上安全运行 任何操作系统都必须解决这样一个问题 9 即 怎样保证正在某个处理器上运行的代码 不会同时访问和修改运行在另一个处理器上 的代码正在访问和修改的数据 例如 正在一个处理器上处理设备中断的最低层驱动程序 的 ISR 排斥其他对临界的 驱动程序定义的数据 或设备寄存器 的访问 以防它的设备 同时在另一个处理器上中断 此外 在单一处理器的机器中被序列化的驱动程序 I O 操作在 SMP 机器中能被同时执行 这就是说 当一个处理输入 I O 操作的驱动程序例程在一个处理器上被执行的时候 另一 个与设备通讯的例程能同时在另一个处理器上被执行 不论是运行在单处理器机器上 还 是 SMP 机器上 都要求包括 WDM 驱动程序在内的所有内核模式驱动程序能同步访问系统定 义的数据或系统提供给驱动程序例程共享的资源 并且在任何时候要同步对物理设备的访 问 NT 内核组件输出了一个机制 被称为自旋锁 spin lock 对称多处理器平台中一个或 多个正在运行的例程同时访问时 它被用来保护共享数据 或设备寄存器 内核对自旋 锁的应用使用了两个策略 在任何时刻 一个且仅一个例程能拥有一个特定的自旋锁 仅仅自旋锁的拥有者才能 访问它所保护的数据 另一个例程必须取得自旋锁后 才能访问相同的数据 并且 除非自旋锁的当前拥有者主动释放了它 否则其他任何例程都不能得到它 象硬件和软件中断向量一样 内核为系统中的每一个自旋锁制定一个相关的 IRQL 值 内核模式例程只有运行在自旋锁指定的 IRQL 上时 才能到特定的自旋锁 这些策略用来保护某个驱动程序例程被更高优先级的驱动程序例程所抢占 前者通常是在 较低的 IRQL 上运行 但是现在却拥有某个自旋锁 后者则希望获取同样的自旋锁 这通常 会造成死锁 分配给某个自旋锁的 IRQL 通常是能获得这个自旋锁的最高层 IRQL 例程的 IRQL 一个最低 层驱动程序的 ISR 频繁地与驱动程序的 DPC 例程共享一个状态区 后者靠调用驱动程序提 供的临界区例程来访问共享区域 在这个例子中 保护共享区域的自旋锁拥有与 DIRQL 相 同的 IRQL 设备中断通常发生在 DIRQL 当临界区例程拥有自旋锁并且在 DIRQL 上访问共 享区域 ISR 不能在单处理器机器中运行 这是因为设备中断被屏蔽 正如前面提到的那 样 在一个对程多处理器机器中 当临界区例程拥有自旋锁并且在 DIRQL 访问共享数据时 ISR 还不能获得自旋锁以保护共享数据 通过等待内核的调度者对象之一 一组内核模式线程能同步访问共享数据或资源 这些调 度对象有 事件 互斥体 信号量 定时器 或另一个线程 然而 大多数驱动程序不创 建它们自己的线程 因为当它们避免线程环境交换的同时 获得了更好的性能 对时间要 求比较苛刻的内核模式支持例程和驱动程序无论何时运行在 IRQL DISPATCH LEVEL 或 DIRQL 都必须使用内核的自旋锁 从而来同步对共享数据和资源的访问 想要得到更详细的信息 可以参看第 16 章 使用自旋锁和管理硬件优先级 第 3 章 内 核调度对象 1 3 5 1 3 5 基于对象基于对象 Windows NT Windows 2000 是基于对象的系统 在执行体中 各种各样的组件定义一个或 多个对象类型 每个组件输出仅内核模式具有的支持例程 当这些例程被调用时 它们操 纵它的对象类型的实例 没有组件被允许直接访问另一个组件的对象类型的任何实例 每 个组件要想使用其他的组件对象 必须调用输出的支持例程 对这些约定的严格遵守使得 Window NT Windows 2000 具有移植性和伸缩性 例如 操作系 10 统将来的某个版本能包含一个完全或部分被重写的内核组件 这个组件定义了相同的对象 类型 但是可能使用了完全不同的内部结构 却可以输出一组具有与现存组件所输出的例 程相同名字和参数的支持例程 这个假定的被重写的内核版本将对现存系统中任何其他的 执行组件的移植性没有任何影响 换句话说 操作系统组件没有使用后门通讯 并且驱动 程序也必须避免这种使用 以保持系统的移植性和可配置性 与操作系统相似 驱动程序及其设备也是基于对象的 包括用户模式代码在内 对于系统 中所有其他的组件 对某个设备的连接被描述成 I O 管理器的文件对象之一的打开操作 在 I O 系统中 每一个驱动程序的逻辑 虚拟 和 或物理设备被描述为设备对象 在 I O 管理器中 每一个驱动程序的加载映像被描述成一个驱动程序对象 I O 管理器为文件对 象 设备对象和驱动程序对象定义对象类型 像任何其他的可执行组件 驱动程序通过调用内核模式支持例程来使用对象 这些支持例 程是由 I O 管理器和其他系统组件输出的 内核模式支持例程通常拥有明确的名称 指明 了每次操纵的特定对象和在这个对象上执行的操作 这些支持例程名称的形式如下 PrefixOperationObject 这里 Prefix 指明了输出支持例程的内核模式组件 并且还通常指明了定义对象类型的组件 大多数前 缀有两个字母 Operation 描述对这个对象作什么 Object 指明对象类型 例如 IoCreateDevice 在设备初始化过程中每个内核模式驱动程序都要调用这个例程一 次或多次 从名字可以看出 这个例程创建一个设备对象 以描述一个物理 逻辑 或虚 拟设备 作为 I O 请求的目标 为了方便起见 一个系统组件能输出调用其他组件的支持例程 特别是 I O 管理器输出 特定例程 以简化驱动程序开发 例如 IoConnectInterrupt 是一个最低层的驱动程序调 用 被用来注册它们的中断服务例程 ISR 它调用针对中断的内核的支持例程 在线 DDK 中的术语表包括了一组系统对象的定义 它们对驱动程序开发者非常有用 关于 对最低层和中间层驱动程序特别有用的支持例程的详细信息 参见 Windows 2000 驱动程 序开发参考 的卷 1 和卷 2 以及在线 DDK 1 3 6 1 3 6 带有可复用带有可复用 IRPIRP 的包驱动的包驱动 I OI O I O 管理器的主要工作是接收 I O 请求 通常来自用户模式应用程序 创建 IRP 以描述 它们 发送 IRP 到合适的驱动程序 跟踪它们直到它们被完成 还有返回状态到每个 I O 操作的初始请求者 I O 管理器 即插即用管理器和电源管理器使用 IRP 与包括 WDM 驱动 程序在内的内核模式驱动程序通信 并且允许驱动程序之间相互通讯 注意 一些 IRP 可以被发送到多个驱动程序 例如 一个在某个磁碟上打开文件的请求可 能首先到达文件系统驱动程序 通过中间层镜像驱动程序 最终到达磁盘驱动程序 可能 是一个 PnP 硬件总线驱动程序 因此 每个 IRP 有一个固定的部分和一个或多个驱动程序特定的 I O 栈位置 stack location 11 在固定部分 或头 中 I O 管理器维护与原始请求有关的信息 例如调用者的线程 ID 和参数 还有在其上被打开文件的设备对象的地址 等等 固定部分也包含一个 I O 状态块 驱动程序在其中设置请求的 I O 操作的状态信息 在最高层驱动程序的 I O 栈位置中 I O 管理器 即插即用管理器 或电源管理器设 置驱动程序特定的参数 例如由相应驱动程序请求的特定操作 描述成一个函数代码 和它使用的环境 以确定的它将要做些什么 如果需要的话 按照顺序 每一个较高 层的驱动程序创建相邻的较低层驱动程序的 I O 栈位置 因为给定的 IRP 通过每个驱动程序的标准例程集被处理 每一个标准例程能在 IRP 中访问 那个驱动程序的 I O 栈位置 从而在驱动程序操作的每个阶段重用 IRP 另外 更高层的 驱动程序能创建 或重用 IRP 以发送请求到低层的驱动程序 参见第 2 章 分层的 I O IRP 和 I O 对象 可以得到 IRP 通过分层的驱动程序的处理 过程的介绍 如果希望得到关于 IRP 设备类型特定的信息 参看 Windows 2000 驱动程序 开发参考 的卷 2 对于 PnP 和电源管理 IRP 参看 即插即用 电源管理和安装设计指南 和 Windows 2000 驱动程序开发参考 的卷 1 1 3 7 1 3 7 支持异步支持异步 I OI O I O 管理器提供异步 I O 支持 从而使得 I O 请求的发出者 通常是用户模式应用程序 但有些时候是另一个驱动程序 可以继续执行 而不用等待它的 I O 请求完成 提供异步 I O 支持提高了系统整体的吞吐量 同样也提高了任何作出 I O 请求的代码的性能 结果之一是 内核模式驱动程序不必按照 I O 请求被送往 I O 管理器的顺序来处理它们 I O 管理器或更高层驱动程序能依据 I O 请求被接受的顺序重新编程它们 或者能将一个 大的数据传输请求拆分成几个较小的传输请求 此外 驱动程序能重叠 I O 请求处理 特 别是在对称多处理器平台中 就像 1 3 4 多处理器安全 一节中提到的那样 还有 对内核模式驱动程序的单独 I O 请求的处理不必要序列化 这就是说 在驱动程序 开始处理下一个进来的 I O 请求之前 它不必处理完每个 IRP 就像在单处理器机器中 驱动程序在被写成支持同步 I O 的单任务操作系统所作的那样 IRP 被传递给驱动程序的标准例程 通过完成任何例程指定的操作以最终满足当前请求 驱动程序响应当前的 IRP 当然 最低层的驱动程序被要求帮助 I O 管理器和任何高层的 驱动程序处理同样的 IRP 并通过设置 IRP 中的 I O 状态块来跟踪每个请求的状态 驱动程序也能在其设备对象的特定部分维护当前 I O 操作的信息 这个部分被称为设备扩 展 若想得到 IRP 处理和设备对象如何表示驱动程序的物理和逻辑设备的概述 可以参看第 2 章 分层的 I O IRP 和 I O 对象 关于设备对象和设备扩展更详细的信息 参见第 3 章 针对驱动程序系统定义的对象和支持 12 第第 2 2 章章 分层的分层的 I OI O IRPIRP 和和 I OI O 对象对象 本章介绍 Microsoft Windows 2000 的 I O 模型 内容包括 内核模式驱动程序如何适合系 统 驱动程序如何处理 IRP 系统定义的标准驱动程序例程 通用设备配置和相应的分层 驱动程序 以及描述设备和驱动程序的对象 本章的组织如下 2 1 Windows 2000 I O 模型概述 2 2 终端用户 I O 请求和 Windows 2000 文件对象 2 2 1 用户 I O 请求的注意事项 2 3 IRP 和驱动程序特定 I O 栈位置 2 3 1 处理 IRP 的注意事项 2 4 驱动程序对象和标准驱动程序例程 2 4 1 对象不透明性 2 4 2 标准驱动程序对象入口点 2 4 3 其他的标准驱动程序例程 2 4 4 标准驱动程序例程的注意事项 2 5 设备配置和分层驱动程序 2 5 1 简单设备和驱动程序配置 2 5 2 添加驱动程序的注意事项 2 6 设备对象和分层的驱动程序 2 6 1 针对简单配置的设备对象 2 6 2 设备对象的注意事项 注意除了第一节 每节都包含了一个 注意事项 列表 这些小节总结对驱动程序的基本 要求和限制 就像本节从整体上介绍一样 2 1 Windows 2000 I O 模型概述模型概述 每一个操作系统都有一个隐含的或明确的 I O 模型 以处理与外围设备之间的数据流 Microsoft Windows 2000 I O 模型的最大不同之处是它支持异步 I O 就如第 1 章中描述 的那样 另外 I O 模型有下列特性 I O 管理器提供一致的接口给所有的内核模式驱动程序 包括最低层 中间层和文件 驱动程序 所有的对驱动程序的 I O 请求被作为 I O 请求包 IRP 发送 I O 操作是分层的 I O 管理器输出 I O 系统服务 用户模式保护子系统代表它们的应 用程序和 或终端用户 调用它们完成 I O 操作 I O 管理器解释这些调用 创建一个 或多个 IRP 并且通过可能的分层驱动程序发送它们到物理设备 I O 管理器定义一组驱动程序支持的标准例程 一些是必需的 一些是可选的 所有 的驱动程序遵从一个相对一致的实现模型 允许外围设备之间的差别 并且总线 功 能 过滤器和文件系统驱动程序被要求的不同功能 就如操作系统本身 驱动程序是基于对象的 驱动程序 它们的设备和系统硬件被表 示为对象 I O 管理器和其他操作系统组件输出内核模式支持例程 驱动程序通过操 纵合适的对象调用这些例程来完成工作 除了使用 IRP 传送传统的 I O 请求之外 I O 管理器与 PnP 和电源管理器一起工作发送包 13 含 PnP 和电源管理请求的 IRP 如果希望了解驱动程序是如何操纵这些 IRP 的 可参看 安装 即插即用和电源管理设计指南 2 2 终端用户终端用户 I O 请求和请求和 Windows 2000 文件对象文件对象 内核模式驱动程序被 Microsoft Windows 2000 保护子系统向终端用户隐藏 这个子系统实 现一个已经很友善的编程接口 例如 Windows 或 POSIX 设备对用户模式代码是可见的 它包括保护子系统 仅仅作为命名的文件对象被 I O 管理器控制 图 2 1 说明了终端用户和 I O 管理器之间的这种关系 图 2 1 代表文件 卷和设备的文件对象 Windows 2000 保护子系统 例如 Win32 子系统 通过 I O 系统服务传送 I O 请求到合适的 内核模式驱动程序 图 2 1 中显示的子系统依赖于显示 视频适配器 键盘和鼠标设备驱 动程序的支持 保护子系统隔离它的终端用户和应用程序 使得它们不必知道关于内核模式组件 包括驱 动程序 的任何细节 同样 I O 管理器隔离保护子系统 使得它们不必知道关于机器特 定的设备配置或驱动程序实现的任何细节 I O 管理器的分层方法也使得大多数驱动程序不必知道任何下列的细节 是否一个 I O 请求在任何特定的保护子系统中被生成 如 Win32 或 POSIX 是否一个给定的保护子系统拥有特定种类的用户模式驱动程序 什么是保护子系统的 I O 模型和什么是对驱动程序的接口 I O 管理器提供给驱动程序一个单独的 I O 模型 一组驱动程序能用来完成 I O 操作的内 核模式支持例程 和 I O 请求发出者与响应这个请求的驱动程序之间的一个一致接口 如图 2 1 所示 子系统和它的本地应用程序仅仅通过 I O 管理器提供的文件对象句柄 能 访问驱动程序设备或海量存储设备上的文件 为了打开这样一个文件对象或获得一个句柄 以实现与设备或数据文件的 I O 文件子系统使用一个请求调用 I O 系统服务以打开一个 命名的文件 这个命名的文件可以拥有一个子系统指定的别名 符号连接 以将文件对 象联系到内核模式名字 I O 管理器 输出这些系统服务 负责寻找或创建文件对象 这个文件对象用来描述设备 或数据文件 I O 管理器还要寻找合适的驱动程序 图 2 2 描述了当子系统代表应用程序 打开描述数据文件的文件对象时发生的事情 1 子系统调用一个 I O 系统服务以打开一个命名文件 2 I O 管理器调用对象管理器以寻找命名的文件 并帮助它决定到文件对象的符号连接 它也调用安全引用监视器以检查子系统是否拥有正确的权限打开那个文件对象 3 如果卷还没有被安装 mount I O 管理器暂停打开请求 并且调用一个或多个 Windows 2000 文件系统 直到它们中间之一认可这个文件对象存储在文件系统使用的 海量存储设备之一上面 当文件系统已经安装了卷 I O 管理器继续处理这个请求 4 I O 管理器为这个打开请求分配内存并初始化一个 IRP 对于驱动程序来说 打开等同 于一个 创建 请求 5 I O 管理器调用文件系统驱动程序 传递它给 IRP 文件系统驱动程序访问它的在 IRP 中的 I O 栈位置 以确定什么操作必须被完成 检查参数 确定是否请求的文件在缓存 中 并且如果没有的话 在 IRP 中设置相邻的较低层的驱动程序的 I O 栈位置 14 6 驱动程序处理 IRP 并完成请求的 I O 操作 调用 I O 管理器和其他系统组件 图 2 2 种没有显示 提供的内核模式支持例程 7 驱动程序将 IRP 连同 I O 状态块集返回到 I O 管理器 以指明请求的操作是成功被执行 了 还是失败了 8 I O 管理器从 IRP 获得 I O 状态 所以它能通过保护子系统返回状态信息到原始调用者 9 I O 管理器释放完成的 IRP 10 如果打开操作成功 I O 管理器返回文件对象的句柄到子系统 如果出现错误 它 返回合适的状态到子系统 子系统成功打开一个描述数据文件 设备或卷的文件对象后 它使用返回的句柄为设备 I O 操作 通常是读 写 或设备 I O 控制请求 在后续的请求中指明文件对象 为了创 建这样的请求 子系统调用 I O 系统设备 I O 管理器将这些请求作为 IRP 发送它们到合 适的驱动程序 2 2 1 2 2 1 用户用户 I OI O 请求的注意事项请求的注意事项 当设计一个内核模式的驱动程序时 切记以下几点 驱动程序可以被分层 并且多个驱动程序能处理单独的 I O 请求 IRP 驱动程序不能做任何有关其他驱动程序将会在设备栈位置中的假设 因此 每个驱动 程序应该被准备用于接收来自任何其他驱动程序的请求 并能处理所有潜在的错误 驱动程序在 IRP 的 I O 状态块中获得请求的 I O 操作成功或失败的消息 I O 管理器 将请求的 I O 操作成功或失败的消息发送给用户模式的请求者 驱动程序不必 也不应该被设计成能提供应用程序特定的支持 保护子系统或它的子 系统特定的用户模式驱动程序提供这种支持 对这条规则有一个例外 依赖于一个应 用专用设备的 MS DOS 应用程序能请求 Windows 2000 驱动程序以控制这个设备 还能 请求一个紧密结合的 Wind32 用户模式的虚拟设备驱动程序 VDD 有关 VDD 的详细 信息参看在线 DDK 中的 Virtual Device Drivers 虚拟设备驱动程序 文档 2 3 IRP 和驱动程序指定的和驱动程序指定的 I O 栈位置栈位置 图 2 2 带有两个 I O 栈位置的 IRP 但实际上一个 IRP 可以拥有任意多个 I O 栈位置 这 依赖于有多少分层的驱动程序处理给定的请求 图 2 3 在分层的驱动程序中处理 IRP 图 2 3 更详细的说明了图 2 2 中的驱动程序是怎样使用 I O 支持例程 IoXxx 为一个读 写请求处理 IRP 1 I O 管理器用一个 IRP 调用文件系统驱动程序 FSD 这个 IRP 是为子系统读 写请求 分配的 FSD 访问 IRP 中它的 I O 栈位置 以决定它完成什么操作 2 FSD 能将原始请求分成更小的请求 可能是针对几个设备驱动程序 这项工作是通过 调用一个 I O 支持例程 IoAllocateIrp 一次或多次以分配额外的 IRP 这些额外的 IRP 连同为更低层驱动程序创建的 I O 栈位置 被填充为全零 被返回给 FSD 由它随 意决定 FSD 能在原始 IRP 中安装相邻的较低层驱动程序的 I O 栈位置 并传递它给更 15 低层的驱动程序 通过这种方法 FSD 能重用原来的 IRP 而不是象图 2 3 种所示的那样 分配额外的 IRP 3 对于每个驱动程序分配的 IRP 图 2 3 中的 FSD 调用一个 I O 支持例程以注册一个 FSD 支持的完成例程 在这个完成例程中 FSD 能确定低层驱动程序是否满足请求 并能在 低层驱动程序完成任务后释放每个驱动程序分配的 IRP 不论每个驱动程序分配的 IRP 是被成功完成 还是返回一个错误状态 或者是被放弃 I O 管理器都将调用 FSD 支持 的完成例程 更高层驱动程序负责释放 IRP 这个 IRP 是它根据自己的需求为较低层驱 动程序分配并安装的 I O 管理器在所有驱动程序完成任务后释放它分配的 IRP 下一步 FSD 调用一个 I O 支持例程 IoGetIrpStackLocation 访问相邻的较低层的驱 动程序的 I O 栈位置 从而为临近低层驱动程序设置请求 图 2 3 种 相邻的较低层 驱动程序碰巧是最低层的驱动程序 FSD 然后调用 I O 支持例程 IoCallDriver 将 那个 IRP 传递给相邻的较低层驱动程序 4 当最低层驱动程序被使用 IRP 调用时 它检查它的 I O 栈位置以确定它将在目标设备上 完成什么操作 通过 IRP MJ XXX 函数代码指定 目标设备在它的被指定的 I O 栈位 置中被设备对象表示 并且连带 IRP 被传送给驱动程序 最低层驱动程序假定 I O 管理 器已经发送 IRP 到一个入口点 这个入口点是驱动程序为 IRP MJ XXX 这里是 IRP MJ READ 或 IRP MJ WRITE 操作定义的 并且假定高层驱动程序已经为请求检查过 其他参数的有效性 如果没有较高层驱动程序 最低层驱动程序将检查 IRP MJ XXX 的输入参数是否是有效 的 如果它们是有效的 驱动程序通常调用 I O 支持例程以通知 I O 管理器设备操作正 在 IRP 上等待决定 并且要么将 IRP 放入队列 要么传递它给另一个驱动程序提供的例 程 这些例程可以访问目标设备 这里是物理设备或逻辑设备 磁盘或磁盘上的一个分 区 5 I O 管理器确定目标设备的驱动程序是否正在处理另一个 IRP 如果

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论