4. 开发环境搭建
好,咱们进入第四章。这一章讲的是怎么把DU驱动真正跑起来。说白了,就是三件事:配好内核、编出模块、加载调试。
我见过不少工程师,驱动代码写得挺漂亮,结果卡在编译和加载环节。嗯,这里要注意,R-Car的图形栈对内核配置有硬性要求,漏一个选项就可能黑屏。
4.1 内核配置选项(Kconfig)
先说说Kconfig。DU驱动在内核里不是默认打开的,你得手动选上。我个人习惯是在做BSP移植时,先把所有图形相关选项列个清单,然后逐项确认。
关键路径在这里:
Device Drivers --->
Graphics support --->
<*> DRM Support for Renesas R-Car DU
[*] Enable HDMI output support
[*] Enable LVDS output support
[*] Enable VSP-based display support
注意,<*> 表示编译进内核,<M> 表示编译成模块。我建议前期调试阶段用 <M>,这样改完驱动不用整个重编内核,省时间。
除了DU本身,还有几个依赖项必须打开:
| 配置项 | 路径 | 说明 |
|---|---|---|
| CONFIG_DRM | Graphics support → DRM | DRM核心框架,DU的上层依赖 |
| CONFIG_DRM_RCAR_DU | Graphics support → Renesas R-Car DU | DU驱动主模块 |
| CONFIG_DRM_RCAR_HDMI | 同上,子选项 | HDMI输出支持 |
| CONFIG_DRM_RCAR_LVDS | 同上,子选项 | LVDS输出支持 |
| CONFIG_DRM_RCAR_VSP | 同上,子选项 | VSP硬件合成支持 |
| CONFIG_VIDEO_RENESAS_VSP1 | Multimedia support → VSP1 | VSP1驱动,DU依赖它做合成 |
4.2 编译DU驱动模块
配置完内核,接下来就是编译。如果你把DU设成了模块(<M>),编译命令很简单:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules
编完之后,在 drivers/gpu/drm/rcar-du/ 目录下会生成 rcar-du-drm.ko 文件。这就是我们要的模块。
如果你想把所有模块打包到内核镜像里一起烧录,可以用:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_install INSTALL_MOD_PATH=/path/to/rootfs
我个人习惯是单独编模块,然后手动拷贝到目标板。这样每次改驱动只需要重新编一个 .ko 文件,不用重新打包整个文件系统。
V=1 参数可以看到完整编译命令,方便排查头文件路径或链接错误。比如:make V=1 ARCH=arm64 ...
4.3 动态加载与卸载
模块编好了,怎么加载到内核里?最直接的方式是用 insmod:
insmod rcar-du-drm.ko
但注意,DU模块有依赖关系。它依赖 drm.ko 和 vsp1.ko。如果这些模块没先加载,insmod 会报错。我建议用 modprobe,它会自动处理依赖:
modprobe rcar-du-drm
卸载模块用 rmmod:
rmmod rcar-du-drm
你想想看,如果模块正在被使用(比如有应用程序打开了DRM设备),rmmod 会失败。这时候得先关掉那些进程。
查看模块是否加载成功,用 lsmod:
lsmod | grep rcar
如果看到 rcar_du_drm 在列表里,说明加载成功了。
- 先加载
vsp1.ko(VSP驱动) - 再加载
rcar-du-drm.ko(DU驱动) - 最后检查
/dev/dri/目录下是否有card0或controlD64设备节点
4.4 调试手段
驱动加载完了,怎么知道它工作正常?我常用的调试手段有这几个:
- dmesg 日志:加载模块后立刻看内核日志。
dmesg | tail -50。如果看到 "rcar-du: probe failed" 之类的错误,说明初始化有问题。 - DRM调试接口:内核提供了
/sys/kernel/debug/dri/目录,里面能看到每个DRM设备的状态。比如cat /sys/kernel/debug/dri/0/name可以查看设备名称。 - modinfo:查看模块的详细信息,包括作者、描述、参数等。
modinfo rcar-du-drm.ko。 - strace:如果应用程序打不开DRM设备,用
strace -e openat,ioctl跟踪系统调用,看是哪个步骤失败了。
mount -t debugfs none /sys/kernel/debug。有些文件系统默认没挂载,不挂的话 /sys/kernel/debug/dri/ 目录是空的。
4.5 知识体系图
下面这张图总结了本章的核心流程,从内核配置到模块加载再到调试,一条线串下来:
4.6 常见问题与避坑
最后,我总结几个实际项目中容易踩的坑:
- 模块加载顺序错误:先加载DU再加载VSP,会导致DU初始化时找不到VSP,probe失败。正确顺序是先VSP后DU。
- 内核版本不匹配:编模块用的内核头文件版本必须和运行内核一致。否则
insmod会报 "Invalid module format"。用uname -r确认版本。 - debugfs未挂载:前面提过,不挂载debugfs就看不了DRM状态。很多新手会忽略这一步。
- 设备树节点缺失:DU驱动依赖设备树中的
rcar-du节点。如果设备树里没配或者配错了,驱动加载成功但不会创建DRM设备。
#!/bin/sh
modprobe vsp1
modprobe rcar-du-drm
sleep 1
ls /dev/dri/
dmesg | tail -10
嗯,这一章的内容就到这儿。配置、编译、加载、调试,四个步骤环环相扣。把这些搞定了,DU驱动就能在你的板子上跑起来了。