2. 显示硬件基础
在进入 DRM 驱动开发之前,必须先建立一张清晰的“显示硬件地图”。Linux DRM 把显示子系统抽象成若干对象:Framebuffer 描述像素数据,Plane 描述图层,CRTC 描述扫描输出,Encoder 描述信号编码,Connector 描述物理接口,EDID 描述显示器能力,DPMS 描述电源状态。理解它们之间的连接关系,是后续编写 KMS 驱动、调试显示异常、实现多屏输出的基础。
一、核心对象与职责
DRM 显示通路可以理解为一条从内存到屏幕的流水线。应用或合成器把画面写入 Framebuffer,Plane 从 Framebuffer 中取出一块区域,CRTC 按扫描时序把 Plane 内容混合成最终画面,Encoder 把像素流转换为 HDMI、DP、MIPI DSI 等接口所需的电信号,Connector 则负责与外部显示器建立连接并读取 EDID。每个对象都有独立的属性、状态和生命周期,内核通过 atomic 机制统一提交它们的状态变化。
- Framebuffer:一块像素缓冲区,包含格式、宽高、pitch、修饰符等信息,是显示的“数据源”。
- Plane:图层抽象,负责从 Framebuffer 中裁剪、缩放、旋转并混合到 CRTC,支持 primary、overlay、cursor 等类型。
- CRTC:显示控制器中的扫描输出单元,决定分辨率、刷新率、时序和背景色,是显示通路的“心脏”。
- Encoder:把 CRTC 输出的像素流编码成特定接口信号,例如 TMDS、DP 链路或 DSI 数据包。
- Connector:物理接口抽象,如 HDMI-A-1、DP-1、eDP-1,负责热插拔检测、EDID 读取和连接状态维护。
- EDID:显示器通过 DDC/I2C 提供的扩展显示标识数据,包含厂商、型号、支持分辨率、时序和音频能力。
- DPMS:显示电源管理状态,通常包括 On、Standby、Suspend、Off,用于控制背光、链路和扫描输出。
二、硬件显示通路与对象关系
下面这张图展示了 DRM 显示通路中对象之间的连接关系。Framebuffer 是数据源,Plane 是取数层,CRTC 是扫描与混合单元,Encoder 是信号编码器,Connector 是物理出口,EDID 和 DPMS 则分别影响 Connector 的能力发现与电源状态。
三、EDID 与 DPMS 的作用
EDID 是 Connector 在热插拔后通过 DDC 通道读取的一段结构化数据。内核解析 EDID 后,会得到显示器支持的分辨率、刷新率、像素时钟、物理尺寸以及音频信息。用户空间工具如 modetest、edid-decode 可以查看这些能力。没有 EDID 时,驱动通常只能使用保守的默认模式,或者依赖内核命令行强制指定模式。
# 查看 Connector 状态与 EDID 解析结果
modetest -c
# 输出示例:
# Connector: HDMI-A-1
# status: connected
# modes: 1920x1080@60, 1280x720@60
# edid: 00 ff ff ff ff ff ff 00 ...
# 解码 EDID 内容
edid-decode /sys/class/drm/card0-HDMI-A-1/edid
DPMS 则决定显示链路的电源状态。当用户空间调用 drmModeConnectorSetProperty 或通过 modetest -D 设置 DPMS 时,内核会通知 CRTC 停止扫描、Encoder 关闭链路、Connector 进入低功耗状态。DPMS Off 并不等于断开连接,Connector 仍然可以检测热插拔事件。
四、典型场景:一次模式设置发生了什么
假设用户空间执行一次 atomic commit,把 1920x1080 的 Framebuffer 显示到 HDMI 显示器上。内核会按以下顺序处理:
- 检查 Connector 状态,确认显示器已连接且 EDID 有效。
- 根据 EDID 选择匹配的显示模式,计算 CRTC 时序参数。
- 把 Framebuffer 绑定到 Plane,设置源裁剪区域和目标显示区域。
- 把 Plane 绑定到 CRTC,设置背景色和混合方式。
- 把 CRTC 绑定到 Encoder,Encoder 再绑定到 Connector。
- 提交 atomic 状态,硬件开始扫描输出,DPMS 切换为 On。
关键点:DRM 中对象之间不是简单的“父子”关系,而是通过 possible_crtcs、possible_clones、encoder 链表等约束形成一张有向图。驱动必须正确声明这些能力,用户空间才能找到合法的显示配置。
五、常见误区与复盘
| 误区 | 现象 | 正确理解 |
|---|---|---|
| 把 CRTC 当成“屏幕” | 多屏时混淆主副显示 | CRTC 是扫描控制器,Connector 才是物理接口 |
| 认为 Plane 只能有一个 | 无法实现叠加层 | 一个 CRTC 可绑定多个 Plane,按 zpos 混合 |
| 忽略 EDID 校验 | 模式列表为空或异常 | EDID 损坏时需回退默认模式或强制模式 |
| DPMS Off 后仍访问硬件 | 寄存器读写超时 | DPMS Off 后链路关闭,需先恢复再访问 |
排障提示:当显示无输出时,按“Framebuffer → Plane → CRTC → Encoder → Connector”的顺序逐级检查。先用 modetest -c 确认 Connector 状态,再用 modetest -p 查看 Plane 能力,最后检查 CRTC 是否处于 active 状态。多数问题集中在 Connector 未连接、EDID 读取失败或 CRTC 未绑定 Encoder 这三类。