#!/static/sh
#
# sidux general startup script
# (C) Klaus Knopper <knoppix@knopper.net>
# (C) 2003-2006 Joerg Schirottke <master@kanotix.com>
# (C) 2006 Stefan Lippers-Hollmann <s.l-h@gmx.de>
# License: GPL V2.
#
# This script needs some of the builtin busybox commands (if, test, ...)
# mount/umount, insmod/rmmod are also a builtin in busybox.
#

# override tool behaviour through distro-defaults
FLL_DISTRO_NAME="sidux"
FLL_LIVE_USER="sidux"
FLL_IMAGE_DIR="SIDUX"
FLL_IMAGE_FILE="SIDUX"
FLL_MOUNTPOINT="/SIDUX"
FLL_UNION_SOURCE="/ramdisk/var/tmp/union"
FLL_UNION_TARGET="$FLL_MOUNTPOINT"
FLL_UNION_OPTIONS="rw"
FLL_PERSISTENT_HOME="sidux.img"
FLL_MEDIA_DIR="SIDUX"
FLL_MEDIA_NAME="SIDUX.ISO"
FLL_MEDIUM="cdrom"
FLL_MEDIA_MOUNTPOINT="/isosrc"

. /etc/default/distro

# We are always live
FLL_DISTRO_MODE="live"

# hardcoded configurable options
# Default maximum size of dynamic ramdisk in kilobytes
RAMSIZE=1000000
# End of options

# Option Defaults
NOSCSI=""
NOUSB=""
NOFIREWIRE="yes"
NOCD=""
MODSD=""
NOIDERAID="yes"
FSTAB=""
COPYTO=""
BOOTFROM=""
DO_REMOUNT=""
FSTABFILE="${FLL_IMAGE_FILE}.FSTAB"
REAL_TARGET=""
UNIONFS=""
USB2="ehci-hcd.ko"
AUFS=""
INTERACTIVE=""
MODULES=""

# (some) Status variables
SCSI_PROBE=""
FOUND_SCSI=""
FOUND_KNOPPIX=""
FOUND_FSTAB=""

# Builtin filesystems
BUILTIN_FS="iso9660 ext2"
# Modular filesystems
# ext3 is also modular but we'll want to try it before ext2
MODULAR_FS="reiserfs xfs jfs vfat ntfs"
# What filesystem types to try and mount as when using mount_it
MOUNTIT_FS="$BUILTIN_FS"

# Don't allow interrupt signals
trap "" 1 2 3 11 15

# Misc functions
mountit()
{
	# Usage: mountit src dst "options"
	# Uses builtin mount of busybox
	LOOPM=""
	case $3 in
		*loop*)
			LOOPM="1"
			;;
	esac
	if test -b $1 || ( test -r $1 && test -n "$LOOPM" ); then
		for fs in $MOUNTIT_FS; do
			case "$fs" in
				vfat)
					# We REALLY need this for FLL_IMAGE on DOS-filesystems
					[ -n "$3" ] && MOUNTIT_OPT="$3,shortname=winnt" || MOUNTIT_OPT="-o shortname=winnt"
					;;
				ntfs)
					[ -n "$3" ] && MOUNTIT_OPT="$3,ro,uid=1000,gid=1000 " || MOUNTIT_OPT="-o ro,uid=1000,gid=1000 "
					;;
				*)
					MOUNTIT_OPT="$3"
					;;
			esac

			case $FS_MODULES_LOADED in
				*$fs*)
					;;
				*)
					[ "$fs" = "ext3" ] && loadmodule jbd
					loadmodule $fs
					FS_MODULES_LOADED="$FS_MODULES_LOADED $fs"
					;;
			esac

			mount -t $fs $MOUNTIT_OPT $1 $2 >/dev/null 2>&1 && return 0
		done
	fi

	return 1
}

# Clean input/output
exec >/dev/console </dev/console 2>&1

# Reset fb color mode
RESET="]R"
# ANSI COLORS
# Erase to end of line
CRE="
[K"
# Clear and reset Screen
CLEAR="c"
# Normal color
NORMAL="[0;39m"
# RED: Failure or error message
RED="[1;31m"
# GREEN: Success message
GREEN="[1;32m"
# YELLOW: Descriptions
YELLOW="[1;33m"
# BLUE: System mesages
BLUE="[1;34m"
# MAGENTA: Found devices or drivers
MAGENTA="[1;35m"
# CYAN: Questions
CYAN="[1;36m"
# BOLD WHITE: Hint
WHITE="[1;37m"

# We only need the builtin commands and /static at this point
PATH=/static
export PATH

umask 022

# Mount /proc, /sys and /dev/pts
mount -t proc /proc /proc
mount -t sysfs /sys /sys
mount -t devpts -o noexec,nosuid devpts /dev/pts

# Disable kernel messages while probing modules in autodetect mode
echo "0" > /proc/sys/kernel/printk

ARCHITECTURE="$(uname -m)"

# Clear screen with colormode reset
#echo "$CLEAR$RESET"
#echo "$CLEAR"
# Just go to the top of the screen
#echo -n "[H[J"
echo ""
# Be verbose
echo "${WHITE}Welcome to $FLL_DISTRO_NAME ($ARCHITECTURE) live linux!${NORMAL}"
echo ""
echo ""

# Read boot command line with builtin cat command (shell read function fails in Kernel 2.4.19-rc1)
CMDLINE="$(cat /proc/cmdline)"

# Check if we are in interactive startup mode
case "$CMDLINE" in
	*BOOT_IMAGE=expert\ *)
		INTERACTIVE="yes"
		:>/interactive
		;;
esac

case "$CMDLINE" in
	*modules-disk*)
		INTERACTIVE="yes"
		;;
esac

# enable debugging?
case "$CMDLINE" in
	*BOOT_IMAGE=debug\ *|*\ debug*)
		DEBUG="yes"
		;;
esac

# Does the user want to skip scsi detection?
case "$CMDLINE" in
	*noscsi*|*nobootscsi*)
	NOSCSI="yes"
	;;
esac

case "$CMDLINE" in
	*scsiisa*)
	SCSI_PROBE="$ISA_SCSI $SCSI_PROBE"
	;;
esac

case "$CMDLINE" in
	*nousb*)
		NOUSB="yes"
		;;
esac

case "$CMDLINE" in
	*bootfirewire*)
		NOFIREWIRE=""
		;;
esac

case "$CMDLINE" in
	*fromhd*)
		NOCD="yes"
		MODSD="yes"
		;;
esac

case "$CMDLINE" in
	*fromdvd*)
		FROMDVD="yes"
		;;
esac

case "$CMDLINE" in
	*fromiso*)
		FROMISO="yes"
		mkdir $FLL_MEDIA_MOUNTPOINT
		MODSD="yes"
		;;
esac

case "$CMDLINE" in
	*idecd*|*atapicd*)
		IDECD="yes"
		;;
esac

case "$CMDLINE" in
	*ideraid*)
		NOIDERAID=""
		# does ideraid need sd_mod
		# MODSD="yes"
		;;
esac

case "$CMDLINE" in
	*image_dir=*)
		FLL_IMAGE_DIR="$image_dir"
		;;
esac

case "$CMDLINE" in
	*image_name=*)
		FLL_IMAGE_FILE="$image_name"
		;;
esac

# Needs possibly updated FLL_IMAGE_DIR and FLL_IMAGE_FILE
FLL_IMAGE_LOCATION="$FLL_IMAGE_DIR/$FLL_IMAGE_FILE"

case "$CMDLINE" in
	*iso_dir=*)
		FLL_MEDIA_DIR="$media_dir"
		;;
esac

case "$CMDLINE" in
	*iso_name=*)
		FLL_MEDIA_NAME="$media_name"
		;;
esac

