切換到保護模式

切換到保護模式很簡單:只需在控制暫存器中設定一個位即可。但是保持在保護模式下,由於不知道接下來要做什麼而沒有 CPU 丟失並重置自己,需要做很多準備。

簡而言之,所需的步驟如下:

  • 需要設定全域性描述符表的記憶體區域以定義至少三個描述符:

    1. 零,NULL 描述符;

    2. 程式碼段的另一個描述符;

    3. 資料段的另一個描述符。

      這可以用於資料和堆疊。

  • 需要初始化全域性描述符表暫存器(GDTR)以指向該定義的儲存區域;

     GDT_Ptr    dw      SIZE GDT
                dd      OFFSET GDT
    
                ...
    
                lgdt    [GDT_Ptr]
    
  • 需要設定 CR0 中的 PM 位:

         mov   eax, cr0      ; Get CR0 into register
         or    eax, 0x01     ; Set the Protected Mode bit
         mov   cr0, eax      ; We're now in Protected Mode!
    
  • 需要從 GDT 載入段暫存器以刪除當前的真實模式值:

         jmp   0x0008:NowInPM  ; This is a FAR Jump. 0x0008 is the Code Descriptor
    
    NowInPM:
         mov   ax, 0x0010      ; This is the Data Descriptor
         mov   ds, ax
         mov   es, ax
         mov   ss, ax
         mov   sp, 0x0000      ; Top of stack!
    

請注意,這是最小,只是為了讓 CPU 進入保護模式。要實際使整個系統準備就緒可能需要更多步驟。例如:

  • 可能必須啟用高階儲存區 - 關閉 A20 門;
  • 絕對應該禁用中斷 - 但是在進入保護模式之前可能會設定各種故障處理程式,以便在處理過程中儘早發生錯誤。

本節的原作者編寫了一個關於進入保護模式並使用它的完整教程