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

简介:

近期把开发从 SVN 迁移到了 Git 上。其实一早就遇到一个问题,那就是 Linux kernel,在 SVN 的版本控制下编译得好好的,但是换成 Git 做版本控制之后,即便是完全一模一样的两套目录树,编译出来就是不一样!

我晕,Linux 编译结果还跟版本控制环境有关?查了资料,还真是有关……

Reference

Linux内核模块加载时的版本检查

修改utsrelease.h 文件里面的版本号后

向linux内核版本号添加字符/为何有时会自动添加“+”号

关于CONFIG_LOCALVERSION_AUTO设置去掉内核版本号SVN后缀

去掉SVN管理kernel编译后版本自动变化

非开源的驱动程序如何绕过version magic的检查

绕过linux Driver Vermagic检查

主要知识点归纳

内核基础版本号

Linux 内核在编译时,在根目录的 Makefile 最开头有几个宏,决定了编译出来的 Linux 基本版本号。我用的内核版本比较老,是这样的:

 
 
  1. VERSION = 2 
  2. PATCHLEVEL = 6 
  3. SUBLEVEL = 36 
  4. EXTRAVERSION = 
  5. ... 

而内核代码在获得这个基本版本号,则需要包含include/linux/version.h文件:

 
 
  1. #define LINUX_VERSION_CODE 132644 
  2. #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) 

其中LINUX_VERSION_CODE就是(2 << 16) + (6 << 8) + (36 << 0)

这个宏很重要,举个例子:不同的 Linux 内核的 ioctl 函数原型是不同的,但是你的驱动又不想写两套,这个时候就应该这么写:

 
 
  1. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)) 
  2. static long my_ioctl (struct file *file,  
  3.                       unsigned int req,  
  4.                       unsigned long arg) 
  5. #else 
  6. static int my_ioctl (struct inode *inode,  
  7.                      struct file *file,  
  8.                      unsigned int req,  
  9.                      unsigned long arg) 
  10. #endif 
  11.     // brah brah brah ... 

内核扩展版本号

这里请注意内核的include/vermagic.h文件,有一个VERMAGIC_STRING宏,定义如下:

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

其中UTS_RELEASE宏来自于include/generated/utsrelease.h文件。

首先,这个文件是自动创建的,你修改了也没用。

其次,这个版本号的来源很复杂,除了 Linux 基础版本号(也就是 Makefile 的前三个变量)之外,还依赖很多变量:

  1. Makefile 里面的EXTRAVERSION宏,这是紧跟在基础版本号后面的
  2. make menuconfig 时指定的CONFIG_LOCALVERSION_AUTO配置宏,决定了到scripts/setlocalversion里面去添加什么样的附加内容
  3. LOCALVERSION,貌似一般情况下这个宏是没有定义的

而这个VERMAGIC_STRING有什么用呢?这经常是用在一些自定义的内核模块里面。如果内核模块的实现依赖于具体 Linux 内核发行版的话,在 insmod 的时候就需要判断内核的 VERMAGIC_STRING。很多情况下,这里面会包含很多信息。

比如我遇到问题的内核模块,其完整的VERMAGIC_STRING就是:“2.6.36+ mod_unload MIPS32_R2 32BIT”

Version magic 不匹配问题的解决

我遇到的错误是这样的,内核执行时,网卡无法加载,以致设备没有网络。可以看到串口有这么一句错误信息:

 
 
  1. 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 就有问题呢?





本文作者:佚名
来源:51CTO
目录
相关文章
|
6天前
|
Linux 开发工具 Perl
Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
【10月更文挑战第20天】Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
20 4
|
13天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
54 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
17天前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
22天前
|
Linux 编译器 C语言
Linux c/c++之多文档编译
这篇文章介绍了在Linux操作系统下使用gcc编译器进行C/C++多文件编译的方法和步骤。
31 0
Linux c/c++之多文档编译
|
26天前
|
存储 Linux 编译器
cmake的单目录和多目录的使用(Linux和Windows)
本文介绍了在Windows和Linux平台上使用CMake构建单目录和多目录项目的步骤,包括如何配置CMakeLists.txt文件以及如何生成和使用可执行文件、库文件。
15 2
|
27天前
|
移动开发 Linux
Linux 文件与目录管理
Linux 文件与目录管理
20 3
|
2月前
|
Linux
深入理解Linux中的cp命令:文件与目录的复制利器
深入理解Linux中的cp命令:文件与目录的复制利器
|
16天前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
|
20天前
|
开发工具 git
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
这篇文章是关于Git常用命令的总结,包括初始化配置、基本提交、分支操作、合并、压缩历史、推送和拉取远程仓库等操作的详细说明。
72 1
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
|
1天前
|
开发工具 git 开发者