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。
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)的方式连接,形成完整的显示数据通路:
- Plane → CRTC:Plane将帧缓冲区(FB)的内容合成到CRTC的扫描输出中。
- CRTC → Encoder:CRTC生成像素时钟和同步信号,传递给Encoder进行编码。
- Encoder → Connector:Encoder将编码后的信号发送到Connector,最终输出到显示设备。
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的图层合成。
2.4 本章小结
- DRM架构分为用户空间层、内核空间层和硬件层,SA8155显示驱动开发聚焦于内核空间的KMS驱动。
- KMS四大核心对象——CRTC、Encoder、Connector、Plane——通过管道模型连接,形成完整的显示数据通路。
- CRTC是显示驱动的核心,负责时序生成和模式配置,是初始配置的重点。
- KMS相比FBDEV在架构设计、多图层支持、热插拔、缓冲区管理等方面具有显著优势,SA8155平台全面采用KMS。