转载:http://blog.csdn.net/adaptiver/article/details/7225980

1.   引子

编译2.6.35.7 kernel版本的时候发现,“2.6.35.7“的内核版本编译成功后生成的版本号变成了“2.6.35.7+”,为什么后面会多一个加号呢?问题出现在Linux版本控制这一块:

打开Makefile我们可以在文件的最上面可以发现

VERSION = 2

PATCHLEVEL = 6

SUBLEVEL = 35

EXTRAVERSION = .7

NAME = Yokohama

这些就是告诉我们内核版本的版本号,生成出来的版本号理论上不应带+号,但为什么带+号呢

include/config/kernel.release文件是生成的带有版本号的文件,该文件由内核顶层Makefile的如下脚本处理:

# Store (new) KERNELRELASE string in include/config/kernel.release

include/config/kernel.release: include/config/auto.conf FORCE

        $(Q)rm -f $@

        $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@

使用scripts/setlocalversion工具来生成include/config/kernel.release。“+”号就是在调用这个脚本时添加的。



 阅读scripts/setlocalversion文件,并查阅资料,做如下笔记:

2.   为何会添加“+”号

在scripts/setlocalversion文件中有这么一段

# scm version string if not at a tagged commit

if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then

 # full scm version string

 res="$res$(scm_version)"

else

 # apped a plus sign if the repository is not in a clean tagged

 # state and  LOCALVERSION= is not specified

 if test "${LOCALVERSION+set}" != "set"; then

  scm=$(scm_version --short)

  res="$res${scm:++}"

 fi

fi

2.1. 如果定义了CONFIG_LOCALVERSION_AUTO(CONFIG_LOCALVERSION_AUTO=y)

此时会执行第一个if下的脚本。执行res="$res$(scm_version)"

如果代码属于Git管理:

打了tag,则会添加tag相关字符;

没有打tag,则会添加log相加字符,例如最新的commit是

commit cdebe039ded3e7fcd00c6e5603a878b14d7e564e

则编译之后文件include/config/kernel.release的内容为2.6.35.7-gcdebe03

2.2. 如果没有定义了CONFIG_LOCALVERSION_AUTO。

此时会执行else下的脚本。

A. 如果没有定义LOCALVERSION,版本号后面会添加“+”号:执行else里的if下的脚本scm=$(scm_version --short),在函数scm_version --short里,如果传入参数short会添加“+”号,

   if $short; then

    echo "+"

    return

   fi

B. 定义了LOCALVERSION则不会执行else里if所在的脚本,从而不会在后面添加“+”号。

C. LOCALVERSION变量可在命令行定义:

make LOCALVERSION=.88 include/config/kernel.release

或者添加为环境变量。

如果既不想添加字符,又不想有“+”号:不定义CONFIG_LOCALVERSION_AUTO,将LOCALVERSION变量定义为空:LOCALVERSION=

3.   往版本号里添加字符的方式

在scripts/setlocalversion文件中还有有这么一段:

# localversion* files in the build and source directory

res="$(collect_files localversion*)"

if test ! "$srctree" -ef .; then

 res="$res$(collect_files "$srctree"/localversion*)"

fi

# CONFIG_LOCALVERSION and LOCALVERSION (if set)

res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"

由此可看出,如果想往版本号里添加字符,有几种方式:

1. 使用LOCALVERSION变量(或者在命令行,或者添加为环境变量)

2. 在linux-2.6.35目录下添加文件localversion,文件内容会自动添加到版本号里去。

3. 定义CONFIG_LOCALVERSION变量

4. 如果linux-2.6.35目录下有文件localversion(其内容为.33),也使用了LOCALVERSION变量,也定义了CONFIG_LOCALVERSION=".XYZ"。

make LOCALVERSION=.44 include/config/kernel.release

此时对2.6.35.7的内核,include/config/kernel.release的内容为2.6.35.7.33.XYZ.55。

可看到添加的三种字符的顺序:文件localversion内容在前,然后是CONFIG_LOCALVERSION的值,最后是LOCALVERSION的值。

4.   另外,关于scripts/setlocalversion文件:

1. 在scripts/setlocalversion文件中,可用echo "aaa" >&2来输出显示相关信息,例如:

echo "LOCALVERSION=${LOCALVERSION}" >&2

2. 这个文件里很多地方是跟根据一些git命令来进行判断的,例如

if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then

if [ -z "`git describe --exact-match 2>/dev/null`" ]; then

if git config --get svn-remote.svn.url >/dev/null; then

[ -w . ] && git update-index --refresh --unmerged > /dev/null

if git diff-index --name-only HEAD | grep -v "^scripts/package" \


原创:

  我们进行linux开发时,使用git库,会生成形如2.6.35.7-gcdebe03的内核版本,而insmod驱动模块时,会对模块和内核的版本进行校验,经常因为无法版本对不上导致无法加载的问题。网上有一些方法可以绕过去,但是比较麻烦。

  所以干脆把linux的git版本先去掉,然后修改makefile,在别的地方打印git版本,这样既能进行版本追溯,也不至于导致insmod经常出错。

介绍模块和linux版本不一致导致的问题,及规避方法,有些复杂:https://yq.aliyun.com/articles/1724

 

转: linux内核版本本地版本号的检查——setlocalversion的更多相关文章

  1. Linux 内核版本命名

    Linux 内核版本命名在不同的时期有其不同的规范,我们熟悉的也许是 2.x 版本奇数表示开发版.偶数表示稳定版,但到 2.6.x 以及 3.x 甚至将来的 4.x ,内核版本命名都不遵守这样的约定. ...

  2. 【2016-08-21】Linux内核版本编号规则简介

    我们已经了解可以使用下面的几天命令来查看Linux内核版本及Ubuntu发行版本的信息: uname -r uname -a cat /proc/version lsb-release -a 等等 可 ...

  3. Linux内核版本

    在Linux中找到/usr/src/kernels/目录,该目录下面有一个系统内核文件 例如:2.6.32-431.11.2.el6.x86_64 Linux内核版本规则 Linux内核版本有三组数字 ...

  4. Linux内核版本介绍与查询

    Linux内核版本命名在不同时期有着不同的规范,在涉及到Linux版本问题时经常容易混淆,主线版本/稳定版/长期支持版本经常搞不清楚,本文主要记录下内核版本命名的规则以及如何查看Linux系统版本信息 ...

  5. 查看Linux内核版本命令

    一.查看Linux内核版本命令(两种方法): .cat /proc/version .uname -a 二.查看Linux系统版本的命令(3种方法): .lsb_release -a即可列出所有版本信 ...

  6. 1.3查看Linux内核版本

    1.目前Linux内核主要维护的三个版本:Linux2.4.Linux2.6和Linux3.x,Android使用的是Linux2.6:Linux3.x是最新推出的Linux内核版本: 2.查看Lin ...

  7. 查看LINUX发行商版本与LINUX内核版本

    查看LINUX发行商版本:[root@server-mysql ~]# cat /etc/issue Red Hat Enterprise Linux Server release 6.3 (Sant ...

  8. 快速升级openwrt的linux内核版本

    一.分析 要升级openwrt的linux内核版本,关键是要制作内核配置文件 二.内核配置文件制作方法 2.1当前openwrt对应的某个开发板有对应的内核配置文件,比如此时的openwrt的linu ...

  9. 查看Linux内核版本

    您可能因多种原因需要确切知道GNU / Linux操作系统上运行的内核版本. 也许您正在调试与硬件相关的问题,或者了解影响旧内核版本的新安全漏洞,并且您想知道您的内核是否易受攻击. 无论是什么原因,从 ...

随机推荐

  1. Gvr SDK for Unity 分析(一)

    Gvr SDK概述 通过谷歌VR SDK for unity 为Android和iOS 构建虚拟现实应用程序 unity SDK在Android上支持构建应用程序for daydream 和 card ...

  2. NVIDIA显卡设置

    在玩3D游戏时,因为我的显卡不是特别给力,所以针对性能做出牺牲质量换取性能的调整. 简单设置 简单的方法是,3D设置-通过预览调整图像设置,根据偏重点来设置平衡:性能或者质量. 高级设置 如果你想自行 ...

  3. Unity arm64

    ERROR ITMS-90086 ERROR ITMS-90086:"missing 64-bit support. beginning on february 1, 2015, new i ...

  4. single单例模式

    单例模式:多用于数据库连接,保证数据库只连接一次,避免重复连接.因为多次打开服务器会造成服务器负担,运行速度会减慢. 以下是一个连接数据库的单例模式: <?php class db_mysql{ ...

  5. ubuntu下解析udt数据包

    udt是通过udp进行端到端可靠传输的一个协议,有其默认拥塞控制算法. 之前ubuntu下wireshark的版本是1.10,不能直接解析udt数据包[1],升级到最新的2.0.0即可过滤udt数据包 ...

  6. wk_01

    Python 学习环境搭建 pyenv是个多版本python管理器,可以同时管理多个python版本共存,如pypy,miniconde等等.我们安装时其会将pyenv安装在当前用户家目录中的.pye ...

  7. [Azure] 使用 Visual Studio 2013 管理中国版 Azure 订阅

    比较关心微软平台技术的朋友应该都知道,微软云服务(Microsoft Azure)以下简称Azure分为全球版和中国版,由于政府法规问题中国版的服务是由二十一世纪互联运营,整体来看中国版Azure和全 ...

  8. [py]给函数传递数组和字典

    一 , 1.1传元组 def fun(x): print x t=(1,2) fun(t) 1.2传元组 #传元组 def fun(x,y): print x,y # t=(1,2) t=(1,2,3 ...

  9. python数字图像处理(17):边缘与轮廓

    在前面的python数字图像处理(10):图像简单滤波 中,我们已经讲解了很多算子用来检测边缘,其中用得最多的canny算子边缘检测. 本篇我们讲解一些其它方法来检测轮廓. 1.查找轮廓(find_c ...

  10. HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...