#!/bin/sh version="prh-011" # This is the Intimate boot script - hacked mercilessly by Paul Hedderly # NEW: Tries to restart pcmcia stuff - "fixes" MD/CF detected as memory_cs # NEW: Button grabber and menu. Could also do a simple "passphrase" test # NEW: runfor XX ... can limit a timerun # NEW: boot method BINDS - binds the MD/CF over the flash root dirs then runs init # NEW: boot methon RAMFS_PIVOT - builds a ramfs / with mount --binds to # the MD/CF and then chroots into that # Reordered: Put everything big into a sub so that it can be replaced easily # Also helps you see the flow now that it's getting more complicated. # Should perhaps put chunks in "library" files? init_vars() { ###DEFAULTS### # Splash screens (if available) NFS_SPLASH="/etc/intimate/pics/IntimateSplashNFS.pnm" HDD_SPLASH="/etc/intimate/pics/IntimateSplashudrive.pnm" SPLASHER="/bin/pnmtofb" # Modules needed before cardmgr is run GENERIC_MODULES="h3600_generic_sleeve pcmcia_core ds h3600_ts" #IDE_CS_MODULES="" # not needed? # Where intimate lives, if it is on microdrive. (For nfsroot leave this as /dev/hda1) ROOTDEV="/dev/hda1" ROOTFS="auto" # Mono ipaqs will like this - swapon early, swapon often. ;) #SWAPDEV="" # Not needed for boot, most times # Some of us (ok, maybe just me) have to suspend before wvlan works. This prompts and pauses 5s. SUSPEND_PAUSE="N" PATH=/bin:/sbin export GENERIC_MODULES IDE_CS_MODULES ROOTDEV ROOTFS SWAPDEV SYSPEND_PAUSE PATH ###END DEFAULTS### } # Run something with a timelimit "runfor ..." runfor() { limit=$1; shift ( $* #$* > /tmp/.limit.$$.out 2> /tmp/.limit.$$.err echo $? > /tmp/.limit.$$.res ) & sub=$! count=0 while [ $count -lt $limit ]; do sleep 1 count=$(($count+1)) [ -s /tmp/.limit.$$.res ] && count=$limit done if [ -f /tmp/.limit.$$.res ]; then result=`cat /tmp/.limit.$$.res` else echo TIMEOUT result=-1 kill $sub > /dev/null 2>&1 fi exit $result } # Return a char for one of the IPAQ buttons # a k # # b c d e # f # g j h # i getkey() { key=`dd if=/dev/touchscreen/key bs=1 count=2 2>/dev/null | \ /usr/bin/tr \\\001-\\\017 a-x|/usr/bin/tr \\\201-\\\230 a-x` key1=`echo $key|sed -ne "s/^\(.\)\(.\)$/\1/p"` key2=`echo $key|sed -ne "s/^\(.\)\(.\)$/\2/p"` [ $key1 = $key2 ] && echo -n $key1 } # This was a test. Quite handy for not having a CF/MD / # mount --binds all the flash root dirs out the way the # coveres those originals with the MD/CF dirs. # No PIVOT - just inits. startintimate_usebinds() { echo "Starting INTIMATE using the BIND method" echo -n "Binding." for dir in bin etc home lib root sbin usr var; do mkdir -p /orig/$dir mount --bind /$dir /orig/$dir mount --bind /mnt/hda1/$dir /$dir echo -n "." done echo "Executing /sbin/init..." exec /sbin/init || { echo FAILED - REBOOTING; dot_reboot; } } # This is the original boot method - it simply mounts the MD/CF and PIVOTs into it # then runs init startintimate_usepivot() { mount -n -t devfs none /mnt/hda1/dev pivot_root /mnt/hda1 /mnt/hda1/boot cd / if [ -f "$HDD_SPLASH" -a -x $SPLASHER ]; then ln -s /dev/fb/0 /dev/fb0 $SPLASHER /$HDD_SPLASH else echo "Executing /sbin/init..." > /dev/vc/0 fi echo "Setting up pm off flash" # pm_setup echo "Executing /sbin/init..." exec /sbin/init || { echo FAILED - REBOOTING; dot_reboot; } } # This is my new method. It mounts a ramfs device and creates # / dirs in it. Then mounts the MD/CF inside it and does mount --bind # for all root dirs. Then it PIVOTS and runs init startintimate_ramfspivot() { set -x echo "Starting INTIMATE using RAMFS and PIVOT_ROOT" umount /mnt/hda1 mkdir -p /mnt/ramroot mount -n -t ramfs ramroot /mnt/ramroot mkdir -p /mnt/ramroot/.HDA1 mkdir -p /mnt/ramroot/boot mkdir -p /mnt/ramroot/dev mkdir -p /mnt/ramroot/flash mkdir -p /mnt/ramroot/proc mkdir -p /mnt/ramroot/tmp mount -n -t devfs devfs /mnt/ramroot/dev mount -n -t proc proc /mnt/ramroot/proc mount -n -t tmpfs tmpfs /mnt/ramroot/tmp mount -n $ROOTDEV /mnt/ramroot/.HDA1 echo -n "Binding." for dir in bin boot etc home lib root sbin usr var; do mkdir -p /mnt/ramroot/$dir mount --bind /mnt/ramroot/.HDA1/$dir /mnt/ramroot/$dir echo -n " $dir" done mkdir -p /mnt/ramroot/.oldroot pivot_root /mnt/ramroot /mnt/ramroot/.oldroot if ([ $? = "0" ]); then umount /.oldroot/dev umount /.oldroot/proc umount /.oldroot/mnt/* umount /.oldroot echo "Executing /sbin/init..." exec /sbin/init || { echo FAILED - REBOOTING; dot_reboot; } else echo FAILED - REBOOTING dot_reboot fi } # Try an NFS root start_nfsroot() { echo "Searching for intimate distribution over ethernet..." # echo "Searching for intimate distribution over ethernet..." > /dev/vc/0 if [ "."$NFSPATH = "." ]; then mount /mnt/nfs else mount -t nfs -o nolock,soft $NFSPATH /mnt/nfs fi if [ $? -eq 0 -a -x /mnt/nfs/sbin/init ] then mount -n -t devfs none /mnt/nfs/dev echo "Booting intimate from nfs..." # echo "Booting intimate from nfs..." > /dev/vc/0 pivot_root /mnt/nfs /mnt/nfs/boot cd / if [ -f "/$NFS_SPLASH" ]; then ln -s /dev/fb/0 /dev/fb0 $SPLASHER /$NFS_SPLASH else echo "Executing /sbin/init..." > /dev/vc/0 fi # killall-by-pid function here killall -9 pump # This lets you unmount /boot and /ramfs - a Good Thing. -9 keeps it from # going weird and dropping the interface echo "Executing /sbin/init..." exec /sbin/init || { echo FAILED - REBOOTING; dot_reboot; } fi } # Start familiar start_familiar() { ###use the killall-by-pid func from init scripts killall pump # ..and add a remove-modules var? rmmod nfs >/dev/null 2>&1 rmmod pcnet_cs >/dev/null 2>&1 rmmod lockd >/dev/null 2>&1 rmmod 8390 >/dev/null 2>&1 rmmod ds >/dev/null 2>&1 rmmod sa1100_cs >/dev/null 2>&1 rmmod pcmcia_core >/dev/null 2>&1 echo ' ___ _ ___ ' echo ' / _/__ ___ _ (_) (_)__ _____' echo ' / _/ _ `/ ` \/ / / / _ `/ __/' echo '/_/ \_,_/_/_/_/_/_/_/\_,_/_/ ' echo "Loading floating point emulator..." echo "Loading floating point emulator..." > /dev/vc/0 /sbin/insmod nwfpe echo "Loading Unix socket support" echo "Loading Unix socket support" > /dev/vc/0 /sbin/insmod unix echo "Setting up RAMFS, please wait... " echo "Setting up RAMFS, please wait... " > /dev/vc/0 tar xfpz .ramfs.tar.gz -C /mnt/ramfs > /dev/null 2>&1 if [ ! -s /etc/inittab ] then echo "You are attemping to boot an incomplete system, starting a shell..." echo "You are attemping to boot an incomplete system, starting a shell..." > /dev/vc/0 mkdir /mnt/ramfs/tmp cd /tmp exec /bin/sh fi echo "Setting Date/Time from previous settings" echo "Setting Date/Time from previous settings" > /dev/vc/0 /bin/date -s "`/bin/cat /etc/lastdate`" echo "Setting up some links... houm" grep ln /linuxrc | sh echo "Executing /sbin/init..." echo "Executing /sbin/init..." > /dev/vc/0 exec /sbin/init } # Load some modules that will be needed load_modules() { depmod -a modprobe pcmcia_core setup_delay=50 vcc_settle=100 modprobe sa1100_cs setup_delay=50 vcc_settle=100 if [ ".$GENERIC_MODULES" != "." ]; then for i in $GENERIC_MODULES; do modprobe $i done fi if [ ".$IDE_CS_MODULES" != "." ]; then for i in $IDE_CS_MODULES; do modprobe $i done fi if [ ".$SUSPEND_PAUSE" = ".Y" ]; then echo "Last chance to suspend and fix pcmcia..." echo "Last chance to suspend and fix pcmcia..." > /dev/vc/0 sleep 5 fi cardmgr -q -o -c /etc/pcmcia } # unload _all_ modules... This is to help solve CF/MD detected as memory_cs # after a reset/crash unload_modules() { for q in `lsmod|sed -e "s/ .*//`; do rmmod $q done } # Display dots for before rebooting dot_reboot() { time=${1:-10} while ([ $time -gt 0 ]); do echo -n . time=$(($time-1)) done reboot } ########################################################################### # MAIN - This is where we actually run stuff! # ########################################################################### init_vars if [ -f /.intimateboot ]; then . /.intimateboot fi echo "Mounting /proc" #echo "Mounting /proc" > /dev/vc/0 mount -n /proc mount /mnt/ramfs mkdir /mnt/ramfs/tmp chmod +t /mnt/ramfs/tmp mkdir -p /mnt/ramfs/var/log/ksymoops mkdir /mnt/ramfs/var/run mkdir -p /mnt/ramfs/var/lib/pcmcia touch /var/run/pcmcia-scheme #KERNEL_VERSION=`uname -r` load_modules until [ "$action" != "" ]; do echo -- "-------------------------------------" echo "What would you like to do?" echo "CAL = INTIMATE (normal)" echo "TEL = FAMILIAR" echo " Q = INTIMATE using the BIND method" echo "--> = REBOOT" echo " up = INTIMATE using RAMFS root + PIVOT" echo "cnt = init=/bin/sh - debug mode" key=`getkey` echo "You pressed: $key" [ "$key" = "b" ] && action="intimate" [ "$key" = "c" ] && action="familiar" [ "$key" = "d" ] && { action="intimate"; bind="yes"; } [ "$key" = "e" ] && action="reboot" [ "$key" = "f" ] && { action="intimate"; bind="ram"; } [ "$key" = "j" ] && exec /bin/sh [ "$action" != "familiar" ] && { cardmgr -q -o -c /etc/pcmcia if [ ! -b $ROOTDEV ]; then echo; echo "Can\'t find $ROOTDEV" echo "Trying to recover PCMCIA" unload_modules sleep 2 load_modules fi if [ ! -b $ROOTDEV ]; then echo "You could also try re-seating the sleeve or the card/drive" action="" fi } done echo echo $action echo [ "$action" = "reboot" ] && exec /sbin/reboot if [ "$action" = "intimate" -a -b $ROOTDEV ] then # insmod -f /root/blkmtd-arm.o device=/dev/hda # mount -n -t jffs2 /dev/mtdblock/4 /mnt/hda1 mount -o noatime -n -t $ROOTFS $ROOTDEV /mnt/hda1 if [ $? -eq 0 -a -x /mnt/hda1/sbin/init ] then echo "Booting intimate from microdrive..." if [ "$bind" = "yes" ]; then startintimate_usebinds elif [ "$bind" = "ram" ]; then startintimate_ramfspivot else startintimate_usepivot fi else umount /mnt/hda1 >/dev/null 2>&1 fi else start_nfsroot echo NFS_root failed : REBOOTING fi