4. modetest 工具介绍

modetest 是 Linux DRM/KMS 子系统中最核心的调试工具之一,被嵌入式显示驱动开发者称为“显示界的瑞士军刀”。它能够直接与 DRM 设备交互,枚举显示资源(CRTC、Encoder、Connector、Plane)、测试显示模式、执行 Page Flip 和 VBlank 事件监听,而无需依赖任何图形栈(如 X11/Wayland/SurfaceFlinger)。在 RK3588 平台开发中,modetest 是验证显示通路、排查驱动故障的首选工具。

适用场景: 驱动移植初期验证 Framebuffer 是否正常输出、MIPI/HDMI/DP 接口是否枚举、分辨率是否匹配、多屏同显/异显配置、以及 VBlank 中断是否工作。
modetest 与 DRM 核心组件交互架构 modetest 与 DRM 核心组件交互架构 modetest (用户态) DRM Core (drm.ko) CRTC Encoder Connector Plane RK3588 VOP / VPU / HDMI / MIPI DSI 硬件 modetest 通过 ioctl 直接操作 DRM 资源,不依赖任何显示服务 支持 -M 指定显卡、-s 设置显示模式、-v 监听 VBlank、-a 执行 Atomic 提交

4.1 modetest 来源

modetest 是 libdrm 测试工具集的一部分,源码托管在 drm 子项目下。它不是一个独立的软件包,而是随 libdrm 一起编译发布的实用程序。

项目 说明
上游仓库 https://gitlab.freedesktop.org/mesa/drm
源码路径 drm/tests/modetest/
依赖库 libdrm、libkms、pthread
RK3588 SDK 位置 external/libdrm/tests/modetest/
License MIT
关键提示: RK3588 的 Android SDK 和 Linux SDK(如 RK3588_LINUX_SDK)均预置了 libdrm 源码。如果目标文件系统没有 modetest 二进制,只需交叉编译 libdrm 的 tests 子目录即可生成。

4.2 编译方法

modetest 的编译分为本地编译和交叉编译两种场景。在 RK3588 开发中,通常使用交叉编译生成 ARM64 二进制,然后推送到目标板执行。

4.2.1 本地编译(x86 开发机验证)

# 安装依赖
sudo apt-get install meson ninja-build libdrm-dev

# 获取源码
git clone https://gitlab.freedesktop.org/mesa/drm.git
cd drm

# 使用 meson 构建
meson setup builddir
ninja -C builddir

# 编译完成后,modetest 位于 builddir/tests/modetest/

4.2.2 交叉编译(RK3588 ARM64 目标)

# 设置交叉编译工具链(以 RK3588 SDK 为例)
export CROSS_COMPILE=aarch64-linux-gnu-
export CC=${CROSS_COMPILE}gcc
export AR=${CROSS_COMPILE}ar
export STRIP=${CROSS_COMPILE}strip

# 配置 meson 交叉编译
meson setup builddir \
  --cross-file /path/to/aarch64-cross-file.txt \
  -Dtests=true

ninja -C builddir

# 提取 modetest 并 strip
${STRIP} builddir/tests/modetest/modetest
# 将 modetest 推送到 RK3588 板卡
adb push builddir/tests/modetest/modetest /data/
交叉编译文件示例(aarch64-cross-file.txt):
[binaries]
c = '/usr/bin/aarch64-linux-gnu-gcc'
cpp = '/usr/bin/aarch64-linux-gnu-g++'
ar = '/usr/bin/aarch64-linux-gnu-ar'
strip = '/usr/bin/aarch64-linux-gnu-strip'
pkgconfig = '/usr/bin/aarch64-linux-gnu-pkg-config'

