近期把开发从 SVN 迁移到了 Git 上。其实一早就遇到一个问题,那就是 Linux kernel 在 SVN 的版本控制下编译得好好的,但是换成 Git 做版本控制之后,即便是完全一模一样的两套目录树,编译出来就是不一样!
我晕,Linux 编译结果还跟版本控制环境有关?查了资料,还真是有关……
本文地址:https://segmentfault.com/a/1190000007226913
ReferenceLinux内核模块加载时的版本检查
修改utsrelease.h 文件里面的版本号后
向linux内核版本号添加字符/为何有时会自动添加“+”号
关于CONFIG_LOCALVERSION_AUTO设置去掉内核版本号SVN后缀
去掉SVN管理kernel编译后版本自动变化
非开源的驱动程序如何绕过version magic的检查
繞過linux Driver Vermagic檢查
Linux 内核在编译时,在根目录的 Makefile 最开头有几个宏,决定了编译出来的 Linux 基本版本号。
我用的内核版本比较老,是这样的:
VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 36 EXTRAVERSION = ...
而内核代码在获得这个基本版本号,则需要包含include/linux/version.h文件:
#define LINUX_VERSION_CODE 132644 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
其中LINUX_VERSION_CODE就是(2 << 16) + (6 << 8) + (36 << 0)
这个宏很重要,举个例子:不同的 Linux 内核的 ioctl 函数原型是不同的,但是你的驱动又不想写两套,这个时候就应该这么写:
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)) static long my_ioctl (struct file *file, unsigned int req, unsigned long arg) #else static int my_ioctl (struct inode *inode, struct file *file, unsigned int req, unsigned long arg) #endif { // brah brah brah ... }
这里请注意内核的include/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
其中UTS_RELEASE宏来自于include/generated/utsrelease.h文件。
首先,这个文件是自动创建的,你修改了也没用。
其次,这个版本号的来源很复杂,除了 Linux 基础版本号(也就是 Makefile 的前三个变量)之外,还依赖很多变量:
Makefile 里面的EXTRAVERSION宏,这是紧跟在基础版本号后面的
make menuconfig 时指定的CONFIG_LOCALVERSION_AUTO配置宏,决定了到scripts/setlocalversion里面去添加什么样的附加内容
LOCALVERSION,貌似一般情况下这个宏是没有定义的
而这个VERMAGIC_STRING有什么用呢?这经常是用在一些自定义的内核模块里面。如果内核模块的实现依赖于具体 Linux 内核发行版的话,在 insmod 的时候就需要判断内核的 VERMAGIC_STRING。很多情况下,这里面会包含很多信息。
比如我遇到问题的内核模块,其完整的VERMAGIC_STRING就是:“2.6.36+ mod_unload MIPS32_R2 32BIT”
我遇到的错误是这样的,内核执行时,网卡无法加载,以致设备没有网络。可以看到串口有这么一句错误信息:
my_net_adapt: version magic "2.6.36+ mod_unload MIPS32_R2 32BIT " should be "2.6.36 mod_unload MIPS32_R2 32BIT "
根本的解决办法,是消除掉前面的 magic 里的加号,让两个 version magic 变成一模一样的。但是我找了资料也没找到为啥。这里要求各路大神了。
将就的解决办法,就是让两个 version magic 都加上加号,这样 magic 检查就可以通过啦。
查看我的 utsrelease.h 文件,可以看到其内容是 “2.6.36”。那么解决方案就有两种:
在目录的 Makefile,改第四个变量为 “EXTRAVERSION = +”。
在 Linux 的根目录下,创建一个没有用的 “.git” 空文件夹,让 setlocalversion 以为这是一个 Git 项目,从而自动加上加号。
第二个方案是基于一个前提的:Linux 根目录不是我整个工程的根目录,因而整个工程的 .git 文件夹在别处。
于是,问题解决了。我们测试也确认这台内核编译出来是 OK 的。但说实话,具体原因是什么,还要研究研究
——为什么在 SVN 下面就没问题,在 Git 就有问题呢?
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/9592.html
摘要:发起部署时,为该上线单开辟一个独立空间,检出代码,选择上线单中的文件可能带版本号同步到目标机群。 GIT配置安装 git 项目配置指南 git部署是最推荐的方式,它无论对于何种语言都是合适的。 一、基本要求: 宿主机php进程用户www_php(假如,可通过配置的检测查看或ps aux|grep php)的ssh-key要加入git/gitlab的deploy-keys。当然也可以ht...
摘要:发起部署时,为该上线单开辟一个独立空间,检出代码,选择上线单中的文件可能带版本号同步到目标机群。 GIT配置安装 git 项目配置指南 git部署是最推荐的方式,它无论对于何种语言都是合适的。 一、基本要求: 宿主机php进程用户www_php(假如,可通过配置的检测查看或ps aux|grep php)的ssh-key要加入git/gitlab的deploy-keys。当然也可以ht...
摘要:浅析笔者在此整理了常见的命令,的重要性无需多言,与其再百度海中搜索命令,不妨尝试收藏笔者的此篇作品。旨在快速高效地处理无论规模大小的任何软件工程。其最大特色就是分支及合并操作非常快速简便。 浅析git 笔者在此整理了常见的git命令,git的重要性无需多言,与其再百度海中搜索git命令,不妨尝试收藏笔者的此篇作品。希望对你的学习有所帮助。 版本控制系统之git Git: (一)简介:G...
摘要:浅析笔者在此整理了常见的命令,的重要性无需多言,与其再百度海中搜索命令,不妨尝试收藏笔者的此篇作品。旨在快速高效地处理无论规模大小的任何软件工程。其最大特色就是分支及合并操作非常快速简便。 浅析git 笔者在此整理了常见的git命令,git的重要性无需多言,与其再百度海中搜索git命令,不妨尝试收藏笔者的此篇作品。希望对你的学习有所帮助。 版本控制系统之git Git: (一)简介:G...
阅读 3357·2021-11-23 09:51
阅读 1286·2021-11-04 16:08
阅读 2809·2021-09-03 10:29
阅读 3443·2021-09-02 09:54
阅读 3423·2019-08-30 15:55
阅读 2397·2019-08-30 15:54
阅读 850·2019-08-29 16:30
阅读 1908·2019-08-29 16:15