如何为特定Linux内核模块添加编译生成后执行的额外命令
问题说明
假设在drivers/platform/ab21/路径下存在驱动文件axpu.c,该驱动通过module_platform_driver宏完成声明,且已完成内核配置将该驱动编译为内核模块。需求为每次该模块被重新编译构建后,自动将生成的drivers/platform/ab21/axpu.ko文件拷贝到/srv/tftp目录下。
此前尝试过两种修改Makefile的方式均未生效:
- 在
drivers/platform/ab21/目录下的Makefile中添加规则:
axpu.ko: \cp axpu.ko /srv/tftp
- 修改内核顶层Makefile,添加规则:
.PHONY: $(PHONY) xxx xxx: drivers/platform/ab21/axpu.ko \cp ^$ /src/tftp/.
失败原因分析
- 第一种子目录Makefile修改方案的问题:
- 自定义的
axpu.ko规则没有接入内核Kbuild构建流程,内核编译模块时不会触发该自定义规则,甚至重定义目标文件规则会干扰正常的编译逻辑 - 规则无正确依赖关系,即便被触发也可能在
axpu.ko生成前就执行拷贝,导致文件找不到
- 自定义的
- 第二种顶层Makefile修改方案的问题:
- 自定义的
xxx目标没有加入默认构建目标(all/modules)的依赖列表,make执行默认构建时根本不会运行该目标下的命令 - 语法错误:自动变量写反,
^$是无效写法,取依赖文件应使用$<(第一个依赖)或$^(所有依赖) - 路径错误:拷贝目标路径写为
/src/tftp,和需求的/srv/tftp不符
- 自定义的
正确实现方案
推荐修改drivers/platform/ab21/目录下的Makefile,保留原有obj-m += axpu.o配置不变,在文件末尾追加符合Kbuild规范的后处理规则,仅当axpu.ko被重新编译更新时才执行拷贝,不会做无用操作:
# 原有配置保留 obj-m += axpu.o # 新增:ko编译完成后自动拷贝到tftp目录 quiet_cmd_copy_tftp = COPY $@ -> /srv/tftp cmd_copy_tftp = cp $@ /srv/tftp/ $(obj)/axpu.ko: $(obj)/axpu.o FORCE $(call if_changed,copy_tftp)
如果习惯修改顶层Makefile实现,也可以在内核顶层Makefile中找到modules目标的定义段,追加以下内容:
# 将拷贝目标加入modules目标的依赖 modules: copy_axpu_tftp .PHONY: copy_axpu_tftp copy_axpu_tftp: drivers/platform/ab21/axpu.ko cp $< /srv/tftp/
注意事项
- 执行编译前请确认
/srv/tftp目录存在,且当前执行make的用户对该目录有写入权限 - 子目录Makefile中编写Kbuild规则时,目标文件前要加
$(obj)/前缀,避免因递归构建时工作目录变化导致找不到文件 - 若需要强制覆盖tftp目录下的旧文件,可以给cp加
-f参数,即cp -f $@ /srv/tftp/,不需要加反斜杠忽略别名
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

