1. DRM 框架概述:架构演进、核心组件与生态对比

Direct Rendering Manager (DRM) 是 Linux 内核中负责图形显示与 GPU 渲染管理的核心框架。自 2000 年代初引入以来,DRM 已从简单的直接渲染管理器演变为现代 Linux 图形栈的基石,支撑着从嵌入式设备到高端桌面 GPU 的全场景显示需求。本章将系统梳理 DRM 的架构演进脉络、核心组件(DRM Core、KMS、GEM、FB)的功能定位,以及它与传统 FBDEV、V4L2 框架的本质区别。

1.1 DRM 架构演进:从直接渲染到现代显示栈

DRM 的演进经历了三个关键阶段,每个阶段都对应着图形硬件与用户需求的重大变革:

阶段 时间 核心变化 驱动模型
第一阶段 2000–2008 引入 DRM Core,提供 GPU 直接访问与 DMA-BUF 机制 单一 DRM 驱动,用户态通过 ioctl 直接操作 GPU
第二阶段 2008–2012 KMS 子系统的加入,将显示模式设置从用户态移入内核 DRM + KMS 双模块,驱动需实现 CRTC/Encoder/Connector
第三阶段 2012–至今 GEM 标准化内存管理,多平面合成、Fence 同步、DMA-BUF 跨设备共享 DRM/KMS/GEM 三层架构,支持 Atomic 接口与通用显示框架
关键演进节点: 2012 年 Linux 3.3 内核合入 Atomic Display Framework 雏形,标志着 DRM 进入"原子化"时代——所有显示状态变更可在一个事务中完成,避免了中间状态导致的画面撕裂与闪烁。

下图展示了现代 DRM 架构的三层结构及其与硬件、用户空间的关系:

DRM 现代架构三层结构 用户空间 (User Space) Mesa / Wayland / Xorg / Vulkan 应用 DRM Core (直接渲染管理器) 设备节点 /dev/dri/card0 · ioctl 分发 · 驱动注册 · 缓冲区管理 KMS (内核模式设置) CRTC · Encoder · Connector · Plane GEM (图形执行管理器) Buffer Object · DMA-BUF · Fence 硬件层 (Hardware) GPU · Display Controller · HDMI/DP 物理接口 · 帧缓冲

1.2 核心组件详解:DRM Core、KMS、GEM、FB

DRM 框架由四个核心组件构成,它们各司其职,共同支撑起完整的显示与渲染管线:

1.2.1 DRM Core — 框架中枢

DRM Core 是框架的入口与调度中心,负责:

  • 设备节点管理: 创建 /dev/dri/card0、controlD64、renderD128 等节点,供用户空间通过 ioctl 访问。
  • 驱动注册与回调: 提供 drm_driver 结构体,驱动开发者只需实现 .load、.unload、.irq_handler 等回调即可接入框架。
  • ioctl 分发: 将用户空间的请求路由到对应的子模块(KMS、GEM、FB 等)。
  • 调试与统计: 通过 /sys/kernel/debug/dri/ 提供寄存器转储、性能计数器等调试接口。
开发提示: 编写 DRM 驱动时,drm_dev_alloc() + drm_dev_register() 是标准初始化流程。从 Linux 5.x 开始,推荐使用 devm_drm_dev_alloc() 实现资源自动管理。

1.2.2 KMS (Kernel Mode Setting) — 显示模式控制

KMS 将显示模式设置(分辨率、刷新率、连接器状态)从用户空间移入内核,确保模式切换的原子性与安全性。核心对象包括:

KMS 对象 内核结构体 职责
CRTC drm_crtc 控制扫描输出时序,生成 VBLANK 中断,管理显示流水线
Encoder drm_encoder 将 CRTC 输出的像素数据编码为特定接口信号(TMDS、LVDS、eDP)
Connector drm_connector 代表物理显示接口(HDMI、DP、VGA),检测热插拔与 EDID 信息
Plane drm_plane 表示一个独立的显示图层,支持缩放、旋转、色彩转换
Bridge drm_bridge 可插拔的显示链路中间件,用于转换信号或添加图像处理

