You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
genkernel_fork/generic/linuxrc

331 lines
7.5 KiB

#!/bin/sh
# Daniel Robbins <drobbins@gentoo.org>
# Copyright 2003 Gentoo Technologies, Inc.
# Distributed under the GPL
. /etc/initrd.defaults
. /etc/initrd.scripts
USE_DEVFS_NORMAL=1
mount -o remount,rw /
mount /proc
[ -n "$QUIET" ] && echo "0" > /proc/sys/kernel/printk
echo "${GOOD} Gentoo initrd startup..."
echo "STEP 1: Command-line parsing"
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 "STEP 2: Module loading"
# Load appropriate kernel modules
for x in $MY_HWOPTS
do
modules_scan $x
done
else
echo "STEP 2: Skipping module load. No modules in initrd"
fi
echo "STEP 3: Mounting necessary filesystems per boot options"
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
echo "Dropping to shell so you can fix your shit"
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 "STEP 4: Determining root device"
while true
do
while [ "${got_good_root}" != "1" ]
do
if [ "${REAL_ROOT}" = "shell" ]
then
/bin/ash
#set REAL_ROOT to "" so we get a prompt for the real root after the shell exits.
REAL_ROOT=""
got_good_root=0
continue
elif [ "${REAL_ROOT}" = "" ]
then
#no REAL_ROOT determined/specified. Prompt user for root block device.
echo "Root block device unspecified or not detected."
echo "Please specify a device to boot, or \"shell\" for a shell."
echo -n ": "
read REAL_ROOT
got_good_root=0
elif [ -b "${REAL_ROOT}" ]
then
got_good_root=1
else
REAL_ROOT=""
got_good_root=0
fi
done
if [ "${CDROOT}" -eq "1" -a "${got_good_root}" = "1" ]
then
break
else
echo "STEP 4a: Mounting root"
mount -o rw ${REAL_ROOT} /newroot
if [ "$?" = "0" ]
then
break
else
echo "Could not mount specified ROOT, try again"
got_good_root=0
REAL_ROOT=""
fi
fi
done
[ -n "$QUIET" ] && echo "6" > /proc/sys/kernel/printk
echo "STEP 5: Finishing up"
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 "STEP 5a: filling tmpfs filesystem"
cd /newroot
# Failsafe if some idiot didn't set loop type
if [ "${LOOPTYPE}" = "" ]
then
echo "YOU FORGOT TO SPECIFY LOOPTYPE TRYING TO AUTODETECT"
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
echo "DETECTED LOOPTYPE: $LOOPTYPE"
fi
if [ "${LOOPTYPE}" = "normal" ]
then
check_loop
# bind-mount /dev/ so that loop devices can be found
mount -o bind /newroot/dev /dev
echo "STEP 5a1: mounting loop filesystem"
mount -t ext2 -o loop,ro /newroot/mnt/cdrom/${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
check_loop
mount -o bind /newroot/dev /dev
echo "STEP 5a1: mounting squashfs filesystem"
mount -t squashfs -o loop,ro /newroot/mnt/cdrom/${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
check_loop
mount -o bind /newroot/dev /dev
echo "STEP 5a1: mounting gcloop (ext2) filesystem"
echo " " | losetup -E 19 -e ucl-0 -p0 /newroot/dev/loop0 /newroot/mnt/cdrom/${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
check_loop
FS_LOCATION="mnt/cdrom/${LOOP}"
elif [ "${LOOPTYPE}" = "noloop" ]
then
FS_LOCATION="mnt/cdrom"
fi
echo "STEP 5a2: filling filesystem"
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
echo "STEP 5b: setting up stuff for pivot_root"
mkdir -p /newroot/tmp/.initrd
fi
echo "STEP 5c: redirect console"
console=/newroot/dev/console
[ ! -e "$console" ] && mknod $console c 5 1
exec < $console > $console 2>&1 || echo "CONSOLE REDIRECTION FAILED, /dev ON ROOT DOES NOT CONTAIN console !!!"
echo "STEP 6: pivot_root and exec/chroot real init"
cd /newroot
pivot_root . tmp/.initrd
if [ "${USE_DEVFS_NORMAL}" -eq "1" -a "${CDROOT}" -eq "0" ]
then
# must mount a new devfs before we can
# umount the old one for some reason
mount -t proc proc /proc
mount -t devfs devfs /dev
umount /tmp/.initrd/proc || echo "COULD NOT UMOUNT tmp/.initrd/proc !!!"
umount /tmp/.initrd/dev || echo "COULD NOT UMOUNT tmp/.initrd/dev !!!"
# at this point it lets us umount the new
# devfs, don't know why, just does, stop
# asking questions!
umount /dev
umount /proc
cp -f /etc/mtab /etc/mtab.initrd-here > /dev/null 2>&1
elif [ "${CDROOT}" -eq "1" ]
then
# If automount at boot was on with devfs, we'll want to umount it
# also umount proc
echo "STEP 6a: clean up mounts"
mount -t proc proc /proc
umount /tmp/.initrd/proc > /dev/null 2>&1 || echo "COULD NOT UMOUNT /tmp/.initrd/proc !!!"
umount /dev > /dev/null 2>&1
umount /proc > /dev/null 2>&1
fi
# /usr/src/linux/Documentation/initrd.txt
# here's the line it says we should do:
# exec chroot . /sbin/init </dev/console >/dev/console 2>&1
exec chroot . /bin/sh <<- EOF
umount /tmp/.initrd || echo "UMOUNT of /tmp/.initrd FAILED!!!" && /sbin/blockdev --flushbufs /dev/ram0
echo "INIT: starting /sbin/init ${CMDLINE}"
exec /sbin/init ${CMDLINE}
EOF
# exec chroot . /sbin/init ${CMDLINE} < /dev/console > /dev/console 2>&1
echo "IF YOU ARE SEEING THIS MESSAGE, A FATAL ERROR HAS OCCURRED"
echo "MOST LIKELY /sbin/init DOES NOT EXIST, ATTEMPTING TO DROP"
echo "YOU TO A SHELL"
exec /bin/bash
exec /bin/sh
exec /bin/ash
exec sh