2. KMS基础概念

KMS(Kernel Mode Setting)把显示输出拆解为一组职责清晰的内核对象。理解这些对象以及它们之间的数据流,是后续排查黑屏、花屏、分辨率异常、热插拔失效等问题的前提。可以把 KMS 想象成一条“像素生产线”:Framebuffer 提供原料,Plane 负责图层合成,CRTC 负责时序扫描,Encoder 负责信号编码,Connector 负责物理输出,Bridge 负责链路转换。

一、核心对象与职责

KMS 中每个对象都对应内核里的一个结构体,并通过 DRM 的 object ID 暴露给用户空间。它们不是孤立的,而是通过 atomic 状态机协同工作。

  • Framebuffer(FB):一块显存缓冲区的抽象,描述像素格式、宽高、pitch、offset 以及底层 GEM 对象。它是“要显示什么”的数据来源。
  • Plane:图层抽象,负责把某个 Framebuffer 按裁剪、缩放、旋转、混合等属性叠加到 CRTC 上。常见类型有 Primary、Overlay、Cursor。
  • CRTC:显示控制器,负责从 Plane 取像素并按像素时钟、行场时序扫描输出。它决定“什么时候、以什么时序”输出。
  • Encoder:把 CRTC 输出的并行像素信号转换为具体接口信号,如 HDMI TMDS、DP 链路、DSI 串行信号。它决定“以什么电气形式”输出。
  • Connector:物理连接器抽象,如 HDMI-A-1、DP-1、eDP-1。它管理连接状态、EDID、支持的显示模式,并负责热插拔检测。
  • Bridge:当 SoC 输出与 Connector 之间需要电平转换、协议转换或复用芯片时使用,例如 MIPI DSI 转 HDMI、DP 转 eDP、LVDS 转 eDP。

一句话记忆:Framebuffer 是“画什么”,Plane 是“怎么叠”,CRTC 是“按什么时序扫”,Encoder 是“编成什么信号”,Connector 是“从哪个口出去”,Bridge 是“中间怎么转”。

二、数据流与对象关系

从用户空间提交一次 atomic commit 开始,数据流大致如下:应用或合成器把渲染结果写入 GEM 缓冲区,创建或复用 Framebuffer;然后通过 atomic 属性把 FB 绑定到某个 Plane,把 Plane 绑定到 CRTC,把 CRTC 绑定到 Encoder,Encoder 再关联到 Connector。内核在 commit 时校验拓扑和模式是否合法,最后在 vblank 时机把新状态生效。

下面这张图展示了 KMS 核心对象之间的连接关系与像素/控制数据流。注意 Bridge 位于 Encoder 与 Connector 之间,是链路转换的关键节点。

KMS 核心对象与数据流 Framebuffer 像素格式 / 宽高 / pitch GEM 缓冲区 Plane Primary / Overlay / Cursor 裁剪 / 缩放 / 混合 CRTC 像素时钟 / 行场时序 扫描输出 Encoder TMDS / DP / DSI 信号编码 Bridge DSI→HDMI / DP→eDP 协议 / 电平转换 Connector HDMI-A-1 / DP-1 / eDP-1 EDID / 热插拔 / 模式 atomic commit 状态校验与生效 像素数据流:Framebuffer → Plane → CRTC → Encoder → Bridge → Connector → 物理接口 控制数据流:用户空间 atomic 属性 → DRM 对象状态 → 内核校验 → vblank 生效

三、关键属性与调试入口

排查 KMS 问题时,最常用的手段是查看对象拓扑和当前状态。modetest 可以列出所有对象及其连接关系,debugfs 则能查看更底层的状态。

# 列出所有 KMS 对象及连接关系
modetest -M rockchip -c

# 查看 connector 状态、EDID、支持模式
modetest -M rockchip -c -p

# 查看 CRTC 当前模式与 Plane 绑定
cat /sys/kernel/debug/dri/0/state

# 查看 connector 热插拔与 EDID 信息
cat /sys/class/drm/card0-HDMI-A-1/status
cat /sys/class/drm/card0-HDMI-A-1/edid | edid-decode

下表总结了各核心对象在故障排查中最值得关注的属性。

对象 关键属性 常见故障现象 排查入口
Framebuffer format、width、height、pitch、modifier 花屏、颜色错乱、偏移 modetest -p、drm_info
Plane type、crtc_id、fb_id、src/dst、zpos 图层不显示、叠加顺序错误 debugfs state、modetest -p
CRTC mode、active、plane_mask 无扫描输出、时序异常 debugfs state、modetest -c
Encoder encoder_type、possible_crtcs 接口无信号、链路训练失败 dmesg、modetest -e
Connector status、edid、modes、dpms 热插拔无效、分辨率不对 /sys/class/drm、modetest -c
Bridge bridge_type、of_node、timings 转换芯片无输出、时序不匹配 dmesg、debugfs、设备树

四、典型场景:HDMI 无输出的排查路径

假设一块板子 HDMI 接显示器无画面。按照 KMS 数据流从后往前排查,可以快速缩小范围。

  1. 先看 Connector 状态:cat /sys/class/drm/card0-HDMI-A-1/status。如果是 disconnected,说明 HPD 检测或 EDID 读取有问题,优先查硬件连接和 HPD 中断。
  2. 如果 status 是 connected,但 modes 为空,说明 EDID 解析失败,检查 DDC 通道和 EDID 数据。
  3. 如果 Connector 正常,查看 CRTC 是否 active、mode 是否设置成功。若 CRTC 未激活,检查 atomic commit 是否被拒绝。
  4. 如果 CRTC 正常,检查 Encoder 是否绑定到正确的 CRTC,以及 Bridge 是否成功 probe。
  5. 最后检查 Framebuffer 和 Plane 是否绑定正确,格式是否被硬件支持。

调试技巧:在 dmesg 中搜索 drm、connector、bridge 关键字,往往能直接看到链路训练失败、EDID 校验失败或 bridge probe 失败的原因。

五、常见误区与复盘

  • 误区一:把 Connector 当成“接口本身”。 Connector 是内核抽象,真正驱动信号的是 Encoder 和 Bridge。HDMI 无输出不一定是 Connector 问题。
  • 误区二:忽略 Bridge 的时序约束。 Bridge 芯片通常对输入时序、像素时钟范围有要求,SoC 输出的 mode 必须落在 Bridge 支持范围内。
  • 误区三:只看 CRTC 不看 Plane。 黑屏但 CRTC active,很可能是 Plane 没有绑定 FB,或者 zpos 被其他图层遮挡。
  • 误区四:热插拔后不重新读取 EDID。 某些显示器切换输入源后 EDID 会变化,必须重新触发 modeset。

复盘建议:每次排查 KMS 问题,先画出当前系统的对象拓扑图,标注每个对象的 ID 和状态,再对照数据流逐段验证。这样比盲目改代码或换线更高效。

掌握 CRTC、Encoder、Connector、Plane、Framebuffer、Bridge 六个核心对象及其数据流,就建立了 KMS 调试的“地图”。后续无论是分析 atomic commit 失败、调试多屏显示,还是排查 Bridge 链路问题,都可以沿着这条数据流逐段定位。