4. KMS (Kernel Mode Setting) 核心
KMS (Kernel Mode Setting) 是 Linux 显示子系统的核心框架,它将显示硬件抽象为五个关键对象:CRTC、Encoder、Connector、Plane 和 Bridge。这些对象通过 DRM (Direct Rendering Manager) 框架组织成一条完整的显示流水线,负责将帧缓冲区的内容最终呈现在显示器上。理解这五个对象的职责与协作关系,是掌握 KMS 架构的基石。
4.1 对象模型总览
下图展示了 KMS 五大核心对象在显示流水线中的典型连接关系。数据从内存中的 Framebuffer 出发,经过 Plane 的合成、CRTC 的时序生成、Encoder 的信号编码、Bridge 的桥接转换,最终通过 Connector 输出到显示设备。
4.2 五大对象职责详解
| 对象 | 职责 | 关键属性 | 典型硬件对应 |
|---|---|---|---|
| CRTC | 生成显示时序(行/场同步、消隐、像素时钟),控制扫描输出 | mode、active、vblank、gamma_lut | Display Controller 中的 Timing Generator |
| Encoder | 将 CRTC 输出的并行 RGB 信号编码为特定接口协议(如 LVDS、HDMI、DP) | possible_crtcs、encoder_type | TMDS 编码器、LVDS 发送器 |
| Connector | 代表物理连接器,检测显示器热插拔,管理 EDID 和显示模式列表 | connector_type、status、edid_blob_ptr | HDMI 端口、VGA D-Sub、USB-C DP Alt Mode |
| Plane | 管理帧缓冲区与 CRTC 之间的合成层,支持缩放、裁剪、旋转 | fb_id、crtc_id、src/dst rect、zpos | 硬件 Overlay 层、Sprite 层 |
| Bridge | 可选中间件,在 Encoder 和 Connector 之间进行信号转换或协议桥接 | encoder、next、funcs | DSI 转 eDP 桥片、HDMI 电平移位器 |
4.3 对象间的绑定关系
KMS 对象之间通过“绑定”形成一条完整的显示流水线。绑定的核心规则如下:
- CRTC ↔ Encoder:一个 CRTC 可以连接多个 Encoder(通过 possible_crtcs 掩码),但同一时刻只能激活一个 Encoder。
- Encoder ↔ Connector:一个 Encoder 通常绑定一个 Connector,但在某些复用场景下(如 DP 多流传输)可以绑定多个。
- Encoder ↔ Bridge:Bridge 作为可选节点,插入在 Encoder 和 Connector 之间,形成链式结构。
- CRTC ↔ Plane:一个 CRTC 可以关联多个 Plane(主平面 + 叠加平面),Plane 通过 crtc_id 指定所属 CRTC。
以下是一个典型的绑定关系示例(以 i915 驱动为例):
// 伪代码:KMS 对象绑定关系
struct drm_crtc *crtc0 = ...;
struct drm_encoder *encoder_dp = ...;
struct drm_connector *connector_hdmi = ...;
struct drm_plane *primary_plane = ...;
struct drm_bridge *bridge_ps8640 = ...;
// 绑定 CRTC 与 Encoder(通过 possible_crtcs 掩码)
encoder_dp->possible_crtcs = 1 << drm_crtc_index(crtc0);
// 绑定 Encoder 与 Connector
connector_hdmi->encoder_ids[0] = encoder_dp->base.id;
connector_hdmi->encoder = encoder_dp;
// 绑定 Bridge 到 Encoder(桥接芯片)
bridge_ps8640->encoder = encoder_dp;
encoder_dp->bridge = bridge_ps8640;
// 绑定 Plane 到 CRTC
primary_plane->crtc = crtc0;
crtc0->primary = primary_plane;
4.4 Plane 的合成机制
Plane 是 KMS 中实现硬件合成(Hardware Composition)的关键对象。现代显示控制器通常包含多个硬件层,Plane 负责将不同帧缓冲区的内容合成到最终的显示画面中。Plane 的核心能力包括:
- Z-order 控制:通过 zpos 属性指定各平面的叠加顺序,值越小越靠近底层。
- 缩放与裁剪:src 矩形定义源帧缓冲区的裁剪区域,dst 矩形定义目标显示区域,硬件自动完成缩放。
- 旋转与翻转:支持 0°/90°/180°/270° 旋转以及水平/垂直翻转。
- Alpha 混合:支持全局 Alpha 值和逐像素 Alpha 混合。
| Plane 类型 | 用途 | 典型数量 | 特殊属性 |
|---|---|---|---|
| Primary Plane | 主显示层,通常为全屏扫描输出 | 每个 CRTC 至少 1 个 | 不可禁用,始终存在 |
| Overlay Plane | 叠加层,用于视频播放、UI 悬浮元素 | 0 ~ 多个 | 支持缩放、裁剪、Alpha |
| Cursor Plane | 硬件光标层,低延迟、低带宽 | 0 ~ 1 个 | 尺寸受限(通常 64x64),独立更新 |
4.5 Bridge 的链式处理
Bridge 对象是 KMS 中相对较晚引入的抽象,用于解决显示信号链路上的“最后一公里”问题。典型的 Bridge 应用场景包括:
- 协议转换:如 MIPI DSI 转 eDP、LVDS 转 HDMI。
- 电平移位:1.8V 逻辑电平转 3.3V 或 5V。
- 信号调理:Re-timer、Redriver 用于延长传输距离。
- 多路复用:多个输入源切换到一个输出端口。
Bridge 在驱动模型中通过链表组织,一个 Encoder 可以挂载多个 Bridge,形成处理链:
// Bridge 链式结构示意
struct drm_bridge {
struct drm_encoder *encoder; // 所属 Encoder
struct drm_bridge *next; // 链中下一个 Bridge
const struct drm_bridge_funcs *funcs;
// ...
};
// 调用链:Encoder -> Bridge[0] -> Bridge[1] -> ... -> Connector
// 每个 Bridge 在 enable/disable 时依次执行自己的回调
4.6 对象模型与 Atomic 框架的交互
KMS 对象模型是 DRM Atomic 框架的基础。Atomic 框架通过 drm_atomic_state 对象捕获所有 KMS 对象的状态变更,并在一次 commit 中原子性地应用。每个 KMS 对象在 Atomic 框架中都有对应的状态结构:
| KMS 对象 | 状态结构体 | 关键状态字段 |
|---|---|---|
| CRTC | drm_crtc_state | mode、active、vblank_enabled、gamma_lut |
| Plane | drm_plane_state | fb_id、crtc_id、src/dst rect、zpos、rotation |
| Connector | drm_connector_state | crtc_id、best_encoder、link_status |
| Encoder | drm_encoder_state | crtc_id(部分驱动使用) |
| Bridge | drm_bridge_state | input_bus_cfg、output_bus_cfg |
drm_atomic_check_only 阶段会遍历所有涉及的对象,调用其 atomic_check 回调进行状态校验。开发者必须确保每个对象的 atomic_check 能够正确验证跨对象依赖(如 Plane 的 src/dst 矩形不能超出 CRTC 的显示范围)。
4.7 对象模型在设备树中的体现
在嵌入式平台中,KMS 对象模型通常通过设备树(Device Tree)进行描述。以下是一个典型的设备树片段,展示了 CRTC、Encoder、Connector 和 Bridge 的拓扑关系:
// 设备树中的 KMS 对象拓扑示例
display-controller@13800000 {
compatible = "vendor,display-controller";
reg = <0x13800000 0x1000>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>; // CRTC 输出端口
dc_out: endpoint {
remote-endpoint = <&encoder_in>;
};
};
};
};
encoder@13801000 {
compatible = "vendor,hdmi-encoder";
reg = <0x13801000 0x100>;
ports {
port@0 {
encoder_in: endpoint {
remote-endpoint = <&dc_out>;
};
};
port@1 {
encoder_out: endpoint {
remote-endpoint = <&bridge_in>;
};
};
};
};
bridge@0d {
compatible = "vendor,ps8640";
reg = <0x0d>;
ports {
port@0 {
bridge_in: endpoint {
remote-endpoint = <&encoder_out>;
};
};
port@1 {
bridge_out: endpoint {
remote-endpoint = <&connector_in>;
};
};
};
};
connector {
compatible = "hdmi-connector";
type = "a";
port {
connector_in: endpoint {
remote-endpoint = <&bridge_out>;
};
};
};
设备树中的 port/endpoint 连接关系,直接映射到 KMS 对象模型中的绑定关系。驱动在 probe 阶段通过 drm_of_find_possible_crtcs 和 drm_of_encoder_active_endpoint 等辅助函数解析这些连接,自动建立对象间的绑定。