bochs 中文文档 下载 App

启动失败排查——"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 或乱码):

  ; 引导扇区最后两字节
  times 510-($-$$) db 0   ; 填充到 510 字节
  dw 0xAA55               ; 注意是小端!写入内存是 55 AA

第二步: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 实现可能因为"参数不可信"而拒绝使用这个磁盘。

检查方法:

  1. 用 bximage 重新创建(或只打印参数):
   bximage -q -create -mode flat -size 60M -filename test.img
   # 输出里有 CHS=121/16/63
  1. 对比 bochsrc 里写的 C/H/S 和 bximage 输出是不是完全一样
  2. 文件大小 ÷ 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 找不到根文件系统。原因:

  1. root=/dev/sda1 参数没传(如果用自定义 Bootloader)
  2. initrd 没指定或 initramfs 里的 /init 脚本有问题
  3. 内核没编译进对应磁盘控制器驱动

Bochs 里可以通过在 Kernel 命令行里加 root 参数解决。

场景四:Windows——NTLDR is missing

NT 系列(XP、2000)引导链是 NTLDR → boot.ini → ntoskrnl。

引导失败时用调试器看 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 有问题或者没写对分区表。