Windows架构设计

根据wrk1.2源码,结合毛批&潘老师的《Windows内核原理与实现》&《Windows Internals》对Windows内核的设计进行归纳。

Windows架构设计

系统结构

与Linux一致,经典的ring0/3双模式。高2G为内核空间,低2G为用户空间。每个用户进程都有自己的4GB虚拟空间,高2G共享,低2G独享且相互隔离。

按照潘老师的说法,Windows是微内核OS,Linux是宏内核OS。Linux的内核模块高度一体化,各内核模块虽然没有地址空间的限制,但容易因一个模块bug而导致kernel panic。Windows则独立性较好,各模块依赖于内部通信机制。实际上当今的Linux也有可装卸模块,所以是微是宏,界线已经很模糊了。

从WRK原始的布局来看,Windows在下一盘很大的棋,除了Windows子系统还想涉足POSIX和OS/2子系统。看起来Win10已经有了POSIX子系统。

像素感人的Raymond绘图:

除了WRK的Basic设计,这个图还扩展了Vista的设计(Win7基本可以理解成优化简化版Vista)。

内核态

Windows内核的架构,潘老师的图很清爽:

内核是分三层的:HAL、微内核、执行体。

HAL

把七七八八的硬件抽象,为微内核层提供接口,封装成hal.dll。

微内核

ntoskrnl.exe的下层部分,负责线程的调度,中断、异常的处理,多处理同步。微内核管理两种类型对象:分发器对象和控制对象。分发器对象实现了各种同步功能,其状态会影响线程调度。分发器对象包括Event,Mutant,Semaphore,Process,Thread,Queue,Gate,Timer。控制对象用于控制内核的操作,不影响线程的调度,包括APC,DPC,中断对象等。

执行体

ntoskrnl.exe的上层部分。包含了OS的基本服务,包括内存管理、进程管理、输入输出、网络和进程间通信等。微内核手握大权,执行体则分门别类的执行。

执行体包括5种类型函数:

  1. 被导出的可在用户模式下调用的函数,它们位于ntdll.dll模块。通过Windows API间接调用。
  2. 虽被导出且用户模式可用,但无法通过任何Windows API来调用(例如LPC函数,查询函数NtQueryInformation以及某些专用函数等)。想要调用可以直接链接ntdll.dll。
  3. 只能在内核模式下调用的导出函数,在WDK中有说明文档。这些函数可以用设备驱动程序调用。
  4. 供执行体组件之间相互调用,未被文档化的函数。这些函数是执行体内部所用。
  5. 属于某个组件的内部函数。

执行体包含的8大组件:

  1. 进程和线程管理器。负责创建和终止。进程和线程的底层支持在微内核层提供,执行体仅仅是在微内核层进程和线程对象基础上,提供了一些语义和功能。
  2. 内存管理器。实现虚拟内存管理,管理系统地址空间,并为每个进程提供私有地址空间(支持进程之间内存共享)。内存管理器为缓存管理器提供了底层基础。
  3. SRM(Security Reference Monitor)。强制本地计算机上实施安全策略,守护OS的资源,执行对象的保护和审计。
  4. I/O管理器。实现与设备无关的输入和输出,负责将I/O请求分发给正确的设备驱动程序。
  5. 缓存管理器。为文件系统提供统一的数据缓存支持,允许文件系统驱动程序将磁盘上数据映射到内存中,并通过内存管理器协调物理内存的分配。
  6. 配置管理器。负责系统注册表的实现和管理。
  7. 即插即用管理器。负责列举设备,为每个枚举到的设备确定哪些驱动程序是必须的,然后加载并初始化这些驱动程序。当检测到设备变化(插拔)时,负责发送恰当的事件通知。
  8. 电源管理器。负责协调电源事件,向设备驱动程序发送电源I/O通知。当系统状态变化时,通知设备驱动程序处理设备的电源状态。

即插即用和电源管理器都算I/O管理器的扩展。

执行体包含的4组支持函数:

  1. 对象管理器。负责创建、管理和删除Windows执行体对象,以及用于表达OS资源的抽象数据类型,比如进程线程和同步对象。
  2. LPC设施。LPC设施负责同机器上的客户进程和服务器进程之间传递消息。LPC是RPC的一个优化版本。
  3. 一组runtime库函数。功能广泛,涵盖字符串处理、算术运算、数据类型转换以及安全结构处理等。
  4. 执行体支持例程。例如系统内存分配(换页内存池和非换页内存池)、互锁的内存访问,以及对两种特殊类型同步对象(资源和互斥体)的支持。

设备驱动程序

除了ntoskrnl.exe和hal.dll,内核的其他模块几乎都是设备驱动程序。设备驱动程序是可以动态加载到系统的模块,文件扩展名为.sys。

文件系统/存储管理

实际上也是个设备驱动,管理硬盘。对NTFS来说就是ntfs.sys。硬盘以分区和卷来管理存储空间。

网络

