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

为什么Stage 2在QEMU中正常运行,在真实硬件上却无响应?

真实硬件下Stage2加载后无输出的问题排查与修复

问题排查与修复方案

1. 驱动器号硬编码错误

QEMU常将USB镜像模拟为软盘(驱动器号0x00),但真实硬件中绝大多数BIOS会把USB盘识别为硬盘,驱动器号从0x80开始。你代码里硬写dl=0x00,导致真实硬件上读的是软盘而非USB盘——虽然USB灯闪可能是BIOS在尝试访问软盘,但实际并未读取到USB盘上的Stage2扇区。

修复:
删除硬编码的mov dl, 0x00,BIOS启动引导扇区时会将当前驱动器号存入dl寄存器,直接使用这个值即可:

mov ah, 0x02
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; 移除 mov dl, 0x00,保留BIOS传入的驱动器号
mov bx, stage_two
int 13h

2. CHS磁盘几何参数不兼容

代码中使用的是1.44M软盘的CHS参数(每磁道18扇区、2磁头),但真实USB盘的CHS参数通常与软盘差异极大,依赖CHS模式的int 13h (ah=0x02)会无法正确定位Stage2扇区。

修复:
优先改用LBA模式的磁盘读取(ah=0x42),该模式兼容性更强,无需依赖硬件特定的CHS参数,支持绝大多数存储设备。若需兼容老BIOS,可先检测LBA支持性,再选择对应读取方式。

3. 段寄存器与跳转地址可靠性问题

部分BIOS会将引导扇区加载到0x07C0:0000而非0x0000:7C00,此时org 0x7C00的段内跳转可能出错;另外,代码未显式设置es寄存器,部分BIOS默认es值不为0,会导致读盘目标地址错误。

修复:

  • 显式设置es=0,确保读盘地址正确:
    xor ax, ax
    mov ds, ax
    mov es, ax  ; 添加此行,将es寄存器置0
    
  • 使用远跳转指定段地址,避免CS寄存器值不确定的问题:
    ; 替换原有的 jmp stage_two
    jmp 0x0000:stage_two
    

4. INT 10h输出参数不全

Stage2中调用int 10h (ah=0xE)时未设置bh(视频页号)和bl(字符颜色),QEMU默认值可正常工作,但部分真实硬件BIOS需要显式指定这些参数才能输出字符。

修复:
在Stage2中补充必要参数:

stage_two:
    mov ah, 0Eh
    mov bh, 0x00  ; 指定视频页0
    mov bl, 0x07  ; 黑底白字(标准文本颜色)
    mov al, 'A'
    int 10h
    jmp $

5. 未验证扇区加载结果

即使int 13h未置CF标志,也不代表数据正确写入目标地址。可添加简单校验,确保Stage2确实被加载。

修复:

  • 在Stage2开头添加特征字节:
    stage_two:
        db 0xAA  ; 加载校验用特征字节
        mov ah, 0Eh
        ...
    
  • 读盘后检查特征字节:
    int 13h
    jc on_error
    ; 验证Stage2是否正确加载
    cmp byte [stage_two], 0xAA
    jne on_error
    

修改后的完整代码

org 0x7c00
bits 16

boot:
    jmp main
    TIMES 3-($-$$) DB 0x90   ; Support 2 or 3 byte encoded JMPs before BPB.

    ; Dos 4.0 EBPB 1.44MB floppy
    OEMname:           db    "mkfs.fat"  ; mkfs.fat is what OEMname mkdosfs uses
    bytesPerSector:    dw    512
    sectPerCluster:    db    1
    reservedSectors:   dw    1
    numFAT:            db    2
    numRootDirEntries: dw    224
    numSectors:        dw    2880
    mediaType:         db    0xf0
    numFATsectors:     dw    9
    sectorsPerTrack:   dw    18
    numHeads:          dw    2
    numHiddenSectors:  dd    0
    numSectorsHuge:    dd    0
    driveNum:          db    0
    reserved:          db    0
    signature:         db    0x29
    volumeID:          dd    0x2d7e5a1a
    volumeLabel:       db    "NO NAME    "
    fileSysType:       db    "FAT12   "

main:
xor ax, ax
mov ds, ax
mov es, ax  ; 显式设置es为0

; Pause for making stable the reading...
mov ah, 0x00
int 16h

mov ah, 0x02
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
; 保留BIOS传入的驱动器号,不硬编码dl
mov bx, stage_two
int 13h
jc on_error

; 验证Stage2是否正确加载
cmp byte [stage_two], 0xAA
jne on_error

; 远跳转到Stage2,确保段地址正确
jmp 0x0000:stage_two

printer:
    mov ah, 0x0E
    mov bh, 0x00  ; 补充视频页参数
    mov bl, 0x07  ; 补充颜色参数
.prntloop:
    lodsb
    or al,al
    jz .done
    int 10h
    jmp .prntloop
.done:
    ret

on_error:
mov si, errorstr
call printer
jmp $

errorstr db "Error.", 0

times 510-($-$$) db 0
dw 0xAA55

stage_two:
    db 0xAA  ; 加载校验特征字节
    mov ah, 0Eh
    mov bh, 0x00
    mov bl, 0x07
    mov al, 'A'
    int 10h
    jmp $

times 1024-($-$$) db 0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:00:58