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 modulesmake 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 文件中将 DEPENDSRDEPENDS 设置为内核配方:
Yocto 的 module 类会自动将 KERNEL_SRCKERNELRELEASE 设置为所选内核配方中的值,因此模块 Makefile 无需任何手动配置即可获取正确的头文件和符号表。