2021-05-12 14:32:11
處理器在 protected mode 下的 protection
前言
真實模式,保護模式,分段,分頁,虛擬記憶體,核心態,使用者態,如果你對這些術語之間的關係非常熟悉,那就不用繼續看了。這篇主要記錄我對使用者態/核心態的一些理解,如有不對還請指教。
下述說明均為 x86-32 模式。
簡述
分段/分頁機制實現了邏輯地址到實體地址的轉換,為每個程式提供了自己獨立的虛擬記憶體空間,與其他應用程式進行隔離,防止修改其他程式相關資料。開啟了分頁機制之後,CPU 硬體會對所有程式碼進行記憶體對映處理,不管是應用程式還是作業系統,都會使用虛擬記憶體機制。
對於4G 線性地址空間而言, linux 將最高 1G 空間對映為記憶體使用的空間,除去高階記憶體等小範圍概念,基本上核心的地址減去 PAGE_OFFSET 偏移就是其實際實體地址。注意這裡我沒有說 4G 線性地址空間的主體,它的主體是所有的進程,甚至包括核心自身。 每個進程都有自己的 CR3 ,每個進程的 CR3 的地址對映的最高 1G 都是一樣的,是通用的核心本身。
剛開始啟動的時候核心是作為一個可執行程式啟動,但在啟動完成後當有系統呼叫時,核心程式碼開始執行,此時它所使用的 CR3 還是原進程的 CR3,所以我們會說一個程式在核心態執行。
我們為什麼需要使用者態/核心態之間的切換?
使用者態/核心態 不是原因,只是結果,只看結果是看不出什麼的。引入 使用者態/核心態 的原因是因為 privilege level, 使用者態/核心態的區分只是實現 privilege protection 的一種形式,而這種方式依賴於 分段/分頁來實現。
記憶體隔離與保護 —————-> 分段/分頁
privilege(特權等級) —————-> 使用者態/核心態
假設只有分段/分頁,其依賴於 GDT/LDT 與 CR3 暫存器指向的 page structure, 乍一看提供了隔離,但是如果沒有 privilege level 的保護,應用程式可以自己修改自己的 CR3 指向的記憶體對映,這個記憶體保護也就形同虛設了,更不用提一些危險的指令了。
假設只有privilege level,那也肯定不行,甚至連多程式執行都不可能。
所以說區分核心態/使用者態除了提供系統呼叫功能,更多的是進行 privilege 保護,不同模式下只允許執行對應的 CPU 指令。所有執行在核心態的程式碼共用一個虛擬記憶體空間,也就是通過分段/分頁機制使得所有進程的 3G~4G 線性地址空間指向同一塊區域,也就是核心區域。從這個方面來看,此時作業系統不再是啟動時的可執行程式,更像是一個單例的共用庫一樣給所有進程使用。許多圖片上將作業系統畫成應用程式下的獨立一層應該更符號這個結構。
總結
之所以寫這篇文章是在自製作業系統的過程中對核心的虛擬地址設定有所疑問,不理解所有程式共用 3G~4G記憶體的原因,很多文章一上來就會告訴你這是核心態使用,我相信從 特權等級 的概念引申出去了解核心態和使用者態會更為簡單。
相關文章