【发布时间】:2020-09-10 13:27:05
【问题描述】:
我实际上制作了一个包含两个阶段的引导加载程序,因为我使用 VESA BIOS 扩展(需要超过 512 个字节)将视频模式设置为 1920px*1080px。
现在我正在尝试调用我自己的内核开始绘制像素等。但它没有用。
我的引导加载程序基于 Michael Petch 的代码,来自 question 的答案
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
知道为什么它不起作用吗?
【问题讨论】:
-
那是很多代码。减少到minimal reproducible example。如果您在加载时遇到问题,请删除图形内容和其他所有内容。确保您的 chs 转换是正确的,也许先硬编码这些值。使用调试器(推荐使用 bochs)查看发生了什么。
-
不需要
load_kernel。第一阶段实际上为 stage2 将尽可能多的扇区读入内存。 Stage2 在技术上是内核的一部分。看起来您真正想要做的是创建单独的 asm 文件并将它们与 stage2 链接,而不是包含kernel.bin withincbin`。您将 stage2.asm 组装成一个 elf 对象(使用 -f elf),与 kernel.asm 相同。您可以将它们与 LD 一起链接到 elf 可执行文件,然后将其输出为二进制文件(我使用 objcopy 将 elf 可执行文件转换为二进制文件)。如果有机会,我可以尝试稍后更深入地回答这个问题。 -
你没有包含
error.asm -
@MichaelPetch
error.asm仅包含一些文本打印功能。 -
@MichaelPetch 你能给我举个例子吗?我真的需要这个。
标签: assembly x86 kernel bootloader osdev