[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8-a'
endian = 'little'

4.3 基本用法

modetest 的基本调用格式为:

modetest [-M <card>] [-c] [-e] [-p] [-f] [-s <connector_id>:<mode>] [-v] [-a]

以下是最常用的操作模式:

操作 命令示例 说明
枚举所有资源 modetest -M rockchip -c -e -p -f 列出 Connector、Encoder、CRTC、Plane 和 Framebuffer
显示测试画面 modetest -M rockchip -s 38:1920x1080-60@AR24 在 Connector 38 上输出 1920x1080@60Hz 彩条
监听 VBlank modetest -M rockchip -v 38 监听指定 CRTC 的 VBlank 事件
Atomic 模式测试 modetest -M rockchip -a -s 38:1920x1080-60@AR24 使用 Atomic API 提交显示配置
注意: Connector ID(如 38)是动态分配的,每次驱动加载或热插拔后可能变化。务必先执行 modetest -c 获取当前有效的 Connector ID。
modetest 基本用法流程 modetest 基本用法流程 步骤1: 枚举资源 modetest -c -e -p -f 步骤2: 获取ID 记录 Connector ID 步骤3: 设置显示模式 -s <conn_id>:<mode>@<fmt> 是否需要 Atomic 或 VBlank 调试? 是 Atomic 模式 modetest -a -s ... 否 Legacy 模式 modetest -s ... RK3588 推荐优先使用 Atomic 模式(-a)以验证完整 KMS 状态

4.4 常用参数解析

modetest 的参数体系覆盖了 DRM/KMS 的全部核心操作。以下按功能分类详细解析:

4.4.1 资源枚举类参数

参数 全称 功能描述 输出示例(RK3588)
-c --connector 枚举所有 Connector,包括类型、状态、物理尺寸、支持的 CEA/VESA 模式列表 Connector 38 (HDMI-A-1) connected, 1920x1080, 1280x720, ...
-e --encoder 枚举所有 Encoder,显示其 ID、类型、可能的 CRTC 掩码 Encoder 37 (TMDS) possible_crtcs: 0x1
-p --plane 枚举所有 Plane,包括主平面、叠加平面、光标平面及其格式支持 Plane 56 (Primary) formats: AR24, XR24, NV12, ...
-f --fb 枚举当前已创建的 Framebuffer 对象 Framebuffer 1 (1920x1080, AR24)

4.4.2 显示测试类参数

参数 格式 功能描述 RK3588 实战建议
-s <conn_id>:<mode>[@<format>] 在指定 Connector 上设置显示模式并输出彩条测试画面 常用:-s 38:1920x1080-60@AR24
-s 多屏 <conn_id>@<crtc_id>:<mode> 指定 CRTC 与 Connector 的绑定关系,用于多屏异显 -s 38@56:1920x1080 -s 39@57:1280x720
-P <plane_id>@<crtc_id>:<w>x<h>+<x>+<y> 在指定 CRTC 上配置 Plane 的位置和尺寸,用于叠加测试 -P 56@56:640x480+100+100
-F pattern 指定测试画面模式:smpte(彩条)、tiles(棋盘)、gradient(渐变) -F smpte 为默认彩条

4.4.3 调试与事件类参数

参数 功能描述 典型输出
-v 监听 VBlank 事件,打印时间戳和帧序列号 crtc 56: seq 12345, time 1234567890.123456
-a 使用 Atomic API 提交所有配置(推荐在 RK3588 上使用) Atomic commit succeeded
-D 启用 DRM 调试日志(需内核开启 DRM_DEBUG) [drm:drm_atomic_commit] committing
-M 指定 DRM 主设备节点,默认 /dev/dri/card0 -M rockchip 或 -M /dev/dri/card1
-R 执行 Page Flip 测试,循环切换 Framebuffer Page flip count: 100

4.4.4 模式字符串详解

-s 参数中的模式字符串遵循以下格式:

<connector_id>:<width>x<height>[-<refresh>][@<fourcc_format>]
字段 示例 说明
connector_id 38 通过 -c 获取的 Connector 编号
width x height 1920x1080 分辨率,必须被 Connector 的 mode list 支持
-refresh -60 刷新率(Hz),可选,不指定则使用第一个匹配分辨率的模式
@fourcc_format @AR24 像素格式,AR24=ARGB8888, XR24=XRGB8888, NV12=YUV420
RK3588 实战经验:
  • HDMI 输出常用 AR24 或 XR24,MIPI DSI 常用 AR24 或 RG16。
  • 如果指定模式不被支持,modetest 会报错 mode not found,此时先用 -c 查看可用模式列表。
  • 多屏同显时,使用相同的 CRTC ID 绑定多个 Connector;多屏异显时,每个 Connector 绑定不同的 CRTC。
  • Atomic 模式(-a)在 RK3588 上能更准确地反映驱动状态,建议作为首选测试方式。
modetest 参数分类思维导图 modetest 参数分类思维导图 modetest 参数 资源枚举 -c -e -p -f 显示测试 -s -P -F 调试事件 -v -a -D -R 设备选择 -M Connector/Encoder/CRTC/Plane 模式设置 / 叠加 / 图案 VBlank / Atomic / PageFlip 指定 card0/card1 RK3588 调试黄金组合:modetest -M rockchip -c -e -p -f 先枚举 再使用 modetest -M rockchip -a -s <conn_id>:<mode>@AR24 进行 Atomic 测试

4.5 实战:RK3588 上首次使用 modetest

以下是在 RK3588 开发板上首次使用 modetest 的完整操作序列:

  1. 确认 DRM 设备节点存在:
    ls /dev/dri/
    # 预期输出: card0  card1  renderD128
  2. 枚举所有显示资源:
    modetest -M rockchip -c -e -p -f
  3. 从输出中找到目标 Connector ID(例如 HDMI 输出为 Connector 38,状态为 connected)。
  4. 输出测试画面:
    modetest -M rockchip -s 38:1920x1080-60@AR24
  5. 观察屏幕是否出现彩条,同时终端打印 VBlank 事件信息。 ← 上一章 📖 返回目录 下一章 →