4. KMS (Kernel Mode Setting) 核心

KMS (Kernel Mode Setting) 是 Linux 显示子系统的核心框架,它将显示硬件抽象为五个关键对象:CRTC、Encoder、Connector、Plane 和 Bridge。这些对象通过 DRM (Direct Rendering Manager) 框架组织成一条完整的显示流水线,负责将帧缓冲区的内容最终呈现在显示器上。理解这五个对象的职责与协作关系,是掌握 KMS 架构的基石。

核心要点: KMS 对象模型的设计遵循“单一职责”原则,每个对象只负责显示流水线中的一个独立环节。这种分层解耦的设计使得驱动开发者可以灵活组合不同厂商的硬件模块,也方便内核进行原子化状态校验与提交。

4.1 对象模型总览

下图展示了 KMS 五大核心对象在显示流水线中的典型连接关系。数据从内存中的 Framebuffer 出发,经过 Plane 的合成、CRTC 的时序生成、Encoder 的信号编码、Bridge 的桥接转换,最终通过 Connector 输出到显示设备。

KMS 五大核心对象流水线架构图 KMS 显示流水线:五大核心对象协作关系 Framebuffer Plane CRTC Encoder Bridge Connector Display Device 说明: 数据流向:Framebuffer → Plane → CRTC → Encoder → (Bridge) → Connector → Display Device。 Bridge 为可选节点,用于实现信号协议转换(如 DSI 转 eDP)或电平移位。

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 电平移位器
设计哲学: CRTC 和 Plane 是“内部”对象,负责数据合成与时序;Encoder、Bridge、Connector 是“外部”对象,负责信号传输与物理连接。这种内外分离使得 SoC 内部的显示控制器可以适配多种外部接口芯片。

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),独立更新
避坑指南: 并非所有硬件都支持完整的 Plane 功能。驱动开发者在实现 plane_helper_funcs 时,必须检查硬件能力(如最大缩放比、对齐要求、像素格式限制),并在 atomic_check 阶段进行校验,避免提交无效配置。

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
关键机制: Atomic 框架在 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 等辅助函数解析这些连接,自动建立对象间的绑定。

4.8 本章小结