3、内核配置与编译:如何开启 CONFIG_DMA_SHARED_BUFFER、CONFIG_DRM 及其 Prime 相关选项
在动手编写 DRM Prime 驱动之前,必须确保 Linux 内核已经正确配置并编译了 DMA-BUF 基础设施和 DRM 子系统的 Prime 支持。本章将详细讲解关键内核选项的定位、依赖关系以及配置验证方法,帮助您构建一个支持 DMA-BUF 导出与导入的内核环境。
3.1 核心配置选项概览
DMA-BUF 与 DRM Prime 的配置涉及三个层次:通用内存共享层、DRM 核心层以及具体 GPU/显示控制器驱动层。下表列出了必须开启的选项及其功能描述:
| 配置选项 | 所属子系统 | 功能描述 | 默认值 |
|---|---|---|---|
CONFIG_DMA_SHARED_BUFFER |
通用内核 | 启用 DMA-BUF 框架,提供缓冲区共享、同步和文件描述符管理 | y(通常默认开启) |
CONFIG_DRM |
DRM 核心 | 启用 Direct Rendering Manager 框架,提供 KMS 和 GEM 内存管理 | n |
CONFIG_DRM_PRIME |
DRM 核心 | 启用 DRM Prime 辅助函数,实现 GEM 对象与 DMA-BUF 的互转 | n(依赖 CONFIG_DRM) |
CONFIG_DRM_GEM_SHMEM_HELPER |
DRM 辅助 | 提供基于 shmem 的 GEM 实现,简化 Prime 导出/导入的页分配 | n(推荐开启) |
配置提示: 在嵌入式平台(如 i.MX8、RK3588、STM32MPU)上,
CONFIG_DMA_SHARED_BUFFER 通常已被 defconfig 默认启用。如果手动裁剪内核,请务必确认该选项未被关闭,否则 DRM Prime 将无法工作。
3.2 配置依赖关系与 Kconfig 解析
理解 Kconfig 的依赖链有助于避免配置遗漏。以下是 DRM Prime 相关选项的简化依赖关系图:
关键依赖规则如下:
- CONFIG_DRM_PRIME 依赖于
CONFIG_DRM和CONFIG_DMA_SHARED_BUFFER。如果后者未开启,DRM Prime 选项将不可见。 - CONFIG_DRM_GEM_SHMEM_HELPER 是一个辅助选项,提供
drm_gem_shmem_prime_export_sg_table()等默认实现。强烈建议开启,可大幅简化驱动开发。 - 具体 GPU 或显示控制器驱动(如
CONFIG_DRM_IMX_LCDIF、CONFIG_DRM_ROCKCHIP)通常在 Kconfig 中使用select DRM_PRIME自动拉取依赖。
3.3 配置操作步骤
以下步骤基于 Linux 内核源码树,使用 menuconfig 图形化配置工具。命令行配置方式(make config 或直接编辑 .config)原理相同。
- 进入内核源码根目录,加载目标平台的默认配置(以 ARM64 为例):
make ARCH=arm64 defconfig - 启动 menuconfig:
make ARCH=arm64 menuconfig - 开启 DMA-BUF(通常位于 "Device Drivers" → "Generic Driver Options"):
Device Drivers ---> Generic Driver Options ---> [*] DMA Buffer Sharing (CONFIG_DMA_SHARED_BUFFER) - 开启 DRM 核心(位于 "Device Drivers" → "Graphics support"):
Device Drivers ---> Graphics support ---> <*> Direct Rendering Manager (XFree86 4.1.0 and later DRI support) (CONFIG_DRM) - 确认 DRM Prime 已自动选中:进入 DRM 子菜单,检查
CONFIG_DRM_PRIME是否为[*]或<*>。如果未自动选中,手动开启:Graphics support ---> Direct Rendering Manager ---> [*] Enable PRIME buffer sharing (CONFIG_DRM_PRIME) - 开启 GEM shmem helper(推荐):
Graphics support ---> Direct Rendering Manager ---> [*] GEM shmem helper (CONFIG_DRM_GEM_SHMEM_HELPER) - 开启具体平台驱动(以 NXP i.MX8M 为例):
Graphics support ---> <*> DRM Support for i.MX DCSS <*> DRM Support for i.MX LCDIF - 保存配置并退出,生成
.config文件。
常见错误: 如果
CONFIG_DRM_PRIME 选项呈灰色不可选,请检查 CONFIG_DMA_SHARED_BUFFER 是否已开启。某些架构(如 x86)的默认配置可能关闭了 DMA-BUF,需要手动打开。
3.4 配置验证方法
编译内核前,建议通过以下方式验证配置是否正确:
3.4.1 使用 grep 检查 .config 文件
grep -E "CONFIG_(DMA_SHARED_BUFFER|DRM|DRM_PRIME|DRM_GEM_SHMEM_HELPER)" .config
期望输出示例:
CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DRM=y
CONFIG_DRM_PRIME=y
CONFIG_DRM_GEM_SHMEM_HELPER=y
3.4.2 使用 scripts/config 脚本检查
scripts/config --state CONFIG_DMA_SHARED_BUFFER
scripts/config --state CONFIG_DRM_PRIME
如果返回 y 或 m,表示已开启。
3.4.3 编译后验证内核模块
编译并启动新内核后,检查 /sys/kernel/debug/dri/ 目录是否存在,以及 /sys/kernel/debug/dma_buf/ 是否包含缓冲区信息:
ls /sys/kernel/debug/dri/
ls /sys/kernel/debug/dma_buf/
验证要点: 如果
/sys/kernel/debug/dma_buf/ 目录存在,说明 DMA-BUF 框架已正确初始化。如果 /sys/kernel/debug/dri/ 下出现 0/name 等子目录,说明 DRM 设备已注册成功。
3.5 配置选项与 Prime 功能的对应关系
下表总结了每个配置选项对 Prime 导出/导入功能的具体影响:
| 功能点 | 所需配置 | 缺失后果 |
|---|---|---|
| 分配 DMA-BUF 并导出为 fd | CONFIG_DMA_SHARED_BUFFER + CONFIG_DRM_PRIME |
dma_buf_export() 返回 NULL,导出失败 |
| 从 fd 导入 DMA-BUF 到 GEM 对象 | CONFIG_DRM_PRIME + CONFIG_DRM_GEM_SHMEM_HELPER |
drm_gem_prime_import() 缺少默认实现,需手动编写 |
| 跨设备共享(如 GPU 到 VPU) | CONFIG_DMA_SHARED_BUFFER + IOMMU 支持 |
共享时出现 DMA 地址映射错误 |
使用 drm_prime_get_sg_table() 等辅助函数 |
CONFIG_DRM_GEM_SHMEM_HELPER |
链接时缺少符号,编译失败 |
3.6 常见平台配置示例
以下列出几种常见嵌入式平台的 Prime 相关配置片段,供参考:
| 平台 | 关键配置项 | 备注 |
|---|---|---|
| NXP i.MX8M Plus | CONFIG_DRM_IMX_DCSS=yCONFIG_DRM_IMX_LCDIF=y |
DCSS 和 LCDIF 驱动均 select DRM_PRIME |
| Rockchip RK3588 | CONFIG_DRM_ROCKCHIP=yCONFIG_ROCKCHIP_VOP2=y |
VOP2 驱动依赖 DRM_PRIME |
| STM32MP157 | CONFIG_DRM_STM=yCONFIG_DRM_STM_DSI=y |
STM DRM 驱动通过 select 开启 Prime |
| QEMU virt (测试用) | CONFIG_DRM_VIRTIO_GPU=y |
virtio-gpu 支持 Prime 导出/导入 |
开发建议: 如果使用 QEMU 或模拟器进行 Prime 功能验证,推荐开启
CONFIG_DRM_VIRTIO_GPU 和 CONFIG_DRM_VIRTIO_GPU_PRIME(如果存在)。这可以在没有真实硬件的情况下测试 Prime 导出/导入流程。
3.7 编译与常见问题排查
配置完成后,执行编译:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
如果编译过程中出现与 Prime 相关的错误,请参考下表排查:
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
undefined reference to 'dma_buf_export' |
CONFIG_DMA_SHARED_BUFFER 未开启 |
检查 .config,确保该选项为 y |
error: 'struct dma_buf_export_info' has no member named 'priv' |
内核版本过旧,API 不兼容 | 升级内核至 5.10+,或适配旧版 API |
WARNING: modpost: missing MODULE_LICENSE() |
驱动模块未声明许可证 | 在驱动源码中添加 MODULE_LICENSE("GPL") |
运行时 drm_prime_import 返回 -ENOSYS |
驱动未实现 gem_prime_import 回调 |
实现 struct drm_driver 中的 Prime 回调函数 |
本章小结: 正确配置
CONFIG_DMA_SHARED_BUFFER、CONFIG_DRM 和 CONFIG_DRM_PRIME 是 DRM Prime 驱动开发的基础。建议在开发板上使用 make savedefconfig 保存最小配置,便于后续复用。下一章将基于已配置好的内核,开始编写第一个 Prime 导出驱动的核心代码。