You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Legacy BIOS汇编Bootloader:.img与.iso格式输入输出异常排查

Legacy BIOS Bootloader:.img与.iso格式下BIOS中断行为不一致问题解析

问题背景

我正在开发基于Legacy BIOS实模式的汇编Bootloader,使用BIOS中断(INT 10h负责视频输出、INT 16h负责键盘输入)实现磁盘选择菜单,但在两种格式下出现相反的异常:

  • .img格式(512字节,QEMU测试或写入USB):屏幕黑屏无输出,但INT 16h可正常检测键盘输入;
  • .iso格式(通过xorriso和isohdpfx.bin生成):菜单正常显示(INT 10h工作),但键盘无响应(INT 16h静默失效)。

生成命令:

nasm -f bin -o boot.img boot.asm
xorriso -as mkisofs \
  -o boot.iso \
  -b boot.img \
  -no-emul-boot \
  -boot-load-size 4 \
  -boot-info-table \
  -isohybrid-mbr isohdpfx.bin \
  -V BOOTDISK . 

1. 为何INT 16h在.img中正常、.iso中失效?

核心原因是启动环境的栈寄存器状态不一致,叠加xorriso参数错误的影响:

  • 纯MBR(.img)启动时,BIOS默认会把栈设置在0x0000:0x7c00下方的安全区域,栈空间完整,INT 16h执行时能正常使用栈保存寄存器、完成中断逻辑。
  • ISO启动时,isohdpfx.bin作为前置MBR会先执行,它会修改SS/SP寄存器的初始值,导致栈位置异常(比如栈指针指向无效内存、栈空间被后续加载的数据覆盖)。INT 16h严重依赖BIOS栈完成中断处理,栈异常会直接导致中断静默失效。
    另外,你设置的-boot-load-size 4会加载4个扇区(2048字节),但boot.img只有512字节,多余的1536字节会填充垃圾数据,大概率覆盖了栈区域,进一步干扰INT 16h的执行。

2. 为何.img中屏幕黑屏,.iso中视频输出正常?

问题出在视频模式初始化逻辑和段寄存器默认值的差异:

  • 纯MBR启动时,部分BIOS不会自动初始化文本模式(比如旧主板或QEMU的特定配置),如果你的代码没有显式调用INT 10h的0x00功能设置80x25文本模式,屏幕会保持黑屏。同时,MBR启动时BIOS默认的DS寄存器可能不是0x0000,而你的代码如果依赖DS/ES指向字符串存储的段,会导致INT 10h找不到输出内容,也会出现黑屏。
  • ISO启动遵循El Torito规范,BIOS会自动初始化文本模式;同时isohdpfx.bin执行后会将DS/ES设置为0x0000,刚好匹配你代码中字符串的存储段,所以INT 10h能正常输出菜单。

3. 问题是否与xorriso、isohdpfx.bin、段对齐或BIOS启动规范相关?

是的,这些因素都直接导致了异常:

  • xorriso参数:-boot-load-size 4是错误配置,你的boot.img是512字节的MBR,应该设置为-boot-load-size 1,避免加载垃圾数据破坏内存环境;-no-emul-boot要求启动镜像兼容El Torito的内存布局,你的代码没有考虑这一点。
  • isohdpfx.bin:这个通用MBR会修改寄存器状态(SS/SP、DS/ES),和纯MBR启动的初始环境完全不同,你的代码没有处理这种差异,导致中断行为异常。
  • 段对齐:你的代码大概率没有显式初始化段寄存器(DS、ES、SS、SP),而是依赖BIOS的默认值。不同启动环境下BIOS的默认段值不同,直接导致数据访问、栈操作出错,进而影响中断执行。
  • BIOS启动规范:MBR(磁盘启动)和El Torito(CD启动)是两种独立的BIOS启动规范,它们的内存布局、寄存器初始值、视频初始化逻辑都有差异,你的代码没有兼容两种环境的初始化流程。

内容的提问来源于stack exchange,提问作者RemoveOS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:23:17