现在的位置: 首页 > 综合 > 正文

Windows内核原理与实现:系统层次

2013年01月12日 ⁄ 综合 ⁄ 共 4780字 ⁄ 字号 评论关闭

注:所谓内核,是指存在于系统空间的代码和数据的集合。但是Windows只将系统空间中部分低层、与硬件靠得很近的称为kernel,所以Windows系统空间中实际有kernel、Windows子系统(视窗服务)和executive(或可翻译为管理层,个人认为这样比较好)。但是这本书将其称为“执行体”,笔记中亦记为“执行体”。
 

Windows功能层次:

1

Windows内核为用户模式代码提供一组系统服务,但应用程序通过一组系统dll最终通过ntdll.dll切换到内核模式下的执行体API函数中调用内核中的系统服务Ntdll.dll是连接用户模式代码和内核模式系统服务的桥梁。对于内核提供的每一个系统服务,该DLL都提供一个相应的存根函数,这些存根函数名称以“Nt”作为前缀Ntdll.dll还提供了许多系统级的支持函数,比如映像加载器函数(以“Ldr”为前缀)、Windows子系统进程通信函数(以“Csr”为前缀)、调试函数(以“Dbg”为前缀)、系统事件函数(以“Etw”为前缀),以及一般的运行支持函数(以“Rtl”为前缀)和字符串支持函数等。

32位系统中,2GB以下称为进程地址空间,2GB以上称为系统地址空间。实际上,两者之间有一块特殊的64KB地址空间,位于0x7fff0000~0x7ffffffff,两种模式下都不可访问。代码中的函数首先检查内存目标地址是否越过了此特殊区域,越过则访问违例;然后,试图将目标地址处的值赋给该地址,即触发一次该地址处的读和写操作,若该内存地址处当前线程不可写,则引发异常,从而使该代码片段中的except子句截获控制。Windows通过这种方式来捕获“用户模式代码传递一个系统空间地址”或者“传递一个无效内存地址”的情形。————那么,用户模式代码对2GB以上地址的访问将导致0x7fff0000~0x7fffffff间的内存访问错误?经过测试不是。实际过程应该是:导致异常后不再实际读/写地址,而是直接返回一个访问错误。

Windows的内核按照面向对象的思想设计,管理两种类型的对象:分发器对象和(dispatcher object)和控制对象。分发器对象实现了各种同步功能,这些对象的状态会影响线程的调度。Windows内核实现的分发器对象包括事件(event)、突变体(mutant)、信号量(semaphore)、进程(process)、线程(thread)、队列(queue)、门(gate)和定时器(timer)。控制对象用于控制内核的操作,但是不影响线程的调度,它包括异步过程调用(APC)、延迟过程调用(DPC)以及中断对象等。

Windows更高级的抽象:

2

Windows中,内核代码可以访问当前进程的整个4GB虚拟地址空间,用户代码只能访问底端的2GB虚拟地址(或3GB,如果打开了内核启动开关/3GB)。

Windows子系统是一个支持用户应用程序的执行环境,除了Windows子系统作为原生环境子系统外,还支持POSIXOS/2环境子系统。但自XP系统后,只有Windows子系统随系统一起发行。

可以将Windows内核分为三层:与硬件直接打交道的硬件抽象层(HAL),把所有和硬件相关联的代码逻辑隔离到一个专门模块中,从而使上面的层次尽可能做到独立与硬件平台;HAL之上的内核层包含了基本的操作系统原语和功能,如线程和进程、线程调度、中断和异常的处理、同步对象和各种同步机制。内核之上是执行体(executive)层,目的是提供一些可供上层应用程序或内核驱动程序直接调用的功能和语义。Windows内核的执行体包含一个对象管理器,用于一致地管理执行体中的对象。执行体层和内核层位于同一个二进制模块中,即内核基本模块,名为ntoskrnl.exe

内核层和执行体层的分工是:内核层实现操作系统的基本机制,所有策略留给执行体。执行体中对象绝大多数封装了一个或多个内核对象,并通过某种方式(比如对象句柄)暴露给应用程序。这种设计体现了机制与策略分离的思想。——内核提供基本对象,执行体封装了对于内核中对象的操作,并将操作接口提供给编程者。

执行体是内核模块ntoskrnl.exe的上层部分,包含五种类型的函数

·被导出的、可在用户模式下调用的函数。接口位于ntdll.dll模块中,应用程序可通过Windows API间接调用

·虽已被导出并可在用户模式下调用,但无法通过任何一个Windows API调用的函数。比如LPCLocal Procedure Call,本地过程调用)函数、各种查询函数(如NtQueryInformation<Xxx>),以及一些专用函数比如NtCreatePagingFile等。对这些函数的调用需要直接链接ntdll.dll——即,Windows API不提供对这些函数的调用接口,但是用户可以直接链接ntdll.dll调用

·只能在内核模式下调用的导出函数,并在Windows DDK(DDKDevice Development Kit,设备开发包)中有关于这些函数的文档。可被驱动程序调用——DDK有说明文档,但是也是间接通过ntdll.dll调用

·供执行体组件之间相互调用,但未被文档化的函数,包括执行体内部使用的一组支持函数

·属于一个组件的内部函数

执行体包括以下组件(对应图1):

