#!/bin/sh
# Copyright (c) 2000-2006 Gratien D'haese - IT3 Consultants
# Please read LICENSE in the source directory

# This is mkCDrec's linuxrc script.  Though it was designed for mkCDrec,
# it is meant to be flexible so that it may be used in other applications.
# Its flexibility comes from three user-definable scripts that are called
# by this on: linuxrc_pre, linuxrc_find_and_prep_root, and linuxrc_post.

# Linuxrc_pre should perform actions required before changing the system's
# filesystem root.  In mkCDrec's case, this script finds the CD-ROM which
# was used by the BIOS to boot the system and mounts it.

# Linux_find_and_prep_root prepares the real root filesystem for mounting.
# In the case of mkCDrec, this script uncompresses the filesystem image,
# which is located on the CD-ROM which the BIOS used to boot the system.
# It is important that this script set the shell variables ROOT_DEV and
# ROOT_NUM, which are used by linuxrc to change the root filesystem
# using the kernel's change root or pivot root mechanism.

# Finally, linuxrc_post performs actions which should occur right before
# init is executed.  In mkCDrec's case, linuxrc_post simply unmounts the
# CD-ROM which the BIOS used to boot the system.
#set -x
echo Executing linuxrc...

# unpack modules (if any)
OLDPWD=$PWD # pushd is not available in BusyBox's ash.
cd /lib/modules
        COMPRESSED_MODULES="`ls *.bz2 2> /dev/null`"
        if [ ! -z "${COMPRESSED_MODULES}" ]; then
                /bin/bzip2 -d ${COMPRESSED_MODULES}
        fi
        # Load modules needed to boot.
        . /etc/modules.initrd
        echo -n "Inserting modules... "
        # if insmod.old exist, use it!
        for m in $MODULES; do
                if [ -x /bin/insmod.old ]; then
                        /bin/insmod.old $m
                else
                        /bin/insmod $m
                fi
        done
cd $OLDPWD

mount -n -t sysfs /sys /sys >/dev/null 2>&1 || mount -t sysfs /sys /sys
if [ -f /etc/udev/udev.conf ];then
        . /etc/udev/udev.conf
fi

[ -x /sbin/udevstart ] && /sbin/udevstart

if [ -f /etc/init.d/boot.udev ]; then
   /etc/init.d/boot.udev start 
fi

# Did we get here via OBDR? Check for the existence of /OBDR file.
if [ -f /OBDR ]; then
   OBDR=true
   TAPE_DEV=`cat /OBDR`
elif [ -f /EFI ]; then
   # Check if EFI file exists; IA64: mount /boot/efi and read rd-base from there
   EFI=true
   EFI_DEV=`cat /EFI`
else
   OBDR=false
   EFI=false
   # find CDROM device
   if [ -x /linuxrc_pre ]; then
        . /linuxrc_pre
   fi
fi # of OBDR

# Check if pivot_root exist (not likely in 2.2 based kernels).
if [ -x /bin/pivot_root ]; then
        PIVOT_ROOT=true
else
        PIVOT_ROOT=false
fi

if [ -x /linuxrc_find_and_prep_root ]; then
        . /linuxrc_find_and_prep_root
else
        echo 'Could not find /linuxrc_find_and_prep_root!'
        echo Being desparate, I will try to open a /bin/sh.
        /bin/sh
fi

if [ "$PIVOT_ROOT" = "true" ]; then
        echo "Using pivot_root..."

        # /proc/filesystems now needed by BB's mount.
        echo "Mounting proc (mount -n -t proc none /proc)..."
        mount -n -t proc none /proc 2>/dev/null || mount -t proc proc /proc
        echo "Mounting real root dev (mount -n -o ro $ROOT_DEV /new_root)..."
        mount -n -o ro $ROOT_DEV /new_root 2>/dev/null || mount -o ro $ROOT_DEV /new_root
        echo 0x0100 > /proc/sys/kernel/real-root-dev
        umount /proc

        cd /new_root
        echo "Running pivot_root (/bin/pivot_root . initrd)..."
        /bin/pivot_root . initrd
        hash -r # Use, for example /usr/bin/[ instead of /bin/[ now.

        # Kernel automatically mounted devfs the first time, but now we must.
        if [ -c initrd/dev/.devfsd ]; then
                echo "Mounting devfs (mount -n -t devfs none dev)..."
                mount -n -t devfs none dev 2>/dev/null || mount -t devfs none dev
                # Old /dev (/initrd/dev) needs to be umounted after init 
                # is executed.  Rc.sysinit can do this.
        else
                echo Devfs support does not seem to exist.
        fi
        # devpts support needed for Gentoo
        [ -d /dev/pts ] || mkdir --mode=755 /dev/pts
        mount -t devpts devpts /dev/pts -o gid=5,mode=620 2>/dev/null || mount -t devpts devpts /dev/pts
        if [ -x /linuxrc_post ]; then
                . /linuxrc_post
        fi

        echo My PID is $$.
        if [ $$ = 1 ]; then
                echo "Running init (exec /usr/sbin/chroot . sbin/init dev/console 2>&1)..."
                exec /usr/sbin/chroot . sbin/init dev/console 2>&1
        else
                echo Using bug circumvention for busybox...
                echo "Running init (exec /usr/sbin/chroot . linuxrc dev/console 2>&1)..."
                exec /usr/sbin/chroot . linuxrc dev/console 2>&1
        fi
        echo 'Init failed!'
        echo Being desparate, I will try to open a /bin/sh.
        /bin/sh
else    # PIVOT_ROOT=false
        echo "Not using pivot_root..."
        echo "Mounting proc (mount -n -t proc none /proc)..."
        mount -n -t proc none /proc 2>/dev/null || mount -t proc proc /proc
        echo "Setting ROOT_NUM (echo $ROOT_NUM > /proc/sys/kernel/real-root-dev)..."
        echo $ROOT_NUM > /proc/sys/kernel/real-root-dev
        umount /proc
        #umount /dev/$cdbootdev
fi

if [ -x /linuxrc_post ]; then
        . /linuxrc_post
fi

exit 0
