2. KMS核心概念:CRTC、Encoder、Connector、Plane、Bridge的角色与数据流关系

KMS(Kernel Mode Setting)是DRM框架中负责显示输出配置的核心子系统。理解KMS的五大对象——CRTC、Encoder、Connector、Plane和Bridge——是掌握显示驱动数据流的基础。每个对象在从帧缓冲区到显示面板的像素流水线中承担特定职责,并通过drm_device结构体组织成完整的显示拓扑。

核心认知:KMS对象模型本质上是将物理显示硬件抽象为软件组件,使得用户空间可以通过统一的Atomic API配置显示流水线,而无需关心底层硬件差异。

2.1 五大KMS对象角色定义

对象 角色 硬件对应 关键操作
CRTC 显示控制器核心,负责扫描输出、时序生成、色彩转换 Display Controller、Timing Controller 设置模式、开启/关闭显示、Gamma校正
Plane 硬件图层,提供帧缓冲到CRTC的像素数据通道 硬件Overlay、Primary Layer、Cursor Layer 设置源/目标矩形、像素格式、Alpha混合
Encoder 像素数据编码器,将CRTC输出的并行数据转换为串行信号 LVDS、HDMI、DP、MIPI DSI发送器 编码格式选择、时钟生成、链路训练
Connector 物理连接器,代表显示面板或外部接口 HDMI接口、DSI接口、eDP接口 热插拔检测、EDID读取、状态查询
Bridge 桥接芯片,在Encoder与Connector之间进行信号转换或增强 DSI-to-eDP桥、HDMI转VGA、MIPI D-PHY中继器 模式转换、电平移位、信号调理
关键区别:Encoder负责信号编码,Bridge负责信号转换/桥接,Connector负责物理连接与检测。三者形成从CRTC到面板的完整链路。

2.2 数据流关系与流水线拓扑

显示数据流从帧缓冲区出发,经过Plane、CRTC、Encoder、Bridge(可选),最终通过Connector到达显示面板。每个阶段完成特定的数据处理与传输任务。

KMS显示数据流流水线 帧缓冲区 Framebuffer Plane 图层/Overlay CRTC 显示控制器 Encoder 信号编码器 Bridge 桥接芯片 Connector 物理连接器 显示面板 Panel 说明:Bridge为可选组件,当Encoder与Connector之间无需信号转换时可省略。MIPI DSI场景中Bridge常用于DSI-to-eDP或DSI-to-HDMI转换。
数据流要点:
  • Plane从帧缓冲区读取像素数据,进行缩放、裁剪、Alpha混合后送入CRTC。
  • CRTC根据设定的显示模式(timing)生成行/场同步信号,将像素数据流发送给Encoder。
  • Encoder将并行RGB数据编码为串行差分信号(如MIPI DSI的D-PHY差分对)。
  • Bridge(若存在)在Encoder与Connector之间进行协议转换或信号调理。
  • Connector最终将信号传递给物理面板,并负责热插拔检测与EDID读取。

2.3 drm_device结构体组织

在DRM框架中,所有KMS对象都通过drm_device结构体进行统一管理。该结构体是DRM驱动的核心上下文,包含设备级别的所有资源、模式配置、文件操作接口等。

struct drm_device {
    struct list_head        devlist;        // 全局设备链表
    struct kobject          kobj;           // 内核对象
    struct device           *dev;           // 底层Linux设备
    struct drm_driver       *driver;        // 驱动方法表
    void                    *dev_private;   // 驱动私有数据

    /* KMS模式配置核心 */
    struct drm_mode_config  mode_config;    // 模式配置管理结构

    /* 文件操作与用户空间接口 */
    struct drm_file         *primary;       // 主文件句柄
    struct drm_file         *render;        // 渲染文件句柄
    struct mutex            filelist_mutex;
    struct list_head        filelist;

    /* 其他子系统 */
    struct drm_vblank_crtc  *vblank;        // Vblank管理
    spinlock_t              vblank_time_lock;
    spinlock_t              vbl_lock;
    struct drm_vblank_work  *vblank_work;

    /* 内存管理 */
    struct drm_gem_mm       *mm_private;    // GEM内存管理器
    struct drm_vma_offset_manager *vma_offset_manager;

    /* 事件与通知 */
    spinlock_t              event_lock;
    struct list_head        pending_event_list;
    struct list_head        event_list;
};
关键字段:mode_config是KMS对象组织的入口,它包含CRTC、Encoder、Connector、Plane、Bridge等对象的链表头,以及帧缓冲区列表、属性列表等。

2.4 drm_mode_config结构体与对象链表

drm_mode_config是KMS对象组织的核心枢纽,所有KMS对象都通过链表挂载在该结构体中。驱动初始化时,需要依次创建各个对象并添加到对应的链表中。

