前言
當前操作系統大部分採用分時的進程調度, 既每個進程運行一小段時間, 然後切換到下一個進程運行, 依次往復.
當進程運行的時候是獨佔CPU
的, 此時操作系統是無法強行介入的, 爲了將執行權讓出來, 就需要硬件的配合了. 硬件每個一個時鐘週期(比如10ms), 就會產生一個時鐘中斷, 而這個時鐘中斷會將執行權強行交給操作系統的調度進程, 然後由調度進程進行後續處理.
以上, 就是我在第一遍看操作系統時留下的印象, 但有幾個問題當時沒有搞明白:
- 如何保存進程的上下文? 在將進程暫停後, 爲了之後再次運行, 需要將運行現場保存起來, 以便再次運行時恢復. 而在
CPU
的角度, 運行現場其實就是幾個寄存器的值. 想標誌寄存器/通用寄存器/段寄存器等等, 調度進程都能拿到, 我都能理解. 但是, 指令寄存器PC
如何保存呢? 當執行權交給調度進程後,PC
自然也就指向了調度進程, 已經丟失了當時的值. - 若在調度進程運行時, 再次發生了時鐘中斷, 不就陷入死循環了.
以上問題, 在多年後我再次重翻操作系統時, 得到了解答.
解惑
如何保存上下文
其實, 前面的分析是沒錯的, 當執行進程切換後, 指令寄存器的值必然指向當前執行的進程. 既然軟件辦不到, 那就硬件來做咯.
找到了這樣一篇CPU文檔 (可能和現在主流 CPU 實現有所差異, 不過作爲參考倒是問題不大):
當觸發中斷時, 會將PC, X, A, CC
寄存器的值保存到棧中. 其中X
A
是通用寄存器, CC
是一個條件碼寄存器, 在文檔的5.1
小節對這些寄存器均有介紹.
哎, 這不就解決了切換後的上下文問題麼.
中斷嵌套問題
當調度程序正在運行時, 再次發生中斷怎麼辦? 如果能將中斷關閉, 不就沒人來打擾了麼.
沒錯, 就是這麼幹. 通過修改CC
寄存器的值, 可以達到關閉中斷的效果.
同時也提供了中斷操作的彙編指令.
至此, 中斷的嵌套問題便解決了.
並且中斷程序結束後, 調用IRET
退出, 可恢復程序執行. 這自然是爲了鍵盤輸入這種中斷使用的.
總結
在看了這麼一份硬件文檔後, 硬件真的是做了很多事情, 很多軟件做不到的事情, 硬件來做, 軟件做的慢的事情, 硬件來做.
當然, 文檔中不止有這些內容,, 奈何我才疏學淺, 看英文文檔着實費盡. 罷了罷了, 解了心中疑惑便好...