2. 显示基础概念
在进入 DRM/KMS 框架之前,必须先建立一套“显示语言”。KMS 中的 CRTC、Encoder、Connector、Plane 之所以要按特定顺序初始化,本质上就是在为一块屏幕配置像素阵列、刷新节奏和传输通道。如果这些基础概念不清晰,阅读内核代码时就会把 mode->clock、hdisplay、htotal 等字段当成孤立数字,而看不出它们之间的因果关系。
一、像素与分辨率:显示的最小单位与阵列规模
像素是显示设备能够独立控制的最小发光或颜色单元。每个像素通常由红、绿、蓝三个子像素组成,通过不同亮度组合形成颜色。分辨率描述的是“横向像素数 × 纵向像素数”,例如 1920×1080 表示每行 1920 个像素、共 1080 行。分辨率决定了画面的空间细节,但它并不等于屏幕的物理尺寸,也不等于接口带宽。
在 KMS 中,分辨率对应 struct drm_display_mode 里的 hdisplay 和 vdisplay。这两个值只是“有效显示区域”,真正送出一帧时,控制器还会在每行前后、每帧前后插入额外时间,这就是后面要讲的消隐区。
二、刷新率、时序与像素时钟:一帧是如何被“推”出去的
刷新率表示屏幕每秒重绘画面的次数,单位是 Hz。60Hz 意味着每 16.67ms 完成一帧。但“完成一帧”并不是只把 1920×1080 个像素发完就结束,显示控制器必须按照严格的时序节奏工作:
- 行同步(HSync):标志一行像素的开始,接收端据此对齐每一行的起点。
- 场同步(VSync):标志一帧像素的开始,接收端据此对齐每一帧的起点。
- 消隐区(Blanking):同步信号前后留出的空闲时间,分为行消隐和场消隐,用于让电子束回扫或让数字接收端完成行/帧切换。
- 像素时钟(Pixel Clock):每秒发送的像素总数,单位 MHz。它决定了整条时序链的节拍。
一帧的总像素数不是 1920×1080,而是 htotal × vtotal。其中 htotal = hdisplay + hfrontporch + hsync + hbackporch,vtotal 同理。像素时钟与刷新率的关系为:
pixel_clock = htotal × vtotal × refresh_rate
以 1920×1080@60Hz 为例(典型 CEA-861 时序):
hdisplay = 1920, hfrontporch = 88, hsync = 44, hbackporch = 148
htotal = 1920 + 88 + 44 + 148 = 2200
vdisplay = 1080, vfrontporch = 4, vsync = 5, vbackporch = 36
vtotal = 1080 + 4 + 5 + 36 = 1125
pixel_clock = 2200 × 1125 × 60 ≈ 148.5 MHz
这个 148.5MHz 就是 KMS 中 mode->clock 的常见取值。它必须与接收端能力匹配,否则会出现黑屏、闪烁或“超出范围”。
核心关系:分辨率决定“画多大”,刷新率决定“多快画”,像素时钟决定“每秒发多少像素”,消隐区决定“行与行、帧与帧之间留多少空隙”。四者共同构成一条完整的显示时序链。
三、显示接口类型:时序之后,像素如何被送出去
时序参数解决的是“什么时候发”,接口类型解决的是“用什么物理通道发”。不同接口对像素时钟、消隐区、同步信号的处理方式不同,这直接影响 KMS 中 Encoder 和 Connector 的驱动实现。
| 接口 | 传输方式 | 典型场景 | KMS 关注点 |
|---|---|---|---|
| HDMI | TMDS 差分,音视频同传 | 电视、显示器、机顶盒 | EDID 解析、TMDS 时钟比、HPD 热插拔 |
| DisplayPort | 微包分组,支持 MST 多流 | PC、专业显示、扩展坞 | 链路训练、DPCD、MST 拓扑 |
| MIPI DSI | 高速串行,命令/视频双模式 | 手机、平板、嵌入式 | DSI 主机控制器、面板初始化序列 |
| eDP | 嵌入式 DP,简化版 | 笔记本、一体机 | 背光控制、面板电源时序 |
| LVDS | 低压差分,并行像素映射 | 工业、车载、老式面板 | 通道映射、像素格式、双通道 |
四、案例与误区:为什么“分辨率对了”仍然黑屏
一个常见场景是:开发者把 hdisplay=1920、vdisplay=1080 填对,但屏幕仍然黑屏。原因往往出在消隐区和像素时钟上。例如某面板要求 htotal=2200、vtotal=1125、clock=148.5MHz,如果驱动只填了有效区,控制器实际输出的 htotal 可能变成 1920,导致像素时钟与接收端不匹配,链路训练失败或画面撕裂。
常见误区:把分辨率等同于时序。分辨率只是 hdisplay × vdisplay,而 KMS 需要的是完整的 drm_display_mode,包括前肩、同步宽度、后肩和像素时钟。缺少任何一项,Encoder 都无法正确生成同步信号。
另一个误区是忽略刷新率与像素时钟的联动。有人为了“超频”把刷新率从 60Hz 改到 75Hz,却没有同步提高像素时钟,结果 htotal × vtotal × 75 超过了接口带宽,出现花屏或间歇性黑屏。正确做法是先确认接口最大像素时钟,再反推可支持的刷新率。
调试建议:使用 modetest 或 cat /sys/class/drm/card0-*/modes 查看内核识别到的完整时序;用示波器或协议分析仪测量 HSync/VSync 频率,验证 pixel_clock 是否与理论值一致。只有“有效区 + 消隐区 + 像素时钟”三者同时正确,显示链路才能稳定工作。
理解这些基础概念后,再去看 DRM/KMS 的初始化流程,就会发现每一个结构体字段都有明确的物理含义:mode 描述时序,crtc 负责扫描输出,encoder 完成格式转换,connector 对接物理接口。它们共同把“像素、分辨率、刷新率、时序、像素时钟、行场同步、消隐区、接口类型”这八个概念,落实为一条可配置、可验证的显示通路。