struct drm_mode_config {
    struct mutex            mutex;              // 模式配置互斥锁
    struct mutex            idr_mutex;          // ID分配互斥锁
    struct idr              crtc_idr;           // CRTC ID分配器
    struct idr              connector_idr;      // Connector ID分配器
    struct idr              encoder_idr;        // Encoder ID分配器
    struct idr              plane_idr;          // Plane ID分配器
    struct idr              bridge_idr;         // Bridge ID分配器

    /* 对象链表头 */
    struct list_head        crtc_list;          // CRTC对象链表
    struct list_head        connector_list;     // Connector对象链表
    struct list_head        encoder_list;       // Encoder对象链表
    struct list_head        plane_list;         // Plane对象链表
    struct list_head        bridge_list;        // Bridge对象链表
    struct list_head        property_list;      // 属性链表
    struct list_head        fb_list;            // 帧缓冲区链表

    /* 最小/最大分辨率限制 */
    int                     min_width, min_height;
    int                     max_width, max_height;

    /* 功能标志 */
    uint32_t                preferred_depth;    // 首选颜色深度
    bool                    poll_enabled;       // 是否启用轮询
    bool                    dpms_property;      // DPMS属性支持

    /* 默认属性 */
    struct drm_property     *edid_property;
    struct drm_property     *dpms_property_obj;
    struct drm_property     *path_property;
    struct drm_property     *tile_property;
    struct drm_property     *link_status_property;
    struct drm_property     *non_desktop_property;
};

2.5 对象创建与关联流程

驱动初始化时,KMS对象的创建顺序和关联关系决定了显示流水线的拓扑结构。以下是典型的初始化流程:

  1. 创建CRTC:调用drm_crtc_init(),传入drm_device和CRTC操作函数表。
  2. 创建Plane:调用drm_universal_plane_init(),指定Plane类型(Primary/Overlay/Cursor)。
  3. 关联Plane到CRTC:通过drm_crtc_init_with_planes()将Primary和Cursor Plane绑定到CRTC。
  4. 创建Encoder:调用drm_encoder_init(),指定Encoder类型和可能的CRTC掩码。
  5. 创建Connector:调用drm_connector_init(),指定Connector类型和检测回调。
  6. 创建Bridge(可选):调用drm_bridge_add(),并通过drm_bridge_attach()挂接到Encoder。
  7. 建立连接:通过drm_mode_connector_attach_encoder()将Connector与Encoder关联。
常见错误:忘记调用drm_mode_config_reset()会导致对象默认属性未初始化,进而引发Atomic Check阶段的校验失败。务必在对象创建完成后调用该函数。

2.6 对象间关联关系总结

关联关系 数据结构字段 说明
CRTC → Plane crtc->primary、crtc->cursor CRTC持有Primary和Cursor Plane的指针
CRTC → Encoder encoder->crtc Encoder通过possible_crtcs掩码选择CRTC
Encoder → Connector connector->encoder_ids[] Connector维护可用的Encoder ID列表
Encoder → Bridge encoder->bridge Encoder通过链表持有Bridge链
Connector → Panel connector->panel Connector持有drm_panel指针(可选)

2.7 完整对象拓扑图

drm_device 对象拓扑与关联关系 drm_device mode_config (对象容器) CRTC crtc_list Plane plane_list Encoder encoder_list Bridge bridge_list Connector connector_list primary/cursor possible_crtcs bridge链 encoder_ids[] 对象组织规则: 1. 所有对象通过链表挂载在 mode_config 中,链表头分别为 crtc_list、plane_list、encoder_list、bridge_list、connector_list。 2. 对象间通过指针或ID掩码建立关联,Atomic Commit 时根据这些关联遍历整个流水线。 3. Bridge 链支持多个桥接芯片串联,每个 Bridge 通过 next 指针形成单向链表。
实践要点:
  • 驱动初始化时,务必按照CRTC → Plane → Encoder → Bridge → Connector的顺序创建对象,确保依赖关系正确。
  • 使用drm_mode_config_reset()初始化所有对象的默认属性,避免Atomic Check失败。
  • 对于MIPI DSI场景,Encoder通常对应DSI主机控制器,Bridge对应DSI转eDP/HDMI桥接芯片,Connector对应DSI接口。
  • 调试时可通过/sys/kernel/debug/dri/0/下的文件查看各对象的状态和关联关系。

2.8 本章小结

KMS核心对象模型是DRM显示驱动的骨架:

  • CRTC是显示控制中心,负责时序生成和像素扫描。
  • Plane提供硬件图层支持,实现多图层合成。
  • Encoder将并行像素数据编码为串行信号。
  • Bridge在Encoder与Connector之间进行信号转换。
  • Connector代表物理接口,负责面板连接与检测。
  • drm_device通过mode_config统一管理所有KMS对象,形成完整的显示流水线拓扑。