Bootloader功能正常但内核无法执行,求故障排查方案
Bootloader跳转内核失败的排查与修复
问题背景
尝试构建16位实模式下的Bootloader与内核:
- Bootloader加载地址为0x7C00,功能正常,能打印启动信息
- 计划将内核加载到0x1000:0000地址,但跳转后内核未执行,QEMU运行仅显示
Loading kernel...后停滞 - 已通过hexdump确认镜像中Bootloader和内核的字节位置正确
核心原因分析
- 磁盘镜像生成方式错误:使用
cat boot.bin kernel.bin > floppy.img会直接覆盖原本创建的2880扇区软盘镜像,导致镜像仅包含2个扇区。BIOS INT 0x13读盘时依赖磁盘几何参数,这种截断的镜像可能导致读盘逻辑异常。 - 内核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
相关产品推荐
相关产品推荐

