Skip to content

下面给你整理一篇**“Bootloader + GDB 验证 VESA framebuffer”小博客**,可以直接放到你的技术博客里(偏实战向 + 踩坑总结风格):


🧠 Bootloader 图形模式调试实战:如何用 GDB 验证 VESA Framebuffer

在编写操作系统 bootloader 时,一个非常关键的步骤是:成功切换到 VESA 图形模式并正确使用 framebuffer

但问题来了:

👉 一旦进入图形模式,传统的 printf / BIOS 输出全都失效 👉 那我们该如何验证程序是否正确运行?

本文记录一套在 GDB 中验证 framebuffer 的实战方法


🚀 一、问题背景

在 Stage2 Bootloader 中,我们完成了以下流程:

  • 获取 VESA 信息
  • 获取 Mode 信息(例如 1024×768×32)
  • 切换到 VESA 图形模式
  • 获取 framebuffer 信息并保存到固定地址(如 0x6400

此时:

  • 屏幕进入图形模式(黑屏)
  • 文本输出消失
  • 无法通过传统方式调试

👉 这时候必须借助 GDB。


🔍 二、在 GDB 中验证 framebuffer 信息

首先检查我们保存的 framebuffer 信息:

plaintext
x/2gx 0x6400

输出类似:

text
0x6400: 0x00000000fd000000  0x0300040000000c00

📌 解析方式

1️⃣ Framebuffer 地址(64-bit)

0xfd000000

👉 这是 framebuffer 的物理地址


2️⃣ Pitch + 分辨率

pitch = 0x00000c00 = 3072
width  = 1024
height = 768

👉 验证方式:

  • 3072 / 1024 = 3
  • ⇒ 每像素 3 字节

👉 说明:RGB888(24-bit)格式


🧪 三、核心验证方法:直接写 framebuffer

GDB 的最大优势是:

👉 可以直接修改内存


✅ 方法一:写单个像素

plaintext
set {int}0xfd000000 = 0x00FF0000

👉 在左上角写入一个红色像素


⚠️ 问题

你可能会发现:

❗ “看不太清”

👉 原因:

  • 只写了一个像素
  • 人眼难以察觉

🟥 四、进阶验证:写一个色块

方法:写一条红线

plaintext
set $i = 0
while $i < 200
  set {int}(0xfd000000 + $i*4) = 0x00FF0000
  set $i = $i + 1
end

👉 效果:

  • 屏幕出现一条红线
  • 明显可见

方法:画一个矩形(推荐)

plaintext
set $y = 0
while $y < 100
  set $x = 0
  while $x < 100
    set {int}(0xfd000000 + ($y * 1024 + $x) * 4) = 0x00FF0000
    set $x = $x + 1
  end
  set $y = $y + 1
end

👉 效果:

✅ 左上角出现一个红色方块 👉 这是最直观的验证方式


⚠️ 五、常见坑总结

❌ 坑 1:在实模式下直接写 framebuffer

如果仍在:

asm
.code16

👉 可能:

  • 访问失败
  • 或行为不稳定

❌ 坑 2:误判色深

text
pitch = 3072

很多人会误以为是 32-bit,但实际上:

3072 / 1024 = 3 bytes/pixel

👉 实际是:

👉 24-bit RGB888


❌ 坑 3:只写一个像素

👉 肉眼不可见

✔ 必须写:

  • 一条线
  • 或一个块

🧩 六、调试建议(非常重要)

在 bootloader 阶段推荐使用:

✔ GDB 能做的

  • 查看 framebuffer 内存
  • 修改 framebuffer
  • 单步执行 VESA 代码
  • 查看寄存器

✔ 不能依赖

  • printf
  • BIOS 输出
  • 屏幕文本

🎯 七、最佳实践总结

在 VESA 图形模式调试中:

👉 “让 framebuffer 作为唯一输出设备”


推荐调试流程:

  1. 获取 framebuffer 地址
  2. 用 GDB 查看结构
  3. 手动写入像素
  4. 在屏幕观察变化
  5. 逐步验证系统行为

🚀 八、总结一句话

👉 在没有文本输出的世界里, 👉 framebuffer 就是你的“调试打印函数”


如果你后面要做:

  • 简易 GUI
  • 字体显示
  • 窗口系统
  • UI 框架

我可以帮你把这套 framebuffer 调试体系升级成:

👉 “最小图形内核渲染引擎”

直接从 bootloader 进阶到图形系统 👀

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