進入保護模式
進入保護模式
進入保護模式的步驟:
- 關閉中斷,打開地址線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

