微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

linux 内核加载错误 Invalid module format

遇到这种情况后,通过 dmesg 看一下内核日志。

如果发现有如下日志,那就好办了。

hello: version magic '2.6.33.3 ' should be '2.6.33.3-85.fc13.i686.PAE SMP mod_unload 686 '

修改内核源码文件include/linux/vermagic.h

把如下 VERMAGIC_STRING 宏的定义删掉

#define VERMAGIC_STRING \ 
UTS_RELEASE " "\ 
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ 
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS\ 
MODULE_ARCH_VERMAGIC

然后,从新定义一个VERMAGIC_STRING宏

#define VERMAGIC_STRING  "should be '2.6.33.3-85.fc13.i686.PAE SMP mod_unload 686 "

注意,双引号中的内容,要与dmesg输出的日志中should be后面的单引号中的内容,完全相同,别漏掉了那个空格哦。

好了,现在重新编译一下你的模块,再加载一次吧。

基本上应该会OK啦。

需要指出的是,这种方法很不正规。

如果你只是急于开发验证模块,不想重新编译安装新内核,可以临时使用一下。

而且,用的时候,也要注意一下,模块编译所用的内核版本与实际运行的内核版本,

大体上也要比较接近才行。否则可能会出问题的。

如果是正式的产品,请务必保证,模块是基于实际运行的内核编译出来的。


好了,问题解决了,下面再闲说几句模块的加载。

实际上,Linux下模块的加载,是通过系统调用sys_init_module完成的。

对于2.6的内核,sys_init_module的代码在kernel/module.c中

sys_init_module调用load_module,load_module则检查模块的 vermagic 是否与内核的一样。

modmagic = get_modinfo(sechdrs,infoindex,"vermagic");
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
tainted |= TAINT_FORCED_MODULE;
printk(KERN_WARNING "%s: no version magic,tainting kernel.\n",      mod->name);
} else if (!same_magic(modmagic,vermagic)) {
printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",      mod->name,modmagic,vermagic);
err = -ENOEXEC;
goto free_hdr;
}

vermagic是内核中保存的magic,其定义如下。可见他的值也就来自于我们上面定义的宏。

static const char vermagic[] = VERMAGIC_STRING;

除了检查vermagic,load_module还会检查模块的许可证的兼容性,

具体调用链是:load_module->set_license->license_is_gpl_compatible

从下面license_is_gpl_compatible的代码,可以看出内核支持的许可证类型。

static inline int license_is_gpl_compatible(const char *license)
{
        return (strcmp(license,"GPL") == 0
                || strcmp(license,"GPL v2") == 0
                || strcmp(license,"GPL and additional rights") == 0
                || strcmp(license,"Dual BSD/GPL") == 0
                || strcmp(license,"Dual MIT/GPL") == 0
                || strcmp(license,"Dual MPL/GPL") == 0);
}

因此,我们的模块代码中MODULE_LICENSE("Dual MIT/GPL")这一项,也要注意符合license_is_gpl_compatible中的要求才行。否则的话,加载模块时,可能又要看到如下的告警了 :)

hello: module license  'xxx'  taints kernel.

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