启动失败排查——"not a bootable disk" 和 "could not read the boot disk"
典型错误信息
Booting from Floppy...
Boot failed: could not read the boot disk
或者:
Booting from Hard Disk...
Boot failed: not a bootable disk
四步排查清单
第一步:引导扇区签名(最常见)
BIOS 判定磁盘"可引导"的唯一标准:引导扇区(首扇区)最后两个字节(偏移 0x1FE, 0x1FF)是不是 0x55 0xAA。
Bochs 调试器里检查:
bochs:1> c # 让 BIOS 跑起来(BIOS 会尝试读引导扇区)
bochs:2> Ctrl+C # 中断
# 软盘场景:
bochs:3> xp /2bx 0x7dfe # 物理地址 0x7c00 + 510 = 0x7dfe
# 硬盘场景(BIOS 把硬盘引导扇区也加载到 0x7c00):
bochs:3> xp /2bx 0x7dfe
如果看到:
0x00007dfe: 55 aa
✅ 签名正确。继续第二步。
如果看到其他值(全 0 或乱码):
- OS 开发:Bootloader.bin 写入软盘/硬盘时,最后两字节没写 0x55AA。在汇编源码里确保有:
; 引导扇区最后两字节
times 510-($-$$) db 0 ; 填充到 510 字节
dw 0xAA55 ; 注意是小端!写入内存是 55 AA
- 经典系统(Win95/XP):安装没完成、或者用的不是可引导的 ISO——确认 ISO 是官方安装盘(带 boot 标志),不是普通数据盘。
第二步:boot: 关键字和设备匹配
bochsrc 里 boot: 指定了启动顺序,但如果你顺序里的设备根本没配置,BIOS 自然找不到。
# 问题:boot: disk 但没配 ata0-master
boot: disk
# bochsrc 里没有 ata0-master: ...
# 解决:要么加 ata0-master,要么改 boot:
boot: floppy # 或者改成 boot: none(不让它尝试引导)
还有一种陷阱:boot: floppy, disk 但只配了 disk,没配 floppyA。BIOS 会先试 floppy(失败),然后试 disk——应该能成功。但某些 BIOS 实现可能在 floppy 上卡一下才继续。
第三步:flat 磁盘 C/H/S 参数
flat 格式磁盘必须手动指定 cylinders / heads / spt。如果这些参数写错了,BIOS 报告的磁盘大小会和真实文件大小不符——某些 BIOS 实现可能因为"参数不可信"而拒绝使用这个磁盘。
检查方法:
- 用 bximage 重新创建(或只打印参数):
bximage -q -create -mode flat -size 60M -filename test.img
# 输出里有 CHS=121/16/63
- 对比 bochsrc 里写的 C/H/S 和 bximage 输出是不是完全一样
- 文件大小 ÷ 512 = 总扇区数;C × H × S 应该等于这个数(允许 ±1~3 误差)
如果参数确实配错了:重新用 bximage 创建磁盘 + 正确的 CHS,然后重做磁盘内容(OS 开发要重写 Bootloader,经典系统要重装)。
第四步:磁盘镜像文件本身损坏
flat 磁盘就是一个普通文件——会不会不小心被宿主机工具截断了?或者写入 Bootloader 时用 dd 但没加 conv=notrunc?
# 错误(会截断文件!)
dd if=bootloader.bin of=hd60M.img bs=512 count=1
# 正确
dd if=bootloader.bin of=hd60M.img bs=512 count=1 conv=notrunc
检查方法:文件大小。flat 磁盘的文件大小应该等于 C × H × S × 512。如果比这个小,就是被截断了——删掉重建。
常见场景的启动失败
场景一:OS 开发——新建了软盘但 Bootloader 没写 0x55AA
bochsrc: floppyA: type=1_44, path="boot.img", status=inserted
bochsrc: boot: floppy
启动 Bochs → Boot failed: could not read the boot disk。
检查:bochsdbg → xp /2bx 0x7dfe → 00 00(签名缺失)
修复:Bootloader 汇编源码末尾加 dw 0xAA55,重新汇编,用 dd conv=notrunc 写入软盘。
场景二:经典系统——Win98 安装完重启后还是进入 Setup
bochsrc: boot: cdrom, floppy, disk
Win98 安装完重启,因为安装盘还在光驱里,BIOS 先试光盘 → 又进入 Setup。
解决:把 bochsrc 里 ata1-master 的 status 改成 ejected,或者直接注释掉,或者改 boot 顺序把 disk 放第一位。
场景三:Linux——Kernel panic not syncing: VFS: Unable to mount root fs
这个不是 Bochs 问题——是 Linux Kernel 找不到根文件系统。原因:
- root=/dev/sda1 参数没传(如果用自定义 Bootloader)
- initrd 没指定或 initramfs 里的 /init 脚本有问题
- 内核没编译进对应磁盘控制器驱动
Bochs 里可以通过在 Kernel 命令行里加 root 参数解决。
场景四:Windows——NTLDR is missing
NT 系列(XP、2000)引导链是 NTLDR → boot.ini → ntoskrnl。
- NTLDR 文件在 C 盘根目录(FAT32 或 NTFS)
- 如果 flat 磁盘的分区表没写对,NTLDR 会在错误的物理位置
- 快速修复:用 Win98 引导盘(或 FreeDOS)引导后执行
sys C:把系统引导文件重新写入
引导失败时用调试器看 BIOS 行为
bochsdbg 里追踪 BIOS 尝试引导磁盘的过程:
bochs:1> pb 0x7c00 # BIOS 把引导扇区加载到这里后会跳转
bochs:2> c # 让 BIOS 跑起来
# 如果断点触发 → 引导扇区加载成功,只是扇区里内容不对
# 如果断点一直不触发 → BIOS 根本没从那个设备读到扇区
bochs:3> Ctrl+C
bochs:4> # 用 xp 看物理内存 0x7c00 处有没有被加载东西
bochs:5> xp /512bx 0x7c00
如果 0x7c00 全是 0 → BIOS 没读到任何数据。检查磁盘设备配置(ata0-master 或 floppyA)、status=inserted、path 指向的文件是否真的存在。
如果 0x7c00 有数据但末尾不是 0x55AA → 磁盘里的第一个扇区不是引导扇区。对于 OS 开发,说明 Bootloader 写入没成功;对于经典系统,说明安装盘 ISO 有问题或者没写对分区表。