前言
当前操作系统大部分采用分时的进程调度, 既每个进程运行一小段时间, 然后切换到下一个进程运行, 依次往复.
当进程运行的时候是独占CPU
的, 此时操作系统是无法强行介入的, 为了将执行权让出来, 就需要硬件的配合了. 硬件每个一个时钟周期(比如10ms), 就会产生一个时钟中断, 而这个时钟中断会将执行权强行交给操作系统的调度进程, 然后由调度进程进行后续处理.
以上, 就是我在第一遍看操作系统时留下的印象, 但有几个问题当时没有搞明白:
- 如何保存进程的上下文? 在将进程暂停后, 为了之后再次运行, 需要将运行现场保存起来, 以便再次运行时恢复. 而在
CPU
的角度, 运行现场其实就是几个寄存器的值. 想标志寄存器/通用寄存器/段寄存器等等, 调度进程都能拿到, 我都能理解. 但是, 指令寄存器PC
如何保存呢? 当执行权交给调度进程后,PC
自然也就指向了调度进程, 已经丢失了当时的值. - 若在调度进程运行时, 再次发生了时钟中断, 不就陷入死循环了.
以上问题, 在多年后我再次重翻操作系统时, 得到了解答.
解惑
如何保存上下文
其实, 前面的分析是没错的, 当执行进程切换后, 指令寄存器的值必然指向当前执行的进程. 既然软件办不到, 那就硬件来做咯.
找到了这样一篇CPU文档 (可能和现在主流 CPU 实现有所差异, 不过作为参考倒是问题不大):
当触发中断时, 会将PC, X, A, CC
寄存器的值保存到栈中. 其中X
A
是通用寄存器, CC
是一个条件码寄存器, 在文档的5.1
小节对这些寄存器均有介绍.
哎, 这不就解决了切换后的上下文问题么.
中断嵌套问题
当调度程序正在运行时, 再次发生中断怎么办? 如果能将中断关闭, 不就没人来打扰了么.
没错, 就是这么干. 通过修改CC
寄存器的值, 可以达到关闭中断的效果.
同时也提供了中断操作的汇编指令.
至此, 中断的嵌套问题便解决了.
并且中断程序结束后, 调用IRET
退出, 可恢复程序执行. 这自然是为了键盘输入这种中断使用的.
总结
在看了这么一份硬件文档后, 硬件真的是做了很多事情, 很多软件做不到的事情, 硬件来做, 软件做的慢的事情, 硬件来做.
当然, 文档中不止有这些内容,, 奈何我才疏学浅, 看英文文档着实费尽. 罢了罢了, 解了心中疑惑便好…