Linux DRM/KMS显示驱动开发与模式设置调试 - 第1节

1.1 什么是 DRM

DRM(Direct Rendering Manager,直接渲染管理器)是 Linux 内核中负责图形显示和 GPU 管理的核心子系统。它最初由 Precision Insight 公司为 DRI(Direct Rendering Infrastructure)项目开发,自 Linux 内核 2.4.19 起被合入主线。

DRM 提供了一套统一的、与硬件无关的 API,使得用户空间的图形栈(如 Mesa、Xorg、Wayland)能够安全、高效地与 GPU 交互。其核心职责包括:

  • 命令提交:将用户空间的渲染命令提交到 GPU 执行。
  • 内存管理:管理 GPU 显存(VRAM)和共享内存(GEM/TTM)。
  • 同步机制:提供 fence、dma-fence 等同步原语,协调 CPU 与 GPU 的执行顺序。
  • 显示控制:通过 KMS 组件管理显示输出。
关键概念:DRM 是一个内核级框架,不是具体的驱动。实际的硬件驱动(如 i915、amdgpu、msm)通过实现 DRM 提供的回调接口来注册到该框架中。

1.2 什么是 KMS

KMS(Kernel Mode Setting,内核模式设置)是 DRM 框架中负责显示输出管理的子组件。它将在传统 Linux 显示栈中由用户空间(X Server)完成的模式设置、分辨率切换、平面合成等任务移入内核空间。

KMS 的核心对象模型包括:

KMS 对象 描述 示例
CRTC 显示控制器,负责从内存读取像素数据并生成视频时序信号 Intel 的 Pipe A/B/C
Encoder 编码器,将 CRTC 输出的并行信号转换为特定接口标准(如 HDMI、DP、LVDS) eDP-Encoder、HDMI-Encoder
Connector 物理连接器,代表实际的显示接口(如 HDMI 端口、DP 端口) HDMI-A-1、DP-1
Plane 硬件平面(图层),支持叠加合成,减少 CPU 合成开销 Primary Plane、Overlay Plane、Cursor Plane
Framebuffer 内存中的像素缓冲区,包含颜色格式、分辨率、偏移等信息 drm_framebuffer 对象

KMS 的引入带来了以下优势:

  • 无闪烁启动:内核在启动阶段即可设置正确的显示模式,避免从 BIOS 文本模式到图形模式的切换闪烁。
  • 多显示支持:统一管理多个显示器的热插拔、分辨率切换和克隆/扩展模式。
  • 安全性:模式设置操作需要 root 权限或通过 DRM master 机制授权,防止恶意程序篡改显示状态。

1.3 DRM 与 KMS 的关系

DRM 和 KMS 是包含与被包含的关系。KMS 是 DRM 框架中的一个功能模块,专门处理显示输出。可以用下面的层次关系来理解:

DRM 与 KMS 的层次关系 用户空间:Mesa / Xorg / Wayland / Weston 系统调用接口:ioctl / mmap / poll DRM 核心框架 (drm.ko) GEM 内存管理 | TTM 显存管理 | dma-fence 同步 | 文件操作 KMS 子模块 (drm_kms_helper.ko) CRTC / Encoder / Connector / Plane / Framebuffer 硬件驱动:i915.ko / amdgpu.ko / msm.ko / vc4.ko 实现 drm_driver / drm_mode_config_funcs 回调 硬件:GPU + 显示控制器 + 编码器 + 物理连接器

从图中可以看出:

  • KMS 是 DRM 核心框架的一个子模块,通过 drm_kms_helper.ko 提供辅助功能。
  • DRM 核心负责内存管理、同步、文件操作等通用功能,而 KMS 专注于显示模式设置和输出管理。
  • 硬件驱动同时实现 DRM 核心回调和 KMS 回调,两者在驱动层融合。
一句话总结:DRM 是“GPU 管理框架”,KMS 是“显示输出管理模块”。KMS 是 DRM 的一部分,但 DRM 不依赖 KMS(无显示需求的 GPU 计算设备可以只使用 DRM 核心而不加载 KMS)。

1.4 DRM 在现代 Linux 图形栈中的位置

现代 Linux 图形栈是一个多层架构,DRM/KMS 位于最底层,直接与硬件交互。理解 DRM 的位置有助于把握整个显示链路的数据流和控制流。

DRM 在现代 Linux 图形栈中的位置 应用层:GUI 程序 / 游戏 / 视频播放器 图形工具包:GTK / Qt / SDL / EFL 显示服务器 / 合成器 Wayland Compositor (Weston / KWin / Mutter) 或 Xorg 用户空间图形库:Mesa 3D (libGL / libEGL / libgbm) Gallium3D 驱动 / Vulkan 驱动 / 软件光栅化 系统调用:open / ioctl / mmap / poll Linux 内核:DRM / KMS 子系统 drm.ko / drm_kms_helper.ko / i915.ko / amdgpu.ko / msm.ko GEM / TTM / dma-fence / KMS CRTC/Encoder/Connector/Plane 硬件:GPU / 显示控制器 / 显示器

从架构图中可以总结出 DRM/KMS 的关键作用:

层级 组件 与 DRM/KMS 的关系
应用层 GUI 程序、游戏 通过 EGL/GLX 间接使用 DRM,不直接操作 KMS
显示服务器 Wayland Compositor、Xorg 直接通过 DRM ioctl 进行页面翻转(page flip)、设置显示模式
用户空间图形库 Mesa (libgbm, libdrm) libdrm 封装 DRM ioctl;libgbm 提供缓冲区分配接口
内核 DRM/KMS 子系统 提供 ioctl 接口,管理 GPU 和显示硬件
硬件 GPU、显示控制器 DRM/KMS 驱动的管理对象
注意:在传统 Xorg 架构中,X Server 直接操作 DRM/KMS。而在现代 Wayland 架构中,Wayland Compositor(如 Weston、KWin)取代了 X Server 的角色,直接与 DRM/KMS 交互。Mesa 的 libdrm 库是用户空间访问 DRM 的标准入口。

1.5 DRM/KMS 的核心设计理念

DRM/KMS 的设计遵循以下关键原则:

  • 原子操作(Atomic):KMS 支持原子模式设置,允许将多个显示更新(如分辨率、平面位置、缓冲区切换)打包为一个原子事务提交,要么全部成功,要么全部回滚,避免中间状态导致的画面撕裂。
  • 无锁页面翻转(Page Flip):通过 VBlank 同步机制,在垂直消隐期切换 framebuffer,实现无撕裂的显示更新。
  • 主/从设备模型:DRM 设备分为主设备(primary node,支持 GPU 和显示操作)和渲染设备(render node,仅支持 GPU 计算,不涉及显示)。
  • 驱动与框架分离:DRM 框架定义接口,硬件驱动实现具体回调。驱动开发者只需关注硬件差异,无需重复实现通用逻辑。