11.1. Building initrd

To boot our live system, we will need an initrd file, which will contain a kernel image as well as a few files and directories, necessary in pre-booting stage

First, mount some directories already squashed

mkdir -v rw/{dev,etc,usr}
mount -n -t squashfs root.sqsh ro -o loop
mount -t unionfs -o dirs=rw/dev=rw:ro/dev=ro unionfs dev
mount -t unionfs -o dirs=rw/etc=rw:ro/etc=ro unionfs etc
mount -t unionfs -o dirs=rw/usr=rw:ro/usr=ro unionfs usr

Now create initrd with the following:

if [ -f $LIVECD/boot/initrd.gz ]
then
  rm -f $LIVECD/boot/initrd.gz
fi
dd if=/dev/zero of=$LIVECD/boot/initrd bs=1024 count=16384 &&
mke2fs -i 1024 -F $LIVECD/boot/initrd &&
mount -o loop $LIVECD/boot/initrd $LIVECD/mnt &&
cd $LIVECD/mnt &&
mkdir bin sbin lib dev proc mnt sys etc
cp -av $LIVECD/bin/{bash,mount,grep,find,umount,echo,ln,mkdir,sleep} bin/ &&
cp -Hv $LIVECD/usr/bin/{awk,xargs} bin/ &&
cp -av $LIVECD/sbin/udev* sbin/ &&
cp -av $(find $LIVECD/usr -name "test" -type f) bin/ &&
cp -av $(find $LIVECD/usr -name "chroot" -type f) bin/ &&
cp -av $(find $LIVECD -name "pivot_root" -type f) sbin/ &&
cp -Hv $LIVECD/lib/{libncursesw.so.5,libdl.so.2,libc.so.6,ld-linux.so.2} lib/ &&
cp -Hv $LIVECD/lib/{libreadline.so.5,libhistory.so.5} lib/ &&
cp -Hv $LIVECD/lib/{libblkid.so.1,libuuid.so.1,libm.so.6} lib/ &&
cp -av $LIVECD/dev/{console,null,ram0} dev/ &&
cp -av $LIVECD/etc/udev etc/ &&
mkfifo dev/initctl &&
ln -sv bash bin/sh &&
ln -sv test bin/[ &&

cat > $LIVECD/mnt/linuxrc << "EOF"
#!/bin/sh
                                                                                
# ID is a file in root of the livecd, used to identify the cd.
# Simple hack of http://www.culmination.org/Mike/2.6-udev-nptl-bootcd.txt

ID="livecd"

TMP_MOUNT="/mnt"
                                                                                
PATH="/bin:/sbin:/usr/bin:/usr/sbin"
                                                                                
# Mount /proc and /sys

# Create the proc directory if it does not exist

if [ ! -d "/proc/" ]; then
  mkdir /proc
fi

# Mount the proc filesystem

mount -n proc /proc -t proc

# If sysfs is listed as a valid filesystem type in /proc
# then mount it

if ! grep -q '[[:space:]]sysfs' /proc/mounts; then
    if [ ! -d /sys/block ]; then
    	mount -n sysfs /sys -t sysfs
    fi
fi

# Mount a temporary file system over /dev, so that any devices
# made or removed during this boot don't affect the next one.
# The reason we don't write to mtab is because we don't ever
# want /dev to be unavailable (such as by `umount -a').

mount -n ramfs /dev -t ramfs

#create a few dirs

mkdir -v /dev/pts
mkdir -v /dev/shm

                                                                               
#if [ ! -x /sbin/hotplug ]; then
    echo > /proc/sys/kernel/hotplug
#fi

# Start the udev daemon to continually watch for, and act on,
# uevents
/sbin/udevd --daemon

# Now traverse /sys in order to "coldplug" devices that have
# already been discovered
/sbin/udevtrigger

# Now wait for udevd to process the uevents we triggered
/sbin/udevsettle

# Detecting the live CD is a very logical process
                                                                                
# Search for cdrom devices and add them to CDROM_LIST
echo "detecting cdrom devices..."
for I in `find /proc/sys/dev/cdrom | xargs grep -s  "drive name" | awk '{ print $3 }'`
  do CDROM_LIST="$CDROM_LIST /dev/$I"
done

# Now we try to find the livecd using ID as identification
                                                                                
LIVE_DEVICE=""

for cdrom_device in $CDROM_LIST
do
  mount -n -t iso9660 ${cdrom_device} $TMP_MOUNT
  media_found=$?
  if [ $media_found -eq 0 ]; then
      echo -n "media found"
      [ -e "$TMP_MOUNT/$ID" ]
      media_live=$?
      if [ $media_live -eq 0 ]; then
      echo -n ". Livecd found."
      LIVE_DEVICE="$cdrom_device"
      break;
      else
      echo ". Not livecd."
      umount -n $TMP_MOUNT
      fi
  else
    echo "no media found"
  fi
done
if [ "$LIVE_DEVICE" = "" ]; then
  echo "No livecd found!!!"
  exit 1
else
  echo " Booting from $LIVE_DEVICE..."

  echo 0x0100 > /proc/sys/kernel/real-root-dev
  cd $TMP_MOUNT
  pivot_root . mnt
  exec chroot . sh -c 'umount -l -n /mnt;
   exec -a init.new /sbin/init 3' <dev/console >dev/console 2>&1
fi
EOF
chmod 0755 $LIVECD/mnt/linuxrc &&
cd $LIVECD/ &&
umount $LIVECD/mnt &&
gzip $LIVECD/boot/initrd &&
touch $LIVECD/livecd

Umount mounted directories

umount dev etc usr ro
rmdir rw/{dev,etc,usr}

Initrd is ready. We now have to create an iso9660 file system.