#!/bin/sh
#
# assume that this script is installed below the source directory
# e.g. in /usr/src/spb2
source_dir=../

# pae version (=default): x86 kernel can address >=4GB RAM
# (most xen installation require pae enabled domU clients)
# non pae version: older intel pentium m cpus do not have pae extension
# (cat /proc/cpuinfo |grep pae displays if the cpu has pae extension)
# to switch between pae and non pae, copy .config.[non]pae to .config

kernel_version=linux-2.6.25
kernel_base_version=linux-2.6.25
#kernel_version=linux-2.6.24.3
#kernel_base_version=linux-2.6.24.3
#kernel_version=linux-2.6.23.16
#kernel_base_version=linux-2.6.23.16

#uncomment to include opensuse xen patches
#USE_XEN=1

#kernel_version=linux-2.6.23-rc7
#kernel_base_version=linux-2.6.22
if [ "$kernel_version" != "$kernel_base_version" ]; then
 kernel_patch_version=patch-2.6.23-rc7
 kernel_patch=$kernel_patch_version.bz2
fi
kernel_source=$kernel_base_version.tar.bz2
kernel_server=ftp://ftp.kernel.org/pub/linux/kernel/v2.6

errorexit()
{
 echo -e $@
 exit 1
}

OLD_PWD=$PWD
if [ "$source_dir" = "../" ]; then
 src_dir=${PWD%/*}
else
 src_dir=${PWD}/${source_dir%/}
fi
TAR=tar
[ -x $OLD_PWD/tar ] && TAR=$OLD_PWD/tar

# fetch kernel source
if ! [ -d $kernel_version ]; then
 echo "fetching linux kernel..."
 if [ "$kernel_version" = "$kernel_base_version" ]; then
  [ -f $kernel_source ] || wget $kernel_server/$kernel_source
  [ -f $kernel_source ] || errorexit "failed to download $kernel_source to current directory"
 else
  [ -f $kernel_source ] || wget $kernel_server/$kernel_source
  [ -f $kernel_source ] || errorexit "failed to download $kernel_source to current directory"
  if [ "$kernel_version" != "$kernel_base_version" ]; then
   [ -f $kernel_patch -o -f ${kernel_patch%.bz2} ] || wget $kernel_server/testing/$kernel_patch
   [ -f $kernel_patch -o -f ${kernel_patch%.bz2} ] || errorexit "failed to download $kernel_patch to current directory"
  fi
 fi
fi

# extract kernel source
if ! [ -d $src_dir/$kernel_base_version ]; then
#if true; then
 if [ -d $src_dir/linux ]; then
  echo "error: directory or symbolic link $src_dir/linux does already exist"
  echo "(this script will create $src_dir/$kernel_base_version and create"
  echo "symbolic link linux -> $kernel_base_version)"
  echo
  errorexit "remove $src_dir/$kernel_base_version and $src_dir/linux to recreate the kernel sources"
 fi
 # remove symlink if not pointing to an existing directory
 [ -L $src_dir/linux ] && rm $src_dir/linux
 echo "extracting linux kernel"
 $TAR -C $src_dir -xjf $kernel_source || errorexit "could not extract $kernel_source"
 [ -d $src_dir/$kernel_base_version ] || errorexit "directory $kernel_base_version not found"
 rm *.stamp 2>/dev/null
 if [ "$kernel_version" != "$kernel_base_version" ]; then
  [ -f ${kernel_patch%.bz2} ] || bzip2 -d $kernel_patch || errorexit "failed to unpack $kernel_patch"
  cd $src_dir/$kernel_base_version
  patch -p1 <$OLD_PWD/${kernel_patch%.bz2} || errorexit "failed to patch kernel at $src_dir/$kernel_base_version with ${kernel_patch%.bz2}"
  cd .. 
 fi
 ln -s $kernel_base_version $src_dir/linux
 cd $OLD_PWD
fi

#patch source
echo "patching ..."
#[ -d "${0##*/}" ] && cd ${0##*/}

p=squashfs3.3-patch
p2=02_squashfs3.3.diff
patch0=sqfs3.3-kernelpatch-cvs.diff
patch1=lzma-2.6.20_and_squashfs3.3.diff
patch2=xen-opensuse.diff
#add cvs fix to squashfs3.3 patch (last part of cvs patch on squashfs-lzma.org)
#and make changes that squashfs3.3 patch applies after lzma-kernel patch
if [ -f $p ] && ! [ -f $p2 ]; then
 cp $p $p2
 patch -p0 <$patch0
 patch -p0 <$patch1