从上到下一气呵成。有着很复杂的架构。

  1. Windows提供了winsock,实现并扩展了BSD套接字标准。目前常用的是winsock2,版本2加入了异步网络I/O,QoS等新特性。
  2. WinInet是另一个高层API,支持Gopher,FTP和HTTP等协议。IE用WinInet传输。
  3. 命名管道和邮件槽。不同进程间通信。支持不同机器上的进程之间相互通信。命名管道支持连接方式的通信模型,邮件槽支持非连接方式的通信模型,客户进程可以发送广播消息。
  4. NetBIOS。早期的API,向下兼容。
  5. RPC。网络编程的一个标准,往往是分布式系统基础设施的重要组件。RPC建立在其他的网络API基础之上,比如命名管道和winsock。Windows的RPC支持异步调用方式。

以上这些都属于API范畴,提供了用户模式的dll。这些请求会传递给内核的驱动程序。内核网络驱动是经典的TDI+NDIS架构。

早年写过NDIS的一对多虚拟VID网卡驱动,Windows各种不同类型的驱动可谓大相径庭,诸如fs filter驱动,NDIS驱动都较为复杂,NDIS是我目前认为最复杂的一部分。

Windows子系统

Windows子系统的内核部分的核心是win32k.sys(win10上做了更细致的三大拆分)。
表面上(sys后缀)是个设备驱动,实际上却不处理I/O。它为用户代码提供了大量的系统服务。win32k.sys包含窗口管理和GDI。窗口管理负责收集和分发消息,以控制窗口显示和屏幕输出;GDI则包含各种形状绘制和文本输出功能。

Windows子系统的用户部分包括csrss.exe和一组dll(kernel32.dll,user32.dll,gdi32.dll,advapi.dll)。csrss.exe负责控制台窗口功能,创建删除进程或线程等。dll则各司其职,内部就是Windows SDK文档化的那些API。

系统线程和进程

  1. Idle:进程ID为0,每个处理器或核对应有一个线程。
  2. System:ID为4,包含了内核模式系统线程。系统辅助线程、执行体和驱动程序通过PsCreateSystemThread创建的线程都在System中。
  3. smss.exe:会话管理器。Windows系统创建的第一个用户进程,由完成执行体和内核初始化工作最后阶段的内核模式系统线程创建。Smss负责启动时创建环境变量,启动csrss和winlogon。大致流程:
    1. 标记自身为critical,即退出引起Windows崩溃
    2. 进程基本优先级提升到11
    3. 更新处理器affinity(为多会话提供更好的性能)
    4. 创建命名管道、邮件槽,为smss、csrss、lsm之间通信。
    5. 创建ALPC端口接收命令
    6. 创建系统级环境变量
    7. 注册设备创建符号链接
    8. 对象管理器name space中创建\Sessions根目录
    9. autochk.exe检查磁盘
    10. 处理尚未完成的文件改名操作
    11. 初始化页面文件(paging file)
    12. 初始化注册表其他部分(HKLM Software/SAM/Security储巢)
    13. 运行HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SetupExecute中的程序
    14. 打开已知DLL,映射为永久内存区
    15. 创建线程响应会话创建请求
    16. 创建Smss初始化会话0(非交互会话)
    17. 创建Smss初始化会话1(交互会话)
    18. 永久等待在会话0的csrss.exe实例句柄上,而csrss.exe不会退出
    19. 会话启动的smss实例继续这些操作
      1. 调用NtSetSystemInformation,请求建立内核模式的会话数据结构
      2. 创建子系统进程(csrss.exe)
      3. 创建Winlogon实例(交互会话)或者Wininit实例(会话0)
      4. 中间smss进程退出,从此csrss和winlogon/wininit无父无君
  4. lsm.exe:本地会话管理器,管理本地机器上的终端服务器会话的状态。通过ALPC端口SmSsWinStationApiPort向Smss发送请求启动新的会话
  5. winlogon.exe:登录进程,负责用户交互的登录和注销。Ctrl+Alt+Del就是给它发请求。
  6. csrss.exe:Windows子系统环境进程,包括控制台窗口的功能,创建删除进程和线程。
  7. lsass.exe:本地系统安全策略。负责允许哪些用户登录到本地系统、口令策略、授予用户和用户组的特权、系统安全审计设置、认证用户身份、安全审计消息发送到系统的Event Log等功能。
  8. explorer.exe:资源管理器,Windows的默认shell。
  9. services.exe:负责管理Windows系统服务,这里的系统服务指一些特殊的进程,通常不与登录用户进行交互,因而被配置成可以在系统引导时自启动,无需交互登录过程。Windows中很多功能组件都是以服务方式实现的,比如Event Log,任务调度器和各种网络组件等。
  10. Wininit.exe:会话0初始化
    1. 标记自身critical
    2. 初始化用户模式调度设施
    3. 创建%windir%\temp
    4. 创建窗口站(Winsta0)和两个桌面(Winlogon和Default),会话0中进程可以在其中运行
    5. 创建Services.exe
    6. 启动lsass.exe
    7. 启动lsm.exe
    8. 等待直到停机
文章目录
  1. 1. Windows架构设计
    1. 1.1. 系统结构
    2. 1.2. 内核态
      1. 1.2.1. HAL
      2. 1.2.2. 微内核
      3. 1.2.3. 执行体
      4. 1.2.4. 设备驱动程序
      5. 1.2.5. 文件系统/存储管理
      6. 1.2.6. 网络
    3. 1.3. Windows子系统
    4. 1.4. 系统线程和进程
,