将可加载内核模块标记为树内

Marking loadable kernel module as in-tree

这个问题是关于linux内核4.10的。

加载树外 LKM 会导致内核打印警告:

module: loading out-of-tree module taints kernel.

这是从 module.c 中的检查中提出的: if (!get_modinfo(info, "intree")) {

阅读 get_modinfo 发现 "intree" 只是 .ko 文件中的一个魔术字符串 livnig。

运行 readelf 我在系统中发现的随机 LKM 显示如下:

readelf -a imon.ko | grep intree 161: 00000000000006c0 9 OBJECT LOCAL DEFAULT 13 __UNIQUE_ID_intree1

在简单的自定义 hello_world LKM returns 中寻找 intree 时没有结果。

真的是这样吗?

如何将某些模块标记为在树中?是通过向模块添加宏(如 MODULE_LICENCE),还是通过以特定方式或其他方式构建模块来完成?

简而言之,当且仅当模块是正在构建 intree。

有一种明显的方法可以通过将该行添加到模块的常规“.c”文件之一来欺骗系统,但我不确定您为什么要这样做。

更长的版本....

外部模块通常使用类似这样的命令构建:

$ make M=`pwd` modules

或旧语法:

$ make SUBDIRS=`pwd` modules

非空 MSUBDIRS 的存在导致内核的顶层 "Makefile" 设置 KBUILD_EXTMOD 变量。它不会为正常的内核构建设置。

对于模块构建的第 2 阶段(当输出消息 "Building modules, stage 2" 时),make 运行 "scripts/Makefile.modpost" 生成文件。当设置 KBUILD_EXTMOD 时,它会以不同的选项运行 scripts/mod/modpost。特别是,当设置 KBUILD_EXTMOD 时使用 -I 选项。

查看 "scripts/mod/modpost.c" 中 modpost 的源代码,external_module 变量的初始值为 0,但 -I 选项将其设置为 1。函数 add_intree_flag() 被调用,第二个参数 is_intree 设置为 !external_module。当且仅当其 is_intree 参数为真时,add_intree_flag() 函数将 MODULE_INFO(intree, "Y"); 写入“modulename.mod.c”文件。

因此树内模块和外部模块的区别在于“模块名.mod.c”文件中存在MODULE_INFO(intree, "Y");宏调用。这被编译为“modulename.mod.o”并与模块的其他目标文件链接以形成“modulename.ko”文件.