4. 内核图形子系统入门
当图形故障从用户态一路排查到内核时,最先接触到的就是 DRM(Direct Rendering Manager)子系统。它既是显卡驱动的统一入口,也是显示管线在内核中的“总调度台”。理解 DRM 的框架分层、KMS 对象模型以及 Atomic Modesetting 的提交机制,是后续定位黑屏、花屏、刷新异常、分辨率错误等问题的前提。
一、DRM 框架的整体分层
DRM 并不是单一模块,而是一套由字符设备、驱动核心、KMS、GEM 以及各厂商驱动共同组成的框架。用户态通过 /dev/dri/card0 或 renderD128 访问,内核侧则由 drm.ko 提供通用能力,再由 i915、amdgpu、nouveau、msm 等具体驱动实现硬件相关部分。
- DRM Core:提供 ioctl 分发、对象生命周期管理、事件通知等通用机制。
- KMS(Kernel Mode Setting):负责显示模式设置,管理 CRTC、Encoder、Connector、Plane 等对象。
- GEM(Graphics Execution Manager):负责显存/缓冲区对象管理,处理分配、映射与同步。
- 厂商驱动:实现寄存器操作、时钟、电源域、显示控制器等硬件细节。
下图展示了 DRM 框架中用户态、DRM Core、KMS 对象与硬件之间的数据流关系,也是后续日志定位时最常参照的结构。
二、KMS 对象模型:谁决定画面如何显示
KMS 把显示过程抽象为若干对象,每个对象都有唯一的 ID,可通过 drmModeGetResources() 或 modetest 枚举。理解它们之间的绑定关系,是判断“为什么没有输出”的关键。
| 对象 | 职责 | 常见故障表现 |
|---|---|---|
| Framebuffer | 描述一块可扫描的像素缓冲区,含格式、宽高、pitch | 花屏、颜色错乱、尺寸异常 |
| Plane | 图层,负责把 Framebuffer 合成到 CRTC 上 | 图层缺失、叠加顺序错误 |
| CRTC | 扫描输出引擎,产生时序并驱动显示 | 无扫描输出、刷新率错误 |
| Encoder | 把 CRTC 的像素流转换为接口信号 | 接口无信号、协议不匹配 |
| Connector | 代表物理接口,保存连接状态与 EDID | 检测不到显示器、EDID 读取失败 |
典型绑定路径是:Framebuffer → Plane → CRTC → Encoder → Connector → 显示器。任何一环缺失或状态异常,都会导致最终无画面。
三、Atomic Modesetting:一次提交,整体生效
传统 modesetting 是逐步设置,容易出现中间态闪烁或部分生效。Atomic Modesetting 引入“原子提交”概念:先把所有对象的属性变更放入一个 drmModeAtomicReq,检查通过后一次性提交,由内核统一应用。
drmModeAtomicReq *req = drmModeAtomicAlloc();
drmModeAtomicAddProperty(req, plane_id, prop_fb_id, fb_id);
drmModeAtomicAddProperty(req, crtc_id, prop_mode_id, mode_id);
drmModeAtomicAddProperty(req, conn_id, prop_crtc_id, crtc_id);
int ret = drmModeAtomicCommit(fd, req,
DRM_MODE_ATOMIC_ALLOW_MODESET |
DRM_MODE_PAGE_FLIP_EVENT, NULL);
if (ret < 0) {
perror("atomic commit failed");
}
drmModeAtomicFree(req);
提交时常用标志包括 DRM_MODE_ATOMIC_ALLOW_MODESET(允许模式切换)、DRM_MODE_PAGE_FLIP_EVENT(请求翻页事件)以及 DRM_MODE_ATOMIC_TEST_ONLY(只检查不生效)。排查时若看到 -EINVAL,通常意味着属性组合不合法或对象未正确绑定。
modetest -M <driver> -p 可以列出所有 Plane、CRTC、Connector 及其属性,是验证 Atomic 属性是否可用的最快方式。
四、内核日志定位方法
DRM 的日志主要通过 dmesg 输出,驱动通常带有前缀,如 [drm]、[i915]、[amdgpu]。定位时建议按以下顺序进行:
- 确认驱动是否加载:
dmesg | grep -i drm,查看是否有Initialized或probe success。 - 查看 Connector 状态:搜索
connector、EDID、hotplug,判断是否检测到显示器。 - 检查模式设置:搜索
mode、atomic、commit,确认是否成功应用。 - 关注错误码:
-EINVAL、-ENOSPC、timeout往往指向属性非法、带宽不足或硬件无响应。
# 动态开启 DRM 调试日志
echo 0x1f > /sys/module/drm/parameters/debug
dmesg -w | grep -Ei "drm|atomic|connector|crtc"
# 查看当前显示状态
modetest -M i915 -c
cat /sys/kernel/debug/dri/0/state
五、案例与常见误区
案例:某设备启动后 HDMI 无输出。日志显示 connector HDMI-A-1: EDID read failed,随后 atomic commit failed: -EINVAL。排查发现是 Connector 未正确绑定 CRTC,导致 Atomic 提交时属性缺失。修正绑定关系后,EDID 读取成功,画面恢复。
dmesg 中的 DRM 报错。实际上,Atomic 提交失败、EDID 读取异常、Plane 格式不支持等信息,几乎都只在 kernel log 中体现。
复盘时建议建立固定检查清单:驱动是否 probe、Connector 是否 connected、EDID 是否有效、CRTC 是否绑定、Plane 格式是否匹配、Atomic 提交返回码是否为零。按此顺序排查,能覆盖绝大多数内核图形显示问题。