I/O系统组件
==================
Windows I/O系统的设计目标就是为以下一些特性的应用程序提供设备的抽象, 设备包括硬件设备和软件设备(虚拟设备和逻辑设备).
- 对跨设备的共享资源进行统一的安全和命名
- 对于可度量的应用程序, 提供基于IO包的,高性能的异步支持.
- 允许用高级语言写驱动程序, 和更容易的在不同机器架构之间迁移.
- 拥有分层能力和扩展能力. 允许另外的驱动透明的修改其他驱动或设备的行为, 不需要任何对其他驱动或者设备的修改的分层能力和扩展能力.
- 动态的加载和卸载, 这样驱动程序可以在需要的时候加载, 不需要的时候卸载掉, 不占系统资源.
- 支持即插即用, 即系统为新找到的硬件设备定位并安装驱动程序, 然后给他们分配硬件所需要的操作系统资源
- 支持电源管理, 所以某些系统中的设备可以进入省电模式.
- 支持多重可安装的文件系统, 包括FAT, CD-ROM文件系统(CDFS), 统一磁盘格式(universal disk format)UDF, 还有Windows文件系统(NTFS).
- Windows管理工具的支持,还有可诊断能力, 所以驱动可以通过Windows Management Instrumentation的应用程序来管理.
Windows的IO系统包括许多执行元件(executive components)组成, 见上图.
- IO管理器是整个IO系统的核心, 它连接应用程序和系统组件到虚拟的,逻辑的和物理的设备上, 它还定义了支持设备驱动的基础架构.
- 设备驱动一般为某种设备提供IO接口. 设备驱动接受IO manager传递给他们的命令, 然后他们通知IO manager这些命令什么时候结束. 设备驱动经常使用IO manager来forward IO命令给其他的设备驱动, 这些设备驱动是在设备接口或控制中共享的.
- PnP管理器与IO管理器还有一种叫做bus driver的设备驱动结合的十分紧密, bus driver是用来知道硬件资源分配, 还有检测并响应硬件设备的加入和移除的. 当一个设备加入到系统中, 他还没有恰当的设备驱动的时候, 执行即插即用的组件调用用户态的PnP管理器的设备安装服务.
- 电源管理器也和IO管理器结合的很紧, 他们两个一起指导系统和单个的设备驱动程序如何执行电源状态的转换.
- Windows Management Instrumentation (WMI) 支持叫做Windows Driver Model (WDM)的WMI provider函数, 允许设备驱动间接的像provider一样的工作, 在用户台下, 允许设备驱动可以像媒介一般的使用WDM WMI provider来与WMI服务通信.
- 注册表像一个数据库一样的存贮附着在系统上的基本硬件设备的描述信息, 还有驱动初始化设置以及配置设置.
- INF文件, 也就是以.inf为后缀的文件, 是驱动安装文件. INF文件将特定的硬件设备和假设为设备首要控制的驱动相联系. 它们组成了类似脚本的指令来描述1, 相关的设备; 2. 驱动文件的源位置和目标位置; 3. 必须的关于驱动安装的注册表修改; 4. 设备依赖关系信息. Windows 使用数字签名来验证驱动程序是否通过了微软硬件质量实验室的测试. 数字签名存在.cat文件中.
- 硬件抽象层, 使驱动程序同特定的处理器和中断控制器隔离开来, 从而屏蔽了他们的细节, 这样可以隐藏不同平台之间的区别. 本质上来说, HAL是所有计算机母板上的, 不被其他设备控制的, 设备们的bus driver
I/O系统的结构和模式
================
在Windows中, 线程对虚拟文件执行IO操作. 操作系统将所有的IO请求都抽象为在一个虚拟文件上的操作., 隐藏了IO操作的对象可能并不是一个文件结构的设备的事实. 这抽象生成了应用程序对设备的接口. 一个virtual file指的是: 对任何的源或者目的IO设备来说, 线程就当他们是一个文件(文件啦, 目录啦, 管道啦, 邮件槽啦). 所有的读或者写的数据都被看作是简单的面向这些虚拟文件的字节流. 用户态应用程序调用文档记录的函数, 他们依次调用内部的IO系统函数来从文件中读取数据, 向文件中写入数据, 或者执行其他的操作. IO管理器动态的检测这些虚拟文件的请求, 并执行到恰当的设备驱动上.
下面是典型IO请求过程的基本架构.
IO管理器
-------------
IO管理器定义了有秩序的框架, 在这个框架中IO请求会被传递给设备驱动. IO系统是packet driven(封包驱动)的. 多数的IO请求都由IO request packet(IRP)表示, IRP可以在多个IO系统组件中间流动. Fast IO是一个例外, 他不使用IRP. 设计允许一个应用程序线程并发的处理多个IO请求. 一个IRP是一个数据结构, 包含描述IO请求的完整信息.
IO管理器创建代表IO请求的IRP, 传递IRP的指针给正确的驱动, 然后在io操作结束之后析构掉这个IRP包. 对比的, 驱动程序接受IRP包, 执行IRP指定的操作, 将IRP包传回给io管理器, 要么是操作成功了而传回, 要不是准备传递给另外一个驱动程序去作进一步的处理.
关于创建和析构IRP, IO管理器提供代码, 这些代码对于不同的驱动程序来说是常见的, 所有的驱动都调用这些函数来执行他们的IO处理. 通过加强了的IO管理器的普通任务, 个别的驱动变得更简单, 更精简. 比如说, io管理器提供一个函数, 允许一个驱动程序去调用另一个驱动程序. 它也管理IO请求的缓冲, 对驱动和记录提供超时支持, 这里的记录指的是被可安装的文件系统被加载到操作系统中的时候的记录. 有进百个不同的IO管理器的函数可以被驱动程序调用.
IO管理器还提供灵活的IO服务, 这些服务允许环境子系统比如Win32和POSIX来实现各自的IO函数. 这些服务包括成熟的对异步IO的服务, 异步IO服务允许开发人员建立可度量的高性能的服务器应用程序.
驱动程序展现出的统一的, 模块化的接口, 允许IO管理器调用任何的驱动程序而不需要知道关于这个驱动的具体信息和内部实现的细节. 如同我们之前提到的, 操作系统对待所有的IO请求都看做是一个操作一个文件. 驱动将给虚拟文件的请求转换为对物理设备的请求. 驱动程序也可以调用彼此来实现分层的, 独立的IO请求处理.
除了正常的打开, 关闭, 读, 写功能之外, Windows IO系统还提供许多高级的特性, 比如异步处理啦, 缓存啦, scatter/gather IO.