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

Bootloader在0x13中断处停滞,内核加载及跳转异常求助

Bootloader 0x13中断及跳转异常排查指南

一、0x13中断停滞/加载失败的常见原因

  • 磁盘参数错误:int 0x13的AH功能号(读扇区为0x02)、DL驱动器号(软盘0x00/硬盘0x80)、CHS参数(柱面/磁头/扇区,扇区编号从1开始而非0)是否与实际镜像匹配。
  • 内存地址冲突:内核加载目标地址是否被Bootloader自身占用(Bootloader通常在0x7c00,内核建议加载到0x1000及以上地址)。
  • 中断返回状态未检查:执行int 0x13后未检测CF标志位,出错后无处理逻辑直接停滞。
  • 磁盘镜像格式问题:Makefile生成镜像的dd命令参数错误,未生成可引导的软盘/硬盘镜像。

二、三种异常情况的具体排查

1. 显示内核加载成功但无法跳转

  • 内核入口地址不匹配:检查链接脚本的ENTRY指定入口(如_start)是否与Bootloader跳转地址一致,链接脚本的基地址设置需和加载地址对应(如Bootloader跳转到0x100000,链接脚本需设BASE_ADDRESS = 0x100000)。
  • 跳转指令错误:实模式下需使用远跳转指令ljmp而非近跳转jmp,段地址计算需遵循物理地址=段地址*16+偏移的规则,比如ljmp 0x1000:0x0000需确保段寄存器设置正确。
  • 内核初始化错误:若Bootloader在实模式跳转,内核是否直接进入保护模式而未做实模式初始化,导致执行崩溃。

2. 无任何反应

  • Bootloader未正确引导:确认Bootloader末尾存在0xAA55引导标志,Makefile中是否用dd将Bootloader写入镜像第一个扇区(如dd if=bootloader.bin of=disk.img bs=512 count=1 conv=notrunc)。
  • 段寄存器初始化错误:int 0x13要求ES:BX指向目标缓冲区,若DS、ES未初始化会导致写入错误地址,后续代码执行混乱。
  • 屏幕输出逻辑错误:使用int 0x10输出字符时,AH功能号(0x0E为电传输出)、AL的ASCII码、BH页号(设为0)是否正确,输出代码异常会导致无提示。

3. 提示内核加载失败

  • 扇区数量计算错误:内核二进制文件大小对应的扇区数需准确(如1024字节需2个扇区),扇区数不足会导致加载不完整触发错误。
  • 驱动器号硬编码错误:BIOS启动时会将驱动器号存入DL,应直接使用该值而非硬编码,避免虚拟机/真机环境差异导致错误。
  • 内核写入镜像位置错误:Makefile中dd的seek参数需正确(如内核写入第2个扇区需seek=1),位置错误会导致Bootloader读取不到内核。

三、代码层面关键检查点

Bootloader汇编代码

  • 正确设置int 0x13参数并检查返回状态:
    mov ah, 0x02    ; 读扇区功能
    mov al, 2       ; 加载扇区数(根据内核大小调整)
    mov ch, 0       ; 柱面号
    mov dh, 0       ; 磁头号
    mov cl, 2       ; 扇区号(从第2个扇区开始读)
    mov dl, [boot_drive] ; 使用BIOS传入的驱动器号
    mov bx, 0x1000  ; ES:BX指向内核加载地址
    mov es, bx
    xor bx, bx
    int 0x13
    jc load_error   ; CF置位则跳转至错误处理
    
  • 正确跳转至内核:
    mov ax, 0x1000
    mov ds, ax
    mov es, ax
    ljmp 0x1000:0x0000 ; 远跳转到内核入口
    
  • 确保引导标志存在:
    times 510-($-$$) db 0
    dw 0xaa55
    

Bootloader Makefile

  • 编译与镜像生成命令示例:
    bootloader.bin: bootloader.asm
        nasm -f bin bootloader.asm -o bootloader.bin
    disk.img: bootloader.bin kernel.bin
        dd if=/dev/zero of=disk.img bs=1M count=1
        dd if=bootloader.bin of=disk.img bs=512 count=1 conv=notrunc
        dd if=kernel.bin of=disk.img bs=512 seek=1 conv=notrunc
    

内核链接脚本

  • 确保入口与加载地址正确:
    ENTRY(_start)
    SECTIONS {
        . = 0x100000;  # 内核加载到1MB地址
        .text : { *(.text) }
        .data : { *(.data) }
        .bss : { *(.bss) }
    }
    

内核 Makefile

  • 32位无依赖编译示例:
    kernel.bin: kernel.o
        ld -m elf_i386 -T link.ld kernel.o -o kernel.bin
    kernel.o: kernel.c
        gcc -m32 -ffreestanding -c kernel.c -o kernel.o
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:37:32