Skip to content

很好,这一版代码基本已经“正轨了”。我帮你把我们这一路踩过的坑 + 你当前这版为什么是对的系统性梳理一下,这对你后面面试讲项目非常加分。


🧠 一、核心踩坑总结(按严重程度)


🚨 1. GDB 符号错位(最关键)

❌ 现象

plaintext
p/x pm_entry = 0x66

❌ 根因

你之前:

  • ELF 被 objcopy / 重新构建
  • 或者 add-symbol-file 地址错误
  • 或 linker layout ≠ 实际加载地址

👉 导致:

❗GDB 把代码当数据解释了


✅ 正确做法

plaintext
file build/boot/stage2

👉 只用 ELF,不要用 bin


🚨 2. ELF vs BIN 混用(非常经典坑)

你工程里:

makefile
objcopy -O binary → stage2.bin

❗误区

文件用途
stage2(ELF)调试
stage2.bin启动加载

👉 不能互相替代


🚨 3. .code16 + .code32 混乱

你现在是:

asm
.code16
...
ljmp $0x08, $pm_entry
.code32
pm_entry:

❗坑点

  • 如果 ljmp 不是 16-bit 编码 → 会直接炸
  • 你之前踩过:
text
(bad) + rex + 错误反汇编

👉 说明 CPU 根本没正确进入 32 位


🚨 4. GDT 加载地址错(经典 real mode 陷阱)

你这句:

asm
lgdt gdt_ptr

但在 real mode:

text
物理地址 = DS * 16 + offset

❗所以必须:

asm
movw $0, %ds

👉 否则:

❗lgdt 读到错误内存 → 直接崩


🚨 5. stack 没对齐 / 切换错误

你做了:

asm
movw $0x900, %ax
movw %ax, %ss

movw $0xFFFE, %sp

👉 这个是正确姿势


❗之前可能的问题:

  • stack 在错误段
  • ss:sp 未初始化
  • 导致 call / push 直接炸

🚨 6. A20 / VESA / BIOS 调用

你这条链:

asm
call enable_a20
call vesa_get_controller_info
call vesa_get_mode_info
call vesa_set_mode

❗关键坑:

错误后果
A20 没开地址回卷
VBE buffer 地址错数据被覆盖
未保护寄存器调用链炸掉

🚨 7. GDT 放置位置错误(你之前问过)

你现在:

asm
.section .gdt,"a"

👉 这是正确的!


❗之前的坑:

  • 放在 .text
  • 或未对齐

👉 会导致:

❗lgdt 读取非法结构


🧠 二、你这版代码为什么是“正确版本”


✅ 1. 分段结构正确

asm
.section .text
.code16

👉 real mode 正确


✅ 2. GDT 独立 section

asm
.section .gdt,"a"
.align 8

👉 确保:

  • 8字节对齐
  • 结构稳定

✅ 3. GDT pointer 正确

asm
gdt_ptr:
    .word (gdt_end - gdt - 1)
    .long gdt

👉 标准写法(完全正确)


✅ 4. 关键 real → protected 流程正确

asm
movw $0, %ds
lgdt gdt_ptr
movl %cr0, %eax
orb $0x1, %al
movl %eax, %cr0
ljmp $0x08, $pm_entry

👉 这是教科书级别流程


⚠️ 5. 你唯一还可以优化的点


❗ljmp 注释写错了(非常关键)

你写:

asm
// 16-bit encoding: ea <offset16> <seg16>

但实际:

👉 GAS 会根据 .code16 自动生成正确编码

👉 不需要手写 ea


🚨 建议(避免坑)

asm
ljmp $0x08, $pm_entry

👉 OK,不要手动拼机器码


🧠 三、你整个 Boot 流程已经成熟

你现在已经具备:


🔥 Bootloader 能力

  • MBR → Stage2
  • 16-bit → 32-bit 切换
  • A20 控制
  • GDT 构建
  • 保护模式进入
  • VESA 初始化
  • framebuffer 获取
  • debug 输出(0xE9)

👉 这已经是:

💥 一个完整 mini OS boot pipeline


🚀 四、你这次真正进步的点(面试重点)


✅ 你已经掌握:

1️⃣ CPU 模式切换本质

  • real mode
  • protected mode
  • segment descriptor

2️⃣ BIOS / VESA 调用机制


3️⃣ 地址计算本质

text
real mode: DS:SI
linear = DS * 16 + offset

4️⃣ ELF vs BIN 分离


5️⃣ GDB + QEMU 调试链


🧨 五、最后帮你总结一句“可以写进简历”的话

你可以这样写:

实现了基于 x86 架构的自研 Bootloader,完成从 MBR 到 Stage2 的加载流程,支持 A20 开启、GDT 构建、保护模式切换、VESA 图形模式初始化以及帧缓冲获取,并通过 GDB/QEMU 完成底层指令级调试。

035_multi_terminal-40-g5d72b8b · 5d72b8b · 2026-06-26