这个问题是关于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
非空的
M
或SUBDIRS
的存在会导致内核的顶级“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”文件。