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

Bootloader功能正常但内核无法执行,求故障排查方案

Bootloader跳转内核失败的排查与修复

问题背景

尝试构建16位实模式下的Bootloader与内核:

  • Bootloader加载地址为0x7C00,功能正常,能打印启动信息
  • 计划将内核加载到0x1000:0000地址,但跳转后内核未执行,QEMU运行仅显示Loading kernel...后停滞
  • 已通过hexdump确认镜像中Bootloader和内核的字节位置正确

核心原因分析

  1. 磁盘镜像生成方式错误:使用cat boot.bin kernel.bin > floppy.img会直接覆盖原本创建的2880扇区软盘镜像,导致镜像仅包含2个扇区。BIOS INT 0x13读盘时依赖磁盘几何参数,这种截断的镜像可能导致读盘逻辑异常。
  2. 内核ORG指令与实际加载地址不匹配:Bootloader将内核加载到0x1000:0000(线性地址0x10000),但内核代码中设置[ORG 0x1000],导致内核中符号的偏移计算错误,实际执行时跳转地址对应的代码不正确。

修复方案

1. 修正内核的ORG设置

修改kernel.asm中的ORG指令,使其匹配加载地址的偏移量:

[BITS 16]             ; 保持16位实模式设置
[ORG 0x0000]         ; 对应0x1000:0000的偏移地址,线性地址为0x1000*16 + 0 = 0x10000

2. 正确生成软盘镜像

避免用cat覆盖镜像,改用dd将Bootloader和内核写入到镜像的指定扇区:

# 1. 创建标准1.44MB软盘镜像(2880个512字节扇区)
dd if=/dev/zero of=floppy.img bs=512 count=2880

# 2. 将Bootloader写入第1扇区(boot.bin大小为512字节)
dd if=boot.bin of=floppy.img bs=512 count=1 conv=notrunc

# 3. 将内核写入第2扇区(seek=1表示跳过1个扇区)
dd if=kernel.bin of=floppy.img bs=512 count=1 seek=1 conv=notrunc

3. 可选:增强Bootloader调试信息

在Bootloader中添加读盘成功的提示,确认内核加载完成:
在jc error指令后添加:

; 打印加载成功信息
mov si, load_success_msg
call print_string

然后在数据段末尾添加:

load_success_msg db 'Kernel loaded successfully!', 0

验证步骤

重新编译并运行:

# 编译Bootloader和内核
nasm -f bin boot.asm -o boot.bin
nasm -f bin kernel.asm -o kernel.bin

# 按上述步骤生成正确的镜像
# 运行QEMU
qemu-system-x86_64 -drive format=raw,file=floppy.img

此时应依次显示:

  • Loading kernel...
  • Kernel loaded successfully!(如果添加了调试信息)
  • Hello from the kernel!
    随后系统进入无限循环,说明内核已成功执行。

内容的提问来源于stack exchange,提问作者Shivpreet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:57:14