2. Linux DRM/KMS框架简介

2.1 DRM架构分层

DRM(Direct Rendering Manager)是Linux内核中负责图形显示和GPU管理的核心框架。在SA8155平台上,显示驱动的开发完全基于DRM/KMS子系统。DRM架构从上到下分为三个层次:

层次 组件 职责 运行空间
用户空间 libdrm、Wayland/Weston、Android HWC 合成策略、缓冲区管理、显示请求提交 用户态
内核空间 DRM Core + KMS驱动 模式设置、缓冲区分配、CRTC/Encoder/Connector管理 内核态
硬件层 GPU(Adreno)、DPU(Display Processing Unit)、DSI/HDMI PHY 像素渲染、图层合成、时序生成、信号输出 硬件
关键理解:DRM Core提供统一的ioctl接口和对象模型,KMS驱动负责将DRM对象映射到具体的硬件寄存器操作。SA8155的显示驱动开发主要集中在KMS驱动层。

DRM架构的分层设计使得用户空间的显示框架(如Android的SurfaceFlinger或Linux的Weston)可以跨平台复用,只需更换底层的KMS驱动即可适配不同的SoC。

DRM架构分层示意图 用户空间层 libdrm | Wayland/Weston | Android HWC | Xorg 内核空间层 DRM Core(drm.ko) | KMS驱动(msm_drm.ko) 硬件层 Adreno GPU | DPU(Display Processing Unit) | DSI/HDMI PHY SA8155显示驱动开发聚焦于内核空间的KMS驱动层,实现DRM对象到DPU寄存器的映射

2.2 KMS核心概念

KMS(Kernel Mode Setting)是DRM框架中负责显示模式管理和配置的子系统。KMS定义了四个核心对象:CRTC、Encoder、Connector和Plane。理解这四个对象及其关系是掌握SA8155显示驱动开发的基础。

2.2.1 四大核心对象

对象 内核结构体 功能描述 SA8155硬件对应
CRTC struct drm_crtc 显示控制器,生成像素时序,管理扫描输出 DPU中的Mixer + Timing Generator
Encoder struct drm_encoder 将CRTC输出的像素流编码为特定接口格式 DPU中的DSI/HDMI/eDP发送器
Connector struct drm_connector 物理连接器,检测热插拔、读取EDID DSI接口、HDMI端口、DP端口
Plane struct drm_plane 硬件图层,支持叠加合成、缩放、旋转 DPU中的VIG/DMA图层管道
开发提示:在SA8155的KMS驱动初始化中,CRTC的配置是最关键的一步。CRTC决定了显示分辨率、刷新率、像素时钟等核心时序参数。CRTC配置错误会导致无显示、花屏或时序不兼容。

2.2.2 对象连接关系

KMS四个核心对象通过管道(Pipeline)的方式连接,形成完整的显示数据通路:

  1. Plane → CRTC:Plane将帧缓冲区(FB)的内容合成到CRTC的扫描输出中。
  2. CRTC → Encoder:CRTC生成像素时钟和同步信号,传递给Encoder进行编码。
  3. Encoder → Connector:Encoder将编码后的信号发送到Connector,最终输出到显示设备。
KMS核心对象连接关系 Plane 硬件图层 CRTC 显示控制器 Encoder 信号编码器 Connector 物理接口 attach pipe connect 数据流方向:FB → Plane → CRTC → Encoder → Connector → 显示设备 • 一个CRTC可以连接多个Plane(硬件图层叠加) • 一个Encoder只能连接一个CRTC,但可以连接多个Connector(如HDMI+DP)

2.2.3 核心对象关键属性

在SA8155的KMS驱动开发中,每个核心对象都有必须初始化的关键属性:

对象 关键属性 说明
CRTC mode_config 支持的显示模式列表(分辨率、刷新率)
funcs 回调函数集:set_config、gamma_set、enable_vblank
state 原子状态对象,保存CRTC的当前配置
port 设备树端口,关联到具体的DPU硬件实例
Encoder possible_crtcs 位掩码,标识该Encoder可以连接哪些CRTC
funcs 回调函数集:mode_set、enable、disable
encoder_type 编码器类型:DRM_MODE_ENCODER_DSI、DRM_MODE_ENCODER_TMDS
Connector connector_type 连接器类型:DRM_MODE_CONNECTOR_DSI、DRM_MODE_CONNECTOR_HDMIA
funcs 回调函数集:detect、get_modes、mode_valid
edid_blob_ptr EDID数据块指针(HDMI/DP场景)
status 连接状态:connected、disconnected、unknown
Plane type 图层类型:DRM_PLANE_TYPE_PRIMARY、DRM_PLANE_TYPE_OVERLAY、DRM_PLANE_TYPE_CURSOR
funcs 回调函数集:update_plane、disable_plane
format_modifiers 支持的像素格式和修饰符(如NV12、ARGB8888)

2.3 KMS与FBDEV的区别

在Linux显示驱动的发展历程中,FBDEV(Framebuffer Device)是早期的显示框架,而KMS是DRM框架下的现代替代方案。SA8155平台已完全弃用FBDEV,全面采用KMS。两者的核心区别如下:

对比维度 FBDEV DRM/KMS
架构设计 单一帧缓冲区,无分层概念 分层对象模型(CRTC/Encoder/Connector/Plane)
模式设置 通过ioctl直接操作寄存器,无统一接口 标准化的drm_mode_set接口,支持原子提交
多图层支持 不支持硬件图层叠加 支持多个Plane,硬件合成
热插拔检测 需要用户空间轮询 内核事件通知,支持drm_connector状态变化回调
VSync/垂直同步 无标准接口 drm_crtc_vblank系列API,支持vblank事件
缓冲区管理 单一固定缓冲区 GEM/Dumb Buffer,支持多缓冲区、DMA-BUF共享
多显示器支持 困难,需额外驱动逻辑 原生支持,每个Connector独立管理
SA8155适用性 不适用,无FBDEV硬件支持 标准方案,DPU硬件完全适配KMS
避坑提醒:从FBDEV迁移到KMS时,最容易犯的错误是试图用FBDEV的思维去理解KMS。FBDEV是"一块画布"模型,而KMS是"管道+图层"模型。在SA8155上,必须彻底抛弃FBDEV的单一帧缓冲概念,转而理解CRTC的时序生成和Plane的图层合成。
FBDEV vs DRM/KMS 架构对比 FBDEV 架构 单一帧缓冲区(fb0) 直接操作硬件寄存器 DRM/KMS 架构 Plane(图层) CRTC(时序控制器) Encoder + Connector(编码+接口) 演进 核心差异总结 • FBDEV:单缓冲区 + 直接寄存器操作 → 简单但功能有限 • KMS:对象化管道模型(Plane→CRTC→Encoder→Connector)→ 灵活、可扩展 • SA8155强制要求KMS:DPU硬件不支持FBDEV模式 • 开发复杂度:KMS初期学习曲线陡峭,但后期维护和功能扩展远优于FBDEV

2.4 本章小结

  • DRM架构分为用户空间层、内核空间层和硬件层,SA8155显示驱动开发聚焦于内核空间的KMS驱动。
  • KMS四大核心对象——CRTC、Encoder、Connector、Plane——通过管道模型连接,形成完整的显示数据通路。
  • CRTC是显示驱动的核心,负责时序生成和模式配置,是初始配置的重点。
  • KMS相比FBDEV在架构设计、多图层支持、热插拔、缓冲区管理等方面具有显著优势,SA8155平台全面采用KMS。