[英]Bootloader won't load the kernel
我實際上制作了一個包含兩個階段的引導加載程序,因為我使用 VESA BIOS 擴展(需要超過 512 個字節)將視頻模式設置為 1920px*1080px。
現在我正在嘗試調用我自己的 kernel 來開始繪制像素等。但它沒有用。
我的引導加載程序基於 Michael Petch 的代碼,來自這個問題的答案
引導加載程序.asm:
%include "stage2info.inc"
STAGE2_LOAD_SEG equ STAGE2_ABS_ADDR >> 4
STAGE2_LBA_START equ 1
STAGE2_LBA_END equ STAGE2_LBA_START + NUM_STAGE2_SECTORS
[BITS 16]
[ORG 0x7c00]
%include "BPB.inc"
%include "error.asm"
bootloader_main:
xor ax, ax
mov ds, ax
mov ss, ax
mov sp, 0x7c00
cld
load_stage2:
mov [bootDevice], dl
mov di, STAGE2_LOAD_SEG
mov si, STAGE2_LBA_START
jmp check_for_last_lba
read_sector:
call lba_to_chs
mov es, di
xor bx, bx
retry:
mov ax, 0201h
int 13h
jc disk_error
success:
add di, 512>>4
inc si
check_for_last_lba:
cmp si, STAGE2_LBA_END
jl read_sector
stage2_loaded:
mov ax, STAGE2_RUN_SEG
mov ds, ax
mov es, ax
jmp STAGE2_RUN_SEG:STAGE2_RUN_OFS
lba_to_chs:
push ax
mov ax, si
xor dx, dx
div word[sectorsPerTrack]
mov cl, dl
inc cl
xor dx, dx
div word[numHeads]
mov dh, dl
mov dl, [bootDevice]
mov ch, al
shl ah, 6
or cl, ah
pop ax
ret
bootDevice: db 0x00
times 510 - ($-$$) db 0
DW 0xAA55
NUM_STAGE2_SECTORS equ (stage2_end - stage2_start + 511) / 512
stage2_start:
incbin "stage2.bin"
stage2_end:
階段2.asm:
%include "stage2info.inc"
[BITS 16]
[ORG STAGE2_RUN_OFS]
start:
;graphics stuff here...
call load_kernel
cli
lgdt[gdt_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x8:kernel_entry
[BITS 32]
kernel_entry:
mov ax, 0x10
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000
mov esp, ebp
call KERNEL_OFFSET
jmp $
[BITS 16]
load_kernel:
mov bx, KERNEL_OFFSET
mov dh, 15
mov dl, 0
mov ah, 0x02
mov al, dh
mov ch, 0x00
mov dh, 0x00
mov cl, 0x02
int 0x13
ret
GDT:
dq 0
dw 0xFFFFF
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
dw 0xFFFFF
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_descriptor :
dw $ - GDT - 1
dd GDT
incbin "../kernel/kernel.bin"
VESAInfo db 'VBE3'
times 508 db 0
MODEInfo times 256 db 0
ModeInfoBlock times 256 db 0
KERNEL_OFFSET equ 0x1000
%include "error.asm"
stage2info.asm:
STAGE2_ABS_ADDR equ 0x07e00
STAGE2_RUN_SEG equ 0x0000
STAGE2_RUN_OFS equ STAGE2_ABS_ADDR
kernel.asm:
[bits 32]
jmp $
我構建的圖像如下:
#!/bin/bash
nasm -f bin stage2.asm -o stage2.bin
nasm -f bin ../kernel/kernel.asm -o ../kernel/kernel.bin
nasm -f bin bootloader.asm -o bootloader.bin
dd if=/dev/zero of=disk.img bs=512 count=2880
dd if=bootloader.bin of=disk.img conv=notrunc
qemu-system-i386 -fda disk.img -boot a
知道為什么它不起作用嗎?
該問題通過進入保護模式並包含kernel.asm
文件而不是二進制文件來解決。
方法如下(stage2.asm):
%include "stage2info.inc"
[BITS 16]
[ORG STAGE2_RUN_OFS]
start:
pusha
mov ah, 0x00
mov al, 0x03
int 10h
popa
mov ax, 4F00h
mov di, VESAInfo
int 10h
cmp al, 4Fh
jne VBE_error
mov si, [VESAInfo + 0Eh]
loop:
mov ax, [VESAInfo + 10h]
mov es, ax
mov dx, word[es:si]
cmp dx, 0FFFFh
je got_mode
add si, 2
mov cx, dx
mov ax, 4F01h
mov di, MODEInfo
int 10h
cmp al, 4Fh
jne loop
mov ax, word[MODEInfo]
bt ax, 0
jnc loop
bt ax, 4
jnc loop
bt ax, 7
jnc loop
mov ax, word[MODEInfo + 12h]
cmp ax, 1920
jne loop
mov ax, word[MODEInfo + 14h]
cmp ax, 1080
jne loop
xor ax, ax
mov al, byte[MODEInfo + 19h]
cmp ax, 24
jne loop
got_mode:
mov ax, 4F01h
mov cx, dx
mov di, ModeInfoBlock
int 10h
cmp ax, 4Fh
jne VBE_error
mov ax, 4F02h
mov bx, dx
int 10h
cmp ax, 4Fh
jne VBE_error
cli
lgdt [gdt_descriptor] ;Load the global descriptor table
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x8:prepare_segments ;prepare segments
prepare_segments:
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp kernel ;jump to the kernel in kernel.asm!
GDT:
dq 0
dw 0xFFFFF
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
dw 0xFFFFF
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_descriptor :
dw $ - GDT - 1
dd GDT
[BITS 32]
;We're already in the protected mode here!
%include "../kernel/kernel.asm" ;include the kernel
[BITS 16]
VESAInfo db 'VBE3'
times 508 db 0
MODEInfo times 256 db 0
%include "ModeInfoBlock.asm"
KERNEL_OFFSET equ 0x1000
%include "error.asm"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.