如何在真机测试自制16位汇编OS?是否需要GRUB?
在真实PC上测试16位汇编OS的操作指南(Ubuntu 22.04环境)
要不要用GRUB?
- 如果你的
bootloader.asm是自行实现MBR引导逻辑(比如通过BIOS中断0x13读取磁盘扇区、实模式/保护模式切换等),完全不需要GRUB,直接将生成的磁盘镜像写入U盘即可启动。 - 如果你的OS基于GRUB多引导规范开发(依赖GRUB完成内核加载),则必须通过GRUB引导,需要把内核打包为GRUB可识别的格式。
具体操作步骤(分两种场景)
场景1:自行实现MBR引导(无需GRUB)
生成可引导磁盘镜像
确保你的Makefile能输出正确的镜像文件(比如os.img),核心编译/打包命令参考:- 编译bootloader为二进制:
nasm -f bin bootloader.asm -o bootloader.bin - 编译kernel(16位用
-f bin,保护模式32位用-f elf32):nasm -f bin kernel.asm -o kernel.bin - 创建空白软盘镜像:
dd if=/dev/zero of=os.img bs=512 count=2880 - 写入bootloader到MBR:
dd if=bootloader.bin of=os.img conv=notrunc - 写入内核到后续扇区(根据bootloader的读取逻辑,比如从第2扇区开始):
dd if=kernel.bin of=os.img bs=512 seek=1 conv=notrunc
- 编译bootloader为二进制:
将镜像写入U盘
- 插入U盘后,用
lsblk或fdisk -l确认设备名(比如/dev/sdb,务必核对准确,避免覆盖硬盘) - 卸载U盘挂载点:
sudo umount /dev/sdb* - 写入镜像:
sudo dd if=os.img of=/dev/sdb bs=512 conv=sync - 执行
sync确保数据写入完成后再拔U盘
- 插入U盘后,用
真实PC启动测试
插入U盘,重启PC进入BIOS/UEFI设置,将U盘设为第一启动项,观察启动效果。
场景2:依赖GRUB引导
编译内核为ELF格式
- 编译kernel为32位ELF目标文件:
nasm -f elf32 kernel.asm -o kernel.o - 用
linker.ld链接生成ELF内核:ld -m elf_i386 -T linker.ld kernel.o -o kernel.elf
- 编译kernel为32位ELF目标文件:
制作GRUB可引导ISO镜像
- 创建目录结构:
mkdir -p iso/boot/grub - 复制内核到指定路径:
cp kernel.elf iso/boot/ - 创建
iso/boot/grub/grub.cfg配置文件:set timeout=5 set default=0 menuentry "My 16-bit OS" { multiboot /boot/kernel.elf } - 生成ISO镜像:
sudo grub-mkrescue -o os.iso iso/
- 创建目录结构:
写入U盘或刻录光盘
- 写入U盘:
sudo dd if=os.iso of=/dev/sdb bs=4M conv=sync && sync - 或刻录到空白光盘(若PC支持光盘启动)
- 写入U盘:
真实PC启动测试
插入介质后,在BIOS/UEFI中设置对应启动项即可。
真实PC环境适配注意事项
- BIOS中断兼容性:QEMU模拟的BIOS与真实PC的BIOS中断行为可能存在差异,比如
int 0x13磁盘读取、int 0x10显示输出,需在代码中增加容错逻辑。 - 硬件差异:不同PC的内存布局、显卡类型不同,部分旧PC不支持某些VESA模式,需在代码中检测硬件并做适配。
- 启动模式:确保PC设置为Legacy BIOS模式(而非UEFI),因为16位汇编OS通常基于MBR引导,无法直接在UEFI模式下启动。
- 调试技巧:若真实PC启动无输出,可在代码中加入串口输出逻辑,用USB转串口线连接PC与Ubuntu主机,通过
minicom或screen查看调试信息。
内容的提问来源于stack exchange,提问作者Federico Occhiochiuso
相关产品推荐
相关产品推荐

