162306a36Sopenharmony_ci#! /bin/sh 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# Script to apply kernel patches. 462306a36Sopenharmony_ci# usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] 562306a36Sopenharmony_ci# The source directory defaults to /usr/src/linux, and the patch 662306a36Sopenharmony_ci# directory defaults to the current directory. 762306a36Sopenharmony_ci# e.g. 862306a36Sopenharmony_ci# scripts/patch-kernel . .. 962306a36Sopenharmony_ci# Update the kernel tree in the current directory using patches in the 1062306a36Sopenharmony_ci# directory above to the latest Linus kernel 1162306a36Sopenharmony_ci# scripts/patch-kernel . .. -ac 1262306a36Sopenharmony_ci# Get the latest Linux kernel and patch it with the latest ac patch 1362306a36Sopenharmony_ci# scripts/patch-kernel . .. 2.4.9 1462306a36Sopenharmony_ci# Gets standard kernel 2.4.9 1562306a36Sopenharmony_ci# scripts/patch-kernel . .. 2.4.9 -ac 1662306a36Sopenharmony_ci# Gets 2.4.9 with latest ac patches 1762306a36Sopenharmony_ci# scripts/patch-kernel . .. 2.4.9 -ac11 1862306a36Sopenharmony_ci# Gets 2.4.9 with ac patch ac11 1962306a36Sopenharmony_ci# Note: It uses the patches relative to the Linus kernels, not the 2062306a36Sopenharmony_ci# ac to ac relative patches 2162306a36Sopenharmony_ci# 2262306a36Sopenharmony_ci# It determines the current kernel version from the top-level Makefile. 2362306a36Sopenharmony_ci# It then looks for patches for the next sublevel in the patch directory. 2462306a36Sopenharmony_ci# This is applied using "patch -p1 -s" from within the kernel directory. 2562306a36Sopenharmony_ci# A check is then made for "*.rej" files to see if the patch was 2662306a36Sopenharmony_ci# successful. If it is, then all of the "*.orig" files are removed. 2762306a36Sopenharmony_ci# 2862306a36Sopenharmony_ci# Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995. 2962306a36Sopenharmony_ci# 3062306a36Sopenharmony_ci# Added support for handling multiple types of compression. What includes 3162306a36Sopenharmony_ci# gzip, bzip, bzip2, zip, compress, and plaintext. 3262306a36Sopenharmony_ci# 3362306a36Sopenharmony_ci# Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997. 3462306a36Sopenharmony_ci# 3562306a36Sopenharmony_ci# Added ability to stop at a given version number 3662306a36Sopenharmony_ci# Put the full version number (i.e. 2.3.31) as the last parameter 3762306a36Sopenharmony_ci# Dave Gilbert <linux@treblig.org>, 11th December 1999. 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci# Fixed previous patch so that if we are already at the correct version 4062306a36Sopenharmony_ci# not to patch up. 4162306a36Sopenharmony_ci# 4262306a36Sopenharmony_ci# Added -ac option, use -ac or -ac9 (say) to stop at a particular version 4362306a36Sopenharmony_ci# Dave Gilbert <linux@treblig.org>, 29th September 2001. 4462306a36Sopenharmony_ci# 4562306a36Sopenharmony_ci# Add support for (use of) EXTRAVERSION (to support 2.6.8.x, e.g.); 4662306a36Sopenharmony_ci# update usage message; 4762306a36Sopenharmony_ci# fix some whitespace damage; 4862306a36Sopenharmony_ci# be smarter about stopping when current version is larger than requested; 4962306a36Sopenharmony_ci# Randy Dunlap <rdunlap@xenotime.net>, 2004-AUG-18. 5062306a36Sopenharmony_ci# 5162306a36Sopenharmony_ci# Add better support for (non-incremental) 2.6.x.y patches; 5262306a36Sopenharmony_ci# If an ending version number if not specified, the script automatically 5362306a36Sopenharmony_ci# increments the SUBLEVEL (x in 2.6.x.y) until no more patch files are found; 5462306a36Sopenharmony_ci# however, EXTRAVERSION (y in 2.6.x.y) is never automatically incremented 5562306a36Sopenharmony_ci# but must be specified fully. 5662306a36Sopenharmony_ci# 5762306a36Sopenharmony_ci# patch-kernel does not normally support reverse patching, but does so when 5862306a36Sopenharmony_ci# applying EXTRAVERSION (x.y) patches, so that moving from 2.6.11.y to 2.6.11.z 5962306a36Sopenharmony_ci# is easy and handled by the script (reverse 2.6.11.y and apply 2.6.11.z). 6062306a36Sopenharmony_ci# Randy Dunlap <rdunlap@xenotime.net>, 2005-APR-08. 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ciPNAME=patch-kernel 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci# Set directories from arguments, or use defaults. 6562306a36Sopenharmony_cisourcedir=${1-/usr/src/linux} 6662306a36Sopenharmony_cipatchdir=${2-.} 6762306a36Sopenharmony_cistopvers=${3-default} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciif [ "$1" = -h -o "$1" = --help -o ! -r "$sourcedir/Makefile" ]; then 7062306a36Sopenharmony_cicat << USAGE 7162306a36Sopenharmony_ciusage: $PNAME [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] 7262306a36Sopenharmony_ci source directory defaults to /usr/src/linux, 7362306a36Sopenharmony_ci patch directory defaults to the current directory, 7462306a36Sopenharmony_ci stopversion defaults to <all in patchdir>. 7562306a36Sopenharmony_ciUSAGE 7662306a36Sopenharmony_ciexit 1 7762306a36Sopenharmony_cifi 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci# See if we have any -ac options 8062306a36Sopenharmony_cifor PARM in $* 8162306a36Sopenharmony_cido 8262306a36Sopenharmony_ci case $PARM in 8362306a36Sopenharmony_ci -ac*) 8462306a36Sopenharmony_ci gotac=$PARM; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci esac; 8762306a36Sopenharmony_cidone 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci# --------------------------------------------------------------------------- 9062306a36Sopenharmony_ci# arg1 is filename 9162306a36Sopenharmony_cinoFile () { 9262306a36Sopenharmony_ci echo "cannot find patch file: ${patch}" 9362306a36Sopenharmony_ci exit 1 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci# --------------------------------------------------------------------------- 9762306a36Sopenharmony_cibackwards () { 9862306a36Sopenharmony_ci echo "$PNAME does not support reverse patching" 9962306a36Sopenharmony_ci exit 1 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci# --------------------------------------------------------------------------- 10362306a36Sopenharmony_ci# Find a file, first parameter is basename of file 10462306a36Sopenharmony_ci# it tries many compression mechanisms and sets variables to say how to get it 10562306a36Sopenharmony_cifindFile () { 10662306a36Sopenharmony_ci filebase=$1; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci if [ -r ${filebase}.gz ]; then 10962306a36Sopenharmony_ci ext=".gz" 11062306a36Sopenharmony_ci name="gzip" 11162306a36Sopenharmony_ci uncomp="gunzip -dc" 11262306a36Sopenharmony_ci elif [ -r ${filebase}.bz ]; then 11362306a36Sopenharmony_ci ext=".bz" 11462306a36Sopenharmony_ci name="bzip" 11562306a36Sopenharmony_ci uncomp="bunzip -dc" 11662306a36Sopenharmony_ci elif [ -r ${filebase}.bz2 ]; then 11762306a36Sopenharmony_ci ext=".bz2" 11862306a36Sopenharmony_ci name="bzip2" 11962306a36Sopenharmony_ci uncomp="bunzip2 -dc" 12062306a36Sopenharmony_ci elif [ -r ${filebase}.xz ]; then 12162306a36Sopenharmony_ci ext=".xz" 12262306a36Sopenharmony_ci name="xz" 12362306a36Sopenharmony_ci uncomp="xz -dc" 12462306a36Sopenharmony_ci elif [ -r ${filebase}.zip ]; then 12562306a36Sopenharmony_ci ext=".zip" 12662306a36Sopenharmony_ci name="zip" 12762306a36Sopenharmony_ci uncomp="unzip -d" 12862306a36Sopenharmony_ci elif [ -r ${filebase}.Z ]; then 12962306a36Sopenharmony_ci ext=".Z" 13062306a36Sopenharmony_ci name="uncompress" 13162306a36Sopenharmony_ci uncomp="uncompress -c" 13262306a36Sopenharmony_ci elif [ -r ${filebase} ]; then 13362306a36Sopenharmony_ci ext="" 13462306a36Sopenharmony_ci name="plaintext" 13562306a36Sopenharmony_ci uncomp="cat" 13662306a36Sopenharmony_ci else 13762306a36Sopenharmony_ci return 1; 13862306a36Sopenharmony_ci fi 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci return 0; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci# --------------------------------------------------------------------------- 14462306a36Sopenharmony_ci# Apply a patch and check it goes in cleanly 14562306a36Sopenharmony_ci# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ciapplyPatch () { 14862306a36Sopenharmony_ci echo -n "Applying $1 (${name})... " 14962306a36Sopenharmony_ci if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir 15062306a36Sopenharmony_ci then 15162306a36Sopenharmony_ci echo "done." 15262306a36Sopenharmony_ci else 15362306a36Sopenharmony_ci echo "failed. Clean up yourself." 15462306a36Sopenharmony_ci return 1; 15562306a36Sopenharmony_ci fi 15662306a36Sopenharmony_ci if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] 15762306a36Sopenharmony_ci then 15862306a36Sopenharmony_ci echo "Aborting. Reject files found." 15962306a36Sopenharmony_ci return 1; 16062306a36Sopenharmony_ci fi 16162306a36Sopenharmony_ci # Remove backup files 16262306a36Sopenharmony_ci find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci return 0; 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci# --------------------------------------------------------------------------- 16862306a36Sopenharmony_ci# arg1 is patch filename 16962306a36Sopenharmony_cireversePatch () { 17062306a36Sopenharmony_ci echo -n "Reversing $1 (${name}) ... " 17162306a36Sopenharmony_ci if $uncomp ${patchdir}/"$1"${ext} | patch -p1 -Rs -N -E -d $sourcedir 17262306a36Sopenharmony_ci then 17362306a36Sopenharmony_ci echo "done." 17462306a36Sopenharmony_ci else 17562306a36Sopenharmony_ci echo "failed. Clean it up." 17662306a36Sopenharmony_ci exit 1 17762306a36Sopenharmony_ci fi 17862306a36Sopenharmony_ci if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] 17962306a36Sopenharmony_ci then 18062306a36Sopenharmony_ci echo "Aborting. Reject files found." 18162306a36Sopenharmony_ci return 1 18262306a36Sopenharmony_ci fi 18362306a36Sopenharmony_ci # Remove backup files 18462306a36Sopenharmony_ci find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci return 0 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION 19062306a36Sopenharmony_ci# force $TMPFILEs below to be in local directory: a slash character prevents 19162306a36Sopenharmony_ci# the dot command from using the search path. 19262306a36Sopenharmony_ciTMPFILE=`mktemp ./.tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; } 19362306a36Sopenharmony_cigrep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE 19462306a36Sopenharmony_citr -d [:blank:] < $TMPFILE > $TMPFILE.1 19562306a36Sopenharmony_ci. $TMPFILE.1 19662306a36Sopenharmony_cirm -f $TMPFILE* 19762306a36Sopenharmony_ciif [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ] 19862306a36Sopenharmony_cithen 19962306a36Sopenharmony_ci echo "unable to determine current kernel version" >&2 20062306a36Sopenharmony_ci exit 1 20162306a36Sopenharmony_cifi 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ciNAME=`grep ^NAME $sourcedir/Makefile` 20462306a36Sopenharmony_ciNAME=${NAME##*=} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ciecho "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} ($NAME)" 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci# strip EXTRAVERSION to just a number (drop leading '.' and trailing additions) 20962306a36Sopenharmony_ciEXTRAVER= 21062306a36Sopenharmony_ciif [ x$EXTRAVERSION != "x" ] 21162306a36Sopenharmony_cithen 21262306a36Sopenharmony_ci EXTRAVER=${EXTRAVERSION#.} 21362306a36Sopenharmony_ci EXTRAVER=${EXTRAVER%%[[:punct:]]*} 21462306a36Sopenharmony_ci #echo "$PNAME: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER" 21562306a36Sopenharmony_cifi 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci#echo "stopvers=$stopvers" 21862306a36Sopenharmony_ciif [ $stopvers != "default" ]; then 21962306a36Sopenharmony_ci STOPSUBLEVEL=`echo $stopvers | cut -d. -f3` 22062306a36Sopenharmony_ci STOPEXTRA=`echo $stopvers | cut -d. -f4` 22162306a36Sopenharmony_ci STOPFULLVERSION=${stopvers%%.$STOPEXTRA} 22262306a36Sopenharmony_ci #echo "#___STOPSUBLEVEL=/$STOPSUBLEVEL/, STOPEXTRA=/$STOPEXTRA/" 22362306a36Sopenharmony_cielse 22462306a36Sopenharmony_ci STOPSUBLEVEL=9999 22562306a36Sopenharmony_ci STOPEXTRA=9999 22662306a36Sopenharmony_cifi 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci# This all assumes a 2.6.x[.y] kernel tree. 22962306a36Sopenharmony_ci# Don't allow backwards/reverse patching. 23062306a36Sopenharmony_ciif [ $STOPSUBLEVEL -lt $SUBLEVEL ]; then 23162306a36Sopenharmony_ci backwards 23262306a36Sopenharmony_cifi 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ciif [ x$EXTRAVER != "x" ]; then 23562306a36Sopenharmony_ci CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER" 23662306a36Sopenharmony_cielse 23762306a36Sopenharmony_ci CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 23862306a36Sopenharmony_cifi 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ciif [ x$EXTRAVER != "x" ]; then 24162306a36Sopenharmony_ci echo "backing up to: $VERSION.$PATCHLEVEL.$SUBLEVEL" 24262306a36Sopenharmony_ci patch="patch-${CURRENTFULLVERSION}" 24362306a36Sopenharmony_ci findFile $patchdir/${patch} || noFile ${patch} 24462306a36Sopenharmony_ci reversePatch ${patch} || exit 1 24562306a36Sopenharmony_cifi 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci# now current is 2.6.x, with no EXTRA applied, 24862306a36Sopenharmony_ci# so update to target SUBLEVEL (2.6.SUBLEVEL) 24962306a36Sopenharmony_ci# and then to target EXTRAVER (2.6.SUB.EXTRAVER) if requested. 25062306a36Sopenharmony_ci# If not ending sublevel is specified, it is incremented until 25162306a36Sopenharmony_ci# no further sublevels are found. 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciif [ $STOPSUBLEVEL -gt $SUBLEVEL ]; then 25462306a36Sopenharmony_ciwhile : # incrementing SUBLEVEL (s in v.p.s) 25562306a36Sopenharmony_cido 25662306a36Sopenharmony_ci CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 25762306a36Sopenharmony_ci EXTRAVER= 25862306a36Sopenharmony_ci if [ x$STOPFULLVERSION = x$CURRENTFULLVERSION ]; then 25962306a36Sopenharmony_ci echo "Stopping at $CURRENTFULLVERSION base as requested." 26062306a36Sopenharmony_ci break 26162306a36Sopenharmony_ci fi 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci SUBLEVEL=$(($SUBLEVEL + 1)) 26462306a36Sopenharmony_ci FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 26562306a36Sopenharmony_ci #echo "#___ trying $FULLVERSION ___" 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci if [ $(($SUBLEVEL)) -gt $(($STOPSUBLEVEL)) ]; then 26862306a36Sopenharmony_ci echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)" 26962306a36Sopenharmony_ci exit 1 27062306a36Sopenharmony_ci fi 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci patch=patch-$FULLVERSION 27362306a36Sopenharmony_ci # See if the file exists and find extension 27462306a36Sopenharmony_ci findFile $patchdir/${patch} || noFile ${patch} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci # Apply the patch and check all is OK 27762306a36Sopenharmony_ci applyPatch $patch || break 27862306a36Sopenharmony_cidone 27962306a36Sopenharmony_ci#echo "#___sublevel all done" 28062306a36Sopenharmony_cifi 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci# There is no incremental searching for extraversion... 28362306a36Sopenharmony_ciif [ "$STOPEXTRA" != "" ]; then 28462306a36Sopenharmony_ciwhile : # just to allow break 28562306a36Sopenharmony_cido 28662306a36Sopenharmony_ci# apply STOPEXTRA directly (not incrementally) (x in v.p.s.x) 28762306a36Sopenharmony_ci FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$STOPEXTRA" 28862306a36Sopenharmony_ci #echo "#... trying $FULLVERSION ..." 28962306a36Sopenharmony_ci patch=patch-$FULLVERSION 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci # See if the file exists and find extension 29262306a36Sopenharmony_ci findFile $patchdir/${patch} || noFile ${patch} 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci # Apply the patch and check all is OK 29562306a36Sopenharmony_ci applyPatch $patch || break 29662306a36Sopenharmony_ci #echo "#___extraver all done" 29762306a36Sopenharmony_ci break 29862306a36Sopenharmony_cidone 29962306a36Sopenharmony_cifi 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciif [ x$gotac != x ]; then 30262306a36Sopenharmony_ci # Out great user wants the -ac patches 30362306a36Sopenharmony_ci # They could have done -ac (get latest) or -acxx where xx=version they want 30462306a36Sopenharmony_ci if [ $gotac = "-ac" ]; then 30562306a36Sopenharmony_ci # They want the latest version 30662306a36Sopenharmony_ci HIGHESTPATCH=0 30762306a36Sopenharmony_ci for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.* 30862306a36Sopenharmony_ci do 30962306a36Sopenharmony_ci ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'` 31062306a36Sopenharmony_ci # Check it is actually a recognised patch type 31162306a36Sopenharmony_ci findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci if [ $ACVALUE -gt $HIGHESTPATCH ]; then 31462306a36Sopenharmony_ci HIGHESTPATCH=$ACVALUE 31562306a36Sopenharmony_ci fi 31662306a36Sopenharmony_ci done 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci if [ $HIGHESTPATCH -ne 0 ]; then 31962306a36Sopenharmony_ci findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break 32062306a36Sopenharmony_ci applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} 32162306a36Sopenharmony_ci else 32262306a36Sopenharmony_ci echo "No -ac patches found" 32362306a36Sopenharmony_ci fi 32462306a36Sopenharmony_ci else 32562306a36Sopenharmony_ci # They want an exact version 32662306a36Sopenharmony_ci findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || { 32762306a36Sopenharmony_ci echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION. Hohum." 32862306a36Sopenharmony_ci exit 1 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci applyPatch patch-${CURRENTFULLVERSION}${gotac} 33162306a36Sopenharmony_ci fi 33262306a36Sopenharmony_cifi 333