解决模块与内核不匹配问题
(2010-10-08 16:30:33)安装模块时出现:[root@FriendlyARM nfs]# insmod key2.ko
key2: version magic '2.6.32.2 mod_unload modversions ARMv4 ' should be '2.6.32.2-FriendlyARM mod_unload ARMv4 '
这一行的意思就是说,当前插入的模块xxx.ko的版本信息(version magic)与正运行的kernel的版本信息不一致!应该是'2.6.32.2-FriendlyARM mod_unload ARMv4 ',而实际上xxx.ko的版本信息却是:'2.6.32.2mod_unload modversions ARMv4 '; 显然它们之间差别是很小的。实际上,根据上面安装的kernel源码来看,它们应该是没有什么差别的。 所以,下面采用了一种比较极端的方式,强制xxx.ko的版本信息与运行的kernel保持一致。
修改/home/haiyang/linux-2.6.32.2/include/linux/tsrelease.h文件中的宏定义
#define UTS_RELEASE "2.6.32.2
为
#define UTS_RELEASE "2.6.32.2-FriendlyARM”
然后重新编译xxx.ko模块,这时候,它与内核的版本信息应该就是一致的了!试验下来确实如此,xxx.ko已经可以正常工作了!
但是可能会再次出现:
key2: version magic '2.6.32.2 mod_unload modversions ARMv4 ' should be '2.6.32.2-FriendlyARM mod_unload ARMv4 '这是因为arm公司在linux版本中加了自己的标志
此时需要修改:/home/haiyang/linux-2.6.32.2/include/linux/vermagic.h
[root@localhost linux]# vi vermagic.h
#include <linux/utsrelease.h>
#include <linux/module.h>
#ifdef CONFIG_SMP
#define MODULE_VERMAGIC_SMP "SMP "
#else
#define MODULE_VERMAGIC_SMP ""
#endif
#ifdef CONFIG_PREEMPT
#define MODULE_VERMAGIC_PREEMPT "preempt "
#else
#define MODULE_VERMAGIC_PREEMPT ""
#endif
#ifdef CONFIG_MODULE_UNLOAD
#define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload "
#else
#define MODULE_VERMAGIC_MODULE_UNLOAD ""
#endif
#ifdef CONFIG_MODVERSIONS
#define MODULE_VERMAGIC_MODVERSIONS "modversions "
#else
#define MODULE_VERMAGIC_MODVERSIONS ""
#endif
#ifndef MODULE_ARCH_VERMAGIC
#define MODULE_ARCH_VERMAGIC ""
#endif
#define VERMAGIC_STRING
UTS_RELEASE " "
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS
MODULE_ARCH_VERMAGIC
"vermagic.h" 34L, 837C
其中,VERMAGIC_STRING就是内核的版本信息,每个kernel module的版本信息就是从源代码树中的该宏定义获取的。所以,编译模块的时候一定要和实际使用该模块的内核的源代码树保持一致!不要张冠李戴,否则就会在加载模块的时候出现上述问题!
我的修改是#define MODULE_VERMAGIC_MODVERSIONS "modversions "
#define MODULE_VERMAGIC_MODVERSIONS " "
NOTES: 本方法并不是正规的解决办法,我是由于不想重新编译安装linux kernel,并且能够确保当前源码树中的kernel版本与系统运行的kernel版本是相同的情况下采用的权宜之计。如果不能保证这一点,最好不要采用这种方法。以免产生一些莫名其妙的问题!!
实际上最好的办法是:
要在menuconfig中改
解决办法如下:
在配置单中添加如下信息
General setup --->
· Prompt for development and/or incomplete code/drivers
(-EmbedSky) Local version - append to kernel release
内核版本的差异导致的。
例如
(做s3c2410_ts触摸屏的驱动,程序交叉编译后,insmod出现如下的错误:
s3c2410_ts: version magic '2.6.29.4 mod_unload modversions ARMv5 'should be '2.6.29.4-FriendlyARM mod_unload ARMv4 '
linux kernel 中文组的朋友说是编译器版本的问题。重新配置linux kernel,并编译,更新开发板的内核。使用同样的编译器编译module,用nfs mount到开发板,insmod就OK了。果然是内核与module有冲突。)