无法从16位进入32位模式

时间:2018-06-19 06:45:11

标签: assembly x86 nasm qemu protected-mode

我正在尝试创建一个以32位模式加载内核的简单引导加载程序。我阅读了很多文章和论坛,并编写了一个512字节的bootsector,然后是一个bootloader stage2。在第2阶段,我可以加载gdt,A20,保护模式。但是当我跳到32位模式时,它无法在qemu中运行。我用不同的文件多次检查了我的代码。 现在我不知道我的代码有错误或qemu运行不正常。 我在bootloader stage2中的所有代码:(我的汇编程序是NASM)

bits 16
org 0x0
;-----------------------------------
jmp short main
; give the descriptor offsets names
%define NULL_DESC 0
%define CODE_DESC 0x8
%define DATA_DESC 0x10
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;---------------main---------------
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
main:
;------------------------------------setup segments and stack
cli     
;set up our segment registers to point to the segment in which we were         loaded – 2000    
mov ax, 2000h
mov ds, ax
mov es, ax
;setup stack in 9000
mov ax, 0x9000                  ; stack begins at 0x9000-0xffff
mov ss, ax
mov sp, 0xFFFF
sti                             ; Restore interrupts
cld                             ; The default direction for string operations will be 'up' - incrementing address in RAM
;------------------------------------install gdt
call InstallGDT
;------------------------------------enable A20 line
cli
push ax
mov al, 0xdd    ; send enable a20 address line command to controller
out 0x64, al
pop ax
;mov ax, 0x2401
;int 0x15
;mov ax, 0x3
;int 0x10
;------------------------------------enter to protected mode
cli
mov eax, cr0
or eax,0x1
mov cr0, eax
jmp CODE_DESC:BEGIN_PROTECTED_MODE

;------------------------------------halt the system
;cli
jmp $
;hlt


InstallGDT:
cli                             ; clear interrupts
pusha                           ; save registers
lgdt    [gdt_descriptor]        ; load GDT into GDTR
sti                             ; enable interrupts
popa                            ; restore registers
;-----------------------------------------------
gdt_data: 
dd 0                            ; null descriptor
dd 0 
; gdt code:             ; code descriptor
dw 0FFFFh           ; limit low
dw 0                ; base low
db 0                ; base middle
db 10011010b        ; access
db 11001111b        ; granularity
db 0                ; base high
; gdt data:             ; data descriptor
dw 0FFFFh           ; limit low (Same as code)10:56 AM 7/8/2007
dw 0                ; base low
db 0                ; base middle
db 10010010b        ; access
db 11001111b        ; granularity
db 0                ; base high
end_of_gdt:

; GDT descriptor
gdt_descriptor:
dw end_of_gdt - gdt_data - 1    ; limit (Size of GDT)
dd gdt_data                     ; base of GDT
;******************************************************
;   ENTRY POINT FOR 32 bits mode
;******************************************************
bits 32
BEGIN_PROTECTED_MODE:               ; after the switch we will get here
;Set registers  
  mov ax,DATA_DESC  
  mov ds, ax
  mov es, ax
 ;mov fs, ax
 ;mov gs, ax
 mov ss, ax
 mov esp,0x90000                    ; stack begins from 90000h
    ;cli
    ;hlt
;print a string
 mov esi,MSG_PROT_MODE
 mov ebx,0xb8000
.loop:
  lodsb
  or al,al
  jz halt
  or eax,0x0100
  mov word [ebx], ax
  add ebx,2
  jmp .loop
halt:
  cli
  hlt

MSG_PROT_MODE db "Loaded 32-bit protected mode", 0

0 个答案:

没有答案