#!/bin/sh # Daniel Robbins # Copyright 2003 Gentoo Technologies, Inc. # Distributed under the GPL . /etc/initrd.defaults . /etc/initrd.scripts USE_DEVFS_NORMAL=1 if [ "$$" != "1" ] then echo "/linuxrc has to be run as the init process as the one" echo "with a PID of 1. Try adding init=\"/linuxrc\" to the" echo "kernel command line or running 'exec /linuxrc'." exit 1 fi mount -o remount,rw / mount -t proc proc /proc [ -n "$QUIET" ] && echo "0" > /proc/sys/kernel/printk CMDLINE=`cat /proc/cmdline` # Scan CMDLINE for any specified real_root= or cdroot arguments for x in ${CMDLINE} do case "${x}" in real_root\=*) REAL_ROOT=`parse_opt "${x}"` ;; cdroot) CDROOT=1 REAL_ROOT="" ;; devfs) USE_DEVFS_NORMAL=1 ;; nodevfs) USE_DEVFS_NORMAL=0 ;; loop\=*) LOOP=`parse_opt "${x}"` ;; looptype\=*) LOOPTYPE=`parse_opt "${x}"` ;; *) ;; esac done # Scan CMDLINE for any "doscsi" or "noscsi"-type arguments for x in $HWOPTS do for y in $CMDLINE do if [ "$y" = "do${x}" ] then MY_HWOPTS="${MY_HWOPTS} $x" elif [ "$y" = "no${x}" ] then MY_HWOPTS="`echo ${MY_HWOPTS} | sed -e 's/${x}//g' -`" fi done done if [ -d "/lib/modules" ] then echo -e "${GOOD}>>${NORMAL}${BOLD} Loading modules...${NORMAL}" # Load appropriate kernel modules for modules in $MY_HWOPTS do modules_scan $modules eval DO_`echo $modules | sed 's/-//'`=1 done else echo -e "${GREEN}>>${NORMAL}${BOLD} Skipping module load; no modules in the initrd!${NORMAL}" fi chooseKeymap() { echo -e "${GOOD}>>${NORMAL}${BOLD} Loading keymaps...${NORMAL}" cat /lib/keymaps/keymapList read -p "<< Load keymap: " keymap if [ -e /lib/keymaps/${keymap}.map ] then echo -e "${GOOD}>>${NORMAL}${BOLD} Loading the ''${keymap}'' keymap...${NORMAL}" loadkmap < /lib/keymaps/${keymap}.map elif [ "$keymap" = "" ] then echo -e "${GOOD}>>${NORMAL}${BOLD} Loading default US keymap...${NORMAL}" loadkmap < /lib/keymaps/us.map else echo -e "${BAD}!! ${NORMAL}${BOLD}Sorry, but keymap ''${keymap}'' is invalid!${NORMAL}" chooseKeymap fi } if [ "${DO_keymap}" ] then chooseKeymap fi echo -e "${GOOD}>>${NORMAL}${BOLD} Mounting filesystems...${NORMAL}" mkdir /newroot if [ "${CDROOT}" -eq "1" ] then mount -t tmpfs tmpfs /newroot mkdir /newroot/dev /newroot/mnt /newroot/mnt/cdrom /newroot/mnt/livecd /newroot/tmp /newroot/tmp/.initrd /newroot/mnt/gentoo [ ! -e /newroot/dev/.devfsd ] && mount -t devfs devfs /newroot/dev devfsd /newroot/dev -np sleep 1 findcdmount /newroot/dev/cdroms/* # not in /dev/cdroms try /dev/ide/cd if [ "${REAL_ROOT}" = "" ] then findcdmount /newroot/dev/ide/cd/* fi if [ "${REAL_ROOT}" = "" ] then exec /bin/ash # Undo stuff # kill_devfsd # We run devfsd with -np now sleep 1 umount /newroot/dev/ sleep 1 umount /newroot # shouldn't be anything in here b/c it was on tmpfs rm -rf /newroot/* CDROOT=0 echo "Could not find CD to boot, gonna need something else" fi fi # Don't do else b/c we set CDROOT=0 if it fails to detect if [ "${CDROOT}" -eq "0" -a "${USE_DEVFS_NORMAL}" -eq "1" ] then [ ! -e /dev/.devfsd ] && mount -t devfs devfs /dev devfsd /dev -np fi echo -e "${GOOD}>>${NORMAL}${BOLD} Determining root device...${NORMAL}" while true do while [ "${got_good_root}" != "1" ] do if [ "${REAL_ROOT}" = "shell" ] then /bin/ash REAL_ROOT="" got_good_root=0 continue elif [ "${REAL_ROOT}" = "" ] then # No REAL_ROOT determined/specified. Prompt user for root block device. echo -e "${BAD}>>${NORMAL} The root block device is unspecified or not detected." echo " Please specify a device to boot, or \"shell\" for a shell." echo -n "boot() :: " read REAL_ROOT got_good_root=0 elif [ -b "${REAL_ROOT}" ] then got_good_root=1 else echo -e "${BAD}>>${NORMAL} Block device ${REAL_ROOT} is not a valid root device..." REAL_ROOT="" got_good_root=0 fi done if [ "${CDROOT}" -eq "1" -a "${got_good_root}" = "1" ] then break else echo -e "${GOOD}>>${NORMAL}${BOLD} Mounting root...${NORMAL}" mount -o rw ${REAL_ROOT} /newroot if [ "$?" = "0" ] then break else echo -e "${BAD}>> ${NORMAL}Could not mount specified ROOT, try again" got_good_root=0 REAL_ROOT="" fi fi done [ -n "$QUIET" ] && echo "6" > /proc/sys/kernel/printk check_loop() { if [ "${LOOP}" = "" -o ! -e "mnt/cdrom/${LOOP}" ] then echo "Invalid loop location: ${LOOP}" echo "Please export LOOP with a valid location, or reboot and pass a proper loop=..." echo "kernel command line!" /bin/ash fi } if [ "${CDROOT}" = "1" ] then echo -e "${GOOD}>>${NORMAL}${BOLD} Filling tmpfs...${NORMAL}" cd /newroot # Failsafe if some idiot didn't set loop type if [ "${LOOPTYPE}" = "" ] then echo -e "${WARN}** ${NORMAL}${BOLD}Warning: loop type unspecified!${NORMAL}" if [ "${LOOP}" = "/livecd.loop" ] then LOOPTYPE="normal" elif [ "${LOOP}" = "/zisofs" ] then LOOPTYPE="zisofs" elif [ "${LOOP}" = "/livecd.squashfs" ] then LOOPTYPE="squashfs" elif [ "${LOOP}" = "/livecd.gcloop" ] then LOOPTYPE="gcloop" else LOOPTYPE="noloop" fi fi if [ "${LOOPTYPE}" != "noloop" ] then check_loop if [ "${DO_cache}" ] then echo -e "${GOOD}>>${NORMAL}${BOLD} Copying loop file for caching...${NORMAL}" cp -a /newroot/mnt/cdrom/${LOOP} /newroot/mnt/${LOOP} if [ $? -ne 0 ] then echo -e "${BAD}!!${NORMAL}${BOLD} Failed to cache the loop file! Lack of space?" rm -rf /newroot/mnt/livecd.* 2>/dev/null rm -rf /newroot/mnt/zisofs 2>/dev/null else LOOPEXT="../" fi fi fi if [ "${LOOPTYPE}" = "normal" ] then # bind-mount /dev/ so that loop devices can be found mount -o bind /newroot/dev /dev echo -e "${GOOD}>>${NORMAL}${BOLD} Mounting loop filesystem...${NORMAL}" mount -t ext2 -o loop,ro /newroot/mnt/cdrom/${LOOPEXT}${LOOP} /newroot/mnt/livecd if [ "$?" != "0" ] then echo "FAILED TO MOUNT LOOP FILESYSTEM, barfing out to shell" /bin/ash fi FS_LOCATION="mnt/livecd" umount /dev elif [ "${LOOPTYPE}" = "squashfs" ] then mount -o bind /newroot/dev /dev echo -e "${GOOD}>>${NORMAL}${BOLD} Mounting squashfs filesystem...${NORMAL}" mount -t squashfs -o loop,ro /newroot/mnt/cdrom/${LOOPEXT}${LOOP} /newroot/mnt/livecd if [ "$?" != "0" ] then echo "FAILED TO MOUNT LOOP FILESYSTEM, barfing out to shell" /bin/ash fi FS_LOCATION="mnt/livecd" umount /dev elif [ "${LOOPTYPE}" = "gcloop" ] then echo -e "${GOOD}>>${NORMAL}${BOLD} Mounting gcloop filesystem...${NORMAL}" mount -o bind /newroot/dev /dev echo " " | losetup -E 19 -e ucl-0 -p0 /newroot/dev/loop0 /newroot/mnt/cdrom/${LOOPEXT}${LOOP} if [ "$?" != "0" ] then echo "FAILED TO losetup THE LOOP DEVICE" /bin/ash fi mount -t ext2 -o ro /newroot/dev/loop0 /newroot/mnt/livecd FS_LOCATION="mnt/livecd" umount /dev elif [ "${LOOPTYPE}" = "zisofs" ] then FS_LOCATION="mnt/cdrom/${LOOPEXT}${LOOP}" elif [ "${LOOPTYPE}" = "noloop" ] then FS_LOCATION="mnt/cdrom" fi echo -e "${GOOD}>>${NORMAL}${BOLD} Filling filesystem...${NORMAL}" for x in ${ROOT_LINKS} do ln -s "${FS_LOCATION}/${x}" "${x}" done mkdir initrd proc tmp sys chmod 1777 tmp (cd /newroot/${FS_LOCATION}; cp -a ${ROOT_TREES} /newroot) else mkdir -p /newroot/tmp/.initrd fi [ ! -e /newroot/dev/console ] && mknod /newroot/dev/console c 5 1 echo -ne "${GOOD}>>${NORMAL}${BOLD} Booting" cd /newroot pivot_root . tmp/.initrd echo -n '.' if [ "${USE_DEVFS_NORMAL}" -eq "1" -a "${CDROOT}" -eq "0" ] then umount /tmp/.initrd/proc || echo '*: Failed to unmount the initrd /proc!' mount -n --move /tmp/.initrd/dev dev || echo '*: Failed to move over the /dev tree!' rm /tmp/.initrd/dev -rf || '*: Failed to remove the initrd /dev!' elif [ "${CDROOT}" -eq "1" ] then # If automount at boot was on with devfs, we'll want to umount it # also umount proc mount -t proc proc /proc umount /tmp/.initrd/proc > /dev/null 2>&1 || echo "*: Failed to unmount /tmp/.initrd/proc!" umount /dev > /dev/null 2>&1 umount /proc > /dev/null 2>&1 fi echo -n '.' # /usr/src/linux/Documentation/initrd.txt # here's the line it says we should do: # exec chroot . /sbin/init /dev/console 2>&1 exec dev/console 2>&1 echo '.' exec chroot . /bin/sh <<- EOF umount /tmp/.initrd || echo "*: Failed to unmount the initrd!" /sbin/blockdev --flushbufs /dev/ram0 >/dev/null 2>&1 exec /sbin/init EOF echo "A fatal error has probably occured since /sbin/init did not" echo "boot correctly. Trying to open a shell..." echo exec /bin/bash exec /bin/sh exec /bin/ash exec sh