# Needs possibly updated FLL_MEDIA_DIR and FLL_MEDIA_NAME
FLL_MEDIA="$FLL_MEDIA_DIR/$FLL_MEDIA_NAME"

case "$CMDLINE" in
	*fromiso=*)
		FLL_MEDIA="$fromiso"
		;;
esac

case "$CMDLINE" in
	*fstab*)
		FSTAB="1"
		MODSD="yes"
		;;
esac

case "$CMDLINE" in
	*fstab=*)
		FSTABFILE="$fstab"
		;;
esac

case "$CMDLINE" in
	 *toram*)
	 	DO_REMOUNT="yes"
		COPYTO="ram"
		;;
esac

case "$CMDLINE" in
	*tohd=*)
		DO_REMOUNT="yes"
		COPYTO="hd"
		MODSD="yes"
		;;
esac

case "$CMDLINE" in
	*bootfrom=*)
		DO_REMOUNT="yes"
		BOOTFROM="yes"
		MODSD="yes"
		;;
esac

case $CMDLINE in
	*fromhd*|*fromiso*|*bootusb*|*bootusb2*|*tohd*|*fstab*|*modules-disk*|*ideraid*)
	# strictly perhaps
	# *fromhd*|*tohd*|*fstab*|*modules-disk*)
		MOUNTIT_FS="iso9660 ext3 ext2 $MODULAR_FS"
		;;
esac

# Print CPU info
echo -n "${GREEN}"
awk -F: '/^processor/{printf "Processor"$2" is "};/^model name/{printf $2};/^vendor_id/{printf vendor};/^cpu MHz/{printf " %dMHz",int($2)};/^cache size/{printf ","$2" Cache"};/^$/{print ""}' /proc/cpuinfo 2>/dev/null
echo -n "${NORMAL}"

# Print kernel info
echo "${BLUE}Running Linux Kernel: ${YELLOW}$(uname -r)${BLUE}.${NORMAL}"

# look for kernel modules in these directories
MODULE_DIRS="/$FLL_MEDIUM/$FLL_IMAGE_DIR/modules /modules"

# Dynamic program loader
# $FLL_MOUNTPOINT is already mounted when this is used.
# fallback to i386 defaults.
DYNLOADER="$FLL_MOUNTPOINT/lib/ld-linux.so.2"
[ "$ARCHITECTURE" = "x86_64" ] && DYNLOADER="$FLL_MOUNTPOINT/lib/ld-linux-x86-64.so.2"
#[ "$ARCHITECTURE" = "sparc" ] &&  DYNLOADER="$FLL_MOUNTPOINT/lib/ld-linux.so.2"        # default anyways

# Get total ramsize, and available real ram in kB. We need this later.
# Note that FREEMEM is incorrect, we should add MemCached,
# but the difference should be minimal at this point.
TOTALMEM=64000
FREEMEM=32000
while read info amount kb; do
	case "$info" in
		MemTotal:)
			test "$amount" -gt "0" >/dev/null 2>&1 && TOTALMEM="$amount";;
		MemFree:)
			test "$amount" -gt "0" >/dev/null 2>&1 && FREEMEM="$amount";;
	esac
done </proc/meminfo

# Print meminfo.
echo "${BLUE}Total Memory available: ${YELLOW}${TOTALMEM}kB${BLUE}, Memory free: ${YELLOW}${FREEMEM}kB${BLUE}.${NORMAL}"

# New in Knoppix 5.1: cloop preload cache
# Default values
case "$MEDIUM" in
	*[Cc][Dd]*)
		CLOOP_PRELOAD="preload=64"
		 ;;
	*[Dd][Vv][Dd]*)
		CLOOP_PRELOAD="preload=128"
		;;
	*)
		CLOOP_PRELOAD="preload=32"
		;;
esac

# cloop improves seek performance when caching the directory index
# (first few MB) of each cloop file.
# Default values depending on ramsize, override with cloop_preload=numblocks at boot.
if test "$TOTALMEM" -lt 128000; then
	# up to 128MB: No preload.
	CLOOP_PRELOAD=""
elif test "$TOTALMEM" -lt 256000; then
	# less than 256MB: About 4MB preload w/ blocksize 128k
	CLOOP_PRELOAD="preload=32"
elif test "$TOTALMEM" -lt 512000; then
	# less than 512MB: About 8MB preload w/ blocksize 128k
	CLOOP_PRELOAD="preload=64"
elif test "$TOTALMEM" -lt 1024000; then
	# less than 1GB: About 16MB preload w/ blocksize 128k
	CLOOP_PRELOAD="preload=128"
else
	# 1GB Ram or more
	# About 32MB w/ blocksize 128k
	CLOOP_PRELOAD="preload=256"
fi

case "$CMDLINE" in 
	*\ nocache*|*\ nocloop_preload*|*\ nopreload*)
		CLOOP_PRELOAD=""
		;;
esac

[ -n "$cloop_preload" ] && CLOOP_PRELOAD="preload=$cloop_preload"

# Run a shell if in debug mode
stage=1
rundebugshell()
{
	if [ -n "$DEBUG" ]; then
		echo "${CRE}${BLUE}Starting intermediate Shell stage $stage as requested by \"debug\" option.${NORMAL}"
		echo "${CRE}${BLUE}Type \"exit\" to continue with normal bootup.${NORMAL}"
		[ -x /static/ash ] && /static/ash || /bin/bash
	fi
}

# Mount module disk
mountmodules()
{
	TYPE="$1"
	shift

	echo -n "${CRE}${CYAN}Please insert ${TYPE} modules disk and hit Return. ${NORMAL}"
	read a
	echo -n "${CRE}${BLUE}Mounting ${TYPE} modules disk... ${NORMAL}"

	# Store our MOUNTIT_FS
	MOUNTIT_FS_GENERAL="$MOUNTIT_FS"
	# Only these filesystems are sane on a floppy
	MOUNTIT_FS="ext2 vfat"

	# We always mount over /modules (because it's there ;-)
	if mountit /dev/fd0 /modules "-o ro"; then
		echo "${GREEN}OK.${NORMAL}"
		MOUNTIT_FS="$MOUNTIT_FS_GENERAL"
		return 0
	fi
	
	echo "${RED}NOT FOUND.${NORMAL}"

	MOUNTIT_FS="$MOUNTIT_FS_GENERAL"
	return 1
}

# Unmount module disk
umountmodules()
{
	TYPE="$1"
	shift

	echo -n "${CRE}${BLUE}Unmounting ${TYPE} modules disk... ${NORMAL}"
	umount /modules 2>/dev/null
	echo "${GREEN}DONE.${NORMAL}"
}

# Ask user for modules
askmodules()
{
	TYPE="$1"
	shift

	echo "${BLUE}${TYPE} modules available:${WHITE}"
	c=""
	for m in "$@"; do
		if test -r "/modules/$m"; then
			test -z "$c"  && { echo -n "	$m"; c="1"; } || { echo "		$m"; c=""; }
		fi
	done

	[ -n "$c" ] && echo ""
	echo "${CYAN}Load ${TYPE} Modules?${NORMAL}"
	echo "${CYAN}[Enter full filename(s) (space-separated), Return for autoprobe, ${WHITE}n${CYAN} for none] ${NORMAL}"
	echo -n "${CYAN}insmod module(s)> ${NORMAL}"
	read MODULES

	case "$MODULES" in
		n|N)
			MODULES=""
			;;
		y|"")
			MODULES="$*"
			;;
	esac
}

