CPU Modes
两种 CPU 状态
操作系统要保护系统资源,不能让普通应用程序随意执行影响全局状态的指令。因此 CPU 将指令分为两类:
| 类型 | 含义 | 例子 |
|---|---|---|
| 非特权指令 | 普通应用程序可以执行 | 加法、减法、普通数据处理 |
| 特权指令 | 只能由操作系统内核执行 | 修改 PSW、开关中断、清内存、启动 I/O |
CPU 也相应分为两种运行状态:
| CPU 状态 | 运行内容 | 能否执行特权指令 | 别名 |
|---|---|---|---|
| 用户态 | 应用程序 | 不能 | 目态 |
| 内核态 | 操作系统内核程序 | 可以 | 核心态、管态 |
CPU 当前处于哪种状态通常由 PSW 中的状态位表示。用户态程序若试图执行特权指令,CPU 会发现权限不匹配,触发异常,转入内核态交给操作系统处理。
状态切换
内核态到用户态
内核态到用户态通常由内核主动完成。操作系统准备让某个应用程序运行时,会通过特权指令修改 PSW 中的状态位,并恢复该程序的运行现场,使 CPU 回到用户态执行用户程序。
这个方向是“内核让出 CPU 控制权”。
用户态到内核态
用户态程序不能直接把 CPU 改成内核态。用户态到内核态必须由硬件事件触发,常见来源包括:
| 来源 | 例子 | 本质 |
|---|---|---|
| 系统调用 | 用户程序执行 trap / 访管指令 | 程序主动请求内核服务 |
| 异常 | 缺页、除 0、非法特权指令 | 当前指令执行过程中出现特殊情况 |
| 外部中断 | 时钟中断、I/O 完成中断 | 当前指令外部的设备或时钟事件 |
这个方向是“操作系统夺回 CPU 控制权”。没有这种机制,应用程序一旦运行,就可能长期占用 CPU,操作系统无法重新获得控制。
异常与中断
异常与中断的完整定义、分类和处理过程见 Exception-And-Interrupt-Brief 与 Exception-And-Interrupt-Handling。
它们在操作系统中的作用:
- 让 CPU 从用户态转入内核态。
- 让操作系统在必要时重新获得 CPU 控制权。
- 为系统调用、I/O 完成、时钟调度、错误处理提供统一入口。
异常来自 CPU 内部,通常与当前正在执行的指令有关。OS 第一章关心的是:异常能让 CPU 从用户态转入内核态,使内核有机会处理当前指令引发的问题或请求。
系统调用使用 trap / 访管指令主动触发自陷;缺页故障、除 0、用户态执行特权指令等也会触发异常。分类细节见 异常。
中断来自 CPU 外部,通常与当前正在执行的指令无关。OS 第一章关心的是:中断让操作系统可以在用户程序运行期间重新获得 CPU 控制权。
常见中断:
- 时钟中断:让操作系统周期性获得控制权,可用于计时和调度。
- I/O 中断:设备完成输入输出后通知 CPU。
- 不可屏蔽中断:如电源故障等紧急事件。
CPU 通常在一条指令执行结束后检查外部中断。若允许响应,就进入中断响应过程,转到内核中的中断处理程序。
时间片轮转、进程调度等机制需要操作系统周期性取回 CPU。时钟中断提供了这种机会,因此它是多道程序并发运行的重要硬件基础。
系统调用是应用程序请求操作系统内核服务的接口。凡是涉及共享资源、影响其他进程或需要特权操作的功能,都应通过系统调用进入内核。
典型系统调用包括:
| 类型 | 例子 |
|---|---|
| 进程控制 | 创建进程、终止进程、等待子进程 |
| 文件管理 | 创建、打开、读写、关闭、删除文件 |
| 设备管理 | 请求 I/O、释放设备、获取设备状态 |
| 内存管理 | 申请内存、映射文件、调整地址空间 |
系统调用的基本过程:
- 用户程序准备系统调用号和参数。
- 用户程序执行 trap 指令,也叫陷入指令或访管指令。
- CPU 产生自陷,硬件切换到内核态,并转入系统调用入口。
- 系统调用入口根据系统调用号分派到具体内核处理程序。
- 内核完成服务,设置返回值。
- 通过返回指令回到用户态,用户程序继续执行。
库函数不等于系统调用。某些库函数只是普通用户态代码,如数学计算函数;某些库函数会封装系统调用,如文件创建、进程创建、网络读写等。