1进程和线程管理器,创建、终止等

2内存管理器,实现了虚拟内存管理,既负责系统地址空间的内存管理,又为每个进程提供了一个私有的地址空间,并且也支持进程之间内存共享。内存管理器也为缓存管理器提供了底层支持

3安全引用监视器SRM, Security Reference Monitor)。强制在本地计算机上实施安全策略,守护操作系统的资源,执行对象的保护和审计

4I/O管理器,实现与设备无关的输入和输出功能,负责将I/O请求分发给正确的设备驱动程序

5缓存管理器,为文件系统提供了统一的数据混寸支持,允许文件系统驱动程序将磁盘中的数据映射到内存中并通过内存管理器来协调物理内存的分配

6配置管理器,负责系统注册表的实现和管理

7即插即用管理器,负责列举设备,为每个列举到的设备确定驱动程序并加载、初始化相应驱动程序。检测到系统中设备变化时,负责发送恰当的事件通知

8电源管理器,负责协调电源事件,向设备驱动程序发送电源I/O通知。系统电源状态变化时,通知设备驱动程序处理设备的电源状态。即插即用设备的管理和电源的管理可看做是I/O管理器的扩展功能

还有四组主要支持函数,供以上执行体组建调用。有差不多1/3的支持函数可在Windows DDK中找到相应文档。这四类是:

·对象管理器,负责创建、管理、删除Windows执行体对象,以及用于表达操作系统资源的抽象数据类型,比如进程、线程和各种同步对象

·LPC设施LPC设施负责同一台机器上的客户进程和服务器进程间传递消息。LPCRPCRemote Promote Call,远程过程调用,关于网络上客户进程和服务器进程之间通信的工业标准)的一个优化版本

·一组运行时库函数。功能广泛,涵盖字符串处理、算术运算、数据类型转换和安全结构处理等

·执行体支持例程。如系统内存分配(换页内存池和非换页内存池)、互斥的内存访问,以及对两种特殊类型同步对象(资源和互斥体)的支持

Windows支持两种形式的过滤驱动程序:一种直接插入到设备栈中,从而能够看到每个经过设备栈的文件I/O请求;另一种基于Windows提供的过滤管理器驱动程序(FltMgr)的I/O过滤框架,称为文件系统小过滤驱动程序,它们并不出现在文件系统设备栈中,而是以回调方式来响应FltMgr的事件。
大容量存储设备以“分区(partition)”和“卷(volume)”来管理整个存储空间。分区是存储设备上连续的存储区域(连续扇区),而卷是指扇区的逻辑集合。Windows的存储管理形成了一个存储栈,最接近应用程序的是文件系统,接下来是卷管理部分,最接近存储设备的是分区管理和磁盘驱动程序
磁盘设备的设备栈和驱动程序符合WDM(Windows Driver Model)规范即插即用管理器在设备列举过程中建立起每个磁盘设备的设备栈。设备栈最底下是总线驱动程序,最上方是一个称为分区管理器的驱动程序,负责通知即插即用管理器当前磁盘上有哪些分区,因而系统中的卷管理器可以接收到有关分区创建和删除的通知。这样,每个物理分区和卷管理器联系起来,卷管理器再将卷与文件系统(分区)关联起来,就形成了完整的存储栈。
网络:
Windows套接字:基本套接字连接
WinInet:高层网络API,支持多个协议,包括Gopher、FTP和HTTP,IE使用它来完成数据传输
命名管道(named pipe)和邮件槽(mailslot):支持连接和非连接的通信模型
NetBIOS:
RPC:网络编程的一个标准,往往是分布式系统基础设施的重要组件。
这些网络API都提供了用户模式的动态链接库,它们必须将接收到的请求传递给内核模式下的相应驱动程序。它们一般通过专门的系统服务切换到内核模式(命名管道和邮件槽)或者标准的系统服务接口如NtReadFile、NtWriteFile和NtDeviceloControlFile,由I/O管理器和对象管理器将网络请求转送至相应的驱动程序中。
内核模式部分,网络API驱动程序通过传输驱动程序接口(TDI, Transport Driver Interface)与协议驱动程序通信。
Windows中,网络协议与网络适配器驱动程序是分开的,协议驱动程序独立于任何一个网络适配器,而真正发送和接收数据通过网络适配器进行。网络协议协议驱动程序通过统一的接口与适配器驱动程序进行通信,此接口是NDIS(Network Driver Interface Specification)。符合NDIS的网络适配器驱动程序称为NDIS驱动程序,或NDIS小端口驱动程序(NDIS miniport driver)。TCP/IP驱动程序是tcpip.sys,Windows提供NDIS库即ndis.sys作为协议驱动程序与NDIS驱动程序两者之间的桥梁。NDIS驱动程序并非标准的设备驱动程序,它们通过NDIS库与NDIS客户通信
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通过向内核注册一组出调(callout)函数介入到内核的线程和进程管理等处理逻辑中,同时也可以接收电源事件。对于每个线程,一旦调用了win32k.sys的任何一个系统服务就变成一个GUI线程,从而纳入到Windows子系统的线程和进程管理范畴。Windows内核的线程和进程数据结构为Windows子系统预留了一些域,从而win32k.sys可以方便地操纵它的线程和进程。

抱歉!评论已关闭.