将树外内核模块做成Buildroot包:构建顺序与安装

驱动必须面向产品内核构建

树外驱动应针对实际交付镜像的内核构建,而不是针对构建机正在运行的内核。配方直接使用/lib/modules/$(uname -r)/build,可能在开发者电脑上看似成功,却在自动化中指向错误架构或错误配置。Buildroot的kernel-module辅助基础设施负责把模块连接到产品内核目录与相应编译参数。

本文固定Buildroot 2025.02,并以Linux 6.12外部模块说明解释内核构建要求。edge-sensor是虚构集成示例,真实源码地址、版本和许可证必须从驱动项目核实,文中不编造这些信息,也没有声称构建内核、模块或目标镜像。

固定驱动源码针对产品内核构建,安装到目标镜像后使用干净配置验证。
概念打包流程;未声称已有内核或驱动构建结果

先固定源码与配置前提

选择不可变源码版本,记录归档校验值和实际许可证文件,并确认它支持目标内核API和架构。“支持Linux”可能仅指某个厂商分支,打包机制不能自动修复接口差异。还应把驱动需要的总线、子系统和固件要求列成独立核查项。

Config.in必须依赖BR2_LINUX_KERNEL,因为辅助基础设施假定配置层已经保证这一条件。其他库和工具链要求仍需分别声明。2025.02实现代码会加入linux构建依赖,并为启用的包请求模块支持,但这不能证明驱动所依赖的所有内核子系统都已正确打开。

辅助基础设施先于主包基础设施

kernel-module提供构建和安装钩子,并不能独立替代generic-package或其他主包基础设施。只有模块的项目通常先调用kernel-module,再调用generic-package;同时包含用户态程序的项目,则可以组合其适合的用户态构建基础设施。

# 上方补充经核实的源码身份与许可证元数据。
EDGE_SENSOR_MODULE_SUBDIRS = driver

$(eval $(kernel-module))
$(eval $(generic-package))

这里假定driver目录含外部模块的Kbuild入口。如果模块位于源码根目录,可以使用默认值。组合自定义钩子前,对照固定版本的辅助规则:需要读取已编译模块的钩子,应在kernel-module注册其构建钩子之后再注册。

只传驱动真正识别的变量

MODULE_MAKE_OPTS向内核构建调用补充变量,适合传递驱动专用开关或有明确说明的版本参数。不应借它重复定义另一套架构和编译器配置。先看上游Kbuild实际读取哪些变量;驱动不读取KVERSION时,给它赋值不会产生预期效果。

LINUX_DIR指向已配置的内核构建目录,LINUX_VERSION_PROBED表示从该目录取得的实际内核release,可能因本地版本后缀不同于配置标签。这些值由Buildroot提供,不应覆盖。保留详细构建日志,证明调用进入了正确目录,并携带正确交叉编译参数。

安装模块不等于完成集成

辅助设施通过Buildroot内核参数调用modules_install。应检查目标树中的模块是否进入正确release目录,并进一步确认最终镜像确实包含它。不要增加未限定目的地的宿主modules_install命令,以免写入构建机的/lib/modules。

依赖元数据和别名必须与最终文件系统中的完整模块集合一致。核对产品最终化路径以及生成的modules.dep或可用的二进制对应文件,仅找到一个.ko不能证明modprobe能够解析依赖。固件、设备描述和用户态配置属于其他资产;模块安装正确仍可能因为这些条件缺失而无法绑定硬件。

保存符号关系与内核产物

Linux 6.12的外部模块说明指出,启用符号版本检查时,modules_prepare不会生成Module.symvers,需要相应完整内核构建产物。不能用导出的用户态头文件代替已配置的内核构建树。

若一个外部模块依赖另一个模块导出的符号,除了明确构建依赖,还要保证modpost能够取得相应符号信息。单纯增加先后顺序不一定完成符号共享。检查上游Kbuild组织方式,并成对保留生产者与消费者产物,不能为了得到预期名称的文件而压制未解析符号诊断。

用干净输出检查增加与移除

建议建立只包含所选内核和驱动配置的新输出目录,检查调用参数、安装路径、模块元数据和最终镜像;再用另一个新目录关闭驱动包,确认镜像没有残留文件。后一个反例能够暴露增量构建遗留模块的问题。

驱动版本、内核配置或模块子目录发生变化,都应进行干净比较。开发时重新构建单包很方便,但不能证明已移除文件从目标树消失。保留旧输出用于诊断,而不是首先删除证据。加载和卸载硬件驱动只应在获准的实验设备上进行,并准备恢复方式,因为操作可能中断设备和服务。

验收与交付约定

验收包括明确的配置前提、正确的基础设施调用顺序、与源码布局一致的模块子目录,以及始终指向所选内核和镜像的构建安装路径。最终化后检查依赖元数据,并确认关闭包的镜像没有旧驱动。源码版本、内核release、配置和安装产物散列应一起保存。

这证明的是打包纪律,不代表驱动运行质量,也不保证未来内核兼容。签名、装载ABI检查和硬件行为仍有各自的验收证据。交付应让其他工程师无需原开发者的宿主内核、私有目录或手工安装步骤,就能重建模块与镜像的配套关系。

类似文章