#! /bin/sh
#----------------------------------------------------------
#shell script to generate an initramfs used to do linux 
#second stage boot
#$1 is the Kernel version 
#$2 filename to generate (optional parameter)
#----------------------------------------------------------
KERNEL_VERSION=$1
INITIN=init.in
DATADIR=/usr/share/mkinitramfs


if [ `id -u` -ne 0 ] ; then
  echo "$0 must be executed as root"
  exit 1
  fi

if [ -z "$1" ] ; then
  KERNEL_VERSION=`uname -r`
  fi


#check for optionnal filename
if [ -n "$2" ] ; then
  INITRAMFS_FILE=$2
  fi

WDIR=/tmp/init-$KERNEL_VERSION
INITRAMFS_FILE=/boot/initramfs-$KERNEL_VERSION.img

#list of file or program to dup
#all raid management library
BINARY0="mdadm mdmon"
#Minimal standard utilities
BINARY1="udevd udevadm hwclock lvm"
BINARY2="sh cat cut cp dd killall ls mkdir mv mknod chmod mount"
BINARY3="umount sed sleep ln rm uname readlink basename"
BINARY4="modprobe kmod lsmod insmod depmod rmmod blkid switch_root"
BINARY5="ldconfig losetup dmsetup truncate df blockdev"
#applications to help debugging
BINARY6="less grep ps sash bash set-wireless-regdom"

#to duplicate binaries and needed libraries
duplicate()

{
for bin in $* 
  do
  pos=`which $bin`
  if [ -z "$pos" ] ; then
    echo "'$bin' not found"
    continue;
  fi
  newdir=$WDIR/`dirname $pos`
  mkdir -p $newdir
  cp -Lr $pos $newdir
  lib=`file -L $pos | grep dynamically`
  if [ -n "$lib" ] ; then
    libs=`ldd $pos | grep '=>' | cut -d ' ' -f3`
    for lib in $libs 
      do
      if [ "$lib" == "linux-vdso.so.1" ] ||
	 [ "$lib" == "linux-gate.so.1" ] ; then
        continue
      fi
      if [ ! -f $WDIR/$lib ] ; then
	#copy needed library
	mkdir -p $WDIR/`dirname $lib`
        cp -Lr $lib $WDIR/$lib 
      fi
    done
    libs=`ldd $pos | grep -v '=>' | cut -d ' ' -f1`
    for lib in $libs 
      do
      if [ "$lib" == "linux-vdso.so.1" ] ||
	 [ "$lib" == "linux-gate.so.1" ] ; then
        continue
      fi
      if [ ! -f $WDIR/$lib ] ; then
	#copy needed library
	mkdir -p $WDIR/`dirname $lib`
        cp -Lr $lib $WDIR/$lib 
      fi
    done
  fi
done
}

#to Install the udev configuration files
setudev()

{
if [ -f /etc/udev/udev.conf ]; then
  cp /etc/udev/udev.conf $WDIR/etc/udev/udev.conf
fi

for file in $(find /etc/udev/rules.d/ -type f) ; do
  cp $file $WDIR/etc/udev/rules.d
done
#removing rule calling not existing /etc/rc.d/init.d/setclock start
rm -fr $WDIR/etc/udev/rules.d/55-lfs.rules

mkdir -p $WDIR/usr/lib/udev/rules.d
for file in $(find //usr/lib/udev/rules.d/ -type f) ; do
  cp $file $WDIR/usr/lib/udev/rules.d
done

#adding all default udev library
for biblio in lib lib64
  do
  if [ -d /$biblio/udev ] ; then
    mkdir -p $WDIR/$biblio
    cp -a /$biblio/udev $WDIR/$biblio
    fi
  done
#removing rule called via elogin
rm -fr $WDIR/lib/udev/rules.d/70-power-switch.rules
rm -fr $WDIR/lib/udev/rules.d/70-uaccess.rules
rm -fr $WDIR/lib/udev/rules.d/71-seat.rules
rm -fr $WDIR/lib/udev/rules.d/73-seat-late.rules
}

#to Install all Raid information
setmdadm()

{
if [ -x /usr/sbin/mdadm ] ; then
  # Copy the RAID configuration file if present
  if [ -f /etc/mdadm.conf ] ; then
    cp /etc/mdadm.conf $WDIR/etc
    fi
  duplicate $BINARY0
  fi
}

#to Install all needed kernel module
kermod()

{
if [ -n "$KERNEL_VERSION" ]; then
  NUMKER=`echo $KERNEL_VERSION | sed -e "s/\.\`uname -m\`//"`;
  MODLIST="crypto drivers fs lib net sound block"
  for mod in ${MODLIST}
    do
    mkdir -p /lib/modules/$NUMKER/kernel/$mod
    find								\
	/lib/modules/$NUMKER/kernel/$mod				\
	-type f 2> /dev/null | cpio --make-directories -p --quiet $WDIR
    done
  cp									\
  	/lib/modules/$NUMKER/modules.alias				\
  	/lib/modules/$NUMKER/modules.builtin				\
  	/lib/modules/$NUMKER/modules.builtin.modinfo			\
  	/lib/modules/$NUMKER/modules.order				\
	$WDIR/lib/modules/$NUMKER

 depmod -b $WDIR $NUMKER
fi
}

echo "Preparing initrd for Linux Kernel ${KERNEL_VERSION}"
#set minimal directory

rm -fr $WDIR
mkdir -p $WDIR/etc/{modprobe.d,udev/rules.d}
mkdir -p $WDIR/{dev,run,sys,proc,usr/bin,usr/lib,/usr/sbin,var}
mkdir -p $WDIR/usr/lib/firmware

#link base directories
ln -nsf 						\
	./usr/bin					\
	$WDIR/bin

ln -nsf 						\
	./usr/lib					\
	$WDIR/lib

ln -nsf 						\
	./usr/sbin					\
	$WDIR/sbin

ln -nsf 						\
	../run						\
	$WDIR/var/run

#getting all the current driver list
cp -a							\
	/etc/modprobe.d/*				\
	$WDIR/etc/modprobe.d/

#setting glibc dynamic loading
mkdir -p $WDIR/etc/ld.so.conf.d
cp -a							\
	/etc/ld.so.conf					\
	$WDIR/etc


duplicate $BINARY1 $BINARY2 $BINARY3 $BINARY4 $BINARY5 $BINARY6
setudev
setmdadm
kermod

# Install any firmware if needed
generate-smart-initramfs-pro.sh --verbose $KERNEL_VERSION $WDIR

# Install the init file
install -m 0755 $DATADIR/$INITIN $WDIR/init

# generate compressed default ramfs file 
(						
#adding Intel-Microcode as the initramfs header
cat /usr/lib/firmware/Intel-ucode.cpio;
#generating standard Image
cd $WDIR ;
find . 					|	\
cpio -o -H newc --quiet			|	\
gzip -9 					\
) > $INITRAMFS_FILE


#cleaning all data
rm -fr $WDIR
echo "initrd with Linux Kernel ${KERNEL_VERSION} now Completed"
