bochs 中文文档 下载 App

创建 flat 格式磁盘——OS 开发最常用的镜像格式手把手

flat 格式是什么

flat 格式是最简单的磁盘镜像——就是一个线性的二进制文件,没有头部、没有元数据、没有描述信息。文件大小 = 磁盘容量,文件的第 N 字节就是磁盘的第 N 字节。

这种"极致简单"带来的代价是:没有元数据就不知道 C/H/S 几何参数——Bochs 无法自动推断,必须在 bochsrc 里手动指定 cylinders / heads / spt。

创建步骤

第一步:用 bximage 创建

bximage -q -create -mode flat -size 60M -filename hd60M.img

输出(关键是 CHS 三参数):

CHS=121/16/63  (cylinders/heads/sectors)
total sectors = 122208

第二步:把 CHS 抄到 bochsrc

ata0-master: type=disk, path="hd60M.img", mode=flat, cylinders=121, heads=16, spt=63

第三步:可选——写入引导扇区

OS 开发需要在磁盘首扇区写入 Bootloader。有两种方式:

方式 A:用 dd 写入

Linux/macOS:

dd if=bootloader.bin of=hd60M.img bs=512 count=1 conv=notrunc

Windows 上可以用 HxD、OSFMount 或在 Bochs 里用调试器写。

方式 B:在 bochsdbg 里用调试器写入

bochs:1> w /512bx 0x7c00 0x00    # 先清空
bochs:2> # 或者直接用 asm / db 命令汇编引导代码进去

对于 512 字节的 Bootloader,直接在调试器里逐字节写也是可行的——MIT 6.828 就这么教。

flat 磁盘的容量和 CHS 关系

总扇区数计算公式:

总扇区数 = cylinders × heads × spt

bximage 输出总扇区数和 CHS 值,两者应该相等或接近。如果 bximage 输出的 CHS 和你抄的 bochsrc 对不上,BIOS 枚举磁盘后报告的容量会和真实容量有差异。

标准 CHS 参数速查:

磁盘大小cylindersheadsspt总扇区数
10 MB30641720808
20 MB61241741616
30 MB61561762730
40 MB97751783045
60 MB1211663122208
80 MB1621663163296
100 MB104016631048320
1 GB521255638384385

也可以算:文件大小(字节)÷ 512 = 总扇区数。然后找一组合理的 CHS(让乘积最接近总扇区数且不超过)。

flat 磁盘可以被其他工具读写

因为 flat 格式就是原始数据,任何能读块设备的工具都能直接读写它:

这是 flat 格式最大的优势——没有任何锁定或专有格式,想怎么处理就怎么处理。

常见问题

bochsrc 忘记写 C/H/S

Bochs 会报:

ata0-0: cannot have zero cylinders, heads, or sectors/tracks

原因:flat 格式无法自动推断几何参数。加上就行:

ata0-master: type=disk, path="hd60M.img", mode=flat, cylinders=121, heads=16, spt=63

dd 写入后磁盘文件缩小了

dd 默认会截断输出文件(of=hd60M.img 时)。加 conv=notrunc 就能防止:

dd if=bootloader.bin of=hd60M.img bs=512 count=1 conv=notrunc

flat 磁盘文件大小必须和 bochsrc 里的 C/H/S 匹配——文件缩小了,BIOS 报告的磁盘就会比实际小。

想用 flat 磁盘但不想手动算 C/H/S

改用 sparse 格式——它带元数据能自动推断:

bximage -q -create -mode sparse -size 60M -filename hd60M.img
# bochsrc 里不需要写 C/H/S
ata0-master: type=disk, path="hd60M.img", mode=sparse

但 OS 开发场景建议坚持 flat——学习价值更大(你必须理解 BIOS 枚举磁盘的整个过程)。