Bootloader无法加载内核。

问题描述 投票:1回答:1

实际上,我做了一个有两个阶段的bootloader,因为我通过使用VESA BIOS扩展将视频模式设置为1920px*1080px(这需要超过512字节)。现在我试图调用我自己的内核来开始绘制像素等...但它没有工作。我是根据Michael Petch在这个问题的答案中的代码来设计引导程序的。疑问 bootloader.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:

stage2. 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

知道为什么没有用吗?

assembly x86 kernel bootloader osdev
1个回答
1
投票

进入受保护模式,并将问题解决了。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"
© www.soinside.com 2019 - 2024. All rights reserved.