保護模式(英語:Protected Mode,或有時簡寫為 pmode)是一種80286系列和之後的x86兼容CPU的操作模式。保護模式有一些新的特性,如記憶體保護分頁系統以及硬體支援的虛擬記憶體,能夠增強多任務處理和系統穩定度。現今大部分的x86作業系統都在保護模式下運行,包含LinuxFreeBSD、以及微軟Windows 2.0和之後版本。

另外一種286和其之後CPU的操作模式是真實模式,這是一種向前相容且關閉了保護模式這些特性的CPU運行模式,用來讓新的晶片可以執行舊的軟體。所有的x86 CPU都是在真實模式下開機,來確保傳統作業系統的相容性。為了使用保護模式的特性,要由程式主動地切換到保護模式。在現今的電腦上,這種切換通常是作業系統在開機時候完成的第一件工作。當CPU在保護模式下運行時,可以使用虛擬86模式來執行為真實模式設計的程式碼。

儘管用軟體的方式也有某些可能在真實模式的系統下使用多工,但保護模式下記憶體保護的特色,可以避免有問題的程式破壞其他工作或是作業系統核心所擁有的記憶體。保護模式也有中斷正在執行程式的硬體支援,可以實現先佔式多工

大部分可以使用保護模式的CPU也擁有32位元暫存器的特性(例如80386系列和其後任何的晶片),導入了融合保護模式而成為32位元處理的概念。80286晶片雖有支援保護模式,但是仍然只有16位元暫存器。Windows 2.0和之後版本中的保護模式增強稱為"386增強模式",是因為他們除了保護模式外,還需要32位元的暫存器,並且無法在286上面執行(即使286支援保護模式)。

即使在32位元晶片上已經打開了保護模式,但是為了仿照IBM XT系統記憶體連續的設計特性,1 MiB以上的記憶體並無法存取。這種限制可以由打開A20總線來迴避。

在保護模式下,前面32個中斷都是保留給CPU例外處理用。例如,中斷0D(十進制13)是一般保護模式錯誤,而中斷00是除以零

286的保護模式尋址

編輯
 
286CPU在保護模式下的尋址

286出現之前,x86的地址總線為20位,使用16位的段基址(段首地址的高16位)與4位的段內偏移量,段基址左移4位後與段內偏移量相加形成20位的物理地址,來對220(即1MiB)的地址空間尋址。1982年問世的286 CPU首次使用了保護模式尋址。286 CPU的地址總線為24位,尋址空間為224(即16 MiB)。而286 CPU的寄存器仍為16位。[1]尋址時,段寄存器保存的數據不再是內存物理地址,而是稱作選擇器(selector),其中高13位指向描述符表(descriptor table)的條目;最低的兩位數據定義了請求的權限,從0到3,0是最高權限,3是最低權限;剩下的一位表示是使用全局描述符表(GDT)還是局部描述符表英語Local Descriptor Table(LDT)。描述符表的條目為8字節長,包括24位長的段起始物理地址、16位長的段長(因此段的長度範圍從1 B到216 B,即不超過64 KiB)。每次內存操作所要訪問的物理地址為描述符表相應條目給出的24位段起始物理地址再加上16位的偏移量。可見,286保護模式下的應用程序能訪問的內存線性地址空間僅為64 KB,非常有限。所以程序員編寫使用大內存的應用程序時還必須使用遠指針、近指針,相當繁瑣。這影響了286保護模式的推廣使用。

從386開始的IA32保護模式尋址

編輯
 
IA32 CPU保護模式下的4KiB分頁尋址
 
IA32 CPU保護模式下的4 MiB分頁尋址
 
應用程序的虛擬線性地址空間映射到分頁管理的物理地址空間

1985年問世的80386開啟了32位CPU時代。[2]地址總線為32比特,尋址空間為232(即4 GiB)。[3]386 CPU保護模式下有兩種內存尋址方式:

  • 可以分頁尋址,這是此後的x86上的Windows操作系統與Linux操作系統最廣泛採用的方法;
  • 也可以非分頁尋址而採取與286保護模式兼容的尋址方式,採用16位的選擇器(selector)寄存器與32位的偏移量寄存器尋址,這時描述符表的條目中保存的段起始物理地址為32位,而段長的數據寬度為20位,但可以設置段長的粒度為1 B或4 KiB,所以段的最大長度可以是1 MiB或者4 GiB。

386 CPU開創的分頁內存管理,比286保護模式尋址具有更多的優點:

  • 操作系統可以控制與限制進程對頁面的訪問權限
  • 為應用程序創造一個連續的、獨立的、線性的虛擬內存空間
  • 頁面可以移出主存,存入更慢速的次級外存硬盤。這使得操作系統可以使用比物理內存更大的存儲空間。

IA32的CPU通過兩級:頁目(page directory)與頁表(page table)實現4 KiB的分頁管理,這是最常見的IA32分頁尋址方式。CR3寄存器保存了進程的頁目的物理地址。頁目與頁表中每4字節為一個單元,是一個32位的值,當頁目項第0位為1時,表明頁表已經在物理內存中;當頁表項第0位為1時,表明訪問的數據已經在內存中。另外,當頁目項第7位為1時,表明這是一個4M的頁面,這值已經是物理頁地址,用虛擬地址的低22位作為偏移量。

從應用程序角度,不再使用段地址寄存器(或稱選擇器),僅使用32位的偏移量,為232(即4 GiB)的連續線性尋址空間。

進入保護模式

編輯

進入保護模式前,必須初始化全局描述符表,並最少包含三個描述符:空描述符、代碼段描述符以及數據段描述符。並把(全局描述符表的所占用的字節數-1)和全局描述符表的物理內存地址保存到GDTR寄存器中。如果是IBM兼容的機器,則還需要打開A20總線

通過設置CR0寄存器的PE位進入保護模式。在設置完CR0寄存器的PE位後,需要進行遠轉移以清空PIQ。

; 设置CR0寄存器的PE位
mov eax, cr0       ; 必须通过其他寄存器来修改CR0寄存器
or eax, 1
mov cr0, eax

; 远转移 (cs = 代码段描述符)
jmp cs:@pmode

[bits 32]
@pmode:
; 现在已经进入了保护模式

參見

編輯

參考資料

編輯
  1. ^ A+ - Hardware. PC Microprocessor Developments and Features Tutorials. BrainBell.com. [2007-07-24]. (原始內容 (Tutorial/Guide)存檔於2022-03-31). 
  2. ^ Intel Global Citizenship Report 2003. [2007-07-14]. (原始內容 (Timeline)存檔於2008-03-22). 1985 Intel launches Intel386 processor 
  3. ^ 80386 Programmer's Reference Manual (PDF). Santa Clara, CA: Intel. 1986. Section 2.1 Memory Organization and Segmentation [2022-05-09]. (原始內容 (PDF)存檔於2018-12-28). 

外部連結

編輯