其实这句话已经表达了错误的原因了:加载树外模块污染内核,意思是我们加载的驱动中需要的设备树节点在当前设备树文件中未找到。
我们需要检查驱动文件中of_match_table数组中的compatible属性是否在设备树中有对应节点。
static const struct of_device_id of_match_buttons[] =
{
{.compatible = "jz2440_button", .data= NULL}, //匹配名字为jz2440_button的子节点
{/* sentinel */},
};
static struct platform_driver buttons_drv =
{
.probe = buttons_probe,
.remove = buttons_remove,
.driver ={
.name = "myButtons",
.of_match_table = of_match_buttons, //表示匹配哪些设备树节点,匹配成功后调用probe函数
}
};
loading out-of-tree module taints kernel由/kernel/module.c的check_modinfo()打印(内核版本linux-4.19-rc3)
具体的调用过程:
在命令行中使用insmod加载驱动,会调用到busybox中的相关函数。(位于busybox/modutils/ insmod.c)
insmod_main
|
--> bb_init_module
|
--> init_module
init_module是定义在busybox/modutils/modutils.c的宏
#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
最终会调用到对应内核层的 sys_init_module 函数。(/kernel/module.c)
SYSCALL_DEFINE3(init_module,....)
load_module()
layout_and_allocate() //找出模块布局,分配所有内存
check_modinfo() //校验模块信息
if (!get_modinfo(info, "intree")) {
if (!test_taint(TAINT_OOT_MODULE))
pr_warn("%s: loading out-of-tree module taints kernel.\n",
mod->name);
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
}
最近调一个spi驱动的时候刚好也遇到了这个问题:
打印了loading out-of-tree module taints kernel,但是probe函数也正常运行了,然后驱动也正常运行,感觉之前写下来的结论哪里不对[狗头]。