内核加载后无法执行:自定义OS在QEMU中的启动故障求助
自定义OS内核无法执行问题排查与解决
问题现象
自定义开发的OS出现异常:Bootloader已完成内核加载,但内核无法执行。制作软盘镜像后在VirtualBox中可正常运行,但在QEMU中始终卡在Bootloader执行阶段,无法进入内核。
排查尝试
- 修改ES:BX跳转地址,问题未解决
- 将QEMU虚拟机内存提升至4GB,无效果
解决方案
通过保存BIOS传入的DL寄存器初始值解决了该问题。BIOS启动时会将启动盘的驱动器编号存入DL寄存器,后续Bootloader的磁盘操作可能依赖这个值,QEMU与VirtualBox在驱动器号处理或寄存器保留上存在差异,未保存该值导致后续操作异常,进而无法正常进入内核。
相关代码片段
Makefile
BUILD_DIR := build SRC_DIR := src BOOTLOADER_SRC := $(SRC_DIR)/bootloader.asm KERNEL_SRC := $(SRC_DIR)/kernel.asm UTILS_SRC := $(SRC_DIR)/utils.asm BOOTLOADER_BIN := $(BUILD_DIR)/bootloader.bin KERNEL_BIN := $(BUILD_DIR)/kernel.bin OS_IMG := $(BUILD_DIR)/os.img all: $(OS_IMG) $(BOOTLOADER_BIN): $(BOOTLOADER_SRC) nasm -f bin $< -o $@ $(KERNEL_BIN): $(KERNEL_SRC) $(UTILS_SRC) nasm -f bin $(KERNEL_SRC) -o $@ $(OS_IMG): $(BOOTLOADER_BIN) $(KERNEL_BIN) dd if=/dev/zero of=$@ bs=512 count=2880 dd if=$(BOOTLOADER_BIN) of=$@ conv=notrunc dd if=$(KERNEL_BIN) of=$@ seek=1 conv=notrunc clean: rm -rf $(BUILD_DIR)
Bootloader汇编(关键修复部分)
org 0x7c00 bits 16 start: mov [boot_drive], dl ; 核心修复:保存BIOS传入的启动盘驱动器号 ; 内核加载逻辑 mov ah, 0x02 mov al, 0x10 mov ch, 0x00 mov dh, 0x00 mov dl, [boot_drive] ; 使用保存的驱动器号执行磁盘读取 mov bx, 0x8000 int 0x13 ; 跳转至内核 jmp 0x8000:0x0000 boot_drive: db 0 times 510-($-$$) db 0 dw 0xaa55
Kernel汇编
org 0x0000 bits 16 kernel_start: mov ah, 0x0e mov al, 'K' int 0x10 jmp $ ; 无限循环验证内核启动
辅助函数汇编示例
bits 16 print_char: mov ah, 0x0e int 0x10 ret
内容的提问来源于stack exchange,提问作者Calin
相关产品推荐
相关产品推荐

