为了理解操作系统的工作原理,我已经制作了一个simpel引导加载程序,它可以加载一个小的测试应用程序来测试保护模式等。在0x7c00加载bootsector后,引导加载程序在段0x2000加载测试代码并启动第一个指令。但是当我尝试进入保护模式时,系统会重新启动。任何人都可以帮我解决这个问题吗?
这是我在0x2000部分的代码
BITS 16
; Entering_ProtectedMode:
cli
mov ax, 2000h
mov ss, ax
mov sp, 0FFFFh
sti
cld
mov ax, 2000h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;xor ax, ax
;mov ds, ax ; update data segment
cli ; clear interrupts
lgdt [gdtr] ; load GDT from GDTR (see gdt_32.inc)
call OpenA20Gate ; open the A20 gate
call EnablePMode ; jumps to ProtectedMode
OpenA20Gate:
in al, 0x93 ; switch A20 gate via fast A20 port 92
or al, 2 ; set A20 Gate bit 1
and al, ~1 ; clear INIT_NOW bit
out 0x92, al
ret
EnablePMode:
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG : ProtectedMode
;*********************************
;* Global Descriptor Table (GDT) *
;*********************************
NULL_DESC:
dd 0 ; null descriptor
dd 0
CODE_DESC:
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
DATA_DESC:
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
gdtr:
dw gdtr - NULL_DESC - 1 ; length of GDT
dd NULL_DESC ; base of GDT
CODE_SEG equ CODE_DESC - NULL_DESC
DATA_SEG equ DATA_DESC - NULL_DESC
;******************
;* Protected Mode *
;******************
BITS 32
ProtectedMode:
.halt:
jmp .halt
;mov ax, 10h
;mov ds, ax ; update data segment
答案 0 :(得分:1)
试试这个:
OpenA20Gate:
in al, 0x92; instead of 0x93; switch A20 gate via fast A20 port 92
or al, 2 ; set A20 Gate bit 1
and al, ~1 ; clear INIT_NOW bit
out 0x92, al
ret
EnablePMode:
mov eax, cr0
or eax, 1
mov cr0, eax
...
; CODE_SEG必须等于8,如“8:ProtectedMode”。在GDT的第一个描述符处有8个点。 16位:15-3 - GDT中的索引(0表示零描述符,1表示第一个描述符 - 代码,2表示第二个描述符 - 数据),2 - 表指示符(0表示GDT,1表示LDT ),1-0 - RPL(请求权限级别)。
jmp CODE_SEG:ProtectedMode