# Try to load the given module with optional parameters
# module can be a full path or a module.ko name
# (in which case $MODULE_DIRS is searched).
# loadmodule module options...
loadmodule()
{
	MODULE="$1"
	shift

	INSMOD=""

	# Find insmod in CURRENT file system configuration
	for p in $MODULE_DIRS /static; do
		checkfor="$p/insmod"
		if test -x "$checkfor"; then
			INSMOD="$checkfor"
			break
		fi
	done

	# At last resort, try builtin insmod
	test -z "$INSMOD" && INSMOD="insmod" # builtin insmod
	LOAD=""
	for p in $MODULE_DIRS; do
		for ext in ".ko" "" ".o"; do
			checkfor="$p/$MODULE$ext"
			if test -r "$checkfor"; then
				LOAD="$checkfor"
				break 2
			fi
		done
	done
	test -n "$LOAD" || return 1

	# Fork a new process to avoid crashing our main shell
	echo "$INSMOD $LOAD" "$@" | /static/ash
	return "$?"
}

# Load many modules at once
# loadmodules TYPE(comment) module ...
loadmodules()
{
	TYPE="$1"
	shift

	test -n "$INTERACTIVE" && echo "6" > /proc/sys/kernel/printk
	for m in "$@"; do
		echo -n "${CRE}${BLUE}Probing ${TYPE}... ${MAGENTA}$m${NORMAL}"
		if loadmodule "$m" >/dev/null 2>&1; then
			case "$TYPE" in
				scsi|SCSI)
					FOUND_SCSI="yes"
					;;
			esac
		fi
	done

	test -n "$INTERACTIVE" && echo "0" > /proc/sys/kernel/printk
	echo -n "${CRE}"
}

unloadmodule()
{
	MODULE="$1"
	RMMOD=""

	# Find rmmod in CURRENT file system configuration
	for p in $MODULE_DIRS /static; do
		checkfor="$p/rmmod"
		if test -x "$checkfor"; then
			RMMOD="$checkfor"; break
		fi
	done

	# At last resort, try builtin rmmod
	test -z "$RMMOD" && RMMOD="rmmod" # builtin rmmod

	# For a new process to avoid crashing our main shell
	echo "$RMMOD" "$MODULE" | /static/ash
	return "$?"
}

# Check for SCSI, use modules on bootfloppy first
ISA_SCSI="aha1740 aha1542 aha152x pas16 psi240i qlogicfas qlogicfc seagate t128 u14-34f wd7000"