fi
#opensuse xen patch
if [ "$USE_XEN" ]; then
if [ -d patches.xen ]; then
 #remove a part of opensuse xen patches (file which  is not in vanilla kernel)
 if cat patches.xen/xen3-fixup-arch-x86 |grep -q "arch/x86/kdb/kdba_bt.c"; then
  patch -p0 <$patch2
 fi
 #apply xen patches
 if cat $src_dir/linux//arch/x86/xen/Kconfig |grep -qv "config PARAVIRT_XEN"; then
  cd $src_dir/linux
  [ -d patches.xen -o -L patches.xen ] || ln -s ../spb2/patches.xen
  $OLD_PWD/patches-xen.sh
 fi
fi
fi

cd $OLD_PWD

# create temporary symlinks: xyz.diff -> xyz.patch
for p in *.patch; do
 [ -f $p ] || continue
 # skip patches starting with m.... (=external module patches)
 [ "${p#m}" == "$p" ] || continue
 [ -f ${p%.patch}.diff ] || ln -s $p ${p%.patch}.diff
done
 
for p in *.diff; do
 [ -f $p ] || continue
 # skip patches starting with m.... (=external module patches)
 [ "${p#m}" == "$p" ] || continue
 # skip patches $patch0, $patch1 which have been used to patch patches
 [ $p = $patch0 ] && continue
 [ $p = $patch1 ] && continue
 [ $p = $patch2 ] && continue
 [ -f ${p%.diff}.stamp ] && continue
 cd $src_dir/$kernel_base_version
 echo "apply patch $p:"
 patch -p1 <$OLD_PWD/$p && touch $OLD_PWD/${p%.diff}.stamp
 cd $OLD_PWD
done

# remove temporary symlinks: *.diff
for p in *.patch; do
 [ -f $p ] || continue
 [ -L ${p%.patch}.diff ] && rm ${p%.patch}.diff
done
cd $OLD_PWD

# add some header files
echo "add header files..."
for f in *.h; do
 [ -f $f ] || continue
 cd $src_dir/$kernel_base_version
 [ -f include/linux/$f ] || cp $OLD_PWD/$f include/linux
 [ $f = config.h ] && cd $OLD_PWD && continue
 [ -f fs/squashfs/$f ] || cp $OLD_PWD/$f fs/squashfs
 cd $OLD_PWD
done

# add mISDN
echo "add mISDN drivers..."
for d in mISDN*; do
 [ -d $d ] || continue
 [ -f $d.stamp ] && continue
 cd $d
 if ! [ -f std2kern.orig ]; then
  cp std2kern std2kern.orig
  cat std2kern.orig |sed "s,\(^KERNELDIR=\).*,\1$src_dir/$kernel_base_version," >std2kern
 fi
 echo "*** below, when asked, enter yes (+ <enter>) ***"
 sleep 5
 ./std2kern
 cd $OLD_PWD
 touch $d.stamp
done

#configure
echo "preparing kernel configuration..."
if ! [ -f $src_dir/$kernel_base_version/.config ]; then
[ -f .config ] || errorexit "cannot configure linux kernel; file .config is missing."
cd $src_dir/$kernel_base_version
[ -f .config ] || cp $OLD_PWD/.config .
make oldconfig
make prepare
cd $OLD_PWD
fi

echo "now use command"
echo "  genkernel --no-clean all" 
echo "to build and install your kernel into gentoo"
echo "(use emerge genkernel to install command genkernel)"
if ! [ "`which lzma 2>/dev/null`" ]; then
 echo
 echo "warning: program lzma, required to compress linux kernel, not found; use command: emerge lzma "
fi
cd $OLD_PWD
exit 

# currently not used (replaced by genkernel)
#build
echo "about to compile kernel... (press ctrl+c to quit)"
sleep 10
cd $src_dir/$kernel_version
make bzImage
make modules
cd $OLD_PWD

#install internal modules (modules coming with linux source tree) 
echo "installing modules..."
cd $src_dir/$kernel_version
make modules_install
cd $OLD_PWD

