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

Bootloader加载内核至1MB地址失败:QEMU内存为空问题

排查两阶段Bootloader内核加载至0x100000失败的问题

以下是针对你的场景补充的排查方向和解决方案:

1. 确认实模式下内存访问的地址合法性

实模式下CPU仅支持16位地址总线(最大访问物理地址0xFFFFF,即1MB-1),直接访问0x100000会触发地址回卷。如果Stage2仍处于实模式,必须通过段地址+偏移地址的方式访问1MB以上内存:

  • 设置段寄存器ES = 0x1000,偏移BX = 0x0,此时物理地址为ES*16 + BX = 0x100000
  • 调用int 0x13时必须使用这个段偏移组合,而非直接将偏移设为0x100000(16位寄存器无法存储该值)

2. 验证int 0x13的调用参数与返回状态

  • 如果使用传统int 0x13(AH=0x02):
    • 检查CX(柱面/扇区)、DX(磁头/驱动器)参数是否与磁盘镜像中内核的位置匹配
    • 调用后立即检查AH寄存器的值:AH=0表示成功,非0值对应BIOS错误码(如0x01表示无效命令,0x04表示扇区未找到)
  • 如果使用扩展int 0x13(AH=0x42):
    • 确认DAP(Disk Address Packet)结构体中的起始LBA扇区号、扇区数、内存地址(段+偏移)是否正确

3. 检查Stage2的模式切换与跳转逻辑

若内核是32位保护模式代码:

  • 确认Stage2已正确进入保护模式:加载GDT、设置CR0寄存器的PE位
  • 跳转至0x100000时,需使用保护模式下的段描述符(如代码段描述符的基地址设为0,限长覆盖足够内存),而非实模式的段跳转指令

4. 验证内核二进制文件的生成正确性

  • 确保内核编译后通过objcopy -O binary kernel.elf kernel.bin转换为纯二进制文件,而非直接使用ELF格式(ELF头会占据前若干字节,导致加载的代码无法正确映射到0x100000)
  • 再次检查链接脚本:确认ENTRY指向内核的入口函数,且.text段的起始地址明确设为0x100000

5. 添加Bootloader调试输出

在Stage2的关键节点添加BIOS打印(调用int 0x10):

  • 加载内核前打印"Loading kernel to 0x100000..."
  • 调用int 0x13后打印返回状态(如AH的值)
  • 加载完成后打印"Kernel loaded, jumping..."
    通过这些输出可以定位是磁盘读取失败,还是跳转逻辑有问题

6. 检查QEMU的启动参数

确认QEMU启动时使用的磁盘镜像路径正确,且未启用任何会修改内存映射的参数(如-m设置的内存足够,至少16MB)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:52:20