Added tag 0.98 for changeset 7b957b5b0c56
[grml-terminalserver.git] / linuxrc
1 #!/static/sh
2 # Filename: /linuxrc
3 # Purpose:  minirt for kernel 2.6 running on grml live-cd
4 # Authors:  (c) Klaus Knopper <knoppix@knopper.net>, (c) Michael Prokop <mika@grml.org>
5 # Latest change: Tue Mar 27 23:05:51 CEST 2007
6 #######################################################################################
7
8 # hardcoded configurable options
9 # Default maximum size of dynamic ramdisk in kilobytes
10 RAMSIZE=1000000
11 # End of options
12
13 # Don't allow interrupt signals
14 trap "" 1 2 3 15
15
16 # Misc functions
17 INSMOD="/static/insmod"
18 # [ -x /modules/insmod ] && INSMOD="/modules/insmod"
19
20 RMMOD="/static/rmmod"
21 # [ -x /modules/rmmod ] && RMMOD="/modules/rmmod"
22
23 # Builin filesystems
24 # BUILTIN_FS="iso9660 ext2 vfat"
25 BUILTIN_FS="iso9660 ext2 ext3 reiserfs vfat xfs jfs reiser4"
26
27 mountit(){
28 # Usage: mountit src dst "options"
29 for fs in $BUILTIN_FS; do
30  if test -b $1; then
31   options="$3"
32   case "$fs" in vfat)
33    # We REALLY need this for Knoppix on DOS-filesystems
34    shortname="shortname=winnt"
35    [ -n "$options" ] && options="$options,$shortname" || options="-o $shortname"
36   ;;
37   esac
38   mount -t $fs $options $1 $2 >/dev/null 2>&1 && return 0
39  fi
40 done
41 return 1
42 }
43
44 FOUND_SCSI=""
45 FOUND_GRML=""
46 INTERACTIVE=""
47
48 # Clean input/output
49 exec >/dev/console </dev/console 2>&1
50
51 # Mount /proc and /dev/pts
52 mount -t proc /proc /proc
53
54 # Disable kernel messages while probing modules in autodetect mode
55 echo "0" > /proc/sys/kernel/printk
56
57 mount -t devpts /dev/pts /dev/pts
58 # Kernel 2.6
59 mount -t sysfs /sys /sys >/dev/null 2>&1
60
61 # Read boot command line with builtin cat command (shell read function fails in Kernel 2.4.19-rc1)
62 CMDLINE="$(cat /proc/cmdline)"
63
64 # Simple shell grep
65 stringinfile(){
66   case "$(cat $2)" in *$1*) return 0;; esac
67   return 1
68 }
69
70 # same for strings
71 stringinstring(){
72   case "$2" in *$1*) return 0;; esac
73   return 1
74 }
75
76 # Reread boot command line; echo last parameter's argument or return false.
77 getbootparam(){
78   stringinstring " $1=" "$CMDLINE" || return 1
79   result="${CMDLINE##*$1=}"
80   result="${result%%[   ]*}"
81   echo "$result"
82   return 0
83 }
84
85 # Check boot commandline for specified option
86 checkbootparam(){
87   stringinstring " $1" "$CMDLINE"
88   return "$?"
89 }
90
91 if checkbootparam "nocolor" ; then
92   echo "Disabling colors in bootsequence as requested on commandline."
93   # Reset fb color mode
94   RESET="\e]R"
95   # ANSI COLORS
96   # Erase to end of line
97   CRE="\r\e[K"
98   # Clear and reset Screen
99   CLEAR="\ec"
100 else
101   # Reset fb color mode
102   RESET="\e]R"
103   # ANSI COLORS
104   # Erase to end of line
105   CRE="\r\e[K"
106   # Clear and reset Screen
107   CLEAR="\ec"
108   # Normal color
109   NORMAL="\e[0;39m"
110   # RED: Failure or error message
111   RED="\e[1;31m"
112   # GREEN: Success message
113   GREEN="\e[1;32m"
114   # YELLOW: Descriptions
115   YELLOW="\e[1;33m"
116   # BLUE: System mesages
117   BLUE="\e[1;34m"
118   # MAGENTA: Found devices or drivers
119   MAGENTA="\e[1;35m"
120   # CYAN: Questions
121   CYAN="\e[1;36m"
122   # BOLD WHITE: Hint
123   WHITE="\e[1;37m"
124 fi
125
126 # don't output anything if running with bootsplash feature
127 if checkbootparam "splash" ; then
128   echo ""
129   echo "${WHITE}Welcome to"
130   echo ""
131   echo "${RED}   ____ ____  __  __ _     "
132   echo "${RED}  / ___|  _ \|  \/  | |    "
133   echo "${RED} | |  _| |_) | |\/| | |    "
134   echo "${RED} | |_| |  _ <| |  | | |___ "
135   echo "${RED}  \____|_| \_\_|  |_|_____|"
136   echo ""
137   echo "${WHITE}grml.org - Linux for users of texttools and sysadmins."
138   echo "${NORMAL}"
139   exec >/dev/null </dev/null 2>&1
140 fi
141
142 # helper functions {{{
143 #log_success_msg () {
144 #  echo " * $@"
145 #}
146
147 log_failure_msg () {
148   echo " ${RED}*${NORMAL} $@"
149 }
150
151 #log_warning_msg () {
152 # echo " ${BLUE}*${NORMAL} $@"
153 #}
154
155 # int log_begin_message (char *message)
156 log_begin_msg () {
157   echo -n " ${GREEN}*${NORMAL} $@"
158 }
159
160 log_warn_msg () {
161   echo -n " ${YELLOW}*${NORMAL} $@"
162 }
163
164 # int log_end_message (int exitstatus)
165 SUCCESS=" ${BLUE}[ ${GREEN}ok ${BLUE}]${NORMAL}"
166 FAILED=" ${NORMAL}[${RED}fail${NORMAL}]"
167 # }}}
168
169 # Clear screen with colormode reset
170 # echo "$CLEAR$RESET"
171 # echo "$CLEAR"
172 # Just go to the top of the screen
173 # echo -n "\e[H\e[J"
174 echo ""
175 echo "${WHITE}Welcome to"
176 echo ""
177 echo "${RED}   ____ ____  __  __ _     "
178 echo "${RED}  / ___|  _ \|  \/  | |    "
179 echo "${RED} | |  _| |_) | |\/| | |    "
180 echo "${RED} | |_| |  _ <| |  | | |___ "
181 echo "${RED}  \____|_| \_\_|  |_|_____|"
182 echo ""
183 echo "${WHITE}grml.org - Linux for users of texttools and sysadmins."
184 echo "${NORMAL}"
185
186 # We need the builtin commands and /static only starting at this point
187 PATH=/static
188 export PATH
189
190 umask 022
191
192 case "$CMDLINE" in *debuglinuxrc*) set -x; echo "linuxrc debugging activated"; DEBUG="yes"; ;; esac
193 case "$CMDLINE" in *BOOT_IMAGE=expert\ *) INTERACTIVE="yes"; :>/interactive; ;; esac
194 case "$CMDLINE" in *BOOT_IMAGE=vmware\ *) VMWARE="yes"; ;; esac
195 case "$CMDLINE" in *modules-disk*) INTERACTIVE="yes"; ;; esac
196 case "$CMDLINE" in *BOOT_IMAGE=debug\ *|*\ debug\ *) DEBUG="yes"; ;; esac
197 case "$CMDLINE" in *secure*) SECURE=",nosuid"; ;; esac
198 # Does the user want to skip scsi detection?
199 NOSCSI=""
200 NOUSB=""
201 NOFIREWIRE=""
202 case "$CMDLINE" in *noscsi*|*nobootscsi*) NOSCSI="yes"; ;; esac
203 case "$CMDLINE" in *nousb\ *|*nobootusb*) NOUSB="yes"; ;; esac
204 case "$CMDLINE" in *nofirewire*|*nobootfirewire*) NOFIREWIRE="yes"; ;; esac
205 NOCD=""
206 case "$CMDLINE" in *fromhd*) NOCD="yes"; ;; esac
207 case "$CMDLINE" in *fromdvd*) FROMDVD="yes"; ;; esac
208 case "$CMDLINE" in *idecd*|*atapicd*) IDECD="yes"; ;; esac
209 case "$CMDLINE" in *noideraid*) NOIDERAID="yes"; ;; esac
210 USB2="ehci-hcd.ko"
211 case "$CMDLINE" in *nousb2*) USB2="" NOUSB2="yes"; ;; esac
212 case "$CMDLINE" in *\ usb*) USB="yes"; ;; esac
213
214 GRML_DIR="GRML"
215 GRML_NAME="GRML"
216 case "$CMDLINE" in *grml_dir=*) GRML_DIR="$grml_dir"; ;; esac
217 case "$CMDLINE" in *grml_name=*) GRML_NAME="$grml_name"; ;; esac
218
219 # NFS
220 for i in $cmdline; do case "$i" in nfsdir=*|NFSDIR=*) eval $i;; esac; done
221 [ -n "$nfsdir" ] && NFS="$nfsdir"
222
223 if [ -n "$DEBUG" ]; then
224    log_begin_msg "Bootoption debug detected. Printing kernel command line:"
225    echo ""
226    cat /proc/cmdline
227 fi
228
229 # Run a shell if in debug mode
230 # echo "${BLUE}Dropping you to a busybox shell for debugging.${NORMAL}"
231 stage=1
232 rundebugshell(){
233  if [ -n "$DEBUG" ]; then
234   log_begin_msg "Starting intermediate shell stage $stage as requested by \"debug\" option."
235   echo ""
236   echo "   ${GREEN}-${NORMAL} Just exit the shell to continue boot process...${NORMAL}"
237   if [ -x /static/sh ]; then
238     /static/sh
239   else
240     /bin/bash
241   fi
242  fi
243 }
244 rundebugshell
245
246 # Mount module disk
247 mountmodules(){
248 TYPE="$1"; shift
249 echo -n "${CRE}Please insert ${TYPE} modules disk and hit Return."
250 read a
251 echo -n "${CRE}Mounting ${TYPE} modules disk... "
252 # We always mount over /modules/scsi (because it's there ;-)
253 if mountit /dev/fd0 /modules/scsi "-o ro"; then
254 echo "${GREEN}OK.${NORMAL}"
255 return 0
256 fi
257 echo "${RED}NOT FOUND.${NORMAL}"
258 return 1
259 }
260
261 # Unmount module disk
262 umountmodules(){
263 TYPE="$1"; shift
264 echo -n "${CRE}Unmounting ${TYPE} modules disk... "
265 umount /modules/scsi 2>/dev/null
266 echo "${GREEN}DONE.${NORMAL}"
267 }
268
269 # Ask user for modules
270 askmodules(){
271  TYPE="$1"; shift
272  echo "${TYPE} modules available:${WHITE}"
273  c=""
274  for m in "$@"; do
275   if test -f "/modules/scsi/$m"; then
276    test -z "$c"  && { echo -n " $m"; c="1"; } || { echo "               $m"; c=""; }
277   fi
278  done
279  [ -n "$c" ] && echo ""
280  echo "Load ${TYPE} Modules?"
281  echo "[Enter full filename(s) (space-separated), Return for autoprobe, n for none] "
282  echo -n "insmod module(s)> "
283  read MODULES
284  case "$MODULES" in n|N) MODULES=""; ;; y|"")  MODULES="$*"; ;; esac
285 }
286
287 # Try to load the given modules (full path or current directory)
288 loadmodules(){
289  TYPE="$1"; shift
290  test -n "$INTERACTIVE" && echo "6" > /proc/sys/kernel/printk
291  echo ""
292  for i in "$@"; do
293   echo -n "   Probing ${TYPE}... ${WHITE}$i${NORMAL}: "
294    if test -f /modules/scsi/$i.ko && $INSMOD /modules/scsi/$i.ko >/dev/null 2>&1 && echo "  $SUCCESS" || echo " failed " ; then
295      case "$TYPE" in scsi|SCSI) FOUND_SCSI="yes"; ;; esac
296    fi
297  done
298  test -n "$INTERACTIVE" && echo "0" > /proc/sys/kernel/printk
299  echo -n "${CRE}"
300 }
301
302 # Check for SCSI, use modules on bootfloppy first
303 # Trying to do kind of /proc/pci hardware detection
304 if checkbootparam oldscsi ; then
305   PROCPCI="`cat /proc/pci 2>/dev/null`"
306   case "$PROCPCI" in *[Aa][Ii][Cc]-*|*[Aa][Hh][Aa]-*) SCSI_PROBE="$SCSI_PROBE aic7xxx" ;; esac
307   case "$PROCPCI" in *[Bb][Uu][Ss][Ll][Oo][Gg][Ii][Cc]*) SCSI_PROBE="$SCSI_PROBE BusLogic" ;; esac
308   case "$PROCPCI" in *[Tt][Rr][Mm]-[Ss]1040*|*[Dd][Cc]395*|*[Dd][Cc]315*) SCSI_PROBE="$SCSI_PROBE dc395x" ;; esac
309   case "$PROCPCI" in *53[Cc]8*) SCSI_PROBE="$SCSI_PROBE sym53c8xx" ;; esac
310   case "$PROCPCI" in *53[Cc]9*) SCSI_PROBE="$SCSI_PROBE NCR53C9x" ;; esac
311   case "$PROCPCI" in *53[Cc]406*) SCSI_PROBE="$SCSI_PROBE NCR53c406a" ;; esac
312   case "$PROCPCI" in *[Ii][Nn][Ii][Tt][Ii][Oo]\ *|*[Ii][Nn][Ii]-[Aa]100[Uu]2[Ww]*) SCSI_PROBE="$SCSI_PROBE initio" ;; esac
313   case "$PROCPCI" in *[Mm][Pp][Tt]*[Ss][Cc][Ss][Ii]*) SCSI_PROBE="$SCSI_PROBE mptbase mptscsih" ;; esac
314   case "$PROCPCI" in *[Aa][Dd][Vv][Aa][Nn][Cc][Ee][Dd]\ [Ss][Yy][Ss]*) SCSI_PROBE="$SCSI_PROBE advansys" ;; esac
315   case "$PROCPCI" in *[Aa][Tt][Pp]8*|*[Aa][Ee][Cc]6*) SCSI_PROBE="$SCSI_PROBE atp870u" ;; esac
316   case "$PROCPCI" in *[Dd][Tt][Cc]*) SCSI_PROBE="$SCSI_PROBE dtc" ;; esac
317   case "$PROCPCI" in *[Ee][Aa][Tt][Aa]*) SCSI_PROBE="$SCSI_PROBE eata" ;; esac
318   case "$PROCPCI" in *[Ff]*[Dd][Oo][Mm][Aa][Ii][Nn]*) SCSI_PROBE="$SCSI_PROBE fdomain" ;; esac
319   case "$PROCPCI" in *[Gg][Dd][Tt]\ *) SCSI_PROBE="$SCSI_PROBE gdth" ;; esac
320   case "$PROCPCI" in *[Mm][Ee][Gg][Aa][Rr][Aa][Ii][Dd]*) SCSI_PROBE="$SCSI_PROBE megaraid_mm megaraid_mbox" ;; esac
321   case "$PROCPCI" in *[Qq][Ll][Oo][Gg][Ii][Cc]*) SCSI_PROBE="$SCSI_PROBE qlogicfas408 qlogicfas qlogicfc" ;; esac
322   case "$PROCPCI" in *53[Cc]974*) SCSI_PROBE="$SCSI_PROBE tmscsim" ;; esac
323   case "$PROCPCI" in *[Uu][Ll][Tt][Rr][Aa][Ss][Tt][Oo][Rr]*) SCSI_PROBE="$SCSI_PROBE ultrastor" ;; esac
324   case "$PROCPCI" in *3[Ww][Aa][Rr][Ee]*) SCSI_PROBE="$SCSI_PROBE 3w-xxxx" ;; esac
325 fi
326
327 # New sysfs based SCSI detection (thanks, Jörg Schirottke)
328 sysfsscsi(){
329 SYS=$(for x in $(find /sys/devices/ -name modalias); do grep pci: $x; done|cut -f2 -d:)
330 while read id driver; do
331  for sysid in $SYS; do
332   case $sysid in $id)
333    if [ -z "$SCSI_PROBE" ]; then
334     SCSI_PROBE="$driver"
335    else
336     SCSI_PROBE="$SCSI_PROBE $driver"
337    fi
338    ;;
339   esac
340  done
341 done <<EOF
342 $(cat /modules/scsi/scsi-modules.txt)
343 EOF
344 }
345
346 if test -n "$INTERACTIVE"; then
347 # Let the user select interactively
348   askmodules SCSI $(cd /modules/scsi; echo *.ko)
349 else
350 # these are the autoprobe-safe modules
351   sysfsscsi
352   MODULES="$SCSI_PROBE"
353 fi
354
355 if test -z "$NOSCSI" ; then
356  log_begin_msg "Scanning for SCSI devices."
357  $INSMOD /modules/scsi/firmware_class.ko 1>/dev/null
358  test -n "$MODULES" && loadmodules SCSI $MODULES &&  echo -n "" || echo "           ${BLUE}[${NORMAL} none found ${BLUE}]${NORMAL} (try bootoption scsi=probe)"
359 else
360   log_warn_msg "Not scanning for SCSI devices as requested on commandline." && echo " $SUCCESS"
361 fi
362
363 if checkbootparam scsi ; then
364   MODULE="$(getbootparam 'scsi' 2>/dev/null)"
365   if test "$MODULE" = "probe" ; then
366     log_begin_msg "Bootoption scsi=probe found. Trying to autoprobe SCSI modules:"
367     echo ""
368     echo -n "   Trying to load scsi_debug: " ; $INSMOD /modules/scsi/scsi_debug.ko 1>/dev/null && echo "           $SUCCESS" || echo " [ failed ]"
369     for module in /modules/scsi/*.ko ; do
370       echo -n "   Probing ${WHITE}${module}${NORMAL}..."
371       $INSMOD ${module} >/dev/null 2>&1 && echo " $SUCCESS" || echo " [ failed ]"
372     done
373   elif test "$MODULE" = "ask" ; then
374     askmodules SCSI $(cd /modules/scsi; echo *.ko)
375     test -z "$NOSCSI" && test -n "$MODULES" && loadmodules SCSI $MODULES
376   else
377     [ -n "$MODULE" ] || echo "   ${RED}Neither a specific module nor option probe nor option ask for SCSI module given. Skipping.${NORMAL}"
378     [ -n "$MODULE" ] && echo -n "   Trying to load module ${WHITE}${MODULE}${NORMAL}:" ; \
379       $INSMOD "/modules/scsi/${MODULE}.ko" 1>/dev/null && echo "  $SUCCESS" || echo " [ failed ]"
380   fi
381 fi
382 # End of SCSI check
383
384 if test -n "$VMWARE" ; then
385   log_begin_msg "Bootoption VMware detected. Trying to load SCSI modules:"
386   echo ""
387   for module in mptbase mptscsih mptspi BusLogic ; do
388     echo -n "   Trying to load ${WHITE}${module}${NORMAL}: "
389     $INSMOD /modules/scsi/${module}.ko >/dev/null 2>&1 && echo " $SUCCESS" || echo " [ failed ]"
390   done
391 fi
392
393 # Check for USB, use modules on bootfloppy first
394 if test -z "$NOUSB"; then
395   log_begin_msg "Checking for USB."
396   if test -f /modules/div/usbcore.ko; then
397     $INSMOD /modules/div/usbcore.ko >/dev/null 2>&1
398     FOUNDUSB=""
399     for i in $USB2 uhci-hcd.ko ohci-hcd.ko usbhid.ko ; do
400       test -f /modules/div/$i && $INSMOD /modules/div/$i >/dev/null 2>&1 && FOUNDUSB="yes"
401     done
402     if test -n "$FOUNDUSB"; then
403       test -f /modules/div/usb-storage.ko && $INSMOD /modules/div/usb-storage.ko >/dev/null 2>&1
404       echo "                   $SUCCESS"
405     else
406       echo "                   ${BLUE}[${NORMAL} not found ${BLUE}]${NORMAL}"
407       true
408     fi
409     if [ -n "$NOUSB2" ] ; then
410       echo "   Not loading usb2 module ehci-hcd as requested on commandline."
411       echo "   Notice: to skip loading of USB in initrd at all use bootoption nousb"
412     fi
413   fi
414 else
415   log_warn_msg "Not scanning for USB devices as requested on commandline." && echo " $SUCCESS"
416   echo "   Notice that bootoption nousb affects initrd only, it does *not*"
417   echo "   avoid loading of usb modules in userspace afterwards"
418   echo "   Boot using something like 'nousb blacklist=uhci-hcd' to avoid loading of usb modules at all"
419 fi
420 # End of USB check
421
422 # Check for Firewire, use modules on bootfloppy first
423 if test -z "$NOFIREWIRE" ; then
424   log_begin_msg "Checking for Firewire."
425   if test -f /modules/div/ieee1394.ko ; then
426     $INSMOD /modules/div/ieee1394.ko > /dev/null 2>&1
427     FOUNDFIREWIRE=""
428     test -f /modules/div/ohci1394.ko && $INSMOD /modules/div/ohci1394.ko > /dev/null 2>&1 && FOUNDFIREWIRE="yes"
429     if test -n "$FOUNDFIREWIRE" ; then
430       test -f /modules/div/sbp2.ko && $INSMOD /modules/div/sbp2.ko > /dev/null 2>&1
431       echo "              $SUCCESS"
432     else
433       echo "               ${BLUE}[${NORMAL} not found ${BLUE}]${NORMAL}"
434       true
435     fi
436   fi
437 else
438   log_warn_msg "Not scanning for firewire devices as requested on commandline." && echo " $SUCCESS"
439   echo "   Notice that bootoption nofirewire affects initrd only, it does *not*"
440   echo "   avoid loading of firewire modules in userspace afterwards"
441   echo "   Boot with something like 'nofirewire blacklist=ohci1394' to avoid loading of firewire modules at all"
442 fi
443 # End of FIREWIRE check
444
445 # Unfortunately, hotpluggable devices tend to need some time in order to register
446 if test -n "$FOUNDUSB" -o -n "$FOUNDFIREWIRE"; then
447   log_begin_msg "Scanning for USB/Firewire devices."
448   sleep 4
449   if test -n "$USB"; then
450     sleep 10
451   fi
452  echo "  $SUCCESS"
453 fi
454
455 if checkbootparam scandelay ; then
456   DELAY="$(getbootparam 'scandelay' 2>/dev/null)"
457   [ -z $DELAY ] && DELAY='10'
458   log_begin_msg "Delaying bootsequence as requested for ${WHITE}${DELAY}${NORMAL} seconds."
459   sleep $DELAY && echo "  $SUCCESS"
460 fi
461
462 # boot via pcmcia
463 if checkbootparam bootpcmcia ; then
464   log_begin_msg "Bootoption bootpcmcia found. Trying to load ${WHITE}PCMCIA${NORMAL} modules..."
465   if $INSMOD /modules/div/pcmcia_core.ko 1>/dev/null ; then
466      $INSMOD /modules/div/firmware_class.ko 1>/dev/null && \
467      $INSMOD /modules/div/pcmcia.ko         1>/dev/null && \
468      $INSMOD /modules/div/rsrc_nonstatic.ko 1>/dev/null && \
469      $INSMOD /modules/div/yenta_socket.ko   1>/dev/null && echo " $SUCCESS"
470   else
471     echo " [ failed ]"
472   fi
473 fi
474
475 # Check for misc modules in expert mode
476 if test -n "$INTERACTIVE" ; then
477   another=""
478   answer=""
479   while test "$answer" != "n" -a "$answer" != "N" ; do
480     echo -n "${CYAN}Do you want to load additional modules from$another floppy disk? [${WHITE}Y${CYAN}/n] ${NORMAL}"
481     another=" another"
482     read answer
483     case "$answer" in n*|N*) break; ;; esac
484     if mountmodules new ; then
485        askmodules new $(cd /modules/scsi; echo *.ko)
486        test -n "$MODULES" && loadmodules new $MODULES
487        umountmodules current
488     fi
489   done
490 fi
491 # All interactively requested modules should be loaded now.
492
493 # Check for ide-scsi supported CD-Roms et al.
494 test -f /proc/scsi/scsi && FOUND_SCSI="yes"
495
496 # Disable kernel messages again
497 echo "0" > /proc/sys/kernel/printk
498
499 # We now enable DMA right here, for faster reading/writing from/to IDE devices
500 # in FROMHD or TORAM mode
501 case "$CMDLINE" in *\ nodma*) ;; *)
502  for d in $(cd /proc/ide 2>/dev/null && echo hd[a-z]); do
503   if test -d /proc/ide/$d; then
504     MODEL="$(cat /proc/ide/$d/model 2>/dev/null)"
505     test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
506     log_begin_msg "Enabling DMA acceleration for: ${MAGENTA}$d   ${YELLOW}[${MODEL}]${NORMAL}"
507     echo "using_dma:1" >/proc/ide/$d/settings && echo ""
508   fi
509  done
510  ;;
511 esac
512
513 stage=2
514 rundebugshell
515 if [ -n "$NFS" ]; then
516   tmp_="$(getbootparam nfsdir)"
517   log_begin_msg "Bootoption NFS found." ; echo "$SUCCESS"
518
519   /static/cdir
520
521   log_begin_msg "Trying to load network driver(s)." ; echo
522   modLoad()
523   {
524     for mod in $@ ; do
525       if [ -n "$DEBUG" ] ; then
526          echo "Debug: trying to load $mod:"
527          modprobe -v $mod
528       else
529          modprobe $mod 2>/dev/null
530       fi
531     done
532   }
533   # modules.alias and modules.dep are in place so USE IT :)!
534   find /sys/devices/ -name modalias |/static/xargs -r /static/grep -h pci: |while read i; do
535     modLoad "$i"
536   done
537   # loading additional modules
538   modLoad sunrpc lockd af_packet nfs
539
540   dhcp_iface_=$(getbootparam dhcp_iface)
541   if [ -z "$dhcp_iface_" ]; then
542         dhcp_iface_=`ifconfig -a | grep '^eth' | sed 's/ .*//'`
543   fi
544
545   # make sure we have a udhcpc executable, if it's not present
546   # assume that busybox provides one
547   if ! [ -x /static/udhcpc ] ; then
548      ln -s /static/busybox /static/udhcpc
549   fi
550
551   for INTERFACE in $dhcp_iface_ ; do
552       log_begin_msg "Requesting network configuration using udhcp for ${INTERFACE}:" ; echo
553       /static/timeout 10 /static/udhcpc --interface="${INTERFACE}" --foreground --quit --script=/static/udhcp-config.sh
554       # echo "press <enter> to start a system shell and configure your system"
555       # sh
556   done
557
558   # recreate dir layout + remove extra modules
559   /static/rdir
560
561   log_begin_msg "Looking for GRML in: ${MAGENTA}$NFS${NORMAL}" ; echo "$SUCCESS"
562   if mount -t nfs "$NFS" -o "async,ro,nolock" /cdrom #>/dev/null 2>&1
563     then
564     if test -f /cdrom/$GRML_DIR/$GRML_NAME
565       then
566       log_begin_msg "Accessing grml CDROM at ${MAGENTA}$NFS${NORMAL}" ; echo "$SUCCESS"
567       FOUND_GRML="$NFS"
568       break
569     fi
570   fi
571 fi
572
573 # Now that the right SCSI driver is (hopefully) loaded, try to find CD-ROM
574 if test -z $NFS ; then
575   DEVICES="/dev/hd?"
576   test -n "$FOUND_SCSI" -a -z "$NOCD" && DEVICES="/dev/scd? /dev/scd?? $DEVICES"
577   # New: Also try parallel port CD-Roms [for Mike].
578   DEVICES="$DEVICES /dev/pcd?"
579   # New: also check HD partitions for a GRML/GRML image
580   # notice: use /dev/sd? for usb-sticks without partition(s)
581   test -n "$FOUND_SCSI" -a -z "$NOSCSI" && DEVICES="$DEVICES /dev/sd?[1-9] /dev/sd?[1-9][0-9] /dev/sd?"
582   DEVICES="$DEVICES /dev/hd?[1-9] /dev/hd?[1-9][0-9]"
583   case "$CMDLINE" in *fromhd=/dev/*) DEVICES="$fromhd"; ;; esac
584   for i in $DEVICES
585   do
586   log_begin_msg "${CRE} ${GREEN}*${NORMAL} Looking for CD-ROM in:    ${MAGENTA}$i${NORMAL}"
587   if mountit $i /cdrom "-o ro" >/dev/null 2>&1
588     then
589     echo "  $SUCCESS"
590     if test -f /cdrom/$GRML_DIR/$GRML_NAME
591       then
592       log_begin_msg "Accessing grml CD-ROM at: ${MAGENTA}$i${NORMAL}" ; echo "  $SUCCESS"
593       FOUND_GRML="$i"
594       break
595     fi
596     umount /cdrom
597   fi
598   done
599 fi
600
601 # Harddisk-installed script part version has been removed
602 # (GRML can be booted directly from HD now).
603 mount_grml()
604 {
605   if test -n "$FOUND_GRML" -a -f $1/$GRML_DIR/$GRML_NAME; then
606     # echo "6" > /proc/sys/kernel/printk
607     mount -t squashfs $1/$GRML_DIR/$GRML_NAME /GRML -o loop,ro$SECURE || FOUND_GRML=""
608   fi
609 }
610
611 remount_grml()
612 {
613   if test -f $TARGET/$GRML_DIR/$GRML_NAME; then
614     umount /GRML # unmount it
615     umount $SOURCE  # unmount CD
616     [ -n "$SOURCE2" ] && umount $SOURCE2  # umount possible loop-device
617     mount_grml $TARGET
618   else
619     log_failure_msg "Warning: Changing to $TARGET failed."
620     return 1
621   fi
622
623   return 0
624 }
625
626 boot_from()
627 {
628   # preparations
629   /bin/mkdir $TARGET
630
631   SOURCE_DEV=$(echo $CMDLINE | /usr/bin/tr ' ' '\n' | /bin/sed -n '/bootfrom=/s/.*=//p' | /usr/bin/tail -1)
632
633   LOOP_DEV=$(echo $SOURCE_DEV | /usr/bin/gawk -F/ '{ print $1 "/" $2 "/" $3 }')
634   ISO_PATH=$(echo $SOURCE_DEV | /bin/sed "s|$LOOP_DEV||g" )
635   case "$ISO_PATH" in /*.[iI][sS][oO]) ;; *) ISO_PATH="" ;; esac
636   LOOP_SOURCE=""
637
638   # load filesystems
639   /GRML/sbin/modprobe fuse
640   /GRML/sbin/modprobe ntfs
641   $INSMOD /modules/div/ntfs.ko 1>/dev/null
642
643   if [ -n "$ISO_PATH" ]; then
644      LOOP_SOURCE="$TARGET.loop"
645      LOOP_SOURCE2="$LOOP_SOURCE"
646      TARGET_DEV="$LOOP_SOURCE$ISO_PATH"
647      /bin/mkdir $LOOP_SOURCE
648      /bin/mount -o ro $LOOP_DEV $LOOP_SOURCE || LOOP_SOURCE=""
649      /bin/mount -n -o loop $LOOP_SOURCE2$ISO_PATH $TARGET
650   else
651      TARGET_DEV="$SOURCE_DEV"
652     /bin/mount -n -o ro $SOURCE_DEV $TARGET
653   fi
654   if [ $? -ne 0 ]; then
655      [ -n "$LOOP_SOURCE" ] && /bin/umount $LOOP_SOURCE
656      log_failure_msg "Accessing grml CD-ROM failed. ${MAGENTA}$TARGET_DEV${NORMAL} is not mountable."
657      sleep 2
658      return 1
659   fi
660
661   if [ -f $TARGET/$GRML_DIR/$GRML_NAME ]; then
662     log_begin_msg "Accessing grml CD-ROM at ${MAGENTA}$TARGET_DEV${NORMAL}." ; echo "  $SUCCESS"
663   else
664     log_failure_msg "Accessing grml CD-ROM failed. Could not find $GRML_DIR/$GRML_NAME on ${MAGENTA}$TARGET_DEV${RED}.${NORMAL}"
665     [ -n "$LOOP_SOURCE" ] && /bin/umount $LOOP_SOURCE
666     umount $TARGET
667     sleep 2
668     return 1
669   fi
670   # remount the CD
671   remount_grml
672 }
673
674 copy_to()
675 {
676   # preparations
677   /bin/mkdir $TARGET
678   COPY="$SOURCE/$GRML_DIR"
679
680   # look if we copy to hd or to ram
681   SIZE="$(/usr/bin/du -s $COPY | /usr/bin/gawk '{print int($1*1.1)}')"
682   test -n "$SIZE" || SIZE="800000"
683
684   case "$1" in
685     ram)
686       TARGET_DEV="/dev/shm"
687       TARGET_DEV_DESC="ramdisk"
688       FOUNDSPACE="$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo)"
689       /bin/mount -n -t tmpfs -o size=${SIZE}k $TARGET_DEV $TARGET
690     ;;
691     hd)
692       TARGET_DEV=$(echo $CMDLINE | /usr/bin/tr ' ' '\n' | /bin/sed -n '/tohd=/s/.*=//p' | /usr/bin/tail -1)
693       TARGET_DEV_DESC="$TARGET_DEV"
694       # load filesystems
695       /GRML/sbin/modprobe fuse
696       /GRML/sbin/modprobe ntfs
697       FS="ext3 ext2 reiserfs reiser4 vfat ntfs"
698
699       MOUNTED=""
700       for i in $FS; do
701        if /GRML/bin/mount -o rw -t "$i" "$TARGET_DEV" "$TARGET"; then
702         MOUNTED="true"
703         break
704        fi
705       done
706       if test -z "$MOUNTED"; then
707         log_failure_msg "Copying grml CD-ROM failed. ${MAGENTA}$TARGET_DEV_DESC${NORMAL} is not mountable."
708         sleep 2
709         return 1
710       fi
711       # check for enough free space
712       USED_SPACE=0
713       [ -f $TARGET/$GRML_DIR/$GRML_NAME ] && USED_SPACE=$(/usr/bin/du -s $TARGET/$GRML_DIR/$GRML_NAME | /usr/bin/gawk '{ print $1 }')
714       FOUNDSPACE="$(/bin/df -k $TARGET | /usr/bin/tail -1 | /usr/bin/gawk '{ print $4+int('$USED_SPACE') }')"
715    ;;
716    *)
717      return 1
718    ;;
719   esac
720
721   # sanity check
722
723   if [ $FOUNDSPACE -lt $SIZE ]
724   then
725     log_failure_msg "Copying grml CD-ROM failed. Not enough free space on ${MAGENTA}${TARGET_DEV_DESC}${NORMAL}. Found: ${MAGENTA}${FOUNDSPACE}k${NORMAL} Need: ${MAGENTA}${SIZE}k${NORMAL}"
726     sleep 2
727     umount $TARGET
728     return 1
729   fi
730
731   # do the real copy
732
733   log_begin_msg "Copying grml CD-ROM to ${TARGET_DEV_DESC}... Please be patient."
734   echo
735   if [ -z "$use_cp" -a -x /usr/bin/rsync ]
736   then
737     # first cp the small files
738     /usr/bin/rsync -a --exclude="$GRML_DIR/$GRML_NAME" $COPY $TARGET # Copy grml to $TARGET
739     # then the big file with nice progress meter
740     [ -f $TARGET/$GRML_DIR/$GRML_NAME ] && /bin/rm -f $TARGET/$GRML_DIR/$GRML_NAME
741     /usr/bin/rsync -a --progress --include="$GRML_DIR/$GRML_NAME" --include="$GRML_DIR/" --exclude="*" $COPY $TARGET # Copy grml to $TARGET
742     #/usr/bin/rsync -avP $COPY $TARGET # Copy grml to $TARGET
743     # make sure to support directories from http://grml.org/config/
744     for dir in scripts bootparams config debs ; do
745         if [ -d "/cdrom/$dir" ] ; then
746            log_begin_msg "Customization directory $dir found, copying to $TARGET"
747            cp -a /cdrom/$dir $TARGET/ && echo "$SUCCESS" || echo "$FAILED"
748         fi
749     done
750   else
751     /bin/cp -a -f $COPY $TARGET # Copy grml to $TARGET
752   fi
753   if [ $? -ne 0 ]
754   then
755     log_failure_msg "Copying grml CD-ROM failed. ${MAGENTA}$TARGET_DEV_DESC${NORMAL} possibly has not enough space left."
756     sleep 2
757     return 1
758   fi
759   # remount r/o
760   /bin/mount -n -o remount,ro $TARGET 1>/dev/null 2>&1
761   remount_grml
762 }
763
764 mount_grml /cdrom
765
766 COPYTO=""
767 BOOTFROM=""
768 DO_REMOUNT=""
769 REAL_TARGET=""
770 UNIONFS=""
771
772 case "$CMDLINE" in *toram*) DO_REMOUNT="yes"; COPYTO="ram"; ;; esac
773 case "$CMDLINE" in *tohd=*) DO_REMOUNT="yes"; COPYTO="hd"; ;; esac
774 case "$CMDLINE" in *bootfrom=*) DO_REMOUNT="yes"; BOOTFROM="yes" ;; esac
775
776 # Remount later after copying/isoloading/driverloading?
777 # pre-test if everything succeeded
778 if  test -n "$DO_REMOUNT" -a -n "$FOUND_GRML" ; then
779   # copy library cache
780   cat /GRML/etc/ld.so.cache > /etc/ld.so.cache
781   echo ""
782
783   SOURCE="/cdrom"
784   TARGET="/cdrom2"
785
786   # first copy_to, then boot_from
787   if [ -n "$COPYTO" ]; then
788      copy_to $COPYTO && REAL_TARGET="$TARGET"
789   fi
790   if [ -n "$BOOTFROM" ]; then
791      boot_from
792      if [ "$?" -eq "0" ]; then
793         # set new source / target paths
794         REAL_TARGET="$TARGET"
795         SOURCE2="$LOOP_SOURCE"
796         SOURCE="/cdrom2"
797         TARGET="/cdrom3"
798     fi
799   fi
800 fi
801
802 # Final test if everything succeeded.
803 if test -n "$FOUND_GRML" ; then
804 # copy library cache
805 cat /GRML/etc/ld.so.cache > /etc/ld.so.cache
806
807 UNIONFS=""
808 if checkbootparam "unionfs" ; then
809    $INSMOD /modules/unionfs.ko 1>/dev/null
810    grep -q unionfs /proc/filesystems && UNIONFS=yes
811    unionfs='unionfs'
812    UNIONFS_FILETYPE='unionfs'
813    AUFS=''
814 else
815    $INSMOD /modules/aufs.ko 1>/dev/null
816    grep -q aufs /proc/filesystems && UNIONFS=yes
817    unionfs='unionfs (using aufs)'
818    UNIONFS_FILETYPE='aufs'
819    AUFS='yes'
820 fi
821
822 # Set paths
823 log_begin_msg "Setting paths"
824 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:."
825 export PATH
826
827 # Make space: We don't need the modules anymore from here.
828 /GRML/bin/rm -rf /modules
829 # Debian weirdness
830 /GRML/bin/cp -a /GRML/etc/alternatives /etc/ 2>/dev/null
831
832 # Replace /sbin
833 /GRML/bin/rm -f /sbin
834 /GRML/bin/ln -sf /GRML/sbin /sbin
835
836 # From here, we should have all essential commands available.
837 hash -r
838
839 # Did we remount the source media?
840 if  test -n "$REAL_TARGET"; then
841   /bin/mount -n --move $REAL_TARGET /cdrom # move it back and go on to normal boot
842 fi
843
844 # Clean up /etc/mtab (and - just in case - make a nice entry for looped ISO)
845 egrep " /GRML | /cdrom " /proc/mounts 2>/dev/null | sed 's|/dev/loop0 /cdrom \(.*\) 0 0|'$LOOP_SOURCE$ISO_PATH' /cdrom/ \1,loop=/dev/loop0 0 0|g' >> /etc/mtab
846
847 # Clean up /
848 /GRML/bin/rm -rf /modules /static
849 echo "                       $SUCCESS"
850
851 # New in Kernel 2.4.x: tempfs with variable ramdisk size.
852 # We check for available memory anyways and limit the ramdisks
853 # to a reasonable size.
854 FOUNDMEM="$(awk '/MemTotal/{print $2}' /proc/meminfo)"
855 TOTALMEM="$(awk 'BEGIN{m=0};/MemFree|Cached/{m+=$2};END{print m}' /proc/meminfo)"
856
857 # Be verbose
858 if [ -n "$FOUNDMEM" ] ; then
859    log_begin_msg "Total memory found: $FOUNDMEM kB" ; echo "       $SUCCESS"
860 else
861    log_failure_msg "Could not fetch memory information." ; echo "     $FAILED"
862 fi
863
864 # Now we need to use a little intuition for finding a ramdisk size
865 # that keeps us from running out of space, but still doesn't crash the
866 # machine due to lack of Ram
867
868 # Minimum size of additional ram partitions
869 MINSIZE=20000
870 # At least this much memory minus 30% should remain when home and var are full.
871 MINLEFT=16000
872 # Maximum ramdisk size
873 [ -n "$TOTALMEM" ] && MAXSIZE="$(/usr/bin/expr $TOTALMEM - $MINLEFT)"
874 # Default ramdisk size for ramdisk
875 [ -n "$TOTALMEM" ] && RAMSIZE="$(/usr/bin/expr $TOTALMEM / 5)"
876
877 # Create additional dynamic ramdisk.
878 test -z "$RAMSIZE" -o "$RAMSIZE" -lt "$MINSIZE" && RAMSIZE="$MINSIZE"
879 mkdir -p /ramdisk
880 # tmpfs/varsize version, can use swap
881 RAMSIZE=$(/usr/bin/expr $RAMSIZE \* 4)
882 log_begin_msg "Creating /ramdisk (dynamic size=${RAMSIZE}k) on shared memory"
883 # We need /bin/mount here for the -o size= option
884 /bin/mount -t tmpfs -o "size=${RAMSIZE}k" /ramdisk /ramdisk  && echo "$SUCCESS"
885 mkdir -p /ramdisk/tmp /ramdisk/home/grml && chmod 1777 /ramdisk/tmp && chown grml.grml /ramdisk/home/grml && ln -snf /ramdisk/home /home && /bin/mv /tmp /tmp.old && ln -s /ramdisk/tmp /tmp && rm -rf /tmp.old
886
887 stage=3
888 rundebugshell
889 # unionfs
890 log_begin_msg "Creating $unionfs and symlinks on ramdisk"
891 mkdir -p /UNIONFS
892 if test -n "$UNIONFS" && /bin/mount -t $UNIONFS_FILETYPE -o noatime${SECURE},dirs=/ramdisk=rw:/GRML=ro /UNIONFS /UNIONFS ; then
893  # check architecture
894  if [ -f /GRML/lib/ld-linux.so.2 ] ; then
895    LDLINUX=/GRML/lib/ld-linux.so.2
896    GRMLLIB=/GRML/lib
897  elif [ -f /GRML/lib64/ld-linux-x86-64.so.2 ] ; then
898    LDLINUX=/GRML/lib64/ld-linux-x86-64.so.2
899    EMUL='emul'
900    LIB64='lib64'
901    GRMLLIB=/GRML/lib64
902  fi
903  # We now have unionfs, copy some data from the initial ramdisk first
904  cp -a /etc/fstab /etc/auto.mnt /etc/filesystems /etc/mtab /UNIONFS/etc/
905  # disable resolvconf on the terminalserver client
906  if [ -n "$NFS" ] ; then
907     rm /UNIONFS/etc/resolv.conf
908     cp -a /etc/resolv.conf /UNIONFS/etc
909     echo REPORT_ABSENT_SYMLINK=no >> /UNIONFS/etc/default/resolvconf
910  fi
911  for i in bin boot etc sbin var opt root usr $EMUL $LIB64 lib ; do # Move directories to unionfs
912   if test -d /$i; then
913    /bin/mv /$i /$i.old && \
914    # /GRML/lib/ld-linux.so.2 --library-path /GRML/lib /GRML/bin/ln -snf /UNIONFS/$i /$i && \
915    $LDLINUX --library-path $GRMLLIB /GRML/bin/ln -snf /UNIONFS/$i /$i 1>/dev/null 2>/dev/null
916    rm -rf /$i.old
917   else
918    ln -snf /UNIONFS/$i /$i
919   fi
920  done
921  [ -n "$AUFS" ] && echo "    $SUCCESS" || echo "                 $SUCCESS"
922  log_begin_msg "Merging read-only system with read-writeable /ramdisk."
923  for i in $(cd /UNIONFS; echo *); do # Create links for new stuff on /UNIONFS
924    test "$i" = "home" -o "$i" = "tmp" && continue
925    test -L "/$i" || test -d "/$i" || test -f "/$i" || ln -snf "/UNIONFS/$i" /$i
926  done && echo "   $SUCCESS" || echo "   $FAILED"
927 else
928  echo ""
929  log_failure_msg "ERROR: CANNOT UNITE READ-ONLY MEDIA AND INITIAL RAMDISK!"
930  echo "$FAILED"
931  sleep 2
932  echo "Can not continue booting, dropping you to a busybox shell."
933  stage=4
934  rundebugshell
935 fi
936
937 chown grml.grml /home/grml
938 # old:
939 # chmod 1777 /var/tmp
940 # new:
941 rm -rf /var/tmp/ ; mkdir /var/tmp ; chown root.root /var/tmp ; chmod 1777 /var/tmp
942
943 # Create empty utmp and wtmp
944 :> /var/run/utmp
945 :> /var/run/wtmp
946
947 # Make SURE that these are files, not links!
948 rm -rf /etc/ftpusers /etc/passwd /etc/shadow /etc/group \
949        /etc/ppp /etc/isdn /etc/ssh /etc/ioctl.save \
950        /etc/inittab /etc/network /etc/sudoers \
951        /etc/init /etc/localtime /etc/dhcpc /etc/pnm2ppa.conf 2>/dev/null
952 cp -a /GRML/etc/ftpusers /GRML/etc/passwd /GRML/etc/shadow /GRML/etc/group \
953       /GRML/etc/ppp /GRML/etc/isdn /GRML/etc/ssh \
954       /GRML/etc/inittab /GRML/etc/network /GRML/etc/sudoers \
955       /GRML/sbin/init /GRML/etc/dhcpc /etc/ 2>/dev/null
956
957 # Extremely important, init crashes on shutdown if this is only a link
958 :> /etc/ioctl.save
959 :> /etc/pnm2ppa.conf
960 # Must exist for samba to work
961 [ -d /var/lib/samba ] && :> /var/lib/samba/unexpected.tdb
962 # Diet libc bug workaround
963 # cp -f /GRML/etc/localtime /etc/localtime
964 # echo "${BLUE}Done.${NORMAL}"
965
966 # Now tell kernel where the real modprobe lives
967 echo "/sbin/modprobe" > /proc/sys/kernel/modprobe
968
969 # Change root device from /dev/fd0 to /dev/ram0
970 echo "0x100" > /proc/sys/kernel/real-root-dev
971
972 /bin/umount /sys # (remount in grml-autoconfig)
973
974 stage=4
975 rundebugshell
976 # Give control to the init process.
977 log_begin_msg "Starting init process. "
978 [ -r /mountit ] && rm -f /mountit
979 rm -f /linuxrc
980 exit 0
981
982 else
983  log_failure_msg "Error: Can't find grml filesystem, sorry."
984  echo "
985 Are you booting via USB or firewire?
986 ====================================
987 Try to boot with bootparam scandelay which delays the
988 bootup sequence so modules should have enough time
989 to initialize devices.
990
991 Usage examples on bootprompt of grml-iso:
992
993 grml scandelay       -> adds the default delay of 10 seconds
994 grml scandelay=13    -> adds a delay of 13 seconds
995
996 Are you booting via SCSI?
997 ====================================
998 Use the bootparam scsi.
999 Usage examples on bootprompt of grml-iso:
1000
1001 grml scsi=probe      -> autoprobing of scsi modules
1002 grml scsi=ask        -> list modules and prompt for module which should be loaded
1003 grml scsi=modulename -> loads specified module (without .ko extension)
1004 expert               -> activate expert mode, similar to scsi=ask
1005
1006 Are you getting SquashFS/zlib errors?
1007 =====================================
1008 Try to boot with \"grml nodma\"
1009
1010 Still problems?
1011 ===============
1012 Make sure the ISO itself is ok.
1013 Check the md5sum of downloaded ISO.
1014 Used a CD-RW? Make sure the medium is ok!
1015
1016 Please report any problems you notice to the grml-team!
1017 http://grml.org/contact/
1018 "
1019  echo "${RED}Now dropping you to the busybox shell.${NORMAL}"
1020  echo "${RED}Press reset button to quit.${NORMAL}"
1021  echo ""
1022  PS1="grml# "
1023  export PS1
1024  echo "6" > /proc/sys/kernel/printk
1025  # Allow signals
1026  trap 1 2 3 15
1027  exec /static/sh
1028 fi
1029 # EOF