2. 操作系统结构与硬件基础
操作系统作为计算机系统的核心软件,其设计必须紧密依托底层硬件架构。本章深入剖析操作系统的核心结构——内核态与用户态的隔离机制、系统调用的完整路径、中断与异常的处理流程,以及计算机系统硬件架构(CPU、内存、I/O)的基本原理。理解这些基础是掌握 xv6 和 Linux 内核的关键前提。
2.1 内核态与用户态:特权级隔离
为了保障系统安全与稳定,操作系统将 CPU 的执行状态划分为至少两个特权级:用户态(User Mode)和内核态(Kernel Mode)。用户态程序只能访问受限的指令和地址空间,而内核态拥有对硬件资源的完全控制权。
核心原则:用户态程序不能直接执行特权指令(如修改页表、关闭中断、直接访问磁盘),必须通过操作系统内核提供的接口间接完成。
2.1.1 特权级对比
| 特性 | 用户态(Ring 3) | 内核态(Ring 0) |
|---|---|---|
| 可执行指令 | 普通指令(算术、逻辑、访存) | 所有指令(包括特权指令) |
| 地址空间 | 用户空间(受 MMU 保护) | 内核空间(全局可见) |
| 直接硬件访问 | 不允许 | 允许 |
| 崩溃影响 | 仅影响当前进程 | 可能导致系统崩溃 |
| 切换方式 | 通过系统调用、中断或异常 | 通过特权指令返回 |
2.1.2 用户态与内核态切换流程(SVG)
2.2 系统调用机制
系统调用是用户态程序请求内核服务的唯一合法途径。xv6 和 Linux 均通过软中断或专用指令(如 syscall)实现从用户态到内核态的切换。
2.2.1 系统调用执行步骤
- 用户态准备参数:将系统调用号和参数存入指定寄存器(如 xv6 用
eax存调用号,ebx、ecx存参数)。 - 触发陷阱:执行
int 0x80(xv6)或syscall(Linux)指令,CPU 切换到内核态。 - 内核态处理:根据系统调用号跳转到对应的内核函数(如
sys_write、sys_read)。 - 执行内核服务:内核函数完成实际工作(如读写文件、创建进程)。
- 返回用户态:内核函数返回,CPU 执行
iret或sysret指令,恢复用户态上下文。
xv6 示例:系统调用
write(1, "hello", 5) 在 xv6 中会触发 int 0x80,内核通过 syscall() 函数分发到 sys_write(),最终调用 filewrite() 完成输出。
2.2.2 xv6 系统调用路径(SVG)
2.3 中断与异常
中断和异常是 CPU 响应外部事件或内部错误的机制。它们与系统调用共同构成了操作系统处理异步事件和同步错误的基石。
2.3.1 中断与异常对比
| 特性 | 中断(Interrupt) | 异常(Exception) |
|---|---|---|
| 触发源 | 外部硬件设备(键盘、磁盘、定时器) | CPU 内部指令执行(除零、缺页、非法指令) |
| 触发时机 | 异步(与当前指令无关) | 同步(由当前指令直接导致) |
| 可屏蔽性 | 可屏蔽中断(INTR)和不可屏蔽中断(NMI) | 不可屏蔽(必须处理) |
| 处理流程 | 保存上下文 → 执行中断服务程序 → 恢复上下文 | 保存上下文 → 执行异常处理程序 → 恢复或终止 |
| 典型例子 | 时钟中断、键盘中断、磁盘 I/O 完成 | 缺页异常、除零异常、系统调用(int 0x80) |
2.3.2 中断处理流程(SVG)
2.4 计算机系统硬件架构
操作系统直接管理计算机硬件资源。理解 CPU、内存和 I/O 设备的基本架构,是分析操作系统行为的基础。
2.4.1 硬件架构核心组件
- CPU(中央处理器):执行指令的核心单元。包含运算器、控制器、寄存器组和缓存(L1/L2/L3)。现代 CPU 支持多核、超线程和多种特权级。
- 内存(主存):存储正在运行的程序和数据。以字节为单位编址,通过内存总线与 CPU 连接。操作系统通过 MMU(内存管理单元)实现虚拟地址到物理地址的映射。
- I/O 设备:包括输入设备(键盘、鼠标)、输出设备(显示器、打印机)和存储设备(磁盘、SSD)。操作系统通过设备驱动程序与 I/O 控制器通信。
2.4.2 硬件架构关系图(SVG)
2.5 关键概念总结
| 概念 | 核心作用 | xv6 / Linux 实现要点 |
|---|---|---|
| 内核态与用户态 | 隔离用户程序与内核,保障系统安全 | xv6 使用 int 0x80 切换;Linux 使用 syscall 指令 |
| 系统调用 | 用户程序请求内核服务的唯一入口 | xv6 通过 syscall() 分发;Linux 通过 sys_call_table |
| 中断 | 处理外部硬件事件(异步) | xv6 使用 IDT 管理;Linux 使用 irq_desc 结构 |
| 异常 | 处理 CPU 内部错误(同步) | xv6 缺页异常触发 trap();Linux 缺页异常触发 do_page_fault() |
| 硬件架构 | 提供 CPU、内存、I/O 的物理基础 | xv6 运行在 x86 模拟器上;Linux 支持多种架构(x86、ARM、RISC-V) |
常见误区:系统调用不是函数调用。函数调用在用户态完成,不涉及特权级切换;系统调用必须经过内核,切换栈和特权级,开销远高于普通函数调用。
本章建立了操作系统与硬件之间的桥梁。理解内核态与用户态的隔离、系统调用的完整路径、中断与异常的处理机制,以及 CPU、内存、I/O 的硬件架构,为后续深入分析 xv6 和 Linux 内核的进程管理、内存管理、文件系统等核心子系统奠定了坚实的基础。