概括而言,设备驱动程序有以下三种基本类型:
l 即插即用驱动程序(也称为WDM 驱动程序,见下文介绍)。这一类驱动程序通常是为了驱动硬件设备而由硬件厂商提供,它们与Windows 的I/O 管理器、即插即用管理器和电源管理器一起工作。Windows 自身随带了大量即插即用驱动程序,用于支持各种常见的存储设备、视频适配器、网络适配器、输入设备等。
l 内核扩展驱动程序(也称为非即插即用驱动程序)。这一类驱动程序用于扩展内核的功能,或者提供访问内核模式代码和数据的一种途径。它们并没有集成到即插即用管理器和电源管理器的框架中。在引入即插即用管理机制以前开发的驱动程序都属于这一类型。现在仍然有大量的内核扩展驱动程序。
l 文件系统驱动程序。这一类驱动程序接收针对文件的请求,再进一步将请求转变成真正对于存储设备或网络设备的I/O 请求,从而满足原始的文件请求。
Windows 的即插即用管理器是I/O 系统的一部分,它负责即插即用设备的内核支持,其职责是:自动检测设备的插入和移除;动态地分配硬件资源,例如中断、I/O 端口和I/O寄存器;指示I/O 管理器为设备加载正确的驱动程序;向内核及应用程序提供有关设备插入和移除的通知机制。即插即用管理器根据总线和设备的功能分工,定义了一个驱动程序模型,让总线和设备的驱动程序协作完成设备的列举、插入和拔除等管理工作。支持这一模型的驱动程序称为WDM(Windows Driver Model)驱动程序,共有三种类型:总线驱动程序、功能驱动程序和过滤驱动程序。总线驱动程序既负责管理总线上的设备(配合即插即用管理器),也为总线上的设备提供了访问总线资源的方法。功能驱动程序负责管理具体的设备,向操作系统提供该设备的功能。过滤驱动程序的用途是监视一个设备的I/O请求及其处理过程,甚至增加或改变一个设备或驱动程序的行为。
在WDM 中,每个硬件设备都有一个设备驱动程序栈(简称设备栈),其中包含一个总线驱动程序和一个功能驱动程序,以及零个或多个过滤驱动程序。即插即用管理器在设备列举过程中,依照总线与设备之间的关系,构建起一棵设备树,其中包含当前系统中所有被检测到的总线和设备。设备树的每一个节点都代表一个实际的设备,该设备的设备栈为其提供软件服务,操作系统(实际上是I/O 管理器)通过设备栈来访问或操纵设备。
非即插即用驱动程序的用途多种多样,其中内核扩展是最自然的用法。例如,许多系统工具使用内核扩展类型的驱动程序来获得Windows 内核中的各种系统信息,或者创建系统线程以便在系统进程环境中执行任务。另外,在Windows 内核中,也有一些模块虽然以“.sys”作为文件扩展名,但它们其实并非设备驱动程序,而是单纯的内核扩展动态链接库,供其他的驱动程序或者内核模块调用。
有关Windows 中I/O 管理器、即插即用管理器、电源管理器以及设备驱动程序的进一步介绍,可参考第6 章。
文件系统/存储管理
在现代操作系统中,文件系统是外部存储设备的标准接口,它为应用程序使用这些设备中的数据提供了统一的抽象,多个应用程序和系统本身可以共享使用这些设备。在Windows 中,文件系统的接口部分由I/O 管理器定义和实现,但文件系统的实现部分位于专门的一类驱动程序中。当文件系统接收到I/O 请求时,它会根据文件系统格式规范,将这些请求转变成更低层的对于外部存储设备的I/O 请求,通过它们的设备驱动程序来完成原始的I/O 请求。因此,文件系统的驱动程序定义了外部存储设备中数据的逻辑结构,使得这些数据可直接被操作系统和应用程序使用。
Windows 的原生文件系统是NTFS(NT File System),其驱动程序为ntfs.sys。NTFS是专门为Windows 设计的文件系统格式,它提供了安全性、可靠性、大容量支持、长文件名支持,以及可恢复性等一系列高级特性,目前广泛应用于Windows 系统。另一个常用的文件系统格式是FAT(File Allocation Table),这是从DOS 时代发展起来的文件系统格式,格式规范相对比较简单,目前仍在使用,主要用于兼容老版本的操作系统,以及用于移动设备以便跨操作系统传送数据。
在Windows 中,每个文件系统实例有它自己的设备栈,因而通过插入过滤驱动程序可以过滤文件I/O 请求。Windows 支持两种形式的过滤驱动程序:一种直接插入到设备栈中,从而能够看到每一个经过设备栈的文件I/O 请求;另一种基于Windows 提供的过滤管理器驱动程序(FltMgr)的I/O 过滤框架,称为文件系统小过滤驱动程序,它们并不出现在文件系统设备栈中,而是以回调方式来响应FltMgr 的事件。
文件系统的底层是对存储设备的管理。大容量存储设备以“分区(partition)”和“卷(volume)”来管理整个存储空间。分区是指存储设备上连续的存储区域(连续的扇区),而卷是指扇区的逻辑集合。一个卷内部的扇区可能来自一个分区,也可能来自多个分区,甚至来自不同的磁盘。文件系统则是卷内部的逻辑结构。因此,Windows 的存储管理形成了一个存储栈,最接近于应用程序的是文件系统,接下来是卷管理部分,最接近于存储设备的是分区管理和磁盘驱动程序。
磁盘设备是典型的即插即用设备,其设备栈和驱动程序符合WDM 规范。即插即用管理器在设备列举过程中建立起每个磁盘设备的设备栈。设备栈的最底下是总线驱动程序,最上方是一个称为分区管理器的驱动程序,负责通知即插即用管理器当前磁盘上有哪些分区,因而系统中的卷管理器可以接收到有关分区创建和删除的通知。这样,每个物理分区与卷管理器联系起来,卷管理器再将卷与文件系统关联起来,就形成了完整的存储栈。
有关Windows 中文件系统和存储管理的进一步介绍,可参考第7 章。
网络
网络虽然并非Windows 操作系统中必不可少的组成部分,但实际上,它已经成为绝大多数Windows 系统的标准配置。Windows 为应用程序提供了多种网络API,允许应用软件设计人员根据他们的需求适当选择。以下是Windows 平台上主要的网络API:
Windows 套接字,简称Winsock。它实现并扩展了BSD 套接字标准。Winsock 2.0 版本支持一些新特性,比如异步网络I/O、服务质量(QoS)规范、可扩展名字空间,以及多点消息传输等。
WinInet。这是一个高层网络API,它支持多个协议,包括Gopher、FTP 和HTTP。Microsoft Internet Explorer 使用WinInet 来完成数据传输。
命名管道(named pipe)和邮件槽(mailslot)。用于不同进程之间进行通信。它们支持不同机器上的进程之间相互通信。命名管道支持连接方式的通信模型;邮件槽支持非连接方式的通信模型,客户进程可以发送广播消息。
NetBIOS。这是一个早期的网络编程API,Windows 支持NetBIOS 是为了兼容老的应用程序。NetBIOS 支持有连接的通信和无连接的通信。
RPC。这是网络编程的一个标准,往往是分布式系统基础设施的重要组件。RPC 建立在其他的网络API 基础之上,比如命名管道和Winsock。Windows 的RPC 支持异步调用方式。
这些网络API 都提供了用户模式的动态链接库(DLL),当应用程序通过这些DLL发出网络I/O 请求时,它们必须将接收到的请求传递给内核模式下的相应驱动程序。通常,这些网络API 要么通过专门的系统服务切换到内核模式,比如命名管道和邮件槽就有专门的系统服务;要么通过标准的系统服务接口,比如NtReadFile、NtWriteFile 和NtDeviceIoControlFile,由I/O 管理器和对象管理器将网络请求转送至对应的驱动程序中。
Winsock 是Windows 最重要的网络API,它的用户模式部分不仅包含了一个DLL(即ws2_32.dll),还定义了一个可扩展的框架,允许第三方插入传输服务提供者和名字空间服务提供者,以支持更多的传输服务和名称解析或地址映射能力。Winsock 默认支持TCP/IP、IPX/SPX、AppleTalk 和ATM 等协议,它提供的传输服务和名字空间服务都通过内核模式驱动程序afd.sys 实现网络通信。
在内核模式部分,网络API 驱动程序(譬如afd.sys)通过传输驱动程序接口(TDI,Transport Driver Interface)与协议驱动程序进行通信。TDI 实际上是一组预定义的I/O 请求,它描述了各种网络请求,包括名称解析、建立连接、发送和接收数据等。网络API驱动程序是TDI 客户,而传输协议驱动程序实现了TDI 接口,称为TDI 传输器。TDI 客户与TDI 传输器之间是松耦合关系。一个TDI 传输协议驱动程序可以被多个TDI 客户使用。例如,TCP/IP 驱动程序为tcpip.sys,它既可以被Winsock 驱动程序afd.sys 使用,也可以被netbt.sys 驱动程序使用。Windows 不仅实现了基本的TCP/IP,还支持NAT(网络地址转译)、IP 过滤以及IPSec 规范等协议扩展,这些协议扩展也是内核驱动程序,它们通过私有的接口与tcpip.sys 进行通信。
在Windows 中,网络协议与网络适配器驱动程序是分开的,协议驱动程序独立于任何一个网络适配器,而真正发送和接收数据是通过网络适配器进行的。协议驱动程序通过统一的接口与适配器驱动程序进行通信,此接口是NDIS(Network Driver InterfaceSpecification)。符合NDIS 的网络适配器驱动程序称为NDIS 驱动程序,或NDIS 小端口驱动程序(NDIS miniport driver)。Windows 提供了NDIS 库,即ndis.sys,作为协议驱动程序与NDIS 驱动程序两者之间的桥梁。随Windows XP 和Windows Server 2003 一起发行的NDIS 库是NDIS 5.1;随Windows Vista 一起发行的NDIS 库是NDIS 6。
NDIS 客户(即TDI 传输器)利用NDIS 库提供的功能,对将要发送给NDIS 驱动程序的命令进行格式化,并发送给NDIS 驱动程序;而NDIS 驱动程序则利用NDIS 库,接收请求和送回应答。NDIS 驱动程序并非标准的设备驱动程序,它们通过NDIS 库与NDIS客户进行通信,I/O 管理器并不介入两者之间的通信过程。
有关Windows 网络体系结构的进一步介绍,可参考9.1 节。
来源: <http://book.51cto.com/art/201011/235711.htm>
2.2.3 Windows 子系统
按照Windows NT 最初的设计,它支持三个环境子系统:OS/2、POSIX 和Windows(或称为Win32)。然而,Windows 子系统是必须要运行的,没有它Windows 系统无法运行,而其他两个子系统则被配置成按需启动。而且,到了Windows XP以后,只有Windows子系统随Windows 系统一起发行。这一节将介绍Windows 子系统的概况,更详细的信息,请参考9.2 节。
在Windows 平台上,可执行映像文件的格式为PE 文件格式[PE-SPEC](参见上一小节中插入的关于PE 文件格式的介绍),其头部域Subsystem 指定了该应用程序将被运行在哪个环境子系统中。Microsoft Visual Studio 的链接器(linker)支持/SUBSYSTEM 命令选项,由它来指定子系统的类型。例如,该域为2 说明这是一个Windows GUI 应用程序,为3则是Windows 控制台应用程序(Windows CUI)。
Windows 子系统中既有用户模式部分,也有内核模式部分。内核模式部分的核心是win32k.sys,虽然它的形式是一个驱动程序,但实际上它并不处理I/O 请求,相反,它向用户代码提供了大量的系统服务。从功能上讲,它包含两部分:窗口管理和图形设备接口(GDI)。其中窗口管理部分负责收集和分发消息,以及控制窗口显示和管理屏幕输出;图形设备接口部分包含各种形状绘制以及文本输出功能。
用户模式部分包括Windows 子系统进程(csrss.exe)以及一组动态链接库(DLL)。Csrss.exe 进程主要负责控制台窗口的功能,以及创建或删除进程和线程等。子系统DLL则被直接链接到应用程序进程中,包括kernel32.dll、user32.dll、gdi32.dll 和advapi.dll 等,负责实现已文档化的Windows API 函数。除了有些可以直接在用户模式中完成以外,很多API 函数需要调用执行体API 或win32k.sys 模块提供的系统服务。
Win32k.sys 一方面向用户代码提供系统服务,另一方面也跟Windows 内核紧密地融合在一起。它通过向内核注册一组出调(callout)函数,以便介入到内核的线程和进程管理等处理逻辑中,同时也可以接收电源事件。对于每个线程,一旦它调用了win32k.sys的任何一个系统服务,就变成了一个GUI 线程,从而纳入到了Windows 子系统的线程和进程管理范畴。Windows 内核的线程和进程数据结构为Windows 子系统预留了一些域,从而win32k.sys 可以方便地操纵它的线程和进程。
下面从窗口管理和图形设备接口两方面来介绍Windows 子系统的核心功能和结构。
窗口管理
Windows 子系统的用户界面管理有一个层次结构,通常应用程序只是在一个默认的桌面上运行。图2.5 显示了这一层次结构。每个子系统会话都有自己的会话空间,属于某一会话的资源将从该会话空间中分配。当用户登录到Windows 中时,操作系统将为该用户建立一个会话;即使用户通过远程桌面或者终端服务连接到一个系统中,系统也会为该用户建立一个单独的会话。
概括而言,设备驱动程序有以下三种基本类型:
l 即插即用驱动程序(也称为WDM 驱动程序,见下文介绍)。这一类驱动程序通常是为了驱动硬件设备而由硬件厂商提供,它们与Windows 的I/O 管理器、即插即用管理器和电源管理器一起工作。Windows 自身随带了大量即插即用驱动程序,用于支持各种常见的存储设备、视频适配器、网络适配器、输入设备等。
l 内核扩展驱动程序(也称为非即插即用驱动程序)。这一类驱动程序用于扩展内核的功能,或者提供访问内核模式代码和数据的一种途径。它们并没有集成到即插即用管理器和电源管理器的框架中。在引入即插即用管理机制以前开发的驱动程序都属于这一类型。现在仍然有大量的内核扩展驱动程序。
l 文件系统驱动程序。这一类驱动程序接收针对文件的请求,再进一步将请求转变成真正对于存储设备或网络设备的I/O 请求,从而满足原始的文件请求。
Windows 的即插即用管理器是I/O 系统的一部分,它负责即插即用设备的内核支持,其职责是:自动检测设备的插入和移除;动态地分配硬件资源,例如中断、I/O 端口和I/O寄存器;指示I/O 管理器为设备加载正确的驱动程序;向内核及应用程序提供有关设备插入和移除的通知机制。即插即用管理器根据总线和设备的功能分工,定义了一个驱动程序模型,让总线和设备的驱动程序协作完成设备的列举、插入和拔除等管理工作。支持这一模型的驱动程序称为WDM(Windows Driver Model)驱动程序,共有三种类型:总线驱动程序、功能驱动程序和过滤驱动程序。总线驱动程序既负责管理总线上的设备(配合即插即用管理器),也为总线上的设备提供了访问总线资源的方法。功能驱动程序负责管理具体的设备,向操作系统提供该设备的功能。过滤驱动程序的用途是监视一个设备的I/O请求及其处理过程,甚至增加或改变一个设备或驱动程序的行为。
在WDM 中,每个硬件设备都有一个设备驱动程序栈(简称设备栈),其中包含一个总线驱动程序和一个功能驱动程序,以及零个或多个过滤驱动程序。即插即用管理器在设备列举过程中,依照总线与设备之间的关系,构建起一棵设备树,其中包含当前系统中所有被检测到的总线和设备。设备树的每一个节点都代表一个实际的设备,该设备的设备栈为其提供软件服务,操作系统(实际上是I/O 管理器)通过设备栈来访问或操纵设备。
非即插即用驱动程序的用途多种多样,其中内核扩展是最自然的用法。例如,许多系统工具使用内核扩展类型的驱动程序来获得Windows 内核中的各种系统信息,或者创建系统线程以便在系统进程环境中执行任务。另外,在Windows 内核中,也有一些模块虽然以“.sys”作为文件扩展名,但它们其实并非设备驱动程序,而是单纯的内核扩展动态链接库,供其他的驱动程序或者内核模块调用。
有关Windows 中I/O 管理器、即插即用管理器、电源管理器以及设备驱动程序的进一步介绍,可参考第6 章。
文件系统/存储管理
在现代操作系统中,文件系统是外部存储设备的标准接口,它为应用程序使用这些设备中的数据提供了统一的抽象,多个应用程序和系统本身可以共享使用这些设备。在Windows 中,文件系统的接口部分由I/O 管理器定义和实现,但文件系统的实现部分位于专门的一类驱动程序中。当文件系统接收到I/O 请求时,它会根据文件系统格式规范,将这些请求转变成更低层的对于外部存储设备的I/O 请求,通过它们的设备驱动程序来完成原始的I/O 请求。因此,文件系统的驱动程序定义了外部存储设备中数据的逻辑结构,使得这些数据可直接被操作系统和应用程序使用。
Windows 的原生文件系统是NTFS(NT File System),其驱动程序为ntfs.sys。NTFS是专门为Windows 设计的文件系统格式,它提供了安全性、可靠性、大容量支持、长文件名支持,以及可恢复性等一系列高级特性,目前广泛应用于Windows 系统。另一个常用的文件系统格式是FAT(File Allocation Table),这是从DOS 时代发展起来的文件系统格式,格式规范相对比较简单,目前仍在使用,主要用于兼容老版本的操作系统,以及用于移动设备以便跨操作系统传送数据。
在Windows 中,每个文件系统实例有它自己的设备栈,因而通过插入过滤驱动程序可以过滤文件I/O 请求。Windows 支持两种形式的过滤驱动程序:一种直接插入到设备栈中,从而能够看到每一个经过设备栈的文件I/O 请求;另一种基于Windows 提供的过滤管理器驱动程序(FltMgr)的I/O 过滤框架,称为文件系统小过滤驱动程序,它们并不出现在文件系统设备栈中,而是以回调方式来响应FltMgr 的事件。
文件系统的底层是对存储设备的管理。大容量存储设备以“分区(partition)”和“卷(volume)”来管理整个存储空间。分区是指存储设备上连续的存储区域(连续的扇区),而卷是指扇区的逻辑集合。一个卷内部的扇区可能来自一个分区,也可能来自多个分区,甚至来自不同的磁盘。文件系统则是卷内部的逻辑结构。因此,Windows 的存储管理形成了一个存储栈,最接近于应用程序的是文件系统,接下来是卷管理部分,最接近于存储设备的是分区管理和磁盘驱动程序。
磁盘设备是典型的即插即用设备,其设备栈和驱动程序符合WDM 规范。即插即用管理器在设备列举过程中建立起每个磁盘设备的设备栈。设备栈的最底下是总线驱动程序,最上方是一个称为分区管理器的驱动程序,负责通知即插即用管理器当前磁盘上有哪些分区,因而系统中的卷管理器可以接收到有关分区创建和删除的通知。这样,每个物理分区与卷管理器联系起来,卷管理器再将卷与文件系统关联起来,就形成了完整的存储栈。
有关Windows 中文件系统和存储管理的进一步介绍,可参考第7 章。
网络
网络虽然并非Windows 操作系统中必不可少的组成部分,但实际上,它已经成为绝大多数Windows 系统的标准配置。Windows 为应用程序提供了多种网络API,允许应用软件设计人员根据他们的需求适当选择。以下是Windows 平台上主要的网络API:
Windows 套接字,简称Winsock。它实现并扩展了BSD 套接字标准。Winsock 2.0 版本支持一些新特性,比如异步网络I/O、服务质量(QoS)规范、可扩展名字空间,以及多点消息传输等。
WinInet。这是一个高层网络API,它支持多个协议,包括Gopher、FTP 和HTTP。Microsoft Internet Explorer 使用WinInet 来完成数据传输。
命名管道(named pipe)和邮件槽(mailslot)。用于不同进程之间进行通信。它们支持不同机器上的进程之间相互通信。命名管道支持连接方式的通信模型;邮件槽支持非连接方式的通信模型,客户进程可以发送广播消息。
NetBIOS。这是一个早期的网络编程API,Windows 支持NetBIOS 是为了兼容老的应用程序。NetBIOS 支持有连接的通信和无连接的通信。
RPC。这是网络编程的一个标准,往往是分布式系统基础设施的重要组件。RPC 建立在其他的网络API 基础之上,比如命名管道和Winsock。Windows 的RPC 支持异步调用方式。
这些网络API 都提供了用户模式的动态链接库(DLL),当应用程序通过这些DLL发出网络I/O 请求时,它们必须将接收到的请求传递给内核模式下的相应驱动程序。通常,这些网络API 要么通过专门的系统服务切换到内核模式,比如命名管道和邮件槽就有专门的系统服务;要么通过标准的系统服务接口,比如NtReadFile、NtWriteFile 和NtDeviceIoControlFile,由I/O 管理器和对象管理器将网络请求转送至对应的驱动程序中。
Winsock 是Windows 最重要的网络API,它的用户模式部分不仅包含了一个DLL(即ws2_32.dll),还定义了一个可扩展的框架,允许第三方插入传输服务提供者和名字空间服务提供者,以支持更多的传输服务和名称解析或地址映射能力。Winsock 默认支持TCP/IP、IPX/SPX、AppleTalk 和ATM 等协议,它提供的传输服务和名字空间服务都通过内核模式驱动程序afd.sys 实现网络通信。
在内核模式部分,网络API 驱动程序(譬如afd.sys)通过传输驱动程序接口(TDI,Transport Driver Interface)与协议驱动程序进行通信。TDI 实际上是一组预定义的I/O 请求,它描述了各种网络请求,包括名称解析、建立连接、发送和接收数据等。网络API驱动程序是TDI 客户,而传输协议驱动程序实现了TDI 接口,称为TDI 传输器。TDI 客户与TDI 传输器之间是松耦合关系。一个TDI 传输协议驱动程序可以被多个TDI 客户使用。例如,TCP/IP 驱动程序为tcpip.sys,它既可以被Winsock 驱动程序afd.sys 使用,也可以被netbt.sys 驱动程序使用。Windows 不仅实现了基本的TCP/IP,还支持NAT(网络地址转译)、IP 过滤以及IPSec 规范等协议扩展,这些协议扩展也是内核驱动程序,它们通过私有的接口与tcpip.sys 进行通信。
在Windows 中,网络协议与网络适配器驱动程序是分开的,协议驱动程序独立于任何一个网络适配器,而真正发送和接收数据是通过网络适配器进行的。协议驱动程序通过统一的接口与适配器驱动程序进行通信,此接口是NDIS(Network Driver InterfaceSpecification)。符合NDIS 的网络适配器驱动程序称为NDIS 驱动程序,或NDIS 小端口驱动程序(NDIS miniport driver)。Windows 提供了NDIS 库,即ndis.sys,作为协议驱动程序与NDIS 驱动程序两者之间的桥梁。随Windows XP 和Windows Server 2003 一起发行的NDIS 库是NDIS 5.1;随Windows Vista 一起发行的NDIS 库是NDIS 6。
NDIS 客户(即TDI 传输器)利用NDIS 库提供的功能,对将要发送给NDIS 驱动程序的命令进行格式化,并发送给NDIS 驱动程序;而NDIS 驱动程序则利用NDIS 库,接收请求和送回应答。NDIS 驱动程序并非标准的设备驱动程序,它们通过NDIS 库与NDIS客户进行通信,I/O 管理器并不介入两者之间的通信过程。
有关Windows 网络体系结构的进一步介绍,可参考9.1 节。
来源: <http://book.51cto.com/art/201011/235711.htm>
2.2.3 Windows 子系统
按照Windows NT 最初的设计,它支持三个环境子系统:OS/2、POSIX 和Windows(或称为Win32)。然而,Windows 子系统是必须要运行的,没有它Windows 系统无法运行,而其他两个子系统则被配置成按需启动。而且,到了Windows XP以后,只有Windows子系统随Windows 系统一起发行。这一节将介绍Windows 子系统的概况,更详细的信息,请参考9.2 节。
在Windows 平台上,可执行映像文件的格式为PE 文件格式[PE-SPEC](参见上一小节中插入的关于PE 文件格式的介绍),其头部域Subsystem 指定了该应用程序将被运行在哪个环境子系统中。Microsoft Visual Studio 的链接器(linker)支持/SUBSYSTEM 命令选项,由它来指定子系统的类型。例如,该域为2 说明这是一个Windows GUI 应用程序,为3则是Windows 控制台应用程序(Windows CUI)。
Windows 子系统中既有用户模式部分,也有内核模式部分。内核模式部分的核心是win32k.sys,虽然它的形式是一个驱动程序,但实际上它并不处理I/O 请求,相反,它向用户代码提供了大量的系统服务。从功能上讲,它包含两部分:窗口管理和图形设备接口(GDI)。其中窗口管理部分负责收集和分发消息,以及控制窗口显示和管理屏幕输出;图形设备接口部分包含各种形状绘制以及文本输出功能。
用户模式部分包括Windows 子系统进程(csrss.exe)以及一组动态链接库(DLL)。Csrss.exe 进程主要负责控制台窗口的功能,以及创建或删除进程和线程等。子系统DLL则被直接链接到应用程序进程中,包括kernel32.dll、user32.dll、gdi32.dll 和advapi.dll 等,负责实现已文档化的Windows API 函数。除了有些可以直接在用户模式中完成以外,很多API 函数需要调用执行体API 或win32k.sys 模块提供的系统服务。
Win32k.sys 一方面向用户代码提供系统服务,另一方面也跟Windows 内核紧密地融合在一起。它通过向内核注册一组出调(callout)函数,以便介入到内核的线程和进程管理等处理逻辑中,同时也可以接收电源事件。对于每个线程,一旦它调用了win32k.sys的任何一个系统服务,就变成了一个GUI 线程,从而纳入到了Windows 子系统的线程和进程管理范畴。Windows 内核的线程和进程数据结构为Windows 子系统预留了一些域,从而win32k.sys 可以方便地操纵它的线程和进程。
下面从窗口管理和图形设备接口两方面来介绍Windows 子系统的核心功能和结构。
窗口管理
Windows 子系统的用户界面管理有一个层次结构,通常应用程序只是在一个默认的桌面上运行。图2.5 显示了这一层次结构。每个子系统会话都有自己的会话空间,属于某一会话的资源将从该会话空间中分配。当用户登录到Windows 中时,操作系统将为该用户建立一个会话;即使用户通过远程桌面或者终端服务连接到一个系统中,系统也会为该用户建立一个单独的会话。
在一个会话中,有一个交互式窗口站,可能还有非交互式窗口站。在交互式窗口站中通常有三个桌面:登录桌面、默认桌面和屏幕保护桌面。通常我们运行的图形界面应用程序运行在默认桌面上。交互式窗口站有独立的剪贴板、键盘、鼠标、显示器等,在它的三个桌面中,任一时刻只有一个是激活的,输入输出设备归激活的桌面所有。
在每个桌面中,都有一个顶级窗口列表,这些窗口往往可以相互重叠,有系统菜单、最大化/最小化按钮和滚动条等。通常各个图形界面应用程序的主窗口属于当前桌面的顶级窗口。在Windows 中,窗口可以有子窗口,子窗口占据父窗口的客户区域。因此,桌面上的窗口形成了一个层次结构。图2.5 仅仅显示了顶级窗口的子窗口,实际上,一个窗口总是可以构建它自己的子窗口。
Windows 为常用的窗口定义了一些窗口类(window class),因而应用程序可以非常方便地创建这些窗口类的实例。应用程序如果要定义独特的窗口特性,可以生成一个窗口类,这个窗口类既可以是全新的,也可以是在系统已有窗口类的基础上定义得到。窗口类规定了其对象将如何响应各种消息,包括系统发送给它的消息和用户触发的消息。Windows 窗口的编程模型是消息驱动的,每个窗口对象根据其窗口类指定的窗口过程来响应各种消息。
Windows 子系统会话有一个RIT(Raw Input Thread)线程,负责从输入设备读取原始的输入事件,然后生成消息,寄送到正确的线程消息队列中。每个包含用户界面元素的线程都应该及时地处理这些消息。通常的做法是在一个消息循环中,不停地获取消息,再分发给目标窗口,由目标窗口的窗口过程来响应。有关Windows 子系统中的窗口管理和消息机制的更多信息,请参考9.2.3 节。
图形设备接口
Windows 的图形引擎也是在Windows 子系统中提供的,它有两方面的特点:首先,它提供了一套与设备无关的编程接口,即GDI,这使得应用程序可以适应各种底层显示设备的差异;其次,应用程序与图形设备驱动程序之间的通信足够高效,从而即使在频繁输出和刷新图形元素的情况下,Windows 也能够为用户提供良好的视觉效果。
在技术上,Windows 子系统定义了一个稳定的图形体系结构,以便于第三方的图形设备硬件厂商可以方便地将他们的视频显示器和打印设备集成到Windows中。如图2.6 所示,win32k.sys 通过DDI(显示设备驱动程序接口)与显示驱动程序打交道,而显示驱动程序通过ENG(图形引擎接口)调用win32k.sys 中图形引擎的功能。
图2.6 Windows 子系统的图形模块结构 |
Win32k.sys 的图形引擎实现了基于标准格式位图的图形绘制功能。显示驱动程序在初始化时向图形引擎报告它所支持的物理设备的特征描述。显示驱动程序既可以自己管理图形表面(surface),也可以直接使用图形引擎管理的图形表面。另外,显示驱动程序可以有选择地截取GDI 的图形绘制操作,也可以将图形绘制操作转交给图形引擎。因此,显示驱动程序在实现功能方面有很大的灵活性。
如图2.6 所示,显示驱动程序可以帮助图形引擎实现针对特定视频适配器的图形功能,视频小端口驱动程序更是针对视频适配器的硬件特性。两者的分工原则是:显示驱动程序执行一些对用户可见并且性能紧急的图形操作,譬如,它可以直接访问适配器的视频存储区或者寄存器;而视频小端口驱动程序执行一些不常见的图形操作,或者一些不能被中断打断或其他进程抢占的关键图形操作。
视频端口驱动程序由Windows 操作系统提供,它实际上是一个动态链接库,用于帮助视频小端口驱动程序实现一些公共的、与图形处理有关的功能,以及为小端口驱动程序提供一个与系统内核和执行体打交道的环境。视频小端口驱动程序则负责直接的硬件资源管理和控制。
Windows 子系统的图形系统,除了支持GDI,还提供了对DirectX 的显示支持,包括DirectDraw 和Direct3D,因而允许像游戏、多媒体播放器等应用软件绕过GDI 图形引擎,直接操纵显示器硬件,从而获得更快的显示速度,并且避免屏幕抖动。
有关Windows 子系统图形功能部分的详细信息,请参考9.2.4 节关于Windows 显示驱动程序模型的描述,以及9.2.5 节关于Windows Vista 以后变化情况的简单介绍。
来源: <http://book.51cto.com/art/201011/235712.htm>
2.2.4 系统线程和系统进程
在Windows 中,每个线程代表一个指令执行序列,同时也是一个调度单元;进程定义了一个执行环境,有自己独立的地址空间。每个线程都必定依附于一个进程。Windows内核除了接受来自应用程序的系统服务调用,它自己也有一些线程用于各种用途。这些线程运行在一个特殊的进程环境中,称为System 进程。为区分该进程与本节下文即将介绍的操作系统关键进程,本书将前者称为System 进程,而将后者称为系统进程。System 进程的线程被称为系统线程,其中有一组系统辅助线程(system worker thread),它们代表操作系统或者其他的应用进程来完成一些特殊的工作。
设备驱动程序或执行体既可以在调用者进程中创建线程,也可以在System 进程中创建线程。或者,也可以不创建任何一个线程,而是调用执行体函数ExQueueWorkItem 或I/O 管理器函数IoQueueWorkItem,向系统辅助线程请求得到它们的服务。这两个函数负责把一个工作项目(WorkItem)放到一个队列中,而系统辅助线程将从此队列提取工作项目,并执行工作项目中指定的一个例程。因此,工作项目中的例程是在System 进程的环境中执行的,它不能访问其他进程空间中的数据。
系统辅助线程实际上是一个线程池,Windows 在系统初始化时创建了一定数量的辅助线程,而且,随着辅助线程的负载的变化,执行体也会动态地创建一些辅助线程,以满足系统负载的变化需求。
除了系统辅助线程,内核中的许多组件也会创建系统线程来完成一些必要的工作,例如,内存管理器需要后台系统线程来监视和管理页面的换入和换出。另外,设备驱动程序也可以通过调用PsCreateSystemThread 函数来创建系统线程,以便完成一些并非依附于调用者进程空间的任务,例如网络驱动程序和文件系统驱动程序可以利用系统线程来完成一些必要的后台处理。注意,通过PsCreateSystemThread 函数来创建系统线程时也可以指定其他的进程作为系统线程的宿主进程,从而能够访问该进程地址空间中的数据,但默认的宿主进程是System 进程。在本书后面章节的讲述中,我们会提到一些特定任务的系统线程,甚至可以了解到它们在什么情况下是如何被创建的。
从进程的角度来看,Windows 有一组系统进程对于整个系统的运行来说是必不可少的,包括本章前面介绍过的子系统进程csrss.exe。当Windows 操作系统引导起来,并且用户登录到系统中时,Windows 已经经过了一系列初始化过程,除了负责与用户交互的Shell 进程,还启动了诸多系统进程用于实现各种不同的系统任务。总体而言,以下这些系统进程在Windows 操作系统中扮演了重要的角色:
l 系统空闲进程(Idle)。该进程的ID 为0,其中每个处理器或核对应有一个线程。
l System 进程。在Windows XP 和Windows Server 2003 中该进程的ID 为4,它包含了内核模式系统线程。正如本节上文所述,系统辅助线程,以及执行体和驱动程序通过PsCreateSystemThread 创建的线程,都在System 进程中。
l 会话管理器(Session manager,smss.exe)。这是Windows 系统中第一个创建的用户模式进程。Smss 在Windows 启动过程中承担了一些重要的步骤,例如创建环境变量等,尤为重要的是,它启动了子系统进程csrss.exe 和登录进程winlogon.exe。另外,会话管理器也负责创建新的终端服务器会话(terminal server session),包括建立会话空间的数据结构,然后为新建的终端服务器会话加载子系统,启动csrss.exe 和winlogon.exe。
l 登录进程(winlogon.exe)。它负责处理交互用户的登录和注销。当用户按下Ctrl+Alt+Del 组合键(称为安全注意序列[SAS,Secure Attention Sequence])时,winlogon 就会接到登录请求,然后激发安全认证过程,并启动用户会话中的初始进程。在用户会话的任何时候,当用户按下了SAS 组合键时,winlogon 都会提示一个安全对话框,其中通常包含“注销”、“启动任务管理器”、“锁定计算机”、“更改密码”、“关机”等选项。
l Windows 子系统进程(csrss.exe)。正如本章前文所提到的,Windows 子系统进程负责为用户提供一个子系统环境,包括提供控制台窗口的功能,以及创建或删除进程和线程。
l 本地安全权威子系统进程(lsass.exe)。它负责本地系统安全策略,例如允许哪些用户登录到本地系统中、口令策略、授予用户和用户组的特权,以及系统安全审计设置;同时也负责认证用户的身份,以及将安全审计消息发送到系统的事件日志(EventLog)中。
l Shell 进程(explorer.exe)。这是Windows 的默认Shell,它提供了系统与用户打交道的各种界面,包括开始菜单、任务栏、资源管理器窗口等几乎所有Windows 用户都熟悉的界面。
l 服务控制管理器(services.exe)。它负责管理Windows 的系统服务,这里的系统服务是指一些特殊的进程,它们通常并不与登录用户进行交互,因而被配置成可以在系统引导时自动启动起来,无须交互登录过程。Windows 中有很多功能组件是以服务的方式来实现的,比如事件日志、任务调度器和各种网络组件等。
来源: <http://book.51cto.com/art/201011/235713.htm>