下图展示了 KMS 对象之间的连接关系与数据流:

KMS 对象连接关系与数据流 Plane 0 Plane 1 Plane 2 CRTC 扫描时序生成 Encoder 信号编码 HDMI 接口 说明:多个 Plane 通过 CRTC 合成后,经 Encoder 编码,最终由 Connector 输出到显示设备

1.2.3 GEM (Graphics Execution Manager) — 内存管理

GEM 是 DRM 的通用内存管理框架,解决了 GPU 与 CPU 之间的缓冲区共享与同步问题:

  • Buffer Object (BO): 核心抽象,代表一块可被 GPU 和 CPU 共同访问的内存区域。
  • DMA-BUF: 允许 BO 在不同设备间共享(如 GPU 与 VPU、ISP),实现零拷贝。
  • Fence: 基于 dma_fence 的同步机制,确保 GPU 渲染完成后再进行显示扫描。
  • GEM Handle 与 FD: 用户空间通过 handle(进程内)或 FD(跨进程)引用 BO。
常见陷阱: GEM 的 BO 分配策略因 GPU 而异——集成 GPU 通常使用 drm_gem_shmem_helper 分配连续物理内存,而独立 GPU 则通过 drm_gem_ttm_helper 使用 TTM 管理显存。选错 helper 会导致性能骤降或内存泄漏。

1.2.4 FB (Framebuffer) — 帧缓冲抽象

FB 是 DRM 中最基础的显示输出抽象,提供简单的像素数据写入接口:

  • drm_framebuffer: 代表一个完整的帧缓冲区,包含像素格式、宽高、 pitches、偏移量等信息。
  • drm_client: 基于 FB 的通用显示客户端,用于早期启动阶段的 Logo 显示或应急控制台。
  • 兼容模式: DRM 提供 drm_fbdev_generic_setup() 自动创建 FBDEV 兼容接口,方便旧应用迁移。

1.3 DRM 与 FBDEV、V4L2 的区别

理解 DRM 与 FBDEV、V4L2 的差异,有助于在项目初期选择正确的显示框架:

对比维度 DRM FBDEV V4L2
定位 GPU 渲染 + 显示输出全栈 简单帧缓冲输出 视频采集与输出
硬件加速 原生支持 GPU 3D/2D 加速 无,纯 CPU 操作 支持硬件编解码,但无 3D 渲染
多平面合成 原生支持(Plane 对象) 不支持 通过 Video Mixer 间接支持
模式设置 内核态 KMS,原子切换 通过 FBIOPUT_VSCREENINFO ioctl 通过 S_FMT / S_PARM 控制
缓冲区共享 DMA-BUF / GEM,跨设备零拷贝 仅单设备 mmap DMA-BUF 支持(较晚加入)
典型应用 桌面环境、游戏、嵌入式 HMI Linux 控制台、早期启动 Logo 摄像头、视频播放、视频会议
设备节点 /dev/dri/card0 /dev/fb0 /dev/video0
选型建议: 如果项目需要 GPU 渲染、多窗口合成、高刷新率或 HDR,请直接选择 DRM。FBDEV 仅适用于无 GPU 的极简系统或应急显示。V4L2 则专注于视频流处理,不适合作为通用显示框架。

下图从系统架构角度对比 DRM、FBDEV 与 V4L2 在 Linux 显示栈中的位置:

DRM / FBDEV / V4L2 在 Linux 显示栈中的位置 用户空间应用 DRM GPU + 显示全栈 FBDEV 简单帧缓冲 V4L2 视频采集/输出 硬件设备 (GPU / 显示控制器 / 视频编解码器)

1.4 本章小结

DRM 框架通过 DRM Core、KMS、GEM、FB 四个核心组件,构建了一个从 GPU 渲染到显示输出的完整内核态解决方案。与 FBDEV 的简单帧缓冲和 V4L2 的视频流定位不同,DRM 专为现代图形硬件设计,原生支持多平面合成、原子模式设置、DMA-BUF 跨设备共享等高级特性。掌握这些基础概念,是后续深入学习 GPU 渲染管线与多平面合成实践的前提。