1. DRM 框架概述
DRM(Direct Rendering Manager)是 Linux 内核中负责图形显示与渲染的核心框架。它诞生于 1999 年,最初作为 XFree86 的 DRI(Direct Rendering Infrastructure)项目的一部分,目的是为 3D 加速提供内核级支持。2002 年,DRM 被合入 Linux 主线内核 2.5.x 系列,随后逐步演变为现代 Linux 图形栈中不可或缺的组件。
1.1 发展历史
| 时间 | 里程碑 | 关键变化 |
|---|---|---|
| 1999 | DRI 项目启动 | 在 XFree86 中引入内核级渲染支持 |
| 2002 | DRM 进入主线 | Linux 2.5.x 内核开始包含 DRM 核心 |
| 2008 | KMS 引入 | Kernel Mode Setting 将显示模式管理从用户态移入内核 |
| 2012 | GEM 标准化 | Graphics Execution Manager 成为 DRM 默认内存管理器 |
| 2015 | Atomic API 成熟 | 原子模式设置接口进入稳定阶段 |
| 2020+ | DRM 生态扩展 | 支持 GPU 虚拟化、VKMS、显示子系统的统一化 |
关键认知: DRM 从最初仅为 3D 加速服务的模块,逐步演变为覆盖显示模式管理、内存管理、帧缓冲、合成器接口的完整显示驱动框架。KMS 的引入是 DRM 历史上最重要的转折点。
1.2 在 Linux 图形栈中的位置
DRM 位于 Linux 图形栈的中间层,向上对接用户态图形库(如 Mesa、Wayland、Xorg),向下控制具体的 GPU 和显示控制器硬件。其层次关系如下:
架构要点: 用户态程序通过
libdrm 库调用 ioctl 进入内核 DRM 核心,DRM 核心将请求分发到具体硬件驱动。设备树配置主要影响最底层的硬件驱动层,告知内核如何发现和初始化显示硬件。
1.3 核心组件简介
DRM 框架由三个核心子系统构成,它们共同支撑起显示驱动的全部功能:
1.3.1 KMS(Kernel Mode Setting)
KMS 负责显示模式的管理,包括分辨率、刷新率、色彩深度、显示时序等参数的设置。它将原本在 X 服务器中完成的模式切换工作移入内核,实现了更平滑的启动过程和无闪烁的虚拟终端切换。KMS 的核心对象包括:
- CRTC(Cathode Ray Tube Controller):控制显示扫描输出,管理像素时钟和时序
- Encoder:将 CRTC 输出的像素数据编码为特定接口信号(HDMI、DP、LVDS 等)
- Connector:物理连接器,代表实际的显示接口(HDMI 口、DP 口、eDP 等)
- Plane:硬件图层,支持叠加多个帧缓冲实现合成
- Framebuffer:内存中的像素数据缓冲区
1.3.2 GEM(Graphics Execution Manager)
GEM 是 DRM 的内存管理子系统,负责 GPU 和显示控制器共享内存的分配、映射和同步。GEM 提供以下核心能力:
- 内存对象分配与释放
- CPU 与 GPU 之间的内存映射(mmap)
- 内存对象共享(通过 dma-buf 机制)
- 内存同步(fence 机制)
1.3.3 Dumb Buffer
Dumb Buffer 是 GEM 的一个简化子集,专为不需要 GPU 加速的简单显示场景设计。它提供最基本的帧缓冲分配和映射功能,适用于嵌入式设备、启动阶段的显示或轻量级 GUI。Dumb Buffer 的 API 只有三个核心操作:
// 创建 dumb buffer
int drmIoctl(int fd, DRM_IOCTL_MODE_CREATE_DUMB, struct drm_mode_create_dumb *args);
// 映射到用户空间
int drmIoctl(int fd, DRM_IOCTL_MODE_MAP_DUMB, struct drm_mode_map_dumb *args);
// 销毁 dumb buffer
int drmIoctl(int fd, DRM_IOCTL_MODE_DESTROY_DUMB, struct drm_mode_destroy_dumb *args);
1.4 核心组件关系图
1.5 组件对比
| 组件 | 主要职责 | 适用场景 | 依赖硬件 |
|---|---|---|---|
| KMS | 显示模式管理、时序控制、图层合成 | 所有需要显示输出的场景 | 显示控制器、Encoder、Connector |
| GEM | GPU/显示内存分配、共享、同步 | 需要 GPU 加速或复杂合成 | GPU 或显示控制器 MMU |
| Dumb Buffer | 简单帧缓冲分配与映射 | 嵌入式设备、启动阶段、轻量 GUI | 仅需显示控制器 |
常见误区: Dumb Buffer 并非 GEM 的替代品,而是 GEM 的一个简化实现。对于需要 GPU 加速渲染的场景,必须使用完整的 GEM 接口。Dumb Buffer 仅适用于 CPU 直接写入像素数据的简单显示需求。