1. 课程导入

在嵌入式、车载、工业控制与桌面Linux系统中,显示子系统是用户感知最直接的模块之一。无论是开机Logo、控制台、Wayland合成器,还是视频播放与GPU渲染,最终都要通过内核显示驱动把像素送到屏幕。Linux内核为此提供的标准框架就是DRM(Direct Rendering Manager)与其中的KMS(Kernel Mode Setting)。本课程的目标,是让学习者从“能点亮屏幕”进阶到“能设计、调试和维护一套可产品化的显示驱动”。

一、学习目标与能力地图

本课程围绕“看得懂、改得动、调得通、测得准”四个层次展开。完成学习后,你应当具备以下能力:

  • 理解DRM/KMS的整体架构,能说清Userspace、DRM Core、KMS对象与硬件驱动之间的调用关系。
  • 掌握CRTC、Encoder、Connector、Plane、Framebuffer、Property等核心对象,并能用modetest等工具观察它们。
  • 能阅读并修改一个真实的显示控制器驱动,完成显示管线初始化、模式设置与页面翻转。
  • 能使用dmesg、debugfs、trace、示波器和逻辑分析仪定位黑屏、花屏、撕裂、闪屏等问题。
  • 能理解原子提交、格式协商、带宽与时钟约束,为后续HDR、多屏、合成器适配打基础。

二、核心概念:从像素到屏幕的抽象

KMS把显示硬件抽象成一条“像素流水线”。应用或合成器准备好Framebuffer(帧缓冲,描述像素格式、宽高、pitch与内存对象),通过Plane(图层)叠加到某个CRTC(显示控制器,负责扫描输出与时序生成)上,再由Encoder(编码器,把并行像素流转换为HDMI、MIPI DSI、LVDS、eDP等信号)送到Connector(连接器,代表物理接口与显示设备)。

其中,Mode描述分辨率、刷新率与前后肩、同步极性等时序参数;Property把对象属性暴露给用户空间,使原子提交可以一次性校验并生效;Atomic Commit则是现代DRM推荐的更新方式,避免中间状态导致闪烁。理解这些对象之间的“谁连接谁、谁驱动谁”,是后续所有调试工作的基础。

DRM/KMS 显示管线:对象、数据流与硬件映射 Userspace Wayland / X11 / modetest libdrm / ioctl DRM Core 对象管理 / 原子提交 Property / IOCTL KMS 对象层 CRTC / Plane / Encoder Connector / Mode / FB 硬件驱动 Display Controller / PHY HDMI / MIPI DSI / LVDS Framebuffer 格式 / pitch / GEM Plane Primary / Overlay / Cursor CRTC 扫描输出 / 时序 Encoder 像素流 → 接口信号 Connector EDID / 热插拔 关键约束: 像素时钟 × 位宽 ≤ 接口带宽;Plane 格式需被 CRTC 支持;Mode 必须满足 Connector 的 EDID 与时序能力;Atomic Commit 需通过全部对象校验。

三、整体框架与开发环境搭建

学习DRM/KMS,建议使用“内核源码 + 真实开发板 + 调试工具”三位一体的环境。软件侧需要Linux内核源码(建议5.10以上LTS)、libdrm、modetest、weston或kmscube;硬件侧建议选择带HDMI或MIPI DSI输出的ARM开发板,例如RK3568、i.MX8M、STM32MP157等,便于观察真实时序与接口信号。

# 1. 获取内核源码并确认DRM配置
git clone --depth=1 -b linux-6.1.y \
  https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
make ARCH=arm64 defconfig
./scripts/config --enable CONFIG_DRM
./scripts/config --enable CONFIG_DRM_KMS_HELPER
./scripts/config --enable CONFIG_DRM_ROCKCHIP

# 2. 编译并部署到开发板
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image dtbs
scp arch/arm64/boot/Image root@192.168.1.10:/boot/

# 3. 在目标板上验证KMS对象
modetest -M rockchip -c
modetest -M rockchip -p
modetest -M rockchip -s 42:1920x1080-60

其中,modetest -c列出Connector与可用模式,-p列出Plane与格式,-s执行一次模式设置。若能看到屏幕点亮并输出测试图案,说明KMS基础链路已经打通。

四、典型场景与常见误区

一个典型场景是:开发板启动后HDMI无输出。排查时不要急于改驱动,而应按“电源→时钟→PHY→Encoder→CRTC→Plane→Framebuffer”的顺序逐级确认。常见误区包括:只关注应用层而忽略内核对象状态;把“能显示”等同于“时序正确”;在原子提交中混用旧式set_config导致状态不一致;以及忽视EDID读取失败对模式选择的影响。

排查层级观察手段典型现象优先怀疑对象
电源与复位万用表、示波器无背光、无信号PMIC、GPIO复位
时钟与PHYclk_summary、示波器像素时钟缺失CRTC时钟、PHY配置
KMS对象modetest、debugfsConnector未连接EDID、热插拔
提交与格式dmesg、trace花屏、撕裂Plane格式、Atomic校验
建议在课程初期就养成“先看对象状态,再看寄存器,最后改代码”的习惯。DRM Core已经把大量硬件差异抽象成统一对象,善用/sys/kernel/debug/dri/下的调试节点,可以显著缩短定位时间。
不要在没有确认时钟与电源的情况下直接修改驱动寄存器,这会把简单问题复杂化。显示问题往往跨越电源、时钟、总线、格式与用户空间多个层次,必须按链路逐级收敛。