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

cat > $LIVEKEY/mnt/linuxrc << "EOF"
#!/bin/sh
                                                                                
# ID is a file in root of the livekey, used to mount the key.
# Hack of http://www.culmination.org/Mike/2.6-udev-nptl-bootcd.txt

ID="livekey"

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

#now mount livekey
SUCCESS=1
mount_livekey() {                                                         
mount -n -o ro -L $ID $TMP_MOUNT
SUCCESS=$?
}

while [ $SUCCESS = 1 ]
do
  mount_livekey
  if [ $SUCCESS = 1 ]
  then echo "couldn't mount livekey, sleeping for 5 seconds..."
       /bin/sleep 5
       echo -n "trying again..."
  fi
done
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
EOF
chmod 0755 $LIVEKEY/mnt/linuxrc &&
cd $LIVEKEY/ &&
umount $LIVEKEY/mnt &&
gzip $LIVEKEY/boot/initrd &&
touch $LIVEKEY/livekey

Umount mounted directories

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

Initrd is ready. We now have to make our livekey bootable