操作系统内核

内核是操作系统中最基本、最核心的部分。实现内核功能的程序称为内核程序,运行在内核态

内核态与用户态

CPU 至少提供两种执行状态:

状态 权限 运行内容
内核态 可执行所有指令,访问所有内存和硬件 内核程序
用户态 只能执行非特权指令,访问受限地址空间 普通应用程序

区分两种状态是为了保护。如果任意程序都能直接操作硬件或修改内核数据结构,一个用户程序的 bug 就可能破坏整个系统。CPU 在硬件层面强制执行这一隔离——用户态程序执行特权指令会触发异常,CPU 把控制权交还给内核处理。

内核的典型功能

功能 说明
时钟管理 利用时钟中断实现计时、进程调度
中断处理 响应外部中断和异常,转入对应处理程序
原语 完成不可被中断打断的关键操作
进程管理 进程创建、撤销、调度、切换
存储器管理 内存分配、地址转换、虚拟存储
设备管理 I/O 控制、设备分配、驱动协作

判断一个功能是否应放入内核的标准:是否必须直接访问硬件?是否执行特权指令?是否维护影响系统全局的关键数据结构?图形界面、部分系统工具、某些服务程序不满足这些条件,放在用户态更安全。

大内核与微内核

内核设计的根本分歧在于:多少功能应该放在内核态?

结构 做法 优点 代价
大内核 进程管理、存储管理、设备管理等主要功能都放在内核态 模块之间直接调用,状态切换少,性能较高 内核庞大,任何模块的 bug 都可能影响整个系统
微内核 内核只保留中断处理、原语、进程通信、调度等最基本功能;文件系统、网络栈等作为用户态进程运行 内核小,可靠性高;单个服务崩溃不拖垮内核 服务之间需要频繁的用户态/内核态切换,开销更大

大内核也称宏内核、单内核,典型例子是 Linux、UNIX。微内核的代表是 Minix、QNX。

状态切换有成本

用户态切到内核态需要保存现场、切换栈、修改 CPU 状态位,返回用户态时需要恢复。微内核结构中服务间通信更频繁,切换次数更多,性能开销更明显——这也是实际商用的微内核系统较少的原因:设计上的简洁往往需要为性能做出妥协。

## 常见 OS 结构

除了大内核与微内核的核心选择,操作系统在代码组织上还有多种形式。这些结构可以和上述内核架构组合使用。

结构 思路 特点
分层结构 每层只能调用更低层 层次清晰,便于调试;但严格分层不易,跨层调用效率低
模块化结构 按功能划分模块,模块之间通过明确接口通信 灵活,便于维护和扩展
外核 内核只做资源保护和多路复用,资源管理策略交给应用 应用可针对自身需求做最优资源管理;实现复杂
区分两个"结构"

“大内核 vs 微内核”回答的是代码跑在内核态还是用户态
“分层/模块化/外核”回答的是代码怎么组织、模块之间怎么调用
两者正交。Linux 是大内核 + 模块化;QNX 是微内核 + 模块化。

## 原语

原语是一段具有原子性的内核程序:一旦开始执行就必须一气呵成,中途不能被中断或调度打断。

原语的原子性依赖内核态的执行权限来保证——原语运行时通常关中断,或使用自旋锁等同步机制阻止并发访问。

原语常用于修改系统全局的关键数据结构:

  • 进程控制块的创建、状态切换和撤销
  • 就绪队列和等待队列的插入与删除
  • 设备分配表的修改
  • 信号量的 P/V 操作

这些操作若被中途打断——例如刚修改了一半 PCB 状态就发生进程切换——系统状态可能出现不一致,后续难以恢复。