進入保護模式
阿新 • • 發佈:2019-01-05
目錄
進入保護模式
進入保護模式
進入保護模式的步驟:
- 關閉中斷,開啟地址線A20GATE,使得CPU可以訪問1M以上的記憶體空間。
- 設定CR0暫存器,進入保護模式。
- 載入臨時GDT
- 進入保護模式後,首先執行jmp指令。因為記憶體定址方式改變,需要重新整理指令流水線
開啟A20Gate
1. A20Gate的作用
在真實模式下,A20Gate是關閉的,意味著只能使用20根地址線,需要通過開啟A20Gate,訪問第21根以上的匯流排。
A20Gate關閉時侯的記憶體訪問:
A20Gate關閉式,只能使用20根匯流排,所以定址範圍位 0x00000 ~ 0xFFFFF,總共1M的地址範圍。
當訪問的地址大於這個範圍,高位的值將被擷取掉,導致超出1M的地址訪問會使得CPU回滾到1M內地址範圍的現象
例如
當使用 [0xFFFF :0xFFFF ] 記憶體地址,得到的地址位 0x10FFEF 。但是在真實模式下,由於20根匯流排的限制,最高位的1是無效的,實際的訪問地址
迴繞到
[0x0FFEF]。
A20Gate開啟後的記憶體訪問:
開啟A20Gate, 可以使用到32位的地址匯流排,記憶體地址訪問也達到了1<<32 的4G範圍。
實際上開啟A20Gate,匯流排的定址能力達到了4G,但是cpu的記憶體訪問能力因為16位段暫存器,和16位偏移地址的限制,並不能協調工作。
所以需要進入保護模式突破cpu的記憶體訪問限制。
2. 開啟A20Gate
開啟A20Gate,只要設定io埠0x92的第一位為1就可以了。
;------------------
;開啟A20
cli ;禁止CPU級別的中斷
in al,0x92
or al,0000_0010B ;設定第1位為1
out 0x92,al
設定CR0暫存器,進入保護模式
CR0暫存器
CR0暫存器是一個32位的暫存器
設定CR0暫存器的最高位為0,最低位為1,則可以進入保護模式。
CR0暫存器的作用
- 改變段定址方式,使用段描述符方式定址。
- 真實模式指令的運算元預設為16位,保護模式指令的運算元預設為32位。
程式碼:
;------------------
;進入保護模式
mov eax,CR0
or eax,0x00000001 ;設定第0位為1
mov CR0,eax
loader.asm完整程式碼如下
;Rats OS
;Tab=4
[bits 16]
section loader vstart=LOADER_BASE_ADDR ;指明程式的偏移的基地址
;----------- loader const ------------------
LOADER_BASE_ADDR equ 0x9000 ;記憶體地址0x9000
;---------------------------------------
jmp Entry
;程式核心內容
Entry:
;------------------
;禁止CPU級別的中斷
cli
;------------------
;開啟A20
in al,0x92
or al,0000_0010B ;設定第1位為1
out 0x92,al
;------------------
;進入保護模式
mov eax,cr0
or eax,0x00000001 ;設定第0位為1
mov cr0,eax
;程式掛起
jmp $ ;讓CPU掛起,等待指令?
使用bochs除錯
在0x7c00打斷點,輸入c跳轉執行
$ pb 0x7c00
$ c
輸入顯示切換模式命令
$ show mode
輸入c繼續執行
$ c
可以看到控制他輸出:
00017609546: switched from 'real mode' to 'protected mode'
說明系統成功的從真實模式切換到保護模式
檢視CR0的PE位
$ creg