Appearance
操作系统结构(分层/模块化/宏内核/微内核/外核)
2026 大纲 一(四)操作系统结构,补充说明点名五个术语:分层、模块化、宏内核、微内核、外核。
五个名字摆在一起,但它们不在回答同一个问题
大纲在这一条下点了五个术语:分层、模块化、宏内核、微内核、外核。 摆成一排看,很容易以为它们是"五种可选的操作系统结构",做题时挨个比一遍谁好谁坏。
这么记必然记乱,因为它们回答的根本不是同一个问题。
内核代码有几万行几十万行,要把它讲清楚,至少得回答三件互不相干的事: 这些源代码该怎么切分(分层、模块化在答这个)、 切好之后哪些跑在内核态(宏内核、微内核在答这个)、 内核交给应用的是抽象过的资源还是物理资源(外核在答这个)。
三个问题彼此正交——一个系统可以既是模块化的又是宏内核的,Linux 就是; 也可以既是分层的又是微内核的。问"分层和微内核哪个好"是问错了问题, 就像问"这本书是精装的还是小说"。
所以这一节的读法是:先分清哪个术语在答哪个问题,再在同一个问题内部做比较。 最后一节的外核最容易和微内核混,判据在那里给出。
一、五种结构在回答两个不同的问题
| 结构 | 核心思想 | 它在回答哪个问题 | 代表系统 |
|---|---|---|---|
| 简单(无)结构 | 无明确模块划分,过程之间随意调用 | ——(还没有开始回答) | 早期 MS-DOS |
| 模块化 | 按功能划分独立模块并规定接口,模块间可互相调用 | 代码怎么组织(软件工程维度) | Solaris |
| 分层 | 划分层次,每层只能使用紧邻下层的服务 | 代码怎么组织(软件工程维度) | THE 系统 |
| 宏内核 | 全部核心功能都在内核态 | 哪些功能留在内核态(特权维度) | Linux, Windows |
| 微内核 | 只留最基本功能在内核态,服务下放用户态 | 哪些功能留在内核态(特权维度) | Mach, MINIX, QNX |
| 外核 | 内核不做抽象,只做资源的分配与保护 | 抽象由谁来做(抽象维度) | Exokernel |
这张表最重要的一列是第三列。把五种结构并成一排记,就会误以为它们是同一道选择题的候选项。
二、模块化与分层
模块化程序设计技术基于"分解"和"模块化"原则控制大型软件的复杂度:OS 按功能划分为若干具有一定独立性和大小的模块(进程管理、存储器管理、I/O 设备管理等),并仔细规定好各模块间的接口,模块过大可再细分为子模块。这种设计方法称为模块-接口法。划得太小则模块间联系过多,划得太大则模块内部复杂,取舍靠内聚性与耦合度这两个方向相反的度量。
分层法正是为了把模块化中"决定顺序"的无序性变为有序性而引入的:在目标系统
| 分层的优点 | 具体理由 |
|---|---|
| 易保证系统的正确性 | 自下而上使所有设计决定都有序、都建立在已验证的基础上 |
| 易扩充和易维护 | 增加、修改或替换某层中的模块乃至整层时,只要不改变层间接口,就不会影响其他层次 |
| 分层的缺点 | 具体理由 |
|---|---|
| 系统效率降低 | 单向依赖必须在每层之间建立通信机制;OS 每执行一个功能通常要自上而下穿越多个层次,通信开销累加 |
| 层次难以合理定义 | 划分不当会导致某个功能被迫拆散在多层,或出现"本该向上调用"的尴尬 |
单向依赖为什么能把"验证一个整体"变成"依次验证 n 个局部"(想弄清分层的全部价值来自哪一步时展开)
调试第 1 层
关键在"与高层无关"这五个字:如果允许某一层反过来调用它的上层,那么验证
三、宏内核与可装载内核模块
| 优点 | 缺点 |
|---|---|
| 性能高——模块间是直接函数调用,无消息传递、无额外态切换 | 内核庞大,难以维护 |
| 各模块共享内核数据结构,配合方便 | 一个模块崩溃可能导致整个内核崩溃(都在同一地址空间、同一特权级) |
纯粹的宏内核有个现实困扰:加一个新设备驱动就要重新编译整个内核并重启。现代宏内核(如 Linux)用可装载内核模块(LKM)化解了这一点——把驱动、文件系统等做成可以在系统运行时动态装入和卸载的模块。要看清它改了什么、没改什么:
| 维度 | 是否改变 | 说明 |
|---|---|---|
| 模块运行在哪个态 | 没变 | LKM 装入后仍运行在内核态、与内核共享同一地址空间 |
| 模块间怎么通信 | 没变 | 仍是直接函数调用,没有消息传递开销 |
| 崩溃影响范围 | 没变 | 一个有 bug 的模块照样能拖垮整个内核 |
| 能否运行时增删功能 | 变了 | 获得了接近微内核的可扩充性,无需重编译重启 |
所以 LKM 只借来了微内核"易扩充"的那一半好处,没有借来"隔离"的那一半——它改的是"什么时候链接进内核",不是"跑在哪个特权级"。这也说明"可扩充性"和"隔离性"其实是两件可以分开取舍的事。
四、微内核
微内核把 OS 的绝大部分功能放在内核外面的一组服务器(进程)中实现,它们都运行在用户态,客户与服务器借助微内核提供的消息传递机制交互。内核里留什么由"机制与策略分离"原理决定:机制是实现某一功能的具体执行机构(在系统基层),策略是在机制之上借助参数和算法实现优化或不同功能目标(在系统高层)。传统 OS 把机制放内核较低层、策略放内核较高层,微内核则把机制放进微内核、策略留在外面的服务器里——正因为如此,才有可能把内核做得很小。
| 微内核的基本功能 | 具体放进去的是什么(机制部分) |
|---|---|
| ① 进程(线程)管理 | 优先级队列的维护与"取出并投入执行"这一动作;进程(线程)间通信(最基本、被频繁使用);进程切换、线程调度、多处理机之间的同步。而"用户如何分类、优先级如何确定"这类策略留在外部服务器 |
| ② 低级存储器管理 | 只配置最基本的低级存储管理机制:把用户空间逻辑地址变换为内存物理地址的页表机制与地址变换机制(依赖硬件)。页面置换算法、内存分配与回收策略属于策略,放在外部的存储器管理服务器 |
| ③ 中断和陷入处理 | 捕获中断与陷入事件并做前期处理:保护中断现场、识别中断和陷入的类型,然后把事件信息转换成消息发送给相关服务器,由服务器做后期处理 |
微内核的四条优点、四个特征原文口径,以及"内核放哪三样"的两种说法怎么对上(想按教材原话作答,或想逐条说清微内核好在哪时展开)
四条优点。
| 优点 | 具体理由 |
|---|---|
| 可扩展性提高 | 功能由相对独立的服务器实现,新增硬件/软件只需改相应服务器或再加一个;也便于修改和删除过时功能 |
| 可靠性增强 | 微内核经精心设计与严格测试、接口规范精简;且所有服务器运行在用户态、彼此用消息通信,某个服务器出错不会影响内核,也不会影响其他服务器 |
| 可移植性强 | 与特定 CPU 和 I/O 硬件有关的代码全部集中在内核与其下的硬件隐藏层 |
| 支持分布式系统 | 通信本就基于消息传递,只需给进程和服务器分配唯一标识符并在微内核中配一张系统映射表 |
四个特征。
微内核结构可从四个方面描述:① 足够小的内核——它并非一个完整的 OS,通常只包含与硬件处理紧密相关的部分、一些较基本的功能、客户和服务器之间的通信;② 基于客户/服务器模式——进程(线程)服务器、虚拟存储器服务器、I/O 设备管理服务器等都作为进程实现、运行在用户态;③ 应用"机制与策略分离"原理;④ 采用面向对象技术,用"抽象""隐蔽"控制复杂性,用"对象""封装""继承"提高正确性、可靠性、易修改性与易扩展性。
第 ③ 条的典型例子:进程调度需要一个或多个优先级队列,并能把指定优先级的进程取出投入执行——这属于机制,放进微内核;而"用户如何分类""优先级按什么原则确定"属于策略,放到微内核外的进程管理服务器中。
口径分歧:常见的简写版本把微内核的最基本功能列为「进程调度、进程通信、中断处理」,教材的写法则是「进程(线程)管理、低级存储器管理、中断和陷入处理」。两者并不矛盾,粒度不同——简写版把"进程(线程)管理"里最核心的两项单独拎了出来,但漏掉了"低级存储器管理"这一整项,而地址变换机制是必须留在内核的(它依赖硬件、且每次访存都要用)。按教材三项作答更稳妥,并用"内核留机制、外面放策略"这条统一判据兜底。
五、宏内核 vs 微内核
| 比较 | 宏内核 | 微内核 | 判据 |
|---|---|---|---|
| 哪些功能在内核态 | 全部核心功能 | 只有机制部分与硬件相关部分 | 这一行是根,其余各行都由它派生 |
| 内核大小 | 大 | 小 | 由上一行决定 |
| 模块间通信 | 直接函数调用 | 消息传递 | 由上一行决定 |
| 性能 | 高 | 低(至少 4 次上下文切换) | 通信方式决定 |
| 可靠性 | 低(同一地址空间,一损俱损) | 高(服务器在用户态,出错不波及内核) | 是否共享地址空间决定 |
| 扩展性 | 差(LKM 可部分弥补) | 好 | 服务器是独立进程决定 |
| 可移植性 | 一般 | 强(硬件相关代码集中) | |
| 代表 | Linux, Windows | Mach, MINIX, QNX |
六、外核(Exokernel)
| 内核里还剩什么 | 搬走的是什么 | 搬到哪去了 | |
|---|---|---|---|
| 宏内核 | 服务 + 抽象,全在内核 | ——(什么都没搬) | —— |
| 微内核 | 抽象仍在(只是实现挪到了用户态服务器) | 搬走的是"服务的实现" | 用户态的服务器进程 |
| 外核 | 只剩资源的分配与保护 | 搬走的是"抽象"本身 | 与应用链接在一起的库操作系统(LibOS) |
两者正交:一个微内核系统的应用照样只能通过文件抽象访问磁盘;一个外核系统的应用则可以自己决定要不要用"文件"这个概念。理论上还可以既外核又微内核化——它们改的不是同一件事。
既然外核不做抽象,"文件系统""虚拟内存"就做成库、和应用程序链接在一起、运行在用户态,这就是库操作系统(LibOS)。于是分工变成:外核只做资源的分配(把哪些物理页框、哪些磁盘块判给哪个应用)与保护(确保应用只碰自己分到的);LibOS 在应用自己的地址空间里把物理资源包装成它想要的抽象;应用直接调用 LibOS 的函数,等于调用自己进程内的普通函数。
这就是外核性能收益的来源:抽象层的实现从"内核里一份、所有人共用"变成"应用自己带一份",调用它从系统调用降级成了普通函数调用;而且应用可以为自己的访问模式定制策略,一个数据库进程完全可以用自己的页面置换算法。代价同样具体,共四条:① 应用复杂度上升(要自己管物理资源,原本由 OS 统一承担的正确性负担被推给每个应用);② 失去统一抽象带来的兼容性(各应用带不同 LibOS、用不同文件布局,共享数据变难——通用 OS 做统一抽象,一半理由就是让不同程序能读同一个文件);③ 保护更难做(内核不再理解"文件""进程地址空间",只能在物理资源粒度上保护);④ 全局优化能力下降(内核不掌握各应用的资源使用语义)。这也是它至今停留在研究系统层面、未成为主流的原因。
考点速记
- 五种结构回答三个不同的问题:模块化与分层是"源代码怎么切",宏内核与微内核是"哪些功能跑在内核态",外核是"物理资源交给应用前要不要先被抽象"。三者正交,不能横着比。
- 分层 vs 模块化的判据是调用关系受不受"相邻"约束:分层中每层只能用紧邻下层的服务,不能越级也不能反向;模块化中各模块可以互相调用。
- 模块划分质量靠两个方向相反的度量:内聚性越高越好(模块内部联系紧密程度),耦合度越低越好(模块之间相互影响程度)。模块化的结构性缺陷是决定顺序的无序性,故又称"无序模块法"。
- 分层用单向依赖换来"每一层都能独立验证",代价是每执行一个功能要自上而下穿越多层,通信开销累加导致效率降低。
- 宏内核与微内核的根子只有一条——哪些功能留在内核态。 性能、可靠性、扩展性三条差别全由它派生:内核态功能多 ⇒ 模块间是直接函数调用 ⇒ 快,但同一地址空间 ⇒ 一损俱损。
- 微内核的代价能数出来:早期整体式 OS 一次服务请求 2 次上下文切换,微内核至少 4 次(客户→内核→服务器→内核→客户),服务器还要找别的服务器时达 8 次。根因是函数调用变成了进程间通信。
- 微内核里留什么有一条统一判据:内核留"机制",外面放"策略"。页面置换算法、内存分配回收策略、优先级确定原则这些策略一律在微内核之外。
- 有 LKM 的 Linux 仍是宏内核:模块装入后仍在内核态、仍共享同一地址空间、仍是直接函数调用,一个模块出错照样拖垮内核。它只借来了易扩充,没借来隔离。
- 外核与微内核正交:微内核搬走的是"服务的实现"(文件系统还是那个文件系统,只是挪到用户态),外核搬走的是"抽象"本身(直接把物理页框、磁盘块分给应用)。微内核问"这段代码跑在哪个特权级",外核问"应用拿到的是抽象资源还是物理资源"。
这一节在真题里被考过的形式:
至今只出过一道题,而且只考了第五、六两条速记——微内核相对宏内核的得失。
- 问微内核相对宏内核具有哪些特征(2023-23)。答较高的可靠性 + 较高的安全性 + 较强的可扩展性三条;"较好的性能"是错的,那恰恰是宏内核的优势。判据回到第五条:微内核把服务挪到用户态,得到的三样好处全部来自"分离与隔离",付出的代价也全部来自同一件事——服务之间从函数调用变成了 IPC。⚠️ 四个选项里唯一的错项就是性能,把"微内核更先进"顺手理解成"微内核更快"就会全错。
复习优先级:按选择题准备即可。核心是"微内核用性能换可靠、安全、可扩展"这一句, 以及第二条那个分层与模块化的判据。第一条那个"三个问题正交"的分类不会被直接设问, 但它决定了你会不会把不该比的东西拿来比。上下文切换次数(2 / 4 / 8)是教材原文的数字, 出过一次简答的可能,记住即可。
易错:认为微内核性能更好。它的三样优势(可靠、安全、可扩展)全部以性能为代价换来。
易错:把分层和模块化当成同一回事。分层只能调用紧邻下层,模块化允许模块间互相调用。
易错:把内聚性和耦合度的好坏方向搞反。内聚越高越好,耦合越低越好。
易错:认为支持可装载内核模块(LKM)的 Linux 是微内核。LKM 装入后仍在内核态、仍是直接函数调用,Linux 仍是宏内核。
易错:把页面置换算法这类策略放进微内核。微内核只留机制。
易错:把外核当成"更彻底的微内核"。两者维度不同——微内核挪的是服务实现的位置,外核去掉的是抽象本身。
教材出处
- 汤小丹《计算机操作系统》1.5.1 传统操作系统结构·模块化结构 OS(p23~p24):模块-接口法;模块划分过大过小的权衡;模块独立性的两个衡量标准——内聚性与耦合度;模块化的优点与"各模块设计齐头并进,无法寻找一个可靠的决定顺序,造成各种决定的'无序性',因此模块-接口法又被称为'无序模块法'"。
- 同书 分层式结构 OS(p24):分层法用于把"决定顺序"的无序性变为有序性;"每一层仅能使用其底层所提供的功能和服务"、"各层之间只存在着单向的依赖关系";以调试
、 为例说明逐层验证与高层无关;优点(易保证正确性、易扩充易维护)与缺点(每执行一个功能要自上而下穿越多个层次,通信开销导致效率降低)。 - 同书 1.5.4 微内核 OS 结构(p27~p30):微内核的四个方面(足够小的内核、基于客户/服务器模式、应用"机制与策略分离"原理、采用面向对象技术);足够小的内核所含三部分;机制与策略的定义及"正因为如此,才有可能将内核做得很小";微内核的基本功能三项——进程(线程)管理、低级存储器管理、中断和陷入处理,及各自"机制进内核、策略进服务器"的划分;四条优点;以及效率降低一节给出的上下文切换次数:"在早期的 OS 中……一般只需进行两次上下文的切换"、"在微内核 OS 中……同样的服务请求至少需要进行四次上下文切换"、文件服务器还需磁盘服务器帮助时"需要进行 8 次上下文的切换"。
说明:大纲点名的「外核」在上述两本教材中均未设专节,本文外核一节的表述不标教材出处。
相关知识
操作系统基本概念与发展历程|CPU运行模式(内核态与用户态)|操作系统引导