Skip to main content
大多数 Qualcomm® Linux 驱动直接从内核源码树编译。有些驱动在内核树之外维护——称为树外(out-of-tree)或动态可加载内核模块(DLKM)驱动——它们使用独立的 Makefile 或 Yocto 构建系统单独构建。 Qualcomm 内核图形支持层(KGSL)GPU 驱动就是一个例子:其位于 recipes-graphics/kgsl-dlkm/kgsl-dlkm_git.bb 的配方将该驱动作为树外模块构建并安装。

构建并自动加载模块

独立 Makefile

创建一个通过 $(MAKE) -C 委托给内核构建系统的 Makefile:
在调用 make 之前,将 KERNEL_SRC 设置为已配置内核源码树的路径。

Yocto 配方

通过继承 module 类,将树外模块集成到 Yocto 构建中。该类会自动处理 make modules 和 make modules_install。
KERNEL_MODULE_AUTOLOAD 变量会将模块名写入目标 rootfs 中的 /etc/modules-load.d/,使 systemd-modules-load 在每次启动时插入该模块。

实际示例:KGSL

KGSL 配方展示了一个生产环境中的树外模块:
注意 blacklist msm_kgsl 条目:当树外 KGSL 模块存在时,它会阻止上游树内的桩(stub)模块被加载。 有关 Yocto 中树外模块的更多信息,请参阅 Working with Out-of-Tree Modules。

模块版本管理策略

内核符号版本控制(MODVERSIONS)

当内核配置中设置了 CONFIG_MODVERSIONS=y 时,内核会为每个导出的符号嵌入一个 CRC 校验和。只有当模块的各符号 CRC 与运行中内核匹配时才会被加载,从而防止插入静默的二进制不兼容模块。 要验证目标设备上是否启用了 MODVERSIONS:
针对不同内核树或不同 defconfig 构建的模块,如果存在任何 CRC 不匹配,加载时会产生错误:

vermagic 兼容性

每个 .ko 文件都嵌入了一个 vermagic 字符串,它编码了构建时使用的内核版本、SMP 标志和编译器版本。运行中的内核会拒绝任何 vermagic 不完全匹配的模块。 在部署前检查模块的 vermagic:
表:vermagic 字段

在 Yocto 中固定版本

为确保树外模块始终针对与运行镜像相同的内核版本进行构建,请在模块的 .bb 文件中将 DEPENDS 和 RDEPENDS 设置为内核配方:
Yocto 的 module 类会自动将 KERNEL_SRC 和 KERNELRELEASE 设置为所选内核配方中的值,因此模块的 Makefile 无需任何手动配置即可获取正确的头文件和符号表。