全部博文(534)
分类: LINUX
2007-09-28 17:24:25
CODE:
下面开始正式的打补丁流程。
首先需要找出当前的内核版本,方法是在 Makefile 中找出 VERSION、PATCHLEVEL、SUBLEVEL、EXTRAVERSION 行
并去掉等号两边的空格,然后执行它们。
# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTERVERSION
eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $sourcedir/Makefile`
if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
then
echo "unable to determine current kernel version" >&2
exit 1
fi
如果 VERSION、PATCHLEVEL、SUBLEVEL 中的任意一个为空则报错
补充 :EXTRAVERSION 可以为空,而且默认就是空
CODE:
echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}"
# 注释 :输出当前的内核版本
if [ x$EXTRAVERSION != "x" ]
then
echo "I'm sorry but patch-kernel can't work with a kernel source tree that is not a base version"
exit 1;
fi
如果 $EXTRAVERSION 变量的值不为空,则输出上面的提示信息并退出
表示 patch-kernel 这个脚本只能用于”干净“的版本,也就是你在 kernel.org 下载且没有自己编译过的版本
CODE:
下面是一个”无限循环“, ':' 在 bash 中代表 true 的含义,类似于 true 命令
补充 :这部分是针对 SUBLEVEL 的升级的,而不是针对 EXTRAVERSION 的升级的。也就是说从
对于 2.4.35.1 升级到 2.4.35.3 这种情况不会执行下面的 while 部分代码
while :
do
CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" # 注释 :把 VERSION、PATCHLEVEL、SUBLEVEL 的值合并在一起赋予变量 CURRENTVERSION
if [ $stopvers = $CURRENTFULLVERSION ] # 注释 :如果 stopvers 变量的值刚好等于 CURRENTVERSION 的值,则
then
echo "Stoping at $CURRENTFULLVERSION base as requested." # 注释 :表示当前版本刚好就是要升级的目标版本,不需要再执行后面的工作了。
break # 注释 :这里退出 while 循环
fi
SUBLEVEL=`expr $SUBLEVEL + 1` # 注释 :如果目标版本不等于当前版本,则先把 SUBLEVEL 的值加1
FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" # 注释 :把新的 SUBLEVEL、VERSION、PATCHLEVEL 的值合并在一起,赋予 FULLVERSION
patch=patch-$FULLVERSION # 注释 :设置 patch 文件的名称为 patch-$FULLVERSION
# See if the file exists and find extension # 注释 :然后调用上面的 findfile 函数到 $patchdir 下查找有无该 patch 文件
findFile $patchdir/${patch} || break 如果没有则跳出 while 循环
# Apply the patch and check all is OK # 注释 :如果找到 patch 文件的话,接下来就是打补丁了,调用的是上面的 applypatch 函数
applyPatch $patch || break
done
上面之所以要做成无限循环是因为要实现自动按顺序 apply 多个补丁的功能。例如当前版本是 2.34.2 ,stopvers 是 2.34.6
且 patchdir 下有 2.34.3 ,2.34.4 ,2.34,5 , 2.34.6 这4个补丁文件,则流程如下 ;
1、首先判断当前版本 (2.34.2)!= 2.34.6 则查找 patchdir 下的 patch-2.34.3.xxx 文件(xxx 就是 finfile 中指定的那些扩展名)
2、并 apply 该补丁,这时内核的 SUBLEVEL 将会变成 2.34.3
3、再次判断 2.34.3 != 2.34.6 ,在 patchdir 下查找 2.34.4 补丁,如果找到则 apply 该补丁
4、依此类推,直到 SUBLEVEL = 2.34.6 (也就是 apply patch-2.34.6.xxx 补丁后)
5、这时 stopvers 等于 CURRENTVERSION 则跳出 while 循环,apply 多个补丁的工作也就完成了
补充 :所以这要求你事先得把多个 patch 放在 pathdir 目录下
CODE:
# 注释 :-ac 功能
if [ x$gotac != x ]; then # 注释 :如果 gotac 变量的值不为空,则
# Out great user wants the -ac patches
# They could have done -ac (get latest) or -acxx where xx=version they want
if [ $gotac == "-ac" ] # 注释 :如果 gotac 变量的值等于 "-ac" ,则
then
# They want the latest version
HIGHESTPATCH=0 # 注释 :将 HIGHIEST 变量的值设置为 0
for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.* # 注释 :在 patchdir 下查找类似 patch-x.y.z-ac
do
ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'` # 注释:并尝试取出文件名中 ac 后面的
# Check it is actually a recognised patch type
findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break # 注释 :用 findfile 函数判断该文件的类型和解压方式
if [ $ACVALUE -gt $HIGHESTPATCH ] # 注释 :如果 ACVALUE 的值大于 HIGHESTPATCH 的值
then
HIGHESTPATCH=$ACVALUE # 则把 ACVALUE 的值给 HIGHESTPATCH 变量
fi
done
if [ $HIGHESTPATCH -ne 0 ] # 注释 :如果最终找到一个 ac 文件,则
then
findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break # 用 findfile 判断其类型和解压方式
applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} # 注释 :并调用 applypatch 打上该补丁
else
echo "No ac patches found" # 如果最终一个 ac 文件都找不到则报错
fi
else # 注释 :如果 gotac 变量的值不为空,则表示用户指定了 ac 版本
# They want an exact version
findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || { # 注释 :首先用 findfile 查找该 ac 文件的类型和解压方式
echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION. Hohum." # 如果 findfile 失败,则打印一个错误信息并退出
exit 1
}
applyPatch patch-${CURRENTFULLVERSION}${gotac} # 注释 :再调用 applypatch 打上该补丁
fi
fi
补充 :可以看到 patch-kernel 并不负责修改目录的名称和执行剩下的 make xxx 操作
补充 ;也可以看到如果要从
十、patch-kernel 脚本应用实例
当前版本
CODE:
[root@mail linux-
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 34
EXTRAVERSION =
[root@mail linux-2.4.34.4]#
现有补丁文件
CODE:
[root@mail src]# ll patch*
-rw-r--r-- 1 root root 7782 Sep 25 00:16 patch-
-rw-r--r-- 1 root root 1218800 Sep 25 00:24 patch-2.4.35
-rw-r--r-- 1 root root 8098 Sep 25 00:24 patch-2.4.35-ac1 # 注释 :这两个实际上是用不到的
-rw-r--r-- 1 root root 8972 Sep 25 00:24 patch-2.4.35-ac2
-rw-r--r-- 1 root root 10604 Sep 25 00:13 patch-2.4.35-ac3
[root@mail src]#
使用 patch-kernel 升级到
CODE:
[root@mail linux-
Current kernel version is 2.4.34
Applying patch-2.4.35 (plaintext)... done.
Stoping at 2.4.35 base as requested.
[root@mail linux-2.4.34.4]#
直接升级到
CODE:
[root@mail linux-
Current kernel version is 2.4.35
Stoping at 2.4.35 base as requested.
Applying patch-2.4.35-ac3 (plaintext)... done.
[root@mail linux-2.4.34.4]#
CODE:
[root@mail linux-
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 35
EXTRAVERSION = .3
[root@mail linux-2.4.34.4]#
可以看到 EXTRAVERSION 变成了 .3 了,也就是说明成功了。