https://blog.csdn.net/yubing_615/article/details/52183185

1.问题:本地编译的一整套底层代码down到设备跑都正常,但是由这套代码上传SVN服务器而后checkout出来的代码编译的文件,则出现驱动文件加载不上的情况(驱动以模块方式加载),打印如下
emotor_drv: version magic '3.4.39-lhx SMP preempt mod_unload ARMv7 p2v8 ' should be '3.4.39-9tripod SMP preempt mod_unload ARMv7 p2v8 '

2.分析:初步由打印log信息看,是由version magic不匹配造成,找到信息打印点,kernel/module.c

点击(此处)折叠或打开

  1. printk(KERN_ERR
    "%s: version magic '%s' should be '%s'\n",
  2. mod->name, modmagic, vermagic);

然后

点击(此处)折叠或打开

  1. static const char vermagic[]
    = VERMAGIC_STRING;

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

点击(此处)折叠或打开

  1. #define VERMAGIC_STRING                         \
  2. UTS_RELEASE " "                            \
  3. MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT             \
  4. MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS    \
  5. MODULE_ARCH_VERMAGIC

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

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

再搜KERNELRELEASE

  1. # Read KERNELRELEASE from include/config/kernel.release
    (if it exists)
  2. 382 KERNELRELEASE = $(shell cat include/config/kernel.release 2>
    /dev/null)
  3. 383 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if
    $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)

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

再重新编译

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

  1. cat include/config/kernel.release
  2. 3.3.0-svn87

找到了加载驱动时打印log里的“3.3.0-svn87”

再回到Makefile,搜kernel.release

  1. # Store (new) KERNELRELASE
    string in include/config/kernel.release
  2. 951 include/config/kernel.release: include/config/auto.conf
    FORCE
  3. 952 $(Q)rm
    -f $@
  4. 953 $(Q)echo
    "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"
    > $@

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

查看得知setlocalversion是一个脚本文件,支持自动获取svn,git等源码管理工具的版本号;

3.没有驱动源码的解决方案:

 只需要使version magic一致,驱动就可以顺利加载;由于厂商提供的部分驱动文件没提供源码,并且本地内核也会不断升级(svn版本号会变),所

以最简单的方法是将

附加的-svnXX去掉,这样现存的驱动和后续编译的驱动和内核就都可以保持一致了:

修改如下,

vi   kernel/Makefile 更该为如下代码。

  1. include/config/kernel.release: include/config/auto.conf
    FORCE
  2. 952 $(Q)rm
    -f $@
  3. 953
    #     $(Q)echo
    "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"
    > $@
  4. 954       $(Q)echo
    "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree))"
    > $@

重新编译后,驱动可以正常加载工作了。

PS:当然,version magic是一个很好的功能,如果所有驱动都有源码,对于发布产品的版本,加上svn版本号标记可以有效保证内核驱动版本一致性。

 

4.不改变uImage的解决方案:

vi    kernel/Makefile 更该为如下代码。

950 include/config/kernel.release: include/config/auto.conf FORCE
951         $(Q)rm -f $@
952         $(Q)echo "3.4.39-9tripod" > $@
953         #$(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/set     localversion $(srctree))" > $@

之后重新编译编译内核,再重新编译驱动就可以了。

内核与驱动文件的version magic匹配问题的更多相关文章

  1. 例说linux内核与应用数据通信(三):读写内核设备驱动文件

    [版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet.文章仅供学习交流.请勿用于商业用途]         读写设备文件也就是调用系统调用read()和write(),系 ...

  2. Win64 驱动内核编程-5.内核里操作文件

    内核里操作文件 RING0 操作文件和 RING3 操作文件在流程上没什么大的区别,也是"获得文件句柄->读/写/删/改->关闭文件句柄"的模式.当然了,只能用内核 A ...

  3. Linux内核USB驱动【转】

    本文转载自:http://www.360doc.com/content/12/0321/14/8363527_196286673.shtml 注意,该文件是2.4的内核的驱动源文件,并不保证在2.6内 ...

  4. 【转】 Linux内核中读写文件数据的方法--不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8193954 Linux内核中读写文件数据的方法  有时候需要在Linuxkernel--大 ...

  5. 往android的内核添加驱动及 ueventd.rc 修改【转】

    本文转载自:http://blog.csdn.net/lkqboy2599/article/details/8350100 向android的内核添加驱动,其实就是向linux内核添加驱动.主要在两个 ...

  6. linux内核中的文件描述符(二)--socket和文件描述符

    http://blog.csdn.net/ce123_zhouwei/article/details/8459730 Linux内核中的文件描述符(二)--socket和文件描述符 Kernel ve ...

  7. rdev - 查询/设置内核映像文件的根设备,RAM 磁盘大小或视频模式

    总览 SYNOPSIS rdev [ -rvh ] [ -o offset ] [ image [ value [ offset ] ] ] rdev [ -o offset ] [ image [ ...

  8. 手机支持USB功能、驱动文件对应关系

    手机支持USB功能: 1.UMS(USB MASS Stronge) : 连接PC作为存储盘使用 2.ADB : 用于调试 3.MTP :连接PC作为存储盘使用(win XP需要安装WMP10 以上 ...

  9. 更新新网卡驱动,修复win7雷凌网卡Ralink RT3290在电脑睡眠时和启动网卡时出现蓝屏netr28x.sys驱动文件错误

    更新新网卡驱动,修复win7雷凌网卡Ralink RT3290在电脑睡眠时和启动网卡时出现蓝屏netr28x.sys驱动文件错误 我的本本是win7,雷凌网卡Ralink RT3290   802.1 ...

随机推荐

  1. MySQL 数据库的基本使用

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,而MySQL AB 公司被 Oracle 公司收购,故 MySQL 现在属于 Oracle 公司.MySQL 是一种关联数据 ...

  2. 谈谈C#中各种线程的使用及注意项~

    说到线程,很多人会想到timer吧, 接下来我们就来学习一下 timer 吧,摇摇脑袋,清醒一下,接下来开始学习.... 一.基本概念 1.什么是进程?        当一个程序开始运行时,它就是一个 ...

  3. 王艳 201771010127《面向对象程序设计(java)》第十四周学习总结

    实验十四  Swing图形界面组件 一理论部分 1.Layout Manager(布局管理器):布局管理器是一组类,实现 java.awt.LayoutManager 接口,决定容器中组件的位置和大小 ...

  4. pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。

    pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值.

  5. Eclipse中java文件选中变量名,相同变量都变色显示 .

    第一步设置高亮显示的颜色: Window-->preferences-->General-->Editors-->Text Editors-->Annotations-- ...

  6. 7z命令行简单使用

    7z命令行简单使用 网上有很多博客都有记录7z的命令行使用方式,但看起来乱起八糟的,不知所云. 急于使用者可以直接看实例 注:我仅仅记录我认为常用的命令,毕竟没有那么多的精力去学习不常用的东西. 简介 ...

  7. 02 . Prometheus告警处理

    Prometheus告警简介 告警能力在Prometheus的架构中被划分成两个独立的部分.如下所示,通过在Prometheus中定义AlertRule(告警规则),Prometheus会周期性的对告 ...

  8. Alpha冲刺 —— 5.7

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 Alpha冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.展 ...

  9. 点击label时text输入框被选中

    当点击label标签时,能够选中与其对应的输入框,有2种方式,采用第一种时会产生太多的id,推荐第二种. <form action="03.php"> <labe ...

  10. SpringSecurity(1)---认证+授权代码实现

    认证+授权代码实现 Spring Security是 一种基于 Spring AOP 和 Servlet 过滤器的安全框架.它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和 ...