
大家好,我是情报小哥~
上电的瞬间,一块 ARM 板通常不会立刻跑起炫酷的 GUI。你更可能先看到的是内核日志一行接一行地滚过屏幕。这个画面再熟悉不过,却很少被追问——在没有桌面环境、甚至没有 GPU 驱动完全就绪的时候,这些字符究竟是如何被“画”到屏幕上的?答案就藏在 Framebuffer Console 这套机制里。

打开内核文档,fbdev(帧缓冲设备)、fbcon(Framebuffer Console)和 VT(Virtual Terminal)基本上放在一起讨论。它们的职责可以用一个简单的类比理清:

/dev/ttyX 提供一个独立的文本舞台,负责处理按键、光标、回滚等逻辑,却完全不知道舞台长什么样。/dev/fb0 来修改像素,而无需关心底层寄存器。如果此时没有虚拟终端,不同程序输出的文字将会互相覆盖,如何解决?正是 VT 的多路复用能力让多个会话彼此隔离,而 fbcon 则负责把当前活跃的那个会话忠实地渲染到屏幕上。
一个完整的文本显示路径,可以用自顶向下的分层视角来看:

当用户空间向 /dev/tty1 写入一个字节,VT 层在完成回显和行缓冲处理后,会调用注册好的 consw 操作集。对 fbcon 而言,这就意味着一次“写字”请求。fbcon 从内核内置的字体数据(通常是 VGA8x16 这类点阵字体)里取出该字符对应的 8×16 位图,然后调用 cfb_imageblit 之类的软件绘制函数,在 struct fb_info 所描述的显存区域中,逐个像素地改写对应位置的颜色值。整个过程没有借助任何 GPU 加速,完全由 CPU 把字形“拓印”到内存上。这种“用 CPU 硬画字符”的做法,在资源受限的嵌入式 SoC 上不是妥协,而是一种有意为之的极简智慧——它既避免了动态内存分配,也不引入额外的电源和复杂度负担,正好贴合“够用就好、功耗与复杂度最小化”的嵌入式设计哲学。
这里也藏着另一个经典设计原则:机制与策略分离。fbcon 只负责“控制台该怎么渲染”这一通用机制(绘制光标、滚动、切换字体等),而具体如何把一块矩形填色、如何把图像块拷贝到显存,则由 fbdev 驱动提供的 fb_fillrect、fb_imageblit 等回调实现。更换一块 LCD,只需要替换底层的 fbdev 驱动,上层的控制台行为和快捷键完全不受影响。这种分层解耦让整个系统在面对硬件变化时保持足够的弹性。

在嵌入式 Linux 下“进入 framebuffer console”,就是确保内核打开 CONFIG_FRAMEBUFFER_CONSOLE、驱动提供 /dev/fb0,并在内核命令行添加 console=tty0,最后在用户空间为 tty1 启动一个 getty。这样显示屏上就会出现可交互的文本终端。
内核启动过程中,fbcon 与 fbdev 的绑定时机很关键。常见的方式是通过内核命令行指定,例如:
console=tty1 fbcon=map:0这行参数告诉内核:将主控制台映射到第一个注册成功的 framebuffer 设备上。如果不做特殊指定,fbcon 默认也会自动绑定到第一个可用的 fbdev。此外,通过 sysfs 也可以动态查看和控制绑定关系,例如 /sys/class/vtconsole/vtcon1/bind。

更值得一提的是 early console 机制。在内核内存管理器和调度器都尚未就绪的极早期启动阶段,early console 就能往串口或帧缓冲上输出字符。对于嵌入式开发者来说,这意味着哪怕板子死在了 setup_arch() 之前,依然能拿到一条关键打印。这种“快速上报、及早可见”的设计,深刻体现了嵌入式系统在启动可靠性上的设计哲学:宁可功能简陋,也要尽快让信息可见。
如果手边有开发板,这些命令可以帮你直观地感知 fbcon 的存在:
cat /sys/class/graphics/fb0/modes # 查看当前显示模式fbset -i # 显示 fbdev 详细信息cat /sys/class/vtconsole/vtcon1/name # 确认绑定的 console 驱动也可以在 U-Boot 阶段修改内核命令行,旋转控制台方向或切换分辨率:
console=tty0 console=ttyS0,115200 fbcon=rotate:1 video=HDMI-A-1:1280x720@60重启后屏幕上的字符便跟着旋转了——不需要改应用,甚至不需要改驱动,fbcon 已经帮你处理好了。
理解原理之后,你会发现 fbcon 在嵌入式 Linux 中几乎无处不在:
printk 的输出通过 console 层最终到达 fbcon,形成我们熟悉的滚动字符屏。通常在命令行中添加 console=tty0 即可让内核日志显示在屏幕上。console=tty1。DRM/KMS 和 Wayland 现在是逐渐成为主流,fbdev 被标记为“legacy”。但如果你看一下 DRM 框架中的 drm_fb_helper,就会发现它几乎是 fbcon 思想的一次平移:在 KMS 驱动的顶上再模拟出一个 framebuffer 控制台,让内核日志和急救终端继续可用。理解 fbcon,就掌握了进入嵌入式图形栈深处的一把钥匙。那些分层、解耦、早期可用的设计准则,也不会随着 fbdev 的退役而消散,它们依然在每一个新框架中延续。
持续获取嵌入式实战干货,关注、标星 公众号不错过每一篇技术解析~
推荐好文点击蓝色字体即可跳转
☞专辑|Linux应用程序编程大全 ☞ 专辑|学点网络知识 ☞ 专辑|手撕C语言 ☞ 专辑|手撕C++语言
☞ 专辑|经验分享 ☞ 专辑|从单片机到Linux ☞ 专辑|电能控制技术 ☞ 专辑|嵌入式必备数学知识 ☞ MCU进阶专辑
☞ 经验分享