簡體   English   中英

引導加載程序不會加載 kernel

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM