linux核心版本號添加字元/為何有時會自動添加“+”

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_AUTOCONFIG_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則不會執行elseif所在的腳本,從而不會在後面添加“+”號。
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" \

需要仔細注意:

 

使用modinfo可查看編譯出來的ko檔對應的核心版本號

使用uname或者 cat /proc/version 可在目標系統上查看核心版本號。

可查看kernel編譯過程生成的檔: include/generated/utsrelease.h ,確定編譯出來的核心的版本號。

文章標籤

立你斯 發表在 痞客邦 留言(0) 人氣()