保护模式初步理解
保護模式初步理解
與實模式一樣,保護模式中內存也被邏輯上分成了一個個具有相應功能的段,比如代碼段,數據段,棧段等。 但是保護模式中,每個段的“個性“更鮮明。
我們知道,在實模式中,所有內存都是可讀、可寫、可訪問的,你哪天看哪塊內存不爽了, 輕輕松松就可以把他里面的東西搞亂,非常的不安全。 但在保護模式中,每個段在定義的時候就被賦予了段基址、段長度、段類別(代碼段/數據段/...)、特權級等屬性(這些屬性被放在8個字節中,我們稱之為描述符)。任何程序想訪問其他段、以何種方式訪問(讀/寫/執行),都需要校驗通過才被允許。比如,我是一個可執行的代碼段, 如果其他程序想修改它里面的內容,那是不被允許的。 這樣,cpu通過一些類似的限制,最大限度的保護了程序的安全。
保護模式中比較重要的一個保護方式就是特權級。 所有段被劃分為4個特權級(0~3),其中0最高,3最低。 較為核心的數據和代碼,被放在高特權級層次中,其他的被放在低特權級中。通過這種層次的劃分,可以有效的避免低優先級任務在不被允許的情況下訪問高優先級段。?
所有段通常只在自己相同的特權級中運行, 但也難免有不同特權級之間的跳轉,所以cpu提供了一套比較嚴密的特權級跳轉機制。在正式介紹跳轉規則之前,我想先講一下cpu是如何檢查一個跳轉是否合法。 我們知道,無論是在實模式還是在保護模式中,CS,EIP都是用來保存下一條指令的地址的,不同的是在保護模式中,CS中既存放了當前代碼段基址索引(3~15位存放的是當前代碼段描述符在GDT中的索引),又存放了當前程序的優先級(CPL)。在試圖跳轉時,cpu將CPL與目標段DPL及RPL進行對比校驗,如果校驗成功, 就將目標段選擇子加載到CS中, 并以一定規則修改CPL, 隨后進入目標段運行。
對了,還要介紹一個東西:代碼段類型。 代碼段被分為一致代碼段和非一致代碼段。可以這樣理解它們:
1.內核中的絕大多數代碼對上層都是透明且不可訪問的, 這些代碼可以理解為非一致代碼段, 是被嚴格保護起來的, 只能被相同特權級的其他段訪問。
2.同時,內核也需要與上層進行交互, 所以提供了有限的代碼允許符合條件的上層進行訪問,這些代碼就可以理解為一致代碼段。
其實特權級轉換規則并不復雜,大致可以歸納為以下幾條:
1. 低優先級代碼段通過調用門可以跳轉至高優先級的一致代碼段(非一致不被允許),且CPL不被改變。
2. 相同特權級代碼段之間可以直接跳轉。
3. 高特權級跳轉至低特權級時,需要借助一條指令:retf,且CPL被更改為dest_descriptor.DPL和dest_selector.RPL中更大的值,即特權級被降低。
4. 不同特權級的代碼段需要不同的棧,所以在特權級跳轉時,同時也要切換棧段,具體參考TSS。
總的來說,特權級跳轉是比較麻煩的, 牽扯的概念比較多。把這個弄明白了,基本上就入門了。
與實模式一樣,保護模式中內存也被邏輯上分成了一個個具有相應功能的段,比如代碼段,數據段,棧段等。 但是保護模式中,每個段的“個性“更鮮明。
我們知道,在實模式中,所有內存都是可讀、可寫、可訪問的,你哪天看哪塊內存不爽了, 輕輕松松就可以把他里面的東西搞亂,非常的不安全。 但在保護模式中,每個段在定義的時候就被賦予了段基址、段長度、段類別(代碼段/數據段/...)、特權級等屬性(這些屬性被放在8個字節中,我們稱之為描述符)。任何程序想訪問其他段、以何種方式訪問(讀/寫/執行),都需要校驗通過才被允許。比如,我是一個可執行的代碼段, 如果其他程序想修改它里面的內容,那是不被允許的。 這樣,cpu通過一些類似的限制,最大限度的保護了程序的安全。
保護模式中比較重要的一個保護方式就是特權級。 所有段被劃分為4個特權級(0~3),其中0最高,3最低。 較為核心的數據和代碼,被放在高特權級層次中,其他的被放在低特權級中。通過這種層次的劃分,可以有效的避免低優先級任務在不被允許的情況下訪問高優先級段。?
所有段通常只在自己相同的特權級中運行, 但也難免有不同特權級之間的跳轉,所以cpu提供了一套比較嚴密的特權級跳轉機制。在正式介紹跳轉規則之前,我想先講一下cpu是如何檢查一個跳轉是否合法。 我們知道,無論是在實模式還是在保護模式中,CS,EIP都是用來保存下一條指令的地址的,不同的是在保護模式中,CS中既存放了當前代碼段基址索引(3~15位存放的是當前代碼段描述符在GDT中的索引),又存放了當前程序的優先級(CPL)。在試圖跳轉時,cpu將CPL與目標段DPL及RPL進行對比校驗,如果校驗成功, 就將目標段選擇子加載到CS中, 并以一定規則修改CPL, 隨后進入目標段運行。
對了,還要介紹一個東西:代碼段類型。 代碼段被分為一致代碼段和非一致代碼段。可以這樣理解它們:
1.內核中的絕大多數代碼對上層都是透明且不可訪問的, 這些代碼可以理解為非一致代碼段, 是被嚴格保護起來的, 只能被相同特權級的其他段訪問。
2.同時,內核也需要與上層進行交互, 所以提供了有限的代碼允許符合條件的上層進行訪問,這些代碼就可以理解為一致代碼段。
其實特權級轉換規則并不復雜,大致可以歸納為以下幾條:
1. 低優先級代碼段通過調用門可以跳轉至高優先級的一致代碼段(非一致不被允許),且CPL不被改變。
2. 相同特權級代碼段之間可以直接跳轉。
3. 高特權級跳轉至低特權級時,需要借助一條指令:retf,且CPL被更改為dest_descriptor.DPL和dest_selector.RPL中更大的值,即特權級被降低。
4. 不同特權級的代碼段需要不同的棧,所以在特權級跳轉時,同時也要切換棧段,具體參考TSS。
總的來說,特權級跳轉是比較麻煩的, 牽扯的概念比較多。把這個弄明白了,基本上就入門了。
總結
- 上一篇: 加载Loader.bin
- 下一篇: 3.2.3节:特权级