汇编编写操作系统:如何整合Bootloader与OS并制作可引导镜像
解决二级Bootloader加载失败与镜像制作问题
一、修复一级Bootloader代码的关键问题
你的代码存在两处致命错误,直接导致二级Bootloader加载失败:
- 缺失扇区号设置
BIOS INT 0x13读扇区功能中,cl寄存器用于指定扇区号(低6位)与柱面号高2位。你的代码未初始化cl,默认值为0,会尝试读取不存在的扇区。由于一级Bootloader位于第1扇区(MBR),二级Bootloader应放在第2扇区,需添加:
mov cl, 0x02 ; 扇区号设置为2
- 未检查INT 0x13执行结果
BIOS读扇区失败时会置位进位标志(CF),并在ah中返回错误码。若不检查直接跳转,失败后会执行无效代码,引发闪烁光标。需添加错误处理逻辑:
int 0x13 ; BIOS读盘中断 jc read_error ; CF置位则跳转到错误处理
- 二级Bootloader的ORG匹配
确保二级Bootloader代码开头使用ORG 0x0000,因为它被加载到0x1000:0x0000地址,ORG匹配才能保证标签地址正确。
修复后的完整一级Bootloader代码:
ORG 0x7C00 start: xor ax, ax ; 清空ax寄存器 mov ss, ax ; 栈段设为0 mov sp, 0x7C00 ; 栈指针指向引导扇区地址 ; 加载二级Bootloader mov ah, 0x02 ; BIOS读扇区功能号 mov al, 1 ; 读取扇区数 mov ch, 0 ; 柱面号 mov dh, 0 ; 磁头号 mov dl, 0x80 ; 驱动器号(0x80为第一硬盘) mov cl, 0x02 ; 扇区号设为2 mov bx, 0x1000 ; 二级Bootloader加载段地址 mov es, bx ; 设置es寄存器 xor bx, bx ; es:bx偏移地址设为0 int 0x13 ; 触发BIOS读盘中断 jc read_error ; 检查读盘是否失败 ; 跳转到二级Bootloader jmp 0x1000:0000 read_error: ; 打印错误提示字符'E' mov ah, 0x0E mov al, 'E' mov bh, 0x00 mov bl, 0x07 int 0x10 ; 无限循环挂起 cli hlt times 510-($-$$) db 0 ; 填充0至510字节 dw 0xAA55 ; 引导签名
二、制作可启动镜像的方法
1. 硬盘镜像(虚拟机/物理硬盘适用)
使用dd命令将BIN文件写入镜像:
创建空镜像文件(至少2MB,足够容纳Bootloader与OS):
dd if=/dev/zero of=os.img bs=1M count=2写入一级Bootloader到第一个扇区:
dd if=boot1.bin of=os.img bs=512 count=1 conv=notrunc写入二级Bootloader到第二个扇区:
dd if=boot2.bin of=os.img bs=512 seek=1 count=1 conv=notrunc(可选)写入OS到后续扇区(示例为第三个扇区,
N为OS占用扇区数,需根据文件大小计算):dd if=os.bin of=os.img bs=512 seek=2 count=N conv=notrunc用QEMU测试:
qemu-system-i386 os.img
2. CD镜像(符合El Torito标准)
普通刻录工具无法生成可启动CD,需用mkisofs制作标准ISO:
将所有BIN文件放入同一目录,执行:
mkisofs -o os.iso -b boot1.bin -no-emul-boot -boot-load-size 1 .参数说明:
-b boot1.bin:指定引导文件为一级Bootloader-no-emul-boot:不模拟软盘/硬盘,直接加载引导扇区-boot-load-size 1:加载1个扇区(512字节)的引导代码
用QEMU测试:
qemu-system-i386 -cdrom os.iso
三、调试建议
- 用QEMU调试跟踪执行:
qemu-system-i386 -d int os.img,查看INT 0x13返回值,确认读盘是否成功。 - 在二级Bootloader开头添加打印代码(如用INT 0x10打印字符),验证跳转是否成功。
内容的提问来源于stack exchange,提问作者Luxo Luxo
相关产品推荐
相关产品推荐

