1. Framebuffer 基础概念

1.1 什么是 Framebuffer

Framebuffer(帧缓冲)是 Linux 内核提供的一种抽象显示设备接口,它将显存映射到用户空间,使应用程序可以直接读写屏幕像素数据,而无需经过 X Window 或 Wayland 等复杂图形栈。从本质上看,Framebuffer 是一块连续的物理内存区域,每个像素点对应一个或多个字节,应用程序通过修改这块内存的内容即可实时更新屏幕显示。

核心定义:Framebuffer 是内核中用于存储屏幕图像数据的缓冲区,用户程序通过 mmap 系统调用将其映射到进程地址空间,实现直接像素级操作。

1.2 Framebuffer 在 Linux 系统中的位置

在 Linux 内核架构中,Framebuffer 位于显示子系统的中间层,向上对接用户空间应用程序,向下驱动具体显示硬件。其层次关系如下表所示:

层次 组件 功能描述
用户空间 应用程序 / GUI 库 通过 /dev/fb0 设备文件进行 mmap 映射和 ioctl 控制
内核空间 fbdev 框架 (drivers/video/fbdev) 提供统一的 Framebuffer 操作接口,管理显存和显示参数
硬件层 显示控制器 / GPU 负责将显存中的像素数据转换为视频信号输出到显示器

Framebuffer 设备在内核源码树中的主要路径为 drivers/video/fbdev/,核心头文件为 linux/fb.h,其中定义了 struct fb_info、struct fb_var_screeninfo、struct fb_fix_screeninfo 等关键数据结构。

Framebuffer 在 Linux 显示子系统中的层次架构 Framebuffer 在 Linux 显示子系统中的层次架构 用户空间 (User Space) 应用程序 / Qt / LVGL / 裸机绘图程序 系统调用层:open / ioctl / mmap / write 内核空间 (Kernel Space) fbdev 框架 → struct fb_info → fb_ops 回调函数 硬件层:显示控制器 / GPU / LCD 面板 设备文件 /dev/fb0

1.3 Framebuffer 设备文件 (/dev/fb0)

在 Linux 系统中,Framebuffer 以字符设备文件的形式暴露给用户空间,默认主设备号为 29,次设备号从 0 开始递增。常见的设备文件包括:

  • /dev/fb0 — 主显示设备,通常对应 LCD 屏幕或 HDMI 输出
  • /dev/fb1 — 第二显示设备,可用于双屏扩展或 overlay 层
  • /dev/fb0-current — 某些嵌入式平台提供的符号链接,指向当前激活的 fb 设备
检查方法:在终端执行 ls -l /dev/fb* 可查看系统中可用的 Framebuffer 设备;执行 cat /sys/class/graphics/fb0/virtual_size 可读取分辨率信息。

应用程序操作 /dev/fb0 的标准流程如下:

  1. 打开设备:int fd = open("/dev/fb0", O_RDWR);
  2. 获取固定信息:ioctl(fd, FBIOGET_FSCREENINFO, &finfo); — 获取显存地址、行长度等固定参数
  3. 获取可变信息:ioctl(fd, FBIOGET_VSCREENINFO, &vinfo); — 获取分辨率、位深、像素格式等可变参数
  4. mmap 映射显存:void *fbp = mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  5. 直接读写像素:通过 fbp 指针操作显存数据
  6. 解除映射并关闭:munmap(fbp, screensize); close(fd);
/dev/fb0 设备操作流程 /dev/fb0 设备操作流程 1. open("/dev/fb0") 2. ioctl 获取 finfo / vinfo 3. mmap 映射显存 4. 直接读写像素数据 关键数据结构 fb_fix_screeninfo fb_var_screeninfo

1.4 关键数据结构

操作 Framebuffer 设备时,两个核心数据结构定义在 <linux/fb.h> 中:

数据结构 ioctl 命令 主要字段 说明
struct fb_fix_screeninfo FBIOGET_FSCREENINFO smem_start、smem_len、line_length 固定参数:显存物理地址、大小、每行字节数
struct fb_var_screeninfo FBIOGET_VSCREENINFO xres、yres、bits_per_pixel、red/green/blue/transp 可变参数:分辨率、位深、颜色通道偏移与长度
注意事项:mmap 映射时使用的 screensize 应通过 finfo.line_length * vinfo.yres 计算,而非简单的 xres * yres * (bits_per_pixel / 8),因为 line_length 可能包含对齐填充字节。

1.5 像素格式与颜色空间

Framebuffer 支持多种像素格式,常见的有:

  • RGB565 — 16 位,R:5 G:6 B:5,嵌入式设备常用
  • RGB888 — 24 位,R:8 G:8 B:8,桌面系统标准
  • ARGB8888 — 32 位,A:8 R:8 G:8 B:8,支持透明度
  • CLUT8 — 8 位索引色,配合调色板使用

颜色空间转换(如 YUV 转 RGB)是嵌入式图形优化的关键环节,后续章节将深入探讨基于 NEON 指令集和查表法的加速方案。

常见像素格式内存布局 常见像素格式内存布局 RGB565 (16位) R[15:11] 5位 G[10:5] 6位 B[4:0] 5位 RGB888 (24位) R[23:16] 8位 G[15:8] 8位 B[7:0] 8位 ARGB8888 (32位) A[31:24] 8位 R[23:16] 8位 G[15:8] 8位 B[7:0] 8位

1.6 本章小结

Framebuffer 是 Linux 嵌入式图形开发的基础设施,它通过 /dev/fb0 设备文件和 mmap 机制,让用户空间程序能够直接操作显存。理解 fb_fix_screeninfo 与 fb_var_screeninfo 两个核心数据结构,以及不同像素格式的内存布局,是后续进行 mmap 映射优化和颜色空间转换调优的前提。