宿主挂载磁盘镜像——在 Linux Windows macOS 上把 Bochs 磁盘当本地文件系统读写
为什么要挂载磁盘
OS 开发过程中经常需要在宿主操作系统和 Bochs 模拟的磁盘之间交换文件:
- 把编译好的内核二进制写到 Bochs 的磁盘里
- 把 Bochs 模拟环境里生成的日志拷回宿主查看
- 在 Bochs 外面对磁盘分区、格式化
最干净的方式是直接在宿主挂载 Bochs 的磁盘镜像。
Linux:losetup + mount
flat 磁盘
# 1. 找到一个空闲的 loop 设备
sudo losetup -f # 通常返回 /dev/loop0
# 2. 挂载 flat 磁盘到 loop 设备
sudo losetup /dev/loop0 hd60M.img
# 3. 查看分区表(可选)
sudo fdisk -l /dev/loop0
# 4. 挂载分区
sudo mount /dev/loop0p1 /mnt/bochs-disk # 如果有分区表
# 或者直接挂载整个磁盘(如果没有分区表,如 OS 开发的纯引导扇区)
sudo mount -o loop hd60M.img /mnt/bochs-disk
sparse / VMDK / VHDX 格式
这些格式带元数据,losetup 不能直接挂。用 qemu-img 先转 flat:
qemu-img convert -O raw sparse.img flat.img
sudo mount -o loop flat.img /mnt/bochs-disk
或者用 nbd(Network Block Device)方式:
sudo modprobe nbd max_part=8
qemu-nbd --connect=/dev/nbd0 sparse.img
sudo mount /dev/nbd0p1 /mnt/bochs-disk
卸载
sudo umount /mnt/bochs-disk
sudo losetup -d /dev/loop0 # 释放 loop 设备
注意:mount 之前确保 Bochs 没有在用这个磁盘——同时读写同一块数据会损坏文件系统。
Windows:OSFMount 或 PowerShell
OSFMount(推荐)
OSFMount 是免费工具,专门用来挂载磁盘镜像:
- 下载安装 OSFMount
- 运行 → Mount new virtual disk
- 选择 flat 磁盘文件
- 选择 Mount point(如 Z: 盘)
- 磁盘会出现在资源管理器里,读写就像本地盘
PowerShell(Windows 10+)
# 挂载 VHDX
Mount-DiskImage -ImagePath "C:\path\to\disk.vhdx" -PassThru
# 挂载完成后磁盘在磁盘管理工具里可以看到,手动分配盘符
# 或者用 qemu-img 先转 VHDX 再用 PowerShell 挂载
直接编辑(OS 开发场景)
如果你的磁盘里只有引导扇区(还没分区),用 HxD 直接编辑:
- 打开 HxD
- File → Open → 选 flat 磁盘文件
- 在偏移 0x00000000 处可以直接写入引导代码
- Save
HxD 会以十六进制方式显示整个磁盘内容——OS 开发者常用它快速修改引导扇区。
macOS:hdiutil
macOS 对原始磁盘的支持不如 Linux 方便。最简单的方式是用 hdiutil 转成 UDIF:
# 如果磁盘有分区表,hdiutil 能自动挂载
hdiutil attach hd60M.img
# 卸载
hdiutil detach /dev/disk2
如果失败(raw 格式不被识别),用 qemu-img 先转:
qemu-img convert -O vhd flat.img vhd.vhd
# 然后用 VirtualBox 挂载或直接 hdiutil
只读挂载 vs 读写挂载
默认 mount 是读写。如果只是想查看 Bochs 磁盘里的内容而不想意外修改:
# Linux 只读挂载
sudo mount -o loop,ro hd60M.img /mnt/bochs-disk
# OSFMount 勾选 Read-only
只读挂载的好处是——即使 Bochs 还在运行,宿主也不会破坏数据(只读访问不会触发写)。
OS 开发场景:写入内核到磁盘
典型流程:
# 1. 编译内核
nasm -f bin kernel.s -o kernel.bin
gcc -ffreestanding -c main.c -o main.o
# ... 链接得到 kernel.img
# 2. 挂载 flat 磁盘
sudo losetup /dev/loop0 hd60M.img
sudo mount /dev/loop0p1 /mnt/disk
# 3. 复制内核
cp kernel.img /mnt/disk/
# 4. 卸载
sudo umount /mnt/disk
sudo losetup -d /dev/loop0
# 5. 启动 Bochs 测试
bochsdbg -f bochsrc
这比在 Bochs 里用调试器逐字节写高效得多——尤其是内核有几十 KB 大小时。
常见挂载问题
mount 报 "wrong fs type, bad option, bad superblock"
磁盘文件系统 mount 不识别——可能是:
- flat 磁盘没有分区表(整个磁盘就是引导扇区),直接 mount 文件本身(不要 mount /dev/loop0)
- 文件系统太老(如 FAT12/FAT16),检查内核是否启用了对应的模块
- flat 磁盘文件损坏,用 HxD 检查引导扇区的
0x55AA签名
Windows 上 mount 后文件显示不全
OSFMount 有时只能读到文件系统里的部分文件——这通常是分区表读取问题。用 fdisk 重新扫一下。
不能同时被 Bochs 和宿主挂载
绝对不要同时。mount 会让 Linux 内核缓存文件系统元数据,Bochs 在另一进程里修改磁盘会让宿主的缓存失效,导致文件系统损坏。如果必须交换文件:
- Bochs 里先 sync 一下(或直接关机 Bochs)
- 宿主挂载、操作
- 宿主卸载
- 再启动 Bochs