寫在前面 本隨筆是非常菜的菜雞寫的。如有問題請及時提出。 可以聯繫:[email protected] GitHhub:https://github.com/WindDevil (目前啥也沒有 官方文檔 仍然是一上來就丟出來的官方文檔. 只摘抄了我覺得有意思的部分: 實現特權級機制的根本原因是應用程 ...
寫在前面
本隨筆是非常菜的菜雞寫的。如有問題請及時提出。
可以聯繫:[email protected]
GitHhub:https://github.com/WindDevil (目前啥也沒有
官方文檔
仍然是一上來就丟出來的官方文檔.
只摘抄了我覺得有意思的部分:
實現特權級機制的根本原因是應用程式運行的安全性不可充分信任。
由於二者通過編譯器形成一個單一執行程式來執行,導致即使是應用程式本身的問題,也會讓操作系統受到連累,從而可能導致整個電腦系統都不可用了。
包括之前做MCU
開發的時候,實際上都是這樣的,也很難理解為什麼可以做到應用是應用,操作系統是操作系統,之前使用RT-Thread
做MCU
開發的過程中,如果出現某一個線程出現問題, 貌似 還是會出現整體的問題.包括能不能分別編譯,能不能實現安裝與卸載都是我對操作系統(Linux,windows)的刻板印象.
解決問題的方法:
應用程式不能訪問任意的地址空間(這個在第四章會進一步講解,本章不會涉及)
應用程式不能執行某些可能破壞電腦系統的指令(本章的重點)
有一部分指令不能在應用程式中執行,就可以保證操作系統出現問題嗎?怎麼體現呢?體現之後,那怎麼實現應用程式的功能呢?
具體實現指令分級的方法:
處理器設置兩個不同安全等級的執行環境:用戶態特權級的執行環境和內核態特權級的執行環境。且明確指出可能破壞電腦系統的內核態特權級指令子集,規定內核態特權級指令子集中的指令只能在內核態特權級的執行環境中執行。處理器在執行指令前會進行特權級安全檢查,如果在用戶態執行環境中執行這些內核態特權級指令,會產生異常。
為了讓應用程式獲得操作系統的函數服務,採用傳統的函數調用方式(即通常的 call
和 ret
指令或指令組合)將會直接繞過硬體的特權級保護檢查。為瞭解決這個問題, RISC-V 提供了新的機器指令:執行環境調用指令(Execution Environment Call,簡稱 ecall
)和一類執行環境返回(Execution Environment Return,簡稱 eret
)指令。
操作系統要做什麼:
硬體具有了這樣的機制後,還需要操作系統的配合才能最終完成對操作系統自身的保護。首先,操作系統需要提供相應的功能代碼,能在執行 sret
前準備和恢復用戶態執行應用程式的上下文。其次,在應用程式調用 ecall
指令後,能夠檢查應用程式的系統調用參數,確保參數不會破壞操作系統。
這張圖就很明瞭了,把原來的執行環境棧從特權級的架構去看待,那麼現在只需要在SBI
和ABI
兩部分做編程實現上述功能就可以了:
這裡也是比較重要的一點:
執行環境的另一種功能是對上層軟體的執行進行監控管理。監控管理可以理解為,當上層軟體執行的時候出現了一些異常或特殊情況,導致需要用到執行環境中提供的功能,因此需要暫停上層軟體的執行,轉而運行執行環境的代碼。
把一部分代碼放在操作系統里,這樣就實現了ABI
,每次要執行為好到操作系統的操作的時候都需要操作系統親自執行,這樣如果出現錯誤,那麼一些錯誤就會被阻止.
因為M
模式的內容是在SBI
裡邊的,所以這一部分的內容專註於S
模式和U
模式的特權級切換.
可以看到,為了執行一部分需要在內核中使用的功能的時候就需要進行特權級切換,這裡官方文檔和常規控制流進行對比,把入校流程稱為 異常控制流
- 上層軟體執行過程中出現了一些異常或 特殊情況 , 需要用到執行環境中提供的功能
- 這裡可以看到雖然都叫做 異常 但是實際上有一部分情況是特殊情況需要使用執行環境中的功能,不能非黑即白地把 異常 理解為 壞的
- 用戶態應用直接觸發從用戶態到內核態的異常的原因總體上可以分為兩種
- 其一是用戶態軟體為獲得內核態操作系統的服務功能而執行特殊指令
- 指令本身屬於高特權級的指令,如
sret
指令(表示從 S 模式返回到 U 模式) - 指令訪問了 S模式特權級下才能訪問的寄存器 或記憶體,如表示S模式系統狀態的 控制狀態寄存器
sstatus
等
- 指令本身屬於高特權級的指令,如
- 其二是在執行某條指令期間產生了錯誤(如執行了用戶態不允許執行的指令或者其他錯誤)並被 CPU 檢測到
- 其一是用戶態軟體為獲得內核態操作系統的服務功能而執行特殊指令
- 暫停上層軟體的功能,轉而運行執行環境的代碼 (伴隨 特權級切換 )
- 回到上層軟體暫停的位置繼續執行
配合下圖食用更加: