You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内核加载后无法执行:自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:53:11