我正在尝试创建一个以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