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

加载树外LKM会导致内核打印警告:
module: loading out-of-tree module taints kernel.
这来自module.c中的检查:if (!get_modinfo(info, "intree")) {
读取get_modinfo似乎表明“intree”只是.ko文件中的一个魔术字符串livnig。

在我在系统中发现的随机LKM上运行readelf会显示以下信息:
readelf -a imon.ko | grep intree 161: 00000000000006c0 9 OBJECT LOCAL DEFAULT 13 __UNIQUE_ID_intree1
在简单的自定义hello_world LKM中查找intree时,不返回任何结果。

真的是这样吗?

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

最佳答案

简而言之,当且仅当正在intree中构建模块时,构建系统才会将MODULE_INFO(intree, "Y");行添加到“modulename.mod.c”文件中。

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

较长的版本....

外部模块通常使用类似于以下的命令构建:

$ make M=`pwd` modules

或旧语法:
$ make SUBDIRS=`pwd` modules

非空的MSUBDIRS的存在会导致内核的顶级“Makefile”设置KBUILD_EXTMOD变量。不会为普通的内核build设置它。

对于模块构建的第2阶段(输出“构建模块,第2阶段”消息时),make运行“scripts/Makefile.modpost” makefile。当设置了scripts/mod/modpost时,它将以不同的选项运行KBUILD_EXTMOD。特别地,当设置了-I时,使用KBUILD_EXTMOD选项。

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

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

10-07 16:27