1. 程式人生 > >在loader程序中涉及到的CPU模式切換

在loader程序中涉及到的CPU模式切換

物理內存 地址尋址 索引數據 代碼段 位置 是否 匯編 ast 需要

在實模式下開啟4GB的物理內存地址尋址(稱之為Big Real Mode)

  • 通過A20快速門(Fast Gate)修改0x90端口的數據, 對其進行置位(類似於打開一個開關), 開啟
  • 使用CLI匯編指令關閉外部中斷
  • 使用lgdt加載保護模式需要的系統數據結構
  • 置位cr0寄存器的值開啟保護模式
  • 進入保護模式
  • 重新加載FS寄存器中的數據, 使其支持4GB的物理內存地址的尋址
  • 立刻置位cr0寄存器的數據關閉保護模式
  • 使用STI匯編指令開啟外部中斷
  • 這樣CPU就可以支持4GB的尋址了
  • 註意: 該Big Real Mode是必須的, 我們需要將內核代碼加載到1MB以上的物理內存地址空間上, 那麽就需要開啟4GB的內存尋址, 之所以要在返回到實模式是因為在實模式下所有內存地址都是可以訪問的, 而在保護模式下則不能, 在這裏我們需要訪問一些物理地址所以需要在返回實模式

完成了內核代碼的加載和移動到指定的1MB之上的位置之後的模式切換

  • 在Big Real Mode中已經開啟了A20快速門開關, 這裏就不需要了
  • 手動初始化好gdt數據結構(包括: 段描述符(數據段和代碼段), 段選擇子(用來索引數據段和代碼段), gdt的基地址和長度(這個通過lgdt匯編指令加載到gdtr寄存器中))
  • 手動初始化好idt數據結構
  • 使用CLI匯編指令關閉外部中斷
  • 使用lgdt將上面定義好的數據結構的基地址和長度加載到寄存器中
  • 置位(PE)cr0寄存器的值開啟保護模式
  • 進入保護模式, 以0特權級別執行指令
  • 使用jmp指令將CPU指向保護模式的代碼
  • CPU執行保護模式的代碼
  • 緊接著要進入到IA-32e模式(64位)

進入IA-32e模式

  • 判斷CPU是否支持IA-32e模式, 如果支持則(見下面的步驟)
  • 手動初始化64位的gdt
  • 重新加載gdt, lgdt 到gdtr中
  • 置位cr0寄存器的數據關閉分頁機制PG
  • 置位cr4寄存器的數據PAE開啟物理地址擴展功能(PAE)
  • 置位IA32_EFER寄存器的LME標誌位開啟IA-32e模式
  • 置位cr0寄存器的數據開啟分頁機制PG
  • 使用jmp將CPU指向內核代碼

在loader程序中涉及到的CPU模式切換