CPU 虚拟化 (CPU virtualization) 创造出一种假象 (illusion):每个进程都有独立属于自己的 CPU 与寄存器状态,从而允许多进程在同一时间运行。

CPU 的时分复用 (time sharing):OS 快速切换进程,使得它们「感觉」自己独占了 CPU。

  • 为此 OS 发展出与 CPU,进程交互的多种底层机制 (mechanism) 与高层策略 (policy)。

系统调用

系统调用 (system call) 是 OS 提供的一系列 API。这一机制使得进程能够请求内核执行受限操作 (restricted operations),如与磁盘的 I/O,获取 CPU 与内存的更多系统资源等。

CPU 的两种工作模式:

  • 内核态 (kernel mode):OS 内核运行在内核态下,具有最高权限。
  • 用户态 (user mode):应用程序运行在用户态下,只能执行有限指令,不能直接访问物理资源。

陷阱 (trap) 是 CPU 主动引发的一种同步异常,使 CPU 「陷入」到内核态执行系统调用。

陷阱表 (trap table) 在启动时初始化,OS 将所有陷阱处理器 (trap handlers) 注册在硬件中。

系统调用的有限直接执行协议 LDEP (Limited Direct Execution Protocol)
系统调用的有限直接执行协议 LDEP (Limited Direct Execution Protocol)

中断

CPU 在执行其他进程时,OS 被架空了。

  • 我信你 (cooperative approach):依赖进程进行系统调用使 CPU 陷入内核态,OS 重获控制权 (regain control) => 死循环进程一直占据 CPU,只能重启。
  • 我真得控制你了 (non-cooperative approach):计时器中断 (timer interrupt)。计时器定期触发中断迫使 CPU 暂停当前进程,转而执行内核的中断处理器 (interrupt handler)

CPU 通过中断 (interrupt) 通知 OS 某个事件的发生(而信号通知的是进程)。

  • 同步中断 (synchronous interrupt): 同步与当前进程的执行,又称异常 (exception)
    • 错误 (fault):指令执行之前,如页错误,段错误。
    • 陷阱 (trap):指令执行之后,如系统调用后。
    • 中止 (abort):不可恢复的错误。
  • 异步中断 (asynchronous interrupt)
    • 与当前进程执行无关,如硬件设备(计时器,键盘,鼠标)触发。

中断 v.s. 信号 (e.g. 除零错误)

  • CPU 侦测到异常 1/0,触发 #DE 中断 [中断:CPU 触发 OS 接收]
  • OS 收到通知,CPU 切换到内核态
  • OS 执行 divide_error 处理器,判断该异常无法自动修复
  • OS 向出错的进程发送信号 SIGFPE [信号:OS 发送进程接收]

中断向量表 (interrupt vector table) 在启动时初始化,OS 将中断处理器注册在硬件中。

上下文切换

上下文切换 (context switching) 允许 OS 无缝切换进程。「上下文」指的是进程对应的相关 CPU 寄存器状态。

内核栈 (kernel stack) 是一块每个进程独有,仅在内核态执行时使用的内存空间,用于保存陷阱现场,承载内核函数的调用。

计时器中断的 LDEP
计时器中断的 LDEP

两个层级的上下文。

  • 用户态陷阱上下文,进程陷入内核前的用户态寄存器现场,保存在该进程的内核栈中,对应模式切换 (model switching)
  • 内核调度上下文,进程在内核中被调度切换时的内核态寄存器现场,保存在该进程的 PCB 中,对应上下文切换

恢复进程 B 时,先从 PCB 恢复 B 的内核调度上下文,再在 return-from-trap 后从内核栈恢复 B 的用户态陷阱上下文,从而创造出 B 连续运行的假象。