# Trying to do kind of /proc/pci hardware detection
# SCSI detection using /sys/devices
for d in /sys/devices/*/*; do
	if test -r "$d"/class -a -r "$d"/vendor -a -r "$d"/device; then
		read CLASS  < "$d"/class 2>/dev/null
		
		case "$CLASS" in
			0x0100*)
				read VENDOR < "$d"/vendor 2>/dev/null
				read DEVICE < "$d"/device 2>/dev/null
				
				case "$VENDOR:$DEVICE" in
					*1000:*00[0-2]?)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_spi sym53c8xx"
						;;
					*1000:*040?|*1000:*196?|*101e:*196?|*1028:*000[ef]|*1028:*0013)
						SCSI_PROBE="$SCSI_PROBE scsi_mod megaraid_mm megaraid_mbox"
						;;
					*1000:*04[1-9]?|*1028:*0015)
						SCSI_PROBE="$SCSI_PROBE scsi_mod megaraid_sas"
						;;
					*1001:*9100|*1101:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod initio"
						;;
					*9004:*|*9005:*00??)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_spi aic7xxx"
						;;
					*1011:*|*1028:*000[1-9a]|*9005:*02[08]?)
						SCSI_PROBE="$SCSI_PROBE scsi_mod aacraid"
						;;
					*1014:*002e|*1014:*01bd|*9005:*0250)
						SCSI_PROBE="$SCSI_PROBE scsi_mod ips"
						;;
					*1014:*0[1-2]8?|*1069:*|*9005:*0503)
						SCSI_PROBE="$SCSI_PROBE scsi_mod libata ipr"
						;;
					*1022:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod tmscsim"
						;;
					*1044:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod dpt_i2o"
						;;
					*1077:*1???)
						SCSI_PROBE="$SCSI_PROBE scsi_mod qla1280"
						;;
					*1077:*21??)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_fc qla2xxx qla2100"
						;;
					*1077:*22??)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_fc qla2xxx qla2200"
						;;
					*1077:*23[0-1]?)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_fc qla2xxx qla2300"
						;;
					*1077:*232?)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_fc qla2xxx qla2322"
						;;
					*1077:*24??)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_fc qla2xxx"
						;;
					*1077:*63??)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_fc qla2xxx qla6312"
						;;
					*10df:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_fc lpfc"
						;;
					*10fc:*|*1145:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod nsp32"
						;;
					*1101:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod a100u2w"
						;;
					*1119:*|*8086:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod gdth"
						;;
					*1191:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod atp870u"
						;;
					*134a:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_spi dmx3191d"
						;;
					*1de1:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod dc395x"
						;;
					*9005:*8???)
						SCSI_PROBE="$SCSI_PROBE scsi_mod scsi_transport_spi aic79xx"
						;;
					*104b:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod BusLogic"
						;;
					*1[0d]e1:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod dc395x"
						;;
					*1000:*00[34]?)
						SCSI_PROBE="$SCSI_PROBE scsi_mod mptbase mptscsih"
						;;
					*10cd:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod advansys"
						;;
					*1191:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod atp870u"
						;;
					*134a:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod dtc"
						;;
					*1d44:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod eata"
						;;
					*1036:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod fdomain"
						;;
					*1256:*4201)
						SCSI_PROBE="$SCSI_PROBE scsi_mod pci2220i"
						;;
					*1256:*5201)
						SCSI_PROBE="$SCSI_PROBE scsi_mod pci2000"
						;;
					*1022:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod tmscsim"
						;;
					*6356:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod ultrastor"
						;;
					*13c1:*)
						SCSI_PROBE="$SCSI_PROBE scsi_mod 3w-xxxx"
						;;
				esac
				;;
		esac
	fi
done

# Load fuse, we may need it to access ntfs filesystems
#loadmodule fuse >/dev/null 2>&1

if test -n "$INTERACTIVE"; then
	# Let the user select interactively
	askmodules SCSI $(cd /modules; echo *.ko)
else
	# these are the autoprobe-safe modules
	MODULES="$SCSI_PROBE"
fi

if [ -z "$NOSCSI" ] && [ -n "$MODULES" ]; then
	loadmodules SCSI $MODULES
	# Do we need to load sd_mod here
	# MODSD="yes"
fi
# End of SCSI check

# Check for IDE-Raid devices
if test -z "$NOIDERAID"; then
	(
		cd /modules
		{
			loadmodule ataraid >/dev/null 2>&1 && \
			loadmodule silraid >/dev/null 2>&1
		} || \
		loadmodule medley >/dev/null 2>&1 || \
		loadmodule pdcraid >/dev/null 2>&1
	)
fi
# End of IDE-Raid check

# Check for USB, use modules on bootfloppy first
if test -z "$NOUSB"; then
	echo -n "${CRE}${BLUE}Checking for USB...${NORMAL}"
	if loadmodule usbcore >/dev/null 2>&1; then
		FOUNDUSB=""

		for i in $USB2 uhci-hcd ohci-hcd; do
			loadmodule $i >/dev/null 2>&1 && FOUNDUSB="yes"
		done

		if test -n "$FOUNDUSB"; then
			loadmodule scsi_mod.ko >/dev/null 2>&1
			loadmodule sg.ko >/dev/null 2>&1
			loadmodule libusual.ko >/dev/null 2>&1
			loadmodule ff-memless.ko >/dev/null 2>&1
			loadmodule usbhid.ko >/dev/null 2>&1
			loadmodule usb-storage.ko >/dev/null 2>&1 || loadmodule ub.ko >/dev/null 2>&1
		else
			# For an unknown reason, unloading usbcore hangs sometimes
			# rmmod usbcore >/dev/null 2>&1
			true
		fi
	fi
	
	echo -n "${CRE}"
fi
# End of USB check

# Check for Firewire, use modules on bootfloppy first
if test -z "$NOFIREWIRE"; then
	echo -n "${CRE}${BLUE}Checking for Firewire...${NORMAL}"
	if loadmodule ieee1394 >/dev/null 2>&1; then
		FOUNDFIREWIRE=""
		
		for i in ohci1394; do
			echo -n "${CRE}${BLUE}Loading $i...${NORMAL}"
			loadmodule "$i" >/dev/null 2>&1 && FOUNDFIREWIRE="yes"
		done

		if test -n "$FOUNDFIREWIRE"; then
			echo -n "${CRE}${BLUE}Loading sbp2...${NORMAL}"
			loadmodule sbp2 serialize_io=1 >/dev/null 2>&1
		else
			# For an unknown reason, unloading ieee1394 hangs sometimes
			# echo -n "${CRE}${BLUE}Unloading ieee1394...${NORMAL}"
			# rmmod ieee1394 >/dev/null 2>&1
			true
		fi
	fi

	echo -n "${CRE}"
fi
# End of FIREWIRE check

# Unfortunately, hotpluggable devices tend to need some time in order to register
if test -n "$FOUNDUSB" -o -n "$FOUNDFIREWIRE"; then
	echo -n "${CRE}${BLUE}Scanning for USB/Firewire devices... ${NORMAL}"
	if test -n "$FOUNDFIREWIRE"; then
		# Wait for driver to register
		sleep 2
		
		# Kernel 2.6 does this automatically
		case "$(cat /proc/version 2>/dev/null)" in
			*version\ 2.6.*)
				;;
			*)
				for host in 0 1 2 3 4 5 6 7; do 
					for channel in 0 1; do 
						for id in 0 1 2 3 4 5 6 7; do 
							echo "scsi add-single-device $host $channel $id 0" >/proc/scsi/scsi 2>/dev/null
						done
					done
				done
				;;
		esac
	fi

	sleep 6
	echo "${BLUE}Done.${NORMAL}"
fi

# Check for misc modules in expert mode
if test -n "$INTERACTIVE"; then
	another=""
	answer=""
	while test "$answer" != "n" -a "$answer" != "N"; do
		echo -n "${CYAN}Do you want to load additional modules from$another floppy disk? [${WHITE}Y${CYAN}/n] ${NORMAL}"
		another=" another"
		read answer

		case "$answer" in
			n*|N*)
				break
				;;
		esac

		if mountmodules new; then
			askmodules new $(cd /modules; echo *.ko)
			test -n "$MODULES" && loadmodules new $MODULES
			umountmodules current
		fi
	done
fi
# All interactively requested modules should be loaded now.

# Give USB-Storage devices some more time to register
if test -d /proc/scsi/usb-storage; then
	echo -n "${CRE}${BLUE}Allowing slow USB-devices some more time to register...${NORMAL}"
	ash -c "sleep 6"
	echo "${BLUE}Ok.${NORMAL}"
fi

# Just load sr_mod for usb/firewire/scsi/sata cd drives
loadmodule sr_mod >/dev/null 2>&1

# Load sd_mod for: from(iso|hd) bootfrom tohd fstab
if [ -n "$MODSD" ]; then
	loadmodule sd_mod >/dev/null 2>&1
fi

# Check for ide-scsi supported CD-Roms et al.
test -r /proc/scsi/scsi && FOUND_SCSI="yes"

test -r /modules/ide-generic.ko && loadmodule ide-generic
test -r /modules/ide-disk.ko && loadmodule ide-disk

# Disable kernel messages again
echo "0" > /proc/sys/kernel/printk

# disable DMA in case of hardware bugs
# in FROMHD or TORAM mode
case "$CMDLINE" in
	*\ nodma*)
		for d in $(cd /proc/ide 2>/dev/null && echo hd[a-z]); do
			if test -d /proc/ide/$d; then
				MODEL="$(cat /proc/ide/$d/model 2>/dev/null)"
				test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
				echo "${BLUE}Disabling DMA acceleration for: ${MAGENTA}$d 	${YELLOW}[${MODEL}]${NORMAL}"
				echo "using_dma:0" >/proc/ide/$d/settings
			fi
		done
		;;
esac

stage=1
rundebugshell

# Now that the right SCSI driver is (hopefully) loaded, try to find CDROM
DEVICES="/dev/hd?"
test -n "$FOUNDUSB$FOUNDFIREWIRE" && test -z "$NOCD" && DEVICES="/dev/sr? $DEVICES"

# New: Also try parallel port CD-Roms [for Mike].
DEVICES="$DEVICES /dev/pcd?"

# New: also check HD partitions for a KNOPPIX/KNOPPIX image
test -n "$FOUND_SCSI" -a -z "$NOSCSI" && DEVICES="$DEVICES /dev/sd?[1-9] /dev/sd?[1-9][0-9] /dev/sd?[1-9][0-9]"

# Look for CDROMs first
test -z "$NOCD" && CDROM=$(awk '/name/{for (i=NF;i>=3;i--) {print "/dev/" $i}}' /proc/sys/dev/cdrom/info)
DEVICES="$CDROM /dev/hd?[1-9] $DEVICES /dev/ub?[1-9] /dev/ub?[1-9][0-9] /dev/ub? /dev/hd?[1-9][0-9]"
case "$CMDLINE" in
	*fromhd=/dev/*)
		DEVICES="$fromhd"
		;;
esac

# this is needed now for fromiso
loadmodule loop

findfstab()
{
	# check and load fstab if required
	# takes one argument, the mount fs to look in
	# records the current $i as where it found it in FOUND_FSTAB
	if test -n "$FSTAB" && test -z "$FOUND_FSTAB" && test -r $1/$FSTABFILE; then
		echo "# LINUXRC_FSTAB_START" >> /etc/fstab
		cat $1/$FSTABFILE >> /etc/fstab && echo "# LINUXRC_FSTAB_END" >> /etc/fstab && echo -n "${CRE}${GREEN}Found fstab ${FSTABFILE} at ${MAGENTA}$i${GREEN}...${NORMAL}" && FOUND_FSTAB="$i"
	fi
}

for i in $DEVICES; do
	# unless TESTMNT is set we won't look here for KNOPPIX/chroot
	TESTMNT=""
	MNTOPTIONS="-o ro"
	test -z "$FOUND_KNOPPIX" && echo -n "${CRE}${BLUE}Looking for ${FLL_MEDIUM} in: ${MAGENTA}$i${NORMAL}   "
	# check if we are still looking for the iso
	if test -n "$FROMISO" && test -z "$SCAN_MOUNTED"; then
		if mountit $i $FLL_MEDIA_MOUNTPOINT "-o ro" >/dev/null 2>&1; then
			findfstab $FLL_MEDIA_MOUNTPOINT
			if test -f $FLL_MEDIA_MOUNTPOINT/$FLL_MEDIA; then
				# we found the iso
				echo -n "Found iso   "
				TESTMNT="$FLL_MEDIA_MOUNTPOINT/$FLL_MEDIA"
				i="$TESTMNT"
				MNTOPTIONS="${MNTOPTIONS},loop"
			fi
		fi
	else
		TESTMNT="$i"
	fi
	# mount the device (or iso) on /mnt to check it
	if mountit $i /mnt "$MNTOPTIONS" >/dev/null 2>&1; then
		findfstab /mnt
		if test -z "$FOUND_KNOPPIX" && test -n "$TESTMNT" && test -r /mnt/$FLL_IMAGE_LOCATION; then
			echo -n "${CRE}${GREEN}Accessing $FLL_DISTRO_NAME ${FLL_MEDIUM} at ${MAGENTA}$i${GREEN}...${NORMAL}"
			FOUND_KNOPPIX="$i"
		fi
		# umount mnt and mount the FLL_MEDIUM if we FOUND_KNOPPIX
		umount /mnt >/dev/null
		test -n "$FOUND_KNOPPIX" && test -z "$SCAN_MOUNTED" && mountit $i $FLL_MEDIUM "$MNTOPTIONS" && SCAN_MOUNTED="1"
	fi
	# umount FLL_MEDIA_MOUNTPOINT if we haven't just mounted FLL_MEDIUM
	if test -n "$FROMISO" && test -z "$SCAN_MOUNTED"; then
		umount $FLL_MEDIA_MOUNTPOINT > /dev/null 2>&1
	fi
	if test -n "$FOUND_KNOPPIX" && ( test -z "$FSTAB" || test -n "$FOUND_FSTAB" ); then
		# everything is found so we are finished scanning
		break
	fi
done

if test -n "$FSTAB" && test -z "$FOUND_FSTAB"; then
	echo "${CRE}${RED}Failed to find requested fstab file ${GREEN}${FSTABFILE}${NORMAL}"
fi

# Harddisk-installed script part version has been removed
# (KNOPPIX can be booted directly from HD now).
mount_knoppix()
{
	if test -n "$FOUND_KNOPPIX" && test -f $1/$FLL_IMAGE_LOCATION; then
		# DEBUG
		# echo "6" > /proc/sys/kernel/printk
		# detect compression
		COMP=""
		case $(dd if=$1/$FLL_IMAGE_LOCATION bs=4 count=1 2>/dev/null) in
			"#!/b")
				COMP=cloop
				loadmodule cloop file="$1/$FLL_IMAGE_LOCATION" $CLOOP_PRELOAD || \
					loadmodule cloop file="$1/$FLL_IMAGE"
				mountit /dev/cloop $FLL_MOUNTPOINT "-o ro" || FOUND_KNOPPIX=""
				;;
			"hsqs")
				COMP=squashfs
				#loadmodule squashfs 
				#mount -t squashfs $1/$FLL_IMAGE_LOCATION $FLL_MOUNTPOINT -o loop,ro || FOUND_KNOPPIX=""
				MOUNTIT_FS_GENERAL="$MOUNTIT_FS"
				MOUNTIT_FS="squashfs"
				mountit $1/$FLL_IMAGE_LOCATION $FLL_MOUNTPOINT "-o loop,ro" || FOUND_KNOPPIX=""
				MOUNTIT_FS="$MOUNTIT_FS_GENERAL"
				;;
		esac
	fi

	#FIXME
	## Allow multi-image KNOPPIX mounts
	#if [ -n "$FOUND_KNOPPIX" ] && [ -x "$DYNLOADER" ] && [ -x /KNOPPIX/sbin/losetup ]; then
	#	echo ""
	#	echo -n "${CRE} ${GREEN}Found primary KNOPPIX compressed image at ${MAGENTA}$1/$KNOPPIX_DIR/$KNOPPIX_NAME${GREEN}.${NORMAL}"
	#	
	#	for c in 1 2 3 4 5 6 7; do
	#		if test -r "$1/$KNOPPIX_DIR/$KNOPPIX_NAME$c"; then
	#			if "$DYNLOADER" --library-path /KNOPPIX/lib /KNOPPIX/sbin/losetup "/dev/cloop$c" "$1/$KNOPPIX_DIR/$KNOPPIX_NAME$c"; then
	#				if "$DYNLOADER" --library-path /KNOPPIX/lib /KNOPPIX/bin/mkdir -m 755 -p "/KNOPPIX$c"; then
	#					if mountit "/dev/cloop$c" "/KNOPPIX$c" "-o ro"; then
	#						echo ""
	#						echo -n "${CRE} ${GREEN}Found additional KNOPPIX compressed image at ${MAGENTA}$1/$KNOPPIX_DIR/$KNOPPIX_NAME$c${GREEN}.${NORMAL}"
	#					else
	#						"$DYNLOADER" --library-path /KNOPPIX/lib /KNOPPIX/bin/rmdir "/KNOPPIX$c" 2>/dev/null
	#					fi
	#				else
	#					"$DYNLOADER" --library-path /KNOPPIX/lib /KNOPPIX/bin/losetup -d "/dev/cloop$c" 2>/dev/null
	#				fi
	#			fi
	#		fi
	#	done
	#	$FLL_MOUNTPOINT/bin/ln -snf /KNOPPIX/sbin /sbin && hash -r
	#fi
}

remount_knoppix()
{
	if test -f $TARGET/$FLL_IMAGE_LOCATION; then
		umount $FLL_MOUNTPOINT
# FIXME
# as multi-image mounts are commented out of mount_knoppix
#		for c in 0 1 2 3 4 5 6 7; do
#			umount "/$KNOPPIX_NAME$c" >/dev/null 2>&1
#		done
	
		if [ "$COMP" = "cloop" ]; then
			unloadmodule cloop # release CD
		fi

		umount $SOURCE # unmount CD
		[ -n "$SOURCE2" ] && umount $SOURCE2  # umount possible loop-device

		mount_knoppix $TARGET
	else
		echo "${CRE} ${RED}Warning: Changing to $TARGET failed.${NORMAL}"
		return 1
	fi

	return 0
}

boot_from()
{
	# preparations
	/bin/mkdir $TARGET

	SOURCE_DEV=$(echo $CMDLINE | /usr/bin/tr ' ' '\n' | /bin/sed -n '/bootfrom=/s/.*=//p' | /usr/bin/tail -1)
	LOOP_DEV=$(echo $SOURCE_DEV | /usr/bin/gawk -F/ '{ print $1 "/" $2 "/" $3 }')
	ISO_PATH=$(echo $SOURCE_DEV | /bin/sed "s|$LOOP_DEV||g" )
	case "$ISO_PATH" in
		/*.[iI][sS][oO])
			;;
		*)
			ISO_PATH=""
			;;
	esac
	LOOP_SOURCE=""
  
	# load filesystems
	for i in reiserfs jbd ext3 ntfs; do
		"$FLL_MOUNTPOINT/sbin/modprobe" $i >/dev/null 2>&1 && FS_MODULES_LOADED="$FS_MODULES_LOADED $i"
	done
	FS="reiserfs ext3 ntfs"
 
	if [ -n "$ISO_PATH" ]; then
		LOOP_SOURCE="$TARGET.loop"
		LOOP_SOURCE2="$LOOP_SOURCE"
		TARGET_DEV="$LOOP_SOURCE$ISO_PATH"
		/bin/mkdir $LOOP_SOURCE
		$FLL_MOUNTPOINT/sbin/modprobe loop

		# Try out own mount first.
		mountit $LOOP_DEV $LOOP_SOURCE "-o ro"

		if [ "$?" != "0" ]; then
			for i in $FS; do
				case "$i" in
					#ntfs)
					#	PLAIN="-i"
					#	;;
					*)
						PLAIN=""
						;;
				esac
				/bin/mount $PLAIN -o ro -t $i $LOOP_DEV $LOOP_SOURCE >/dev/null 2>&1 && break
			done
		fi
		test "$?" = "0" || LOOP_SOURCE=""
		/bin/mount -n -o loop $LOOP_SOURCE2$ISO_PATH $TARGET >/dev/null 2>&1
	else
		TARGET_DEV="$SOURCE_DEV"
		mountit $SOURCE_DEV $TARGET "-o ro"

		if [ "$?" != "0" ]; then
			for i in $FS; do
				case "$i" in
					#ntfs)
					#	PLAIN="-i"
					#	;;
					*)
						PLAIN=""
						;;
					esac
				/bin/mount $PLAIN -n -o ro -t $i $SOURCE_DEV $TARGET >/dev/null 2>&1
			done
		fi
	fi

	if [ $? -ne 0 ]; then
		[ -n "$LOOP_SOURCE" ] && { /bin/umount "$LOOP_SOURCE" || umount -l "$LOOP_SOURCE"; } >/dev/null 2>&1
		echo -n "${CRE} ${RED}Accessing $FLL_DISTRO_NAME $FLL_MEDIUM failed. ${MAGENTA}$TARGET_DEV${RED} is not mountable.${NORMAL}"
		sleep 2
		
		return 1
	fi
  
	if [ -f $TARGET/$FLL_IMAGE_LOCATION ]; then
		echo -n "${CRE} ${GREEN}Accessing $FLL_DISTRO_NAME $FLL_MEDIUM at ${MAGENTA}$TARGET_DEV${GREEN}...${NORMAL}"
	else
		echo -n "${CRE} ${RED}Accessing $FLL_DISTRO_NAME $FLL_MEDIUM failed. Could not find $FLL_IMAGE_LOCATION on ${MAGENTA}$TARGET_DEV${RED}.${NORMAL}"
		[ -n "$LOOP_SOURCE" ] && { /bin/umount "$LOOP_SOURCE" || umount -l "$LOOP_SOURCE"; } >/dev/null 2>&1
		umount $TARGET
		sleep 2
	
		return 1
	fi

	# remount the CD 
	remount_knoppix
}

copy_to()
{
	# preparations
	/bin/mkdir $TARGET
	COPY="$SOURCE/$FLL_IMAGE_DIR"
	
	# look if we copy to hd or to ram
	SIZE="$(/usr/bin/du -s $COPY | /usr/bin/gawk '{print int($1*1.1)}')"
	test -n "$SIZE" || SIZE="800000"
	
	case "$1" in 
		ram)
			TARGET_DEV="/dev/shm"
			TARGET_DEV_DESC="ramdisk"
			FOUNDSPACE="$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo)"
			/bin/mount -n -t tmpfs -o size=${SIZE}k $TARGET_DEV $TARGET
			;;
		hd)
			TARGET_DEV=$(echo $CMDLINE | /usr/bin/tr ' ' '\n' | /bin/sed -n '/tohd=/s/.*=//p' | /usr/bin/tail -1)
			TARGET_DEV_DESC="$TARGET_DEV"

		        # load filesystems
			for i in reiserfs jbd ext3 ntfs vfat; do
				"$FLL_MOUNTPOINT/sbin/modprobe" $i >/dev/null 2>&1
			done
			FS="ext3 ext2 reiserfs vfat ntfs"
			#$FLL_MOUNTPOINT/bin/cp -au /KNOPPIX/dev/fuse /dev/ >/dev/null 2>&1
			MOUNTED=""
			for i in $FS; do
				if $FLL_MOUNTPOINT/bin/mount -o rw -t "$i" "$TARGET_DEV" "$TARGET" > /dev/null 2>&1; then
					MOUNTED="true"
					break
				fi
			done
			
			if test -z "$MOUNTED"; then
				echo -n "${CRE}${RED}Copying $FLL_DISTRO_NAME ${FLL_MEDIUM} failed. ${MAGENTA}$TARGET_DEV_DESC${RED} is not mountable.${NORMAL}"
				sleep 2

				return 1
			fi
			
			# check for enough free space
			USED_SPACE=0
			test -r $TARGET/$FLL_IMAGE_LOCATION && USED_SPACE=$(/usr/bin/du -s $TARGET/$FLL_IMAGE_LOCATION | /usr/bin/gawk '{ print $1 }')
			FOUNDSPACE="$(/bin/df -k $TARGET | /usr/bin/tail -1 | /usr/bin/gawk '{ print $4+int('$USED_SPACE') }')"
			;;
		*)
			return 1
			;;
	esac

	# sanity check
	if [ $FOUNDSPACE -lt $SIZE ]; then
		echo -n "${CRE} ${RED}Copying $FLL_DISTRO_NAME $FLL_MEDIUM failed. Not enough free space on ${MAGENTA}${TARGET_DEV_DESC}${RED}. Found: ${MAGENTA}${FOUNDSPACE}k${RED} Need: ${MAGENTA}${SIZE}k${RED} ${NORMAL}"
		sleep 2
		umount $TARGET

		return 1
	fi
	
	# do the real copy
	echo "${CRE} ${GREEN}Copying $FLL_DISTRO_NAME $FLL_MEDIUM to ${MAGENTA}$TARGET_DEV_DESC${GREEN}... Please be patient. ${NORMAL}"

	if [ -z "$COPY_COMMAND" ] && [ -x /usr/bin/rsync ]; then
		# first cp the small files
		/usr/bin/rsync -a --exclude="$FLL_IMAGE_LOCATION*" $COPY $TARGET # Copy Knoppix to $TARGET

		# then the big file with nice progress meter
		/usr/bin/rsync -a --progress --include="$FLL_IMAGE_LOCATION*" --include="$FLL_IMAGE_DIR/" --exclude="*" $COPY $TARGET
	else
		"$COPY_COMMAND" $COPY $TARGET
	fi

	if [ $? -ne 0 ]; then
		echo -n "${CRE} ${RED}Copying $FLL_DISTRO_NAME $FLL_MEDIUM failed. ${MAGENTA}$TARGET_DEV_DESC${RED} possibly has not enough space left.${NORMAL}"
		sleep 2

		return 1
	fi

	# remount r/o
	case "$filesystem" in
		#ntfs)
		#	umount "$TARGET"
		#	sleep 2
		#	mountit "$TARGET_DEV" "$TARGET" "-o ro" || $FLL_MOUNTPOINT/bin/mount -i -t ntfs -o ro "$TARGET_DEV" "$TARGET"
		#	;;
		*)
			$FLL_MOUNTPOINT/bin/mount -n -o remount,ro "$TARGET_DEV" "$TARGET"
			;;
	esac
	remount_knoppix
}

mount_knoppix /$FLL_MEDIUM

# Remount later after copying/isoloading/driverloading?
# pre-test if everything succeeded
if  test -n "$DO_REMOUNT" -a -n "$FOUND_KNOPPIX"; then
	# copy library cache 
	cat $FLL_MOUNTPOINT/etc/ld.so.cache > /etc/ld.so.cache 
	echo "" 
	
	SOURCE="/${FLL_MEDIUM}"
	TARGET="/${FLL_MEDIUM}2"
	
	# first test for possible hdboot/fromiso (which can be combined with toram / tohd)
	if [ -n "$BOOTFROM" ]; then
		boot_from
		if [ $? -eq 0 ]; then
			# set new source / target paths
			REAL_TARGET="$TARGET"
			SOURCE2="$LOOP_SOURCE"
			SOURCE="/${FLL_MEDIUM}2"
			TARGET="/${FLL_MEDIUM}3"
		fi
	fi

	if [ -n "$COPYTO" ]; then
		copy_to $COPYTO && REAL_TARGET="$TARGET"
	fi
fi
 
# Final test if everything succeeded.
if test -n "$FOUND_KNOPPIX"; then
	# copy library cache
	cat $FLL_MOUNTPOINT/etc/ld.so.cache > /etc/ld.so.cache
	echo ""

	# don't use unified filesystems unconditionally for now
	case "$CMDLINE" in
		*unionfs*)
			"${FLL_MOUNTPOINT}/sbin/modprobe" unionfs 2>/dev/null && UNIONFS="yes"
			AUFS=""
			;;
		*aufs*)
			if [ -z "$UNIONFS" ]; then
				"${FLL_MOUNTPOINT}/sbin/modprobe" aufs 2>/dev/null && AUFS="yes"
			fi
			;;
	esac
	
	# Enable kernel messages
	echo "6" > /proc/sys/kernel/printk
	
	# Set paths
	echo -n "${CRE}${BLUE}Setting paths...${NORMAL}"
	PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11"
	export PATH

	# Debian weirdness
	$FLL_MOUNTPOINT/bin/cp -a $FLL_MOUNTPOINT/etc/alternatives /etc/ 2>/dev/null
	
	# Replace /sbin
	$FLL_MOUNTPOINT/bin/rm -f /sbin
	$FLL_MOUNTPOINT/bin/ln -sf $FLL_MOUNTPOINT/sbin /sbin
	
	# From here, we should have all essential commands available.
	hash -r
	
	# Did we remount the source media ? 
	if  test -n "$REAL_TARGET"; then
		/bin/mount -n --move $REAL_TARGET /$FLL_MEDIUM # move it back and go on to normal boot 
	fi
	
	# Clean up /
	$FLL_MOUNTPOINT/bin/rm -rf /modules /static

	if test -n "$FOUND_FSTAB"; then
		grep isosrc /etc/fstab && mount -o remount,rw /isosrc
		cat /etc/fstab | awk '!/^#/{if ($6=="1"){print $2}}' | xargs mkdir -p
		echo "${CRE}${GREEN}Mounting from fstab${NORMAL}"
		/bin/mount -a
	fi

	if ! grep ramdisk /etc/mtab >/dev/null ; then
		# New in Kernel 2.4.x: tempfs with variable ramdisk size.
		# We check for available memory anyways and limit the ramdisks
		# to a reasonable size.
		# Now we need to use a little intuition for finding a ramdisk size
		# that keeps us from running out of space, but still doesn't crash the
		# machine due to lack of Ram

		# Minimum size of additional ram partitions
		MINSIZE=20000

		# At least this much memory minus 30% should remain when home and var are full.
		MINLEFT=16000

		# Maximum ramdisk size
		MAXSIZE="$(expr $TOTALMEM - $MINLEFT)"

		# Default ramdisk size for ramdisk
		RAMSIZE="$(expr $TOTALMEM / 5)"

		# Create additional dynamic ramdisk.
		test -z "$RAMSIZE" -o "$RAMSIZE" -lt "$MINSIZE" && RAMSIZE="$MINSIZE"
		mkdir -p /ramdisk

		# tmpfs/varsize version, can use swap
		RAMSIZE=$(expr $RAMSIZE \* 4)
		echo -n "${CRE}${BLUE}Creating ${YELLOW}/ramdisk${BLUE} (dynamic size=${RAMSIZE}k) on ${MAGENTA}shared memory${BLUE}...${NORMAL}"

		# We need /bin/mount here for the -o size= option
		/bin/mount -t tmpfs -o "size=${RAMSIZE}k,mode=755" /ramdisk /ramdisk || echo "creating the ramdisk failed"
	fi

	if [ "$UNIONFS" = "yes" ] || [ "$AUFS" = "yes" ]; then
		mkdir -p /ramdisk/tmp
		chmod 1777 /ramdisk/tmp
		mv /tmp /tmp.old
		ln -s /ramdisk/tmp /tmp
		rm -rf tmp.old
	else
		mkdir -p /ramdisk/var
		ln -s /ramdisk/var /var
	fi

	mkdir -p	/home \
			/ramdisk/home/${FLL_LIVE_USER} \
			/var

	if ! grep home /etc/mtab > /dev/null ; then
		/bin/mount --bind /ramdisk/home /home
	fi

	echo "${BLUE}Done.${NORMAL}"

	stage=2
	rundebugshell

	# don't use unionfs unconditionally for now
	if [ "$UNIONFS" = "yes" ] || [ "$AUFS" = "yes" ]; then
		#######################
		## unionfs adventure ##
		#######################

		echo -n "${CRE}${BLUE}Creating unified filesystem and symlinks on ramdisk...${NORMAL}"
		mkdir -p /UNIONFS
		[ "$UNIONFS" = "yes" ] && UNION="/ramdisk=rw"
		[ "$AUFS" = "yes" ] && UNION="/ramdisk"
	
		# Add all KNOPPIX images to the union
#		for c in "" 1 2 3 4 5 6 7; do
#			[ -d "/KNOPPIX$c" ] && [ "$UNIONFS" = "yes" ] && UNION="$UNION:/KNOPPIX$c=ro"
#			[ -d "/KNOPPIX$c" ] && [ "$AUFS" = "yes" ] && UNION="$UNION:/KNOPPIX$c"
#		done

		# FIXME:Multi-Image
		# No multi-images in here
		[ -d "$FLL_MOUNTPOINT" ] && UNION="$UNION:$FLL_MOUNTPOINT=ro"

		# Do the actual mount
		if ! grep UNIONFS /etc/mtab; then
			[ "$UNIONFS" = "yes" ] && /bin/mount -t unionfs -o "dirs=$UNION,delete=whiteout" /UNIONFS /UNIONFS	# doesn't work with -mm
			[ "$AUFS" = "yes" ] && /bin/mount -t aufs -o "br:$UNION" /UNIONFS /UNIONFS
		fi
		if grep -q \\/UNIONFS\ \\/UNIONFS /proc/mounts; then
			# We now have unionfs, copy some data from the initial ramdisk first
			cp -a	/etc/fstab \
				/etc/mtab \
					/UNIONFS/etc/
	
			# /dev is a special case, it is now normally handled via udev
			UNIONDEV=""
			case "$CMDLINE" in
				*noudev*)
					UNIONDEV="dev"
					;;
			esac
			
			for i in bin boot etc $UNIONDEV sbin var lib opt root usr; do
				# Move directories to union
				if test -d /$i; then
					mv /$i /$i.old && $DYNLOADER --library-path $FLL_MOUNTPOINT/lib $FLL_MOUNTPOINT/bin/ln -snf /UNIONFS/$i /$i && rm -rf /$i.old
				else
					ln -snf /UNIONFS/$i /$i
				fi
			done
	
			for i in $(cd /UNIONFS; echo *); do
				# Create links for new stuff on /UNIONFS
				test "$i" = "home" -o "$i" = "tmp" && continue
				test -L "/$i" || test -d "/$i" || test -f "/$i" || ln -snf "/UNIONFS/$i" /$i
			done
		else
			echo -n "${CRE}${RED}ERROR: CANNOT UNITE READ-ONLY MEDIA AND INITIAL RAMDISK!${NORMAL}"
			$FLL_MOUNTPOINT/sbin/halt -f -n
		fi
	
		echo ""
		echo "${GREEN}>> Read-only ${FLL_MEDIUM} system successfully merged with read-write /ramdisk.${NORMAL}"

		#######################
	else
		###############
		## link farm ##
		###############

		echo -n "${CRE}${BLUE}Creating directories and symlinks on ramdisk...${NORMAL}"
		# Create common WRITABLE (empty) dirs
		mkdir -p	/var/run \
				/var/backups \
				/var/cache/apache \
				/var/local \
				/var/lock/news \
				/var/nis \
				/var/preserve \
				/var/state/misc \
				/var/tmp \
				/var/lib \
				/var/spool/cups/tmp \
				/var/lib/samba \
				/home/${FLL_LIVE_USER} \
				/root \
				/etc/sysconfig \
				/etc/X11 \
				/etc/cups \
				/etc/dhcpc

		# All files in here should be size zero after Knoppix.clean was run
		cp -a	$FLL_MOUNTPOINT/var/local \
			$FLL_MOUNTPOINT/var/games \
			$FLL_MOUNTPOINT/var/log \
			$FLL_MOUNTPOINT/var/spool \
				/var/ 2>/dev/null
		cp -a	$FLL_MOUNTPOINT/var/lib/games \
			$FLL_MOUNTPOINT/var/lib/wine \
			$FLL_MOUNTPOINT/var/lib/nfs \
			$FLL_MOUNTPOINT/var/lib/xkb \
			$FLL_MOUNTPOINT/var/lib/isdn \
			$FLL_MOUNTPOINT/var/lib/kdm \
			$FLL_MOUNTPOINT/var/lib/pcmcia \
			$FLL_MOUNTPOINT/var/lib/dhcp* \
				/var/lib/ 2>/dev/null
	
		# Link device files (real device file copies should NOT require more space, but in fact, they do)
		/bin/cp -aus /dev/capi /dev/ 2>/dev/null
		ln -s $FLL_MOUNTPOINT/dev/* /dev/ 2>/dev/null
	
		# Problematic directories in /var/lib (lots and lots of inodes)
		ln -s	$FLL_MOUNTPOINT/var/lib/dpkg \
			$FLL_MOUNTPOINT/var/lib/apt \
			$FLL_MOUNTPOINT/var/lib/doc-base \
			$FLL_MOUNTPOINT/var/lib/gnome \
			$FLL_MOUNTPOINT/var/lib/kde \
			$FLL_MOUNTPOINT/var/lib/scrollkeeper \
			$FLL_MOUNTPOINT/var/lib/texmf \
				/var/lib/ 2>/dev/null
	
		# Debian-apt
		ln -s $FLL_MOUNTPOINT/var/cache/apt /var/cache/ 2>/dev/null
		ln -s $FLL_MOUNTPOINT/etc/skel /etc/ 2>/dev/null
	
		# Index files can be HUGE, so better replace cache/man tree by links later
		# cp -a $FLL_MOUNTPOINT/var/cache/man /var/cache/ 2>/dev/null
		# Create links from CDROM for UNWRITABLE (remaining) files
		/bin/cp -aus $FLL_MOUNTPOINT/var/* /var/ 2>/dev/null
		/bin/cp -aus $FLL_MOUNTPOINT/etc/* /etc/ 2>/dev/null

		###############
	fi

	# CUPS wants writable files. :-/
	cp -a $FLL_MOUNTPOINT/etc/cups/*.conf /etc/cups/ 2>/dev/null
	
	# resolv.conf must be writable as well
	rm -f /etc/resolv.conf 2>/dev/null
	touch /etc/resolv.conf

	# Make SURE that these are files, not links!
	rm -rf	/etc/ftpusers \
		/etc/passwd \
		/etc/shadow \
		/etc/gshadow \
		/etc/group \
		/etc/ppp \
		/etc/isdn \
		/etc/ssh \
		/etc/ioctl.save \
		/etc/inittab \
		/etc/network \
		/etc/sudoers \
		/etc/init \
		/etc/localtime \
		/etc/dhcpc \
		/etc/pnm2ppa.conf 2>/dev/null

	cp -a	$FLL_MOUNTPOINT/etc/ftpusers \
		$FLL_MOUNTPOINT/etc/passwd \
		$FLL_MOUNTPOINT/etc/shadow \
		$FLL_MOUNTPOINT/etc/gshadow \
		$FLL_MOUNTPOINT/etc/group \
		$FLL_MOUNTPOINT/etc/ppp \
		$FLL_MOUNTPOINT/etc/isdn \
		$FLL_MOUNTPOINT/etc/ssh \
		$FLL_MOUNTPOINT/etc/inittab \
		$FLL_MOUNTPOINT/etc/network \
		$FLL_MOUNTPOINT/etc/sudoers \
		$FLL_MOUNTPOINT/sbin/init \
		$FLL_MOUNTPOINT/etc/dhcpc \
			/etc/ 2>/dev/null

	# Create empty utmp and wtmp
	# /etc/ioctl.save and /etc/pnm2ppa.conf are extremly important, init crashes on shutdown if this is only a link
	# get rid of broken xorg.conf
	rm -f	/var/run/utmp \
		/var/run/wtmp \
		/etc/ioctl.save \
		/etc/pnm2ppa.conf \
		/etc/X11/xorg.conf \
		/var/lib/samba/unexpected.tdb
	:>	/var/run/utmp
	:>	/var/run/wtmp
	:>	/etc/ioctl.save
	:>	/etc/pnm2ppa.conf

	# Must exist for samba to work
	[ -d /var/lib/samba ] && :> /var/lib/samba/unexpected.tdb

	# Diet libc bug workaround
	/bin/cp --remove-destination "${FLL_MOUNTPOINT}/etc/localtime" /etc/localtime
	
	# localization
	/bin/cp --remove-destination "${FLL_MOUNTPOINT}/etc/default/distro" /etc/default/distro
	rm -f /etc/console/boottime.old.kmap.gz
	/bin/cp --remove-destination "${FLL_MOUNTPOINT}/etc/console/*" /etc/console/ >/dev/null 2>&1

	# busybox/cloop workaround
	chmod 1777 /tmp /var/tmp

	# populate /root/.profile and /root/.bashrc
	/bin/cp --remove-destination /usr/share/base-files/dot.profile	/root/.profile
	/bin/cp --remove-destination /usr/share/base-files/dot.bashrc	/root/.bashrc

	if ! grep -q bash_completion /root/.bashrc; then
		cat >> /root/.bashrc << EOF
# changed by $FLL_DISTRO_NAME
# enable bash completion in interactive shells
if [ -f /etc/bash_completion ]; then
        . /etc/bash_completion
fi
EOF
	fi
	
	echo "${BLUE}Done.${NORMAL}"

	# Clean up /etc/mtab (and - just in case - make a nice entry for looped ISO)
	# FIXME Multi-Image
	/bin/egrep " $FLL_MOUNTPOINT | /$FLL_MEDIUM " /proc/mounts | /bin/sed 's|/dev/loop0 /$FLL_MEDIUM \(.*\) 0 0|'$LOOP_SOURCE$ISO_PATH' /$FLL_MEDIUM/ \1,loop=/dev/loop0 0 0|g' >> /etc/mtab

	# Now tell kernel where the real modprobe lives
	echo "/sbin/modprobe" > /proc/sys/kernel/modprobe
	
	# Change root device from /dev/fd0 to /dev/ram0
	echo "0x100" > /proc/sys/kernel/real-root-dev

	# clean up /etc/rc?.d/
	for i in 0 1 2 3 4 5 6 S; do
		rm -rf "/etc/rc${i}.d"
		mkdir -p "/etc/rc${i}.d"
		ln -fs "$FLL_MOUNTPOINT/etc/rc${i}.d/README" "/etc/rc${i}.d/"
	done
	for i in 0 1 2 3 4 6; do
		ln -fs "$FLL_MOUNTPOINT/etc/init.d/xsession" "/etc/rc${i}.d/K10xsession"
	done
	ln -fs "$FLL_MOUNTPOINT/etc/init.d/live-autoconfig" "/etc/rcS.d/S00live-autoconfig"
	ln -fs "$FLL_MOUNTPOINT/etc/init.d/live-halt" "/etc/rc0.d/S90live-halt"
	ln -fs "$FLL_MOUNTPOINT/etc/init.d/live-reboot" "/etc/rc6.d/S90live-reboot"

	stage=3
	rundebugshell	
	# Give control to the init process.
	echo "${CRE}${BLUE}Starting init process.${NORMAL}"
	rm -f /linuxrc
	
	exit 0
else
	echo "${CRE}${RED}Can't find $FLL_DISTRO_NAME filesystem, sorry.${NORMAL}"
	echo "${RED}Dropping you to a (very limited) shell.${NORMAL}"
	echo "${RED}Press reset button to quit.${NORMAL}"
	echo ""
	
	PS1="sidux# "
	export PS1

	echo "6" > /proc/sys/kernel/printk

	# Allow signals
	trap 1 2 3 11 15
	exec /static/ash
fi

