ROM 与 VGA BIOS 镜像——没有 BIOS 机器点不亮
ROM BIOS 是 Bochs 的"固件"
在真实 PC 上,ROM BIOS 是硬件上电后第一个运行的代码——它做开机自检(POST)、枚举硬件、加载引导扇区、把控制权交给操作系统。Bochs 模拟了一个完整的 PC 硬件,自然也需要一份"ROM BIOS"镜像来扮演这个角色。
bochsrc 里的 romimage: 关键字就是告诉 Bochs:加载哪份 BIOS 镜像、加载到内存哪个地址。
Bochs 自带的 BIOS 镜像
官方二进制包(或编译源码)自带一份开源的 ROM BIOS:
| 文件 | 大小 | 加载地址 | 说明 |
|---|---|---|---|
BIOS-bochs-latest | 128 KB | 0xfffc0000 | 64KB + 扩展,覆盖经典 PC 和现代特性 |
BIOS-bochs-legacy | 64 KB | 0xfffe0000 | 传统 64KB,更接近老机器 |
常用的是 BIOS-bochs-latest。配置:
romimage: file=BIOS-bochs-latest, address=0xfffc0000
如果只写 file 不写 address,Bochs 会自动推断。但显式写出来更好——某些老 BIOS(64KB)必须用 0xfffe0000,128KB 的必须用 0xfffc0000,写反了 Bochs 会在启动时 panic。
VGA BIOS:让屏幕亮起来
ROM BIOS 做硬件初始化,但不负责显示——显示是显卡的事。VGA BIOS 是显卡 ROM 里的代码,负责初始化 VGA 硬件、设置显示模式。
bochsrc 里 vgaromimage: 指定 VGA BIOS:
vgaromimage: file=VGABIOS-lgpl-latest.bin
Bochs 安装包通常提供这些 VGA BIOS:
| 文件 | 对应 VGA 型号 | 适用场景 |
|---|---|---|
VGABIOS-lgpl-latest.bin | Bochs 自带 VGA | 默认通用 |
VGABIOS-lgpl-latest-cirrus.bin | Cirrus Logic GD5446 | bochsrc 里 vga: extension=cirrus 时用 |
VGABIOS-elpin-2.40 | 老版本 | 兼容性测试 |
注意:vgaromimage 和 bochsrc 里 vga: 关键字的 VGA 型号必须匹配——如果 bochsrc 写了 vga: extension=cirrus,但 vgaromimage 用了默认的,显示可能不正常(花屏或无法进入图形模式)。
用 OVMF 替代:UEFI 启动
现代 PC 用 UEFI 替代了传统 BIOS。Bochs 也支持 UEFI 启动,通过加载 TianoCore EDK2 项目的 OVMF(Open Virtual Machine Firmware)镜像:
romimage: file=OVMF_CODE.fd, address=0xfff80000
bochsrc 还需要启用 fw_cfg 设备(UEFI 固件通过它读取系统配置):
fw_cfg: enabled=1
UEFI 启动要求固件镜像 + fw_cfg + (可选)安全引导(Secure Boot)相关镜像。OS 开发者在做 UEFI 相关的实验时,这是必要配置。
BIOS 镜像缺失的报错
如果 bochsrc 里 romimage 的路径写错了,或者根本没写,Bochs 会在启动时直接报:
bochs: BIOS image BIOS-bochs-latest not found
解决方法:检查路径是否正确,尤其是:
- 路径里的
\是否写成了\\(Windows) - BIOS 镜像文件是否真的存在于指定位置(在安装目录里找)
- address 是否正确
VGA BIOS 缺失时 Bochs 不会立即 panic——它会报 vgabios not found 然后默认用最小显示模式,但屏幕可能黑屏。建议始终显式指定。
地址参数怎么选
BIOS 加载地址取决于 BIOS 镜像的大小:
| BIOS 大小 | 加载地址 | bochsrc address 值 |
|---|---|---|
| 64 KB | 0xfe0000 ~ 0xfffff | 0xfffe0000(32 位物理地址空间顶部) |
| 128 KB | 0xfc0000 ~ 0xfffff | 0xfffc0000 |
| 256 KB | 0xf80000 ~ 0xfffff | 0xfff80000 |
物理地址空间的顶部是 BIOS 区域——这个范围是 PC 硬件约定的,Boards 模拟时遵守这个约定。OS 开发者需要记住这些地址,因为早期代码里经常要"自己搬 ROM BIOS 到内存低位做 shadow BIOS",或在内存扫描时识别 BIOS 区域。