1.问题:本地编译的一整套底层代码down到设备跑都正常,但是由这套代码上传SVN服务器而后checkout出来的代码编译的文件,则出现驱动文件加载不上的情况(驱动以模块方式加载),打印如下
log: version magic '3.3.0 preempt mod_unload ARMv5 ' should be '3.3.0-svn87 preempt mod_unload ARMv5 '
2.分析:初步由打印log信息看,是由version magic不匹配造成,找到信息打印点,kernel/module.c
点击(此处)折叠或打开
-
printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
- mod->name, modmagic, vermagic);
点击(此处)折叠或打开
- static const char vermagic[] = VERMAGIC_STRING;
点击(此处)折叠或打开
-
#define VERMAGIC_STRING \
-
UTS_RELEASE " " \
-
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
-
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
- MODULE_ARCH_VERMAGIC
由名字推测是编译内核时版本号给打上了svn相关标记,但是在内核源码中没看到任何地方定义UTS_RELEASE,再到Makefile找,搜到这句
点击(此处)折叠或打开
- (echo \#define UTS_RELEASE \"$(KERNELRELEASE)\";)
点击(此处)折叠或打开
-
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
-
382 KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
- 383 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
一次,果然生成了include/config/kernel.release文件,查看内容
点击(此处)折叠或打开
-
cat include/config/kernel.release
- 3.3.0-svn87
再回到Makefile,搜kernel.release
点击(此处)折叠或打开
-
# Store (new) KERNELRELASE string in include/config/kernel.release
-
951 include/config/kernel.release: include/config/auto.conf FORCE
-
952 $(Q)rm -f $@
- 953 $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@
查看得知setlocalversion是一个脚本文件,支持自动获取svn,git等源码管理工具的版本号;
3.解决:
只需要使version magic一致,驱动就可以顺利加载;由于厂商提供的部分驱动文件没提供源码,并且本地内核也会不断升级(svn版本号会变),所以最简单的方法是将
附加的-svnXX去掉,这样现存的驱动和后续编译的驱动和内核就都可以保持一致了:
修改如下,
点击(此处)折叠或打开
-
include/config/kernel.release: include/config/auto.conf FORCE
-
952 $(Q)rm -f $@
-
953 # $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@
- 954 $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree))" > $@
PS:当然,version magic是一个很好的功能,如果所有驱动都有源码,对于发布产品的版本,加上svn版本号标记可以有效保证内核驱动版本一致性。