视频教程请关注 B 站:"嵌入式Jerry"。
一、背景导读:GPU 与 DRM 到底谁负责"显示"?
在嵌入式 Linux 图形系统中,"画面怎么显示出来"的问题,表面看似简单,实则涉及多个内核子系统与用户态组件的协同:
- DRM 是谁?它真的"驱动"了 GPU 吗?
- GPU 的 galcore、etnaviv 这些驱动和 DRM 是什么关系?
- Weston 启动失败,g2d_open 失败,和 /dev/dri/cardX 有关系吗?
- GPU 是否必须通过 DRM 输出才能工作?是否和 framebuffer 混用?
/dev/galcore
、/dev/dri/card0
、/dev/fb0
到底该看哪个?
本文将结合 i.MX8MP 平台,从设备树到 Weston 启动日志,带你一次理清 GPU 与 DRM 显示体系的完整层级与职责划分。
二、DRM 与 GPU 的分工逻辑:渲染 vs 显示
先明确核心职责:
子系统/模块 | 类型 | 职责说明 |
---|---|---|
GPU 驱动(galcore) | 加速器 | 实现图形的"绘制"功能(2D/3D 加速) |
DRM/KMS | 显示控制 | 控制最终"画面"输出到 LVDS/HDMI |
Framebuffer | 旧式输出 | 提供系统级通用显示缓冲(不推荐) |
🌟 类比理解
- GPU:是"画图"的人,绘制位图图像;
- DRM:是"画框"的人,把图画挂在显示器上;
- Weston:是"调度者",调用 GPU 画画,把结果交给 DRM 上墙。
🌐 层级关系图
┌─────────────┐
│ User App │ ← Chromium, GTK+
└────┬────────┘
↓
┌───────────────┐
│ Weston (Compositor)
└────┬──────────┘
↓
┌────────────┴────────────┐
│ libEGL.so / libGAL.so │ ← G2D 渲染库(用户态)
└────────────┬────────────┘
↓
┌───────┴────────┐
│ /dev/galcore │ ← Galcore 驱动(内核态,G2D)
└───────────────┘
↓ 另一路
┌──────────────┐
│ /dev/dri/cardX │ ← DRM 节点(绑定显示控制器)
└──────────────┘

三、Vivante GPU 的两个驱动方案:galcore vs etnaviv
1️⃣ galcore 驱动(专有闭源)
-
驱动路径:
drivers/mxc/gpu-viv/
-
Yocto 包:
imx-gpu-viv
,imx-gpu-g2d
-
内核接口:
/dev/galcore
-
配套库:
libGAL.so
,libg2d-viv.so
,libEGL.so
,libGLESv2.so
-
典型配置项:
cCONFIG_MXC_GPU_VIV=y
-
特点:必须使用 NXP 提供的用户空间库,适用于图形 UI 显示,但调试不便
2️⃣ etnaviv 驱动(开源)
- 驱动路径:
drivers/gpu/drm/etnaviv/
- 内核接口:通过 DRM 框架注册
/dev/dri/cardX
- Yocto 包:默认含于
mesa
GPU 栈,libEGL 是 mesa 实现 - 特点:开源易调试,兼容性好,但性能和兼容性不如原厂
对比
维度 | galcore (专有) | etnaviv (开源) |
---|---|---|
用户空间库 | imx-gpu-viv | mesa, gallium etnaviv |
DRM 支持 | ❌(通过 framebuffer) | ✅ |
性能 | ✅ | 中等 |
易调试性 | 一般,需配套库 | 较好 |
推荐场景 | 商用项目 | 社区、自定义镜像 |
四、Weston 如何选用 GPU 渲染?配置实践与失败日志分析
1. weston.ini 关键字段
ini
[core]
use-g2d=true
backend=drm-backend.so
说明:
use-g2d=true
:使用 libg2d 绑定的硬件 G2D 加速库backend=drm-backend.so
:使用 DRM 输出画面(非 framebuffer)
2. 启动失败日志分析(真实日志)
txt
[12:17:48.292] Loading module '/usr/lib/libweston-11/g2d-renderer.so'
[12:17:48.323] g2d_open fail.
[12:17:48.323] failed to initialize g2d render
原因:
- Weston 调用 libg2d 打开 /dev/galcore 失败
- 原因可能包括:内核未加载 galcore 模块、设备树中 status = "disabled"
3. /dev/galcore 存在 ≠ 驱动成功加载
务必同时验证:
bash
lsmod | grep galcore # 是否加载
ls /dev/galcore # 是否存在节点
dmesg | grep galcore # 是否报错
五、设备树 + 内核配置:你启用 GPU 驱动了吗?
1. 设备树片段(默认 disabled)
dts
gpu_2d: gpu2d@38008000 {
compatible = "fsl,imx8-gpu";
status = "disabled"; // ← 需要改为 "okay"
};
必须改为:
dts
status = "okay";
2. 内核 menuconfig 设置
路径:
Device Drivers → MXC support drivers → MXC Vivante GPU support
勾选:
text
[*] MXC Vivante GPU support (CONFIG_MXC_GPU_VIV)
六、Yocto 配置参考(imx-gpu-viv)
bitbake
IMAGE_INSTALL:append = " \
imx-gpu-viv \
imx-gpu-g2d \
kernel-module-galcore \
weston \
seatd \
"
DISTRO_FEATURES:append = " opengl wayland "
确保 BSP 使用的是 NXP 官方 layer,例如:
bash
meta-freescale
meta-freescale-distro
避免使用混合 layer(例如 etnaviv + imx-gpu-viv 混用)
七、验证渲染路径是否启用 GPU
1. 查看 weston 日志:
bash
cat /tmp/weston.log | grep renderer
应输出类似:
renderer: using EGL with Vivante G2D
2. 查看设备节点
bash
ls /dev/galcore # GPU 渲染
ls /dev/dri/card* # DRM 显示控制
八、代码级示例:Weston 渲染路径回溯(精简)
简化 weston 源码:
c
/* g2d-renderer.c */
int g2d_renderer_create(struct weston_compositor *ec) {
g2d_fd = open("/dev/galcore", O_RDWR);
if (g2d_fd < 0) {
weston_log("g2d_open fail.\n");
return -1;
}
...
}
这一段说明:Weston 的 G2D 渲染器直接操作 /dev/galcore
,不通过 DRM。
而 DRM 是通过 drm-backend.c
初始化控制显示输出:
c
drm_fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
九、总结与实战建议
问题分类 | 推荐方案 |
---|---|
Weston 启动失败 | 检查 G2D 渲染是否开启失败 |
GPU 渲染无效 | 检查 galcore 驱动和设备树 |
DRM 输出失败 | 检查 /dev/dri/cardX 是否存在 |
Pixman 性能低 | 启用 galcore / use-g2d=true |
开发调试 | 使用 etnaviv + Mesa 更易调试 |
十、结构图总览(核心架构)
[ 应用 ] → [ Weston ] ┬→ libg2d → /dev/galcore(渲染)
└→ DRM API → /dev/dri/cardX(显示)
结语:
本篇文章尝试从系统结构、内核子系统职责分离、设备树/驱动配置、Yocto 安装策略、Weston 配置与调试日志分析多个维度,完整剖析了 DRM 与 Vivante GPU 驱动的逻辑关系。
不仅回答了"谁负责显示,谁负责渲染"的常见疑惑,更通过实际代码与配置,帮助你在 i.MX8MP 等平台上成功部署 Weston + GPU 显示系统。