当前位置: 首页 > 科技观察

Linux内核在Git目录和SVN目录下编译行为不一致的解决方法

时间:2023-03-14 13:51:50 科技观察

最近从SVN迁移到Git开发。其实一大早就遇到了一个问题,就是Linux内核在SVN的版本控制下编译的很好,但是切换到Git进行版本控制后,竟然编译出了两套一模一样的目录树不同!我晕,linux的编译结果也跟版本控制环境有关?查了资料,果然有关系。。。参考Linux内核模块版本加载时检查修改utsrelease.h文件中的版本号,在linux内核版本号中添加字符/为什么有时会自动加“+”关于CONFIG_LOCALVERSION_AUTO设置去掉内核版本号的SVN后缀去除SVN管理编译后自动更改内核版本非开源驱动如何绕过版本魔术检查绕过linux驱动程序Vermagic检查主要知识点总结基本内核版本号当Linux内核是编译后,根目录下的Makefile开头有几个宏,决定了编译出来的Linux的基本版本号。我使用的内核版本比较老,像这样:VERSION=2PATCHLEVEL=6SUBLEVEL=36EXTRAVERSION=...内核代码在获取这个基本版本号的时候需要包含include/linux/version.h文件:#defineLINUX_VERSION_CODE132644#defineKERNEL_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))staticlongmy_ioctl(structfile*file,unsignedintreq,unsignedlongarg)#elsestaticintmy_ioctl(structinode*inode,structfile*file,unsignedintreq,unsignedlongarg)#endif{//brahbrahbrah...}内核扩展版本号这里请注意内核vermagic.h文件的include/,有一个VERMAGIC_STRING宏,定义如下:...#defineVERMAGIC_STRING\UTS_RELEASE""\MODULE_VERMAGIC_SMPMODULE_VERMAGIC_PREEMPT\MODULE_VERMAGIC_VERGMODIODULEDULEDULEDULE_UN\MODULE_ARCH_VERMAGIC其中UTS_RELEASE宏来自于include/generated/utsrelease.h文件。首先这个文件是自动创建的,你修改了也没用。其次,这个版本号的来源非常复杂。除了Linux基础版本号(即Makefile的前三个变量)之外,还取决于很多变量:Makefile中的EXTRAVERSION宏,也就是紧跟在基础版本号之后的make。menuconfig中指定的CONFIG_LOCALVERSION_AUTO配置宏决定LOCALVERSION在scripts/setlocalversion中添加什么样的附加内容。好像这个宏一般没有定义,这个VERMAGIC_STRING有什么用?这经常用在内核模块内部的一些自定义中。如果内核模块的实现依赖于具体的Linux内核发行版,则需要在insmod时判断内核的VERMAGIC_STRING。很多时候,里面会有很多信息。比如我遇到问题的内核模块,它完整的VERMAGIC_STRING是:"2.6.36+mod_unloadMIPS32_R232BIT"Versionmagicmismatchproblemsolution我遇到的错误是这样的,执行内核的时候网卡无法加载,使设备没有互联网。可以看到串口上有这样的错误信息:my_net_adapt:versionmagic'2.6.36+mod_unloadMIPS32_R232BIT'shouldbe'2.6.36mod_unloadMIPS32_R232BIT'根本的解决办法就是去掉前面magic中的加号,这样两个版本魔法变得一模一样了。但是查了资料也没找到原因。这里需要所有的神。最后的解决办法是在两个版本的magics上加一个加号,这样magiccheck就可以通过了。查看我的utsrelease.h文件,上面写着“2.6.36”。那么有两种解决方法:在该目录的Makefile中,将第四个变量改为“EXTRAVERSION=+”。在Linux的根目录下,新建一个无用的“.git”空文件夹,让setlocalversion认为是Git项目,自动加上加号。第二种方案是基于一个前提:linux根目录不是我整个项目的根目录,所以整个项目的.git文件夹在别处。所以,问题解决了。我们测试确认编译出来的内核是OK的。不过说实话,具体是什么原因,还需要研究——为什么在SVN下没有问题,在Git下却有问题?