2015-04-25 115 views
1

对于理解操作系统的工作我已经做它加载一个小的测试程序进行测试保护模式等的启动扇区已在0x7c00被加载后,引导加载器加载测试代码在段为0x2000一个simpel引导程序并开始第一条指令。但是,当我尝试进入保护模式时,系统将重新启动。任何人都可以帮我解决这个问题吗?进入保护模式重新启动

这是我的部分代码为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 

回答

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 
相关问题