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

基于FAT12的自定义Bootloader无法加载第二阶段的问题排查

FAT12 Bootloader Stage2加载失败排查与修复

核心排查方向

1. Stage1磁盘读取逻辑的错误处理缺失

绝大多数加载失败的原因是忽略了int 0x13磁盘中断的返回状态,即使读取失败仍强行跳转至Stage2地址,导致执行空内存代码。

  • 强制在每次int 0x13调用后检查CF标志位:
    int 0x13
    jc disk_read_failure  ; CF置位则跳转到错误分支
    
  • 在disk_read_failure分支添加明确的屏幕输出(比如用int 0x10的0x0e功能打印错误字符),确认是否真的触发了读取失败:
    disk_read_failure:
        mov ah, 0x0e
        mov al, 'F'
        int 0x10
        mov al, 'A'
        int 0x10
        mov al, 'I'
        int 0x10
        mov al, 'L'
        int 0x10
        jmp $  ; 死循环等待
    

2. FAT12参数不匹配

Stage1代码中硬编码的BPB参数必须与镜像构建时的FAT12格式完全一致,否则会导致FAT表/根目录解析错误:

  • 检查代码中的关键参数:
    • 每扇区字节数(通常512)
    • 每簇扇区数(通常1)
    • FAT表个数(通常2)
    • 根目录项数(通常224)
    • 总扇区数(通常2880)
  • 确认镜像构建时用mkfs.fat -F 12的参数与代码一致,比如:
    mkfs.fat -F 12 -n "MYBOOT" -s 1 -r 224 -S 512 boot.img
    

3. Stage2加载地址与org伪指令不匹配

  • 如果Stage2汇编代码开头用了org 0x7e00,Stage1必须将Stage2加载到0x7e00起始的内存地址(Stage1占用0x7c00-0x7dff)
  • 跳转Stage2时必须确保CS:IP指向正确地址,实模式下建议用远跳转明确指定段地址:
    jmp 0x0000:0x7e00  ; 假设DS=0,加载地址为0x7e00
    

4. 镜像构建脚本的正确性

  • 确保Stage1被写入镜像的第一个扇区,且不会被后续操作覆盖:
    dd if=stage1.bin of=boot.img bs=512 count=1 conv=notrunc
    
  • Stage2必须以8.3大写格式写入FAT12镜像,否则Stage1无法找到文件:
    mcopy -i boot.img stage2.bin ::STAGE2.BIN
    
  • 确认镜像大小符合1.44MB软盘规格(2880个512字节扇区):
    dd if=/dev/zero of=boot.img bs=512 count=2880
    

调试技巧

用QEMU+GDB单步调试定位问题:

  1. 启动QEMU并等待调试连接:
    qemu-system-i386 -hda boot.img -s -S
    
  2. 打开GDB连接调试端口:
    gdb -ex "target remote localhost:1234"
    
  3. 在Stage1的磁盘读取、FAT解析、跳转Stage2等关键位置设置断点,查看内存中是否正确加载了Stage2的机器码,以及寄存器状态是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:16:18