两种 CPU 状态

操作系统要保护系统资源,不能让普通应用程序随意执行影响全局状态的指令。因此 CPU 将指令分为两类:

类型 含义 例子
非特权指令 普通应用程序可以执行 加法、减法、普通数据处理
特权指令 只能由操作系统内核执行 修改 PSW、开关中断、清内存、启动 I/O

CPU 也相应分为两种运行状态:

CPU 状态 运行内容 能否执行特权指令 别名
用户态 应用程序 不能 目态
内核态 操作系统内核程序 可以 核心态、管态

CPU 当前处于哪种状态通常由 PSW 中的状态位表示。用户态程序若试图执行特权指令,CPU 会发现权限不匹配,触发异常,转入内核态交给操作系统处理。

1000

状态切换

内核态到用户态

内核态到用户态通常由内核主动完成。操作系统准备让某个应用程序运行时,会通过特权指令修改 PSW 中的状态位,并恢复该程序的运行现场,使 CPU 回到用户态执行用户程序。

这个方向是“内核让出 CPU 控制权”。

用户态到内核态

用户态程序不能直接把 CPU 改成内核态。用户态到内核态必须由硬件事件触发,常见来源包括:

来源 例子 本质
系统调用 用户程序执行 trap / 访管指令 程序主动请求内核服务
异常 缺页、除 0、非法特权指令 当前指令执行过程中出现特殊情况
外部中断 时钟中断、I/O 完成中断 当前指令外部的设备或时钟事件

这个方向是“操作系统夺回 CPU 控制权”。没有这种机制,应用程序一旦运行,就可能长期占用 CPU,操作系统无法重新获得控制。

异常与中断

异常与中断的完整定义、分类和处理过程见 Exception-And-Interrupt-BriefException-And-Interrupt-Handling

它们在操作系统中的作用:

  1. 让 CPU 从用户态转入内核态。
  2. 让操作系统在必要时重新获得 CPU 控制权。
  3. 为系统调用、I/O 完成、时钟调度、错误处理提供统一入口。

异常来自 CPU 内部,通常与当前正在执行的指令有关。OS 第一章关心的是:异常能让 CPU 从用户态转入内核态,使内核有机会处理当前指令引发的问题或请求。

系统调用使用 trap / 访管指令主动触发自陷;缺页故障、除 0、用户态执行特权指令等也会触发异常。分类细节见 异常

中断来自 CPU 外部,通常与当前正在执行的指令无关。OS 第一章关心的是:中断让操作系统可以在用户程序运行期间重新获得 CPU 控制权。

常见中断:

  • 时钟中断:让操作系统周期性获得控制权,可用于计时和调度。
  • I/O 中断:设备完成输入输出后通知 CPU。
  • 不可屏蔽中断:如电源故障等紧急事件。

CPU 通常在一条指令执行结束后检查外部中断。若允许响应,就进入中断响应过程,转到内核中的中断处理程序。

时钟中断和并发

时间片轮转、进程调度等机制需要操作系统周期性取回 CPU。时钟中断提供了这种机会,因此它是多道程序并发运行的重要硬件基础。

# 系统调用

系统调用是应用程序请求操作系统内核服务的接口。凡是涉及共享资源、影响其他进程或需要特权操作的功能,都应通过系统调用进入内核。

典型系统调用包括:

类型 例子
进程控制 创建进程、终止进程、等待子进程
文件管理 创建、打开、读写、关闭、删除文件
设备管理 请求 I/O、释放设备、获取设备状态
内存管理 申请内存、映射文件、调整地址空间

系统调用的基本过程:

  1. 用户程序准备系统调用号和参数。
  2. 用户程序执行 trap 指令,也叫陷入指令或访管指令。
  3. CPU 产生自陷,硬件切换到内核态,并转入系统调用入口。
  4. 系统调用入口根据系统调用号分派到具体内核处理程序。
  5. 内核完成服务,设置返回值。
  6. 通过返回指令回到用户态,用户程序继续执行。
系统调用与库函数

库函数不等于系统调用。某些库函数只是普通用户态代码,如数学计算函数;某些库函数会封装系统调用,如文件创建、进程创建、网络读写等。