BIOS 镜像缺失与 BIOS-bochs-latest 找不到
典型报错
bochs: bochs can't find ROM image: BIOS-bochs-latest
或者启动后 bochsdbg 停住,Ctrl+C 后 info cr 显示 EIP 在 0(BIOS 根本没加载)。
原因定位
BIOS 加载失败只有三种可能:
- bochsrc 里
romimage:行的文件路径根本找不到(最高频) - bochsrc 里
romimage:行被语法错误吞掉了(整个 romimage 行没被解析) - address 参数和 BIOS 镜像大小不匹配(BIOS 确实加载了,但加载到了错误地址)
逐项检查
检查一:bochsrc 里 romimage 行是不是被正确解析
在 bochsdbg 里跑 show config,找 ROM image 相关输出:
bochs:1> show config
...
ROM image: BIOS-bochs-latest (address=0xfffc0000)
...
如果这行显示:
ROM image: (none)→ romimage 行根本没被解析(bochsrc 语法错误或行被跳过)- 路径和你写的不一样 → bochsrc 里可能有多个 romimage 行,后一个覆盖了前一个
- address 不是你期望的值 → bochsrc 自动推断了不同的值(通常 bochsrc 会自动推断,除非你手动指定了 address)
检查二:路径拼写和分隔符
Windows 上反斜杠 \ 是 bochsrc 里的转义符。如果你写了:
romimage: file=C:\Program Files\Bochs-3.1\BIOS-bochs-latest
bochsrc 会把 \P 当转义符处理(某些转义序列如 \n、\t、\r 有特殊含义,其他被丢弃)。结果就是 Bochs 在一个乱码路径里找 BIOS——找不到。
修复:一律用正斜杠 /
romimage: file=C:/Program Files/Bochs-3.1/BIOS-bochs-latest
或者如果 bochsrc 本身就在 Bochs 安装目录下,用相对路径更安全:
romimage: file=BIOS-bochs-latest
检查三:BIOS 镜像文件是否真的存在
在 Bochs 安装目录里找(默认 C:\Program Files\Bochs-3.1\):
BIOS-bochs-latest ← 128KB,最常用
BIOS-bochs-legacy ← 64KB,旧版
如果安装目录里没有 BIOS-bochs-latest:
- 安装时选的是 Minimal(最小)类型,没装全?重新安装时选 Typical 或 Full
- 或者你用的 bochsrc 来自某个教程,教程里假设了 BIOS 文件在当前目录(你需要把 BIOS 复制到 bochsrc 同目录)
- 或者你编译了 Bochs 但没 make install——BIOS 文件通常在
bios/子目录里
检查四:address 参数和 BIOS 大小
Bochs 官方两种 BIOS 的大小和加载地址:
| BIOS 文件 | 大小 | 默认 address |
|---|---|---|
BIOS-bochs-latest | 128KB | 0xfffc0000(128KB × 1024 = 131072;0xffffffff - 131072 + 1 = 0xfffc0000) |
BIOS-bochs-legacy | 64KB | 0xfffe0000 |
如果你用了 128KB BIOS 但 bochsrc 里手动写了 64KB 的 address:
romimage: file=BIOS-bochs-latest, address=0xfffe0000
BIOS 会加载到错误位置,执行时跳转到错误地址→ crash → 黑屏。
最简单:不写 address
romimage: file=BIOS-bochs-latest
bochsrc 会根据 BIOS 文件大小自动推断正确的 address。只有你需要强制指定时才手动写(比如用自定义 BIOS 或 OVMF)。
检查五:UTF-8 BOM 导致的解析问题
bochsrc 文件如果有 UTF-8 BOM(EF BB BF),第一行关键字前会多出三个字节。PowerShell 默认的 Set-Content -Encoding UTF8 就会加 BOM。
检查方法:用十六进制编辑器(HxD)打开 bochsrc,看前三个字节是不是 EF BB BF。如果是,去掉。
修复:
- VS Code:保存时选 "UTF-8"(不是 "UTF-8 with BOM")
- Notepad++:编码 → 转换为 UTF-8(无 BOM)
- PowerShell:
Set-Content -Encoding ascii
检查六:bochsrc 多行 romimage 被覆盖
bochsrc 里如果出现多个 romimage 行,后一个覆盖前一个:
romimage: file=BIOS-bochs-latest # 被后面的覆盖
vgaromimage: file=VGABIOS-lgpl-latest.bin
romimage: file=C:/custom-bios.bin # 实际生效的是这个
这本身不是错误——Bochs 支持覆盖默认配置。但如果你不小心在 bochsrc 里留了两行 romimage(比如先写了默认然后又改了一个,忘了删旧的),可能导致最终生效的不是你期望的那个。
OVMF(UEFI BIOS)的特殊情况
如果你用的不是 Bochs 自带 BIOS 而是 TianoCore 的 OVMF(支持 UEFI 引导):
romimage: file=OVMF_CODE.fd, address=0xfff80000
OVMF 体积比 Bochs 自带 BIOS 大得多(通常 1~5MB),加载地址也不同。确保 address 和 OVMF 大小匹配——或者干脆不写让 Bochs 自动推断。
还需要在 bochsrc 里开 fw_cfg 设备:
fw_cfg: enabled=1
没有 fw_cfg 的话 UEFI 固件无法读取配置信息,会启动失败。
BIOS 加载成功后怎么验证
bochsdbg 里 BIOS 加载到内存后:
bochs:1> xp /16bx 0xfffc0000 # 128KB BIOS 的起始地址
# 应该能看到非零数据(BIOS 代码),不是全 0
如果全 0 → BIOS 没被加载 → 回到上面的检查二/三/四。
如果有非零数据但 bochsrc 里 show config 显示地址不对 → bochsrc 里 romimage address 参数写错了。