这个问题是关于Linux内核4.10。
加载一个树外的LKM会导致内核打印一个警告:
module: loading out-of-tree module taints kernel.
这从module.c中检查引起 : if (!get_modinfo(info, "intree")) {
读取get_modinfo
它接缝,“intree”只是一个魔术字符livnig内.ko
文件。
在我的系统中find的随机LKM上运行readelf
显示:
readelf -a imon.ko | grep intree 161: 00000000000006c0 9 OBJECT LOCAL DEFAULT 13 __UNIQUE_ID_intree1
当在一个简单的自定义hello_world中寻找intree
时,LKM不会返回任何结果。
这是真的吗?
一些模块如何被标记为在树中? 是通过向模块添加一个macros来完成的吗(比如MODULE_LICENCE),还是通过特定的方式构build模块?
总之,构建系统设法添加行MODULE_INFO(intree, "Y");
到“ modulename.mod.c ”文件,当且仅当该模块正在构建intree。
有一个显而易见的方法来通过将该行添加到模块的常规“.c”文件中来愚弄系统,但是我不确定为什么要这样做。
更长的版本….
外部模块通常使用与此类似的命令来构建:
$ make M=`pwd` modules
或旧的语法:
$ make SUBDIRS=`pwd` modules
一个非空M
或SUBDIRS
会导致内核的顶层“Makefile”设置KBUILD_EXTMOD
变量。 它不会被设置为正常的内核版本。
对于模块构建阶段2(当输出“构建模块,阶段2”消息时),运行“脚本/ Makefile.modpost”生成文件。 当KBUILD_EXTMOD
被设置时,它运行带有不同选项的scripts/mod/modpost
。 特别是,当设置KBUILD_EXTMOD
时使用-I
选项。
在“scripts / mod / modpost.c”中查看modpost
的源代码, external_module
变量的初始值为0,但是-I
选项将其设置为1.使用第二个参数is_intree
设置函数add_intree_flag()
to !external_module
。 add_intree_flag()
函数写入MODULE_INFO(intree, "Y");
当且仅当它的is_intree
参数为true时,才将其is_intree
“ modulename.mod.c ”文件。
所以intree模块和外部模块的区别在于MODULE_INFO(intree, "Y");
在“modulename.mod.c”文件中调用宏。 这被编译为“ modulename.mod.o ”,并与模块的其他目标文件链接,形成“ modulename .ko”文件。