4. 显示驱动初始化日志分析:drm驱动加载顺序、pci probe日志、i2c/ddc通道探测日志、edid读取日志

显示驱动的初始化过程是故障排查的第一道关卡。当系统启动时,内核通过 PCI 子系统发现显卡设备,然后由 DRM (Direct Rendering Manager) 框架按特定顺序加载驱动模块、探测硬件资源、初始化 I2C/DDC 通道,并最终读取显示器的 EDID 数据。任何一个环节失败,都会导致“黑屏”、“无显示”或“分辨率异常”。本节将深入解析这些关键步骤的日志特征与排查方法。

核心原则: 显示驱动的初始化顺序是“自上而下、依赖先行”的。如果前一步(如 PCI probe)失败,后续的 EDID 读取日志将根本不会出现。排查时应从最早的错误日志开始,逐层向下分析。

4.1 DRM 驱动加载顺序与日志特征

DRM 子系统采用模块化设计,加载顺序通常为:DRM 核心层 → GPU 特定驱动 → 显示控制器驱动 → 输出接口驱动 (HDMI/DP/eDP)。在 dmesg 中,可以通过以下日志模式识别加载顺序:

加载阶段 典型 dmesg 日志 说明
DRM 核心初始化 [drm] Initialized drm 1.1.0 20060810 DRM 框架加载成功
GPU 驱动绑定 [drm] amdgpu: psp v11.0.0 initialized 特定 GPU 驱动开始初始化
显示控制器初始化 [drm] Display Core v3.2.0 initialized DC (Display Core) 初始化完成
输出接口注册 [drm] Adding connector for HDMI-A-1 物理输出接口被注册到 DRM 框架
排查技巧: 使用 dmesg | grep -i "drm" 过滤所有 DRM 相关日志。如果看不到“Initialized drm”行,说明 DRM 核心模块未加载,应检查内核配置或模块黑名单。
DRM 驱动加载顺序流程图 DRM 驱动加载顺序流程图 DRM 核心初始化 GPU 特定驱动绑定 显示控制器初始化 输出接口注册 排查要点 • 检查每个阶段是否有 ERROR • 确认模块加载顺序正确 • 注意依赖模块是否先行加载

4.2 PCI Probe 日志分析

PCI Probe 是 GPU 驱动与硬件建立通信的第一步。驱动通过 pci_probe() 函数读取设备的 Vendor ID、Device ID、Subsystem ID 等信息,并分配 MMIO 和 IRQ 资源。常见的 dmesg 日志格式如下:

[    2.345678] pci 0000:01:00.0: [1002:67df] type 00 class 0x030000
[    2.345679] pci 0000:01:00.0: reg 0x10: [mem 0xe0000000-0xefffffff 64bit pref]
[    2.345680] pci 0000:01:00.0: reg 0x18: [mem 0xf0000000-0xf07fffff 64bit pref]
[    2.345681] pci 0000:01:00.0: reg 0x20: [io  0x3000-0x30ff]
[    2.345682] pci 0000:01:00.0: BAR 0: assigned [mem 0xe0000000-0xefffffff 64bit pref]
[    2.345683] pci 0000:01:00.0: BAR 2: assigned [mem 0xf0000000-0xf07fffff 64bit pref]
[    2.345684] pci 0000:01:00.0: BAR 5: assigned [io  0x3000-0x30ff]
常见故障模式:
  • BAR 分配失败: 日志中出现 BAR 0: can't allocate [mem ...],通常由 BIOS 设置或 IOMMU 问题导致。
  • IRQ 冲突: irq 16: nobody cared 或 genirq: Flags mismatch,表明中断号被其他设备占用。
  • 设备未找到: pci 0000:01:00.0: [Firmware Bug]: Invalid VPD,可能表示 PCIe 链路不稳定或设备损坏。

关键字段解析:

  • [1002:67df]:Vendor ID (1002 = AMD) : Device ID (67df = Polaris 架构)。
  • class 0x030000:PCI 类代码,0x03 表示显示控制器,0x00 表示 VGA 兼容。
  • reg 0x10/0x18/0x20:BAR (Base Address Register) 编号,对应不同的 MMIO 或 IO 空间。
  • 64bit pref:64 位预取内存空间,用于高性能显存访问。
PCI Probe 资源分配流程图 PCI Probe 资源分配流程图 PCI 设备发现 读取配置空间 BAR 地址分配 IRQ 中断分配 驱动绑定完成 常见失败点 • BAR 空间不足 (BIOS/UEFI) • IRQ 共享冲突 • PCIe 链路训练失败

4.3 I2C/DDC 通道探测日志

I2C/DDC 通道是显卡与显示器之间通信的物理链路,用于读取 EDID 和执行显示控制。DRM 驱动在初始化时会枚举所有可能的 I2C 适配器,并尝试与显示器握手。典型的 dmesg 日志如下:

[    3.456789] [drm] DDC: 0x50 on I2C adapter 0 (i915 gmbus [0])
[    3.456790] [drm] DDC: 0x50 on I2C adapter 1 (i915 gmbus [1])
[    3.456791] [drm] DDC: 0x50 on I2C adapter 2 (i915 gmbus [2])
[    3.456792] [drm] DDC: 0x50 on I2C adapter 3 (i915 gmbus [3])
[    3.456793] [drm] DDC: 0x50 on I2C adapter 4 (i915 gmbus [4])
解读: 每个 I2C 适配器对应一个物理输出接口(HDMI、DP、eDP 等)。0x50 是 EDID 数据在 DDC 通道上的标准 I2C 地址。如果某个接口的 DDC 日志缺失,说明该接口的 I2C 总线未被正确初始化。

故障排查对照表:

日志现象 可能原因 排查方向
DDC 适配器数量少于物理接口数 GPIO 复用配置错误、硬件焊接不良 检查设备树或 ACPI 表
DDC 通信超时 显示器未上电、线缆损坏、I2C 电平不匹配 更换线缆/显示器测试
I2C 总线被锁定 驱动 bug 或硬件死锁 使用 i2cget 工具手动探测
I2C/DDC 通道探测架构图 I2C/DDC 通道探测架构图 GPU 核心 I2C 控制器 I2C 总线 GMBUS[0..4] HDMI-A-1 DP-1 eDP-1 DDC 探测要点 • 每个接口对应一个 I2C 适配器 • 地址 0x50 用于 EDID 读取 • 日志缺失 = 硬件/驱动问题 • 超时 = 显示器通信异常

4.4 EDID 读取日志分析

EDID (Extended Display Identification Data) 是显示器向显卡提供的“身份证”,包含分辨率、刷新率、色彩深度等关键参数。EDID 读取成功与否直接决定显示器能否正常工作。dmesg 中典型的 EDID 日志如下:

[    4.567890] [drm] Got EDID for HDMI-A-1: 2560x1440 60Hz 8bpc
[    4.567891] [drm] EDID block 0 checksum: 0x4a (valid)
[    4.567892] [drm] EDID block 1 checksum: 0x8b (valid)
[    4.567893] [drm] HDMI-A-1: EDID has 2 extension blocks
EDID 读取失败典型日志:
  • [drm] HDMI-A-1: No EDID found — 未检测到显示器或 DDC 通信失败。
  • [drm] EDID block 0 checksum: 0x00 (invalid) — 数据损坏,校验和错误。
  • [drm] HDMI-A-1: EDID is invalid — 读取到的 EDID 数据格式错误。
  • [drm] Failed to get EDID for HDMI-A-1: -5 — I2C 传输错误(-5 = EIO)。

EDID 数据块结构:

块编号 大小 内容 校验方式
Block 0 128 字节 基础显示参数(分辨率、时序、厂商信息) Checksum (字节 127)
Block 1 128 字节 扩展数据(色域、音频、3D 支持等) Checksum (字节 255)
Block 2+ 128 字节/块 CTA-861 扩展块(HDR、动态元数据等) Checksum (每块末尾)
高级排查: 使用 edid-decode 工具可以解析原始 EDID 数据。首先通过 cat /sys/class/drm/card0-HDMI-A-1/edid > edid.bin 导出 EDID,然后运行 edid-decode edid.bin 查看详细内容。如果 EDID 校验失败,可以尝试强制指定分辨率:video=HDMI-A-1:2560x1440@60 作为内核启动参数。
EDID 读取流程与故障点 EDID 读取流程与故障点 ① 发起 I2C 读取 ② 传输 128 字节 ③ 校验和验证 ④ 解析并应用参数 故障点与日志关键字 ① No EDID found — 无响应 ② I2C transfer error — 传输中断 ③ checksum invalid — 数据损坏 ④ EDID is invalid — 格式错误 ⑤ 强制分辨率可绕过 EDID 问题

4.5 综合排查流程

当显示驱动初始化失败时,建议按照以下步骤进行系统化排查:

  1. 检查 PCI 层: 使用 lspci -vnn | grep VGA 确认显卡是否被系统识别。如果 lspci 中无显示,检查硬件连接或 BIOS 设置。
  2. 过滤 DRM 日志: dmesg | grep -E "drm|pci|i2c|edid" 收集所有相关日志,按时间戳排序。
  3. 确认驱动加载: 查找 [drm] Initialized 和 bound to driver 关键字,确认驱动成功绑定。
  4. 验证 I2C/DDC: 检查 DDC 适配器数量是否与物理接口数一致,使用 i2cdetect -l 列出所有 I2C 总线。
  5. 分析 EDID: 如果 EDID 读取失败,尝试使用 edid-decode 分析原始数据,或强制指定分辨率作为临时方案。
  6. 查看内核错误: 使用 dmesg --level=err,warn 过滤错误和警告级别日志,重点关注 BUG、ERROR、FAILED 等关键字。
实战案例: 某系统在 dmesg 中看到 [drm] Failed to get EDID for HDMI-A-1: -5,同时 i2cdetect -y 0 显示地址 0x50 为 "UU"(表示被驱动占用但无响应)。最终排查发现 HDMI 线缆的 DDC 引脚断裂,更换线缆后 EDID 读取正常。