kernel与.ko的version magic匹配

转:http://blog.chinaunix.net/uid-24708340-id-5057664.html
有人说先试试这个 modprobe --force-modversion --force-vermagic
可惜我的busybox不支持

我是最近直接在源码下打了个git,导致新编的镜像有了git的版本信息,而以前编写的驱动,当时没打git呢,所以没有git的版本信息。那就出问题了。老的驱动.ko在我的新内核里加载不了

最近做一个底层源码版本管理的工作:本地调试OK的内核源码,驱动源码,文件系统等,作为一个工程上传至SVN服务器,以便同事们可以方便共享同步代码;

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;

可知打印语句实际由宏VERMAGIC_STRING定义,接着看include/linux/vermagic.h

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

打印信息的不同点“'3.3.0”和“3.3.0-svn87”是由宏UTS_RELEASE生成,那么重点关注UTS_RELEASE
由名字推测是编译内核时版本号给打上了svn相关标记,但是在内核源码中没看到任何地方定义UTS_RELEASE,再到Makefile找,搜到这句

(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\";)

再搜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)

可见KERNELRELEASE由include/config/kernel.release文件读取获得,但是内核源码中并无此文件(为查找差异之前将内核make distclean掉了),再重新编译

一次,果然生成了include/config/kernel.release文件,查看内容

cat include/config/kernel.release
3.3.0-svn87

找到了加载驱动时打印log里的“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))" > $@

kernel.release就是在这里生成的,前面版面号忽略,“-svn87”实际上是执行setlocalversion得到svn版本号加上去的;

查看得知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版本号标记可以有效保证内核驱动版本一致性。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_kerneler

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值