altboot:
authorMatthias Hentges <oe@hentges.net>
Thu, 26 Oct 2006 16:09:59 +0000 (16:09 +0000)
committerMatthias Hentges <oe@hentges.net>
Thu, 26 Oct 2006 16:09:59 +0000 (16:09 +0000)
- Add altbootctl to set altboot options on a permanent or per-reboot basis
- Only remember selections for the next boot that actually make sense
- Cleanup of run_timer()
- Disabled existing kexec modules due to a planned rework

packages/altboot/altboot_0.0.0.bb
packages/altboot/files/altboot-menu/Advanced/70-install-tgz
packages/altboot/files/altboot-menu/Advanced/70-setKernel
packages/altboot/files/altboot-menu/Advanced/80-configure-kexec
packages/altboot/files/altboot-menu/Advanced/80-copyrootfs
packages/altboot/files/altboot.func
packages/altboot/files/altbootctl [new file with mode: 0755]
packages/altboot/files/altbootctl.conf [new file with mode: 0644]
packages/altboot/files/init.altboot

index 1970604..7130af5 100644 (file)
@@ -20,7 +20,7 @@ RDEPENDS_${PN} = "${PN}-conf"
 
 ######################################################################################
 
-PR = "r45"
+PR = "r46"
 
 ######################################################################################
 
@@ -35,6 +35,8 @@ SRC_URI = "file://altboot-menu \
           file://altboot.func \         
           file://init.altboot \
           file://altboot*.cfg \
+          file://altbootctl.conf \
+          file://altbootctl \
           file://beep.raw"
 
 # S = "${WORKDIR}/altboot/"
@@ -56,7 +58,9 @@ do_install() {
        install -m 0644 ${WORKDIR}/beep.raw ${D}/usr/share/sounds
        install -m 0644 ${WORKDIR}/altboot*.cfg ${D}/etc
        install -m 0644 ${WORKDIR}/altboot.func ${D}/etc
+       install -m 0644 ${WORKDIR}/altbootctl.conf ${D}/etc
        install -m 0755 ${WORKDIR}/init.altboot ${D}/sbin
+       install -m 0755 ${WORKDIR}/altbootctl ${D}/sbin
        
        install -m 0755 ${WORKDIR}/altboot-menu/*-* ${D}/etc/altboot-menu
 
index cb8b272..aca0d04 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/sh
-
 M_TITLE="Install RootFS from tar.gz"
+M_FLAGS="noRemember"
 
 run_module(){
        test -e /etc/altboot.func && . /etc/altboot.func || die "ERROR: /etc/altboot.func not found. Check your installation!"  
@@ -259,5 +259,6 @@ install_rootfs_image(){
 
 case "$1" in
 title) echo "$M_TITLE";;
+flags) echo "$M_FLAGS";;
 run)   run_module "$2";;
 esac
index 6192232..50f61d0 100644 (file)
@@ -1,7 +1,8 @@
 # !/bin/sh
 M_TITLE="Choose kernel for next boot"
 
-
+# Deprecated due to altbootctl
+exit 0
 
 # Only kernel 2.6 offers kexec support
 uname -r | grep -q "^2.6" || exit 0
index e294df6..1b8fc6e 100644 (file)
@@ -1,6 +1,8 @@
 # !/bin/sh
 M_TITLE="Configure kexec CMDLINE"
 
+# Deprecated due to altbootctl
+exit 0
 
 
 # Only kernel 2.6 offers kexec support
index af6bd38..2d305e3 100644 (file)
@@ -1,5 +1,6 @@
 # !/bin/sh
 M_TITLE="Copy rootfs to SD/CF"
+M_FLAGS="noRemember"
 
 # Unfinished script.
 exit 0
@@ -317,5 +318,6 @@ run_module() {
 
 case "$1" in
 title) echo "$M_TITLE";;
+flags) echo "$M_FLAGS";;
 run)   run_module;;
 esac
index 7457f66..b3d25ff 100644 (file)
@@ -580,11 +580,15 @@ set_pref() {
        data_id="$2"
        data_value="$3"
        
-       #echo "[$1] [$2] [$3]"
+       #debug_echo "[$1] [$2] [$3]"
        #export "${data_name}"="`eval echo -e \\$${data_name} | sed "s/\#\#\#/\#\#\#\\n/g"|sed s/^\ // | sed s/^$data_id.*//`"
 
-       export "${data_name}"="`eval echo -e \\$${data_name} `$data_id##$data_value###"
-       
+       if test -z "$3"
+       then
+               debug_echo "set_pref(): WARNING, writing empty value to $data_name / $data_id! THIS WILL BREAK THINGS"
+               #data_value=" "
+       fi
+       export "${data_name}"="`eval echo -e \\$${data_name} `$data_id##$data_value###"         
 }
 
 # $1: uniq name
@@ -602,7 +606,32 @@ echo_pref() {
 
 dump_pref() {
        data_name="$1"  
-       echo "`eval echo -e \\$${data_name} | sed "s/\#\#\#/\#\#\#\\n/g"|sed s/^\ // `"
+       echo "`eval echo -e ${data_name} | sed "s/\#\#\#/\#\#\#\\n/g"|sed s/^\ // `"
+       
+       #echo "-- `eval echo ${data_name}` --" 
+       #debug_echo "[$menu_fileflags]"
+}
+
+# $1 = name, $2 = cache_file
+export_pref() {
+       data_name="$1"
+       echo "`eval echo -e ${data_name}`" > "$2"
+}
+
+# $1 = name, $2 = cache_file
+import_pref() {
+       data_name="$1"
+       data_id="$2"
+       
+       #debug_echo "[$1] [$2] [$3]"
+
+       if test -z "$3"
+       then
+               debug_echo "set_pref(): WARNING, writing empty value to $data_name / $data_id! THIS WILL BREAK THINGS"
+               #data_value=" "
+       fi
+       export "${data_name}"="`cat "$2"`"              
+
 }
 
 # $1: uniq name, $2 identifier, $3 out var
@@ -612,10 +641,11 @@ get_pref() {
        data_out="$3"
        data_list="`eval echo -e \\$${data_name}`"
        
+       #echo "data_list: [$data_list]"
        #data_value="`echo "$data_list"| sed "s/\#\#\#/\\n/g"|sed s/^\ // | grep "^$data_id##" | sed -n "s/.*\#\(.*\)$/\1/p"`"
        #data_value="`echo "$data_list"| sed "s/\#\#\#/\\n/g"|sed s/^\ // |  sed -n "/^$data_id/s/.*\#\(.*\)$/\1/p"`"
        data_value="`echo "$data_list"| sed "s/\#\#\#/\\n/g" | sed -n "s/^\ //;/^$data_id\#/s/.*\#\(.*\)$/\1/p"`"
-       # echo "WERT: [$data_value]"
+       #echo "WERT: [$data_value]"
        
        export "${data_out}"="$data_value"
        test -n "$data_value" && return 0
diff --git a/packages/altboot/files/altbootctl b/packages/altboot/files/altbootctl
new file mode 100755 (executable)
index 0000000..e09df19
--- /dev/null
@@ -0,0 +1,309 @@
+#! /bin/sh
+#
+# Copyright Matthias Hentges <devel@hentges.net> (c) 2006
+# License: GPL (see http://www.gnu.org/licenses/gpl.txt for a copy of the license)
+#
+# Filename: hentges-setup.sh
+# Date: 03-Jun-06
+
+die() {
+       echo -e "$*"
+       exit 1
+}
+
+
+PERMANENT_CFG="/etc/altboot-`uname -r | cut -c1-3`.cfg"
+TEMPORARY_CFG="/etc/altboot-`uname -r | cut -c1-3`.cfg.next-reboot"
+
+CFG="$PERMANENT_CFG"
+SCRIPT_CONFIG="/etc/altbootctl.conf"
+
+test -e "$SCRIPT_CONFIG" && . "$SCRIPT_CONFIG" || die "$SCRIPT_CONFIG not found"
+
+# $1= Setting, $2 = new value
+set_pref() {
+       
+       if ( cat "$CFG" | grep -q "$1" )
+       then
+               cat "$CFG" | sed "/^$1/s/\(.*\)\=\(.*\)/\1\=\"$2\"/" > ${CFG}_
+               mv ${CFG}_  ${CFG}
+       else
+               echo "$1=\"$2\"" >> "${CFG}"
+       fi
+}
+
+# $1= Setting
+get_pref() {
+       n="$1"
+       value="`cat "${CFG}" | sed -n "/^$n/s/\(.*\)\=\\"\(.*\)\\"/\2/p"`"
+       #echo "cat "${CFG}" | sed -n "/^$n/s/\(.*\)\=\"\(.*\)\"/\2/p""
+       test -z "$value" && die "Couldn't get value for [$n]"
+       echo "$value"
+}
+
+ask_pref() {
+       SETTING_NAME="$1"
+       
+       SETTING_TEXT_="${SETTING_NAME}_TEXT"
+       SETTING_TEXT="`eval echo -e \\$${SETTING_TEXT_}`"       
+
+       SETTING_VALUES_="${SETTING_NAME}_VALUES"
+       SETTING_VALUES="`eval echo -e \\$${SETTING_VALUES_}`"   
+       
+       SETTING_OLD_VALUE="`get_pref "$SETTING_NAME"`"
+       test -z "$SETTING_TEXT" -o -z "$SETTING_VALUES" && die "ask_pref: [$1] -> [$SETTING_TEXT] [$SETTING_VALUES]"
+       
+       #echo "[$1] -> $SETTING_OLD_VALUE"
+       #echo -e "$SETTING_TEXT"
+
+
+       if test "$SETTING_VALUES" = "<STRING>"
+       then                            
+               while true
+               do
+                       echo -e "\nPlease enter a new value [$SETTING_OLD_VALUE]"
+                       echo -en "Your Choice: "
+                       read junk
+                       
+                       echo ""
+                                               
+                       while true
+                       do
+                               echo -n "Is the new value of [$junk] correct? [Y|n] "
+                               read junk2
+                               
+                               case "$junk2" in
+                               y|Y|"")         END_LOOP=true
+                                               break ;;
+                               *)              END_LOOP=false
+                                               break ;;
+                               esac
+                       done
+                       
+                       if test "$END_LOOP" = "true"
+                       then
+                               SETTING_NEW_VALUE="$junk"
+                               break
+                       fi
+               
+               done
+               
+       else    
+               # If it's not a string, it's a fixed list of possible settings
+               echo -e "\nSelect one of the following:\n"      
+               cnt=1   
+               for val in $SETTING_VALUES
+               do
+                       if test "$val" != "$SETTING_OLD_VALUE"
+                       then
+                               echo -e "\t[$cnt] $val"
+                       else
+                               echo -e "\t[$cnt] $val *"
+                               SETTING_OLD_VALUE_NUM="$cnt"
+                       fi
+                       let cnt=$cnt+1
+               done
+
+               echo ""
+               while true
+               do
+                       echo -en "Your choice [$SETTING_OLD_VALUE_NUM]: "
+                       read junk               
+
+                       if test -n "$junk"
+                       then
+                               cnt=1 ; SETTING_NEW_VALUE=""
+                               for val in $SETTING_VALUES
+                               do
+                                       if test "$junk" = "$cnt"
+                                       then
+                                               SETTING_NEW_VALUE="$val"
+                                               break
+                                       fi
+
+                                       let cnt=$cnt+1
+                               done
+                       else
+                               SETTING_NEW_VALUE="$SETTING_OLD_VALUE"
+                       fi
+
+                       test -n "$SETTING_NEW_VALUE" && break
+               done
+               
+       fi
+               
+       
+       if test "$SETTING_NEW_VALUE" != "$SETTING_OLD_VALUE"
+       then
+               set_pref "$SETTING_NAME" "$SETTING_NEW_VALUE"
+               echo "Changed $SETTING_NAME to $SETTING_NEW_VALUE"
+       else
+               echo "$SETTING_NAME remains unchanged"
+       fi
+       echo -e "\n"
+}
+
+build_menu() {
+       for setting in $TARGETS
+       do      
+               # SETTING_MENUPOS contains $setting_MENUPOS
+               SETTING_MENUPOS_="${setting}_MENUPOS"
+               SETTING_MENUPOS="`eval echo -e \\$${SETTING_MENUPOS_}`" 
+
+               # Store all entries in variables named after the menu name
+               MENU_NAME="SUBMENU_${SETTING_MENUPOS}"
+               export "${MENU_NAME}"="`eval echo -e \\$${MENU_NAME} ` $setting"
+               
+               
+               echo "$AVAILABLE_MENUES" | grep -q "$SETTING_MENUPOS" || AVAILABLE_MENUES="$SETTING_MENUPOS $AVAILABLE_MENUES"
+                                               
+       done    
+       
+       #echo "[$AVAILABLE_MENUES]"
+       
+       while true
+       do
+               echo -e "\nSelect a menu:\n"
+               cnt=1
+               for menu in $AVAILABLE_MENUES Exit
+               do
+                       MENU_NAME="SUBMENU_$menu"
+                       echo -e "\t[$cnt] $menu"
+                       let cnt=$cnt+1
+               done
+               
+               echo ""
+               
+               while true
+               do
+                       echo -n "Your Choice: "
+                       read junk
+
+                       cnt=1 ; GET_MENU=""
+                       for menu in $AVAILABLE_MENUES Exit
+                       do
+                               if test "$cnt" = "$junk"
+                               then
+                                       GET_MENU="$menu"
+                                       break
+                               fi
+                               let cnt=$cnt+1
+                       done
+
+                       if test "$GET_MENU" = "Exit"
+                       then
+                               EXIT_PROG=true
+                               break
+                       else
+                               EXIT_PROG=false
+                       fi
+                       
+                       if test -n "$GET_MENU"
+                       then
+                               show_menu "$menu"
+                               break
+                       fi
+               done            
+               test "$EXIT_PROG" = true && break
+       done
+}
+
+show_menu() {
+       MENU_NAME="SUBMENU_$1"
+
+       
+       while true
+       do
+               echo -e "\nEntries in this menu:\n"
+               cnt=1
+               for entry in `eval echo -e \\$${MENU_NAME}` Back
+               do
+                       MENU_NAME_TEXT="${entry}_TEXT" || MENU_NAME_TEXT="${entry}"
+                       
+                       test "$entry" != Back && tmp_="`eval echo -e \\$${MENU_NAME_TEXT}`" || tmp_="Back"
+                       
+                       echo -e "\t[$cnt] $tmp_"
+                       let cnt=$cnt+1
+               done    
+
+               echo ""
+       
+               while true
+               do
+                       echo -en "Your Choice: "
+                       read junk
+
+                       cnt=1 ; GET_ENTRY=""
+                       for entry in `eval echo -e \\$${MENU_NAME}` Back
+                       do
+                               if test "$cnt" = "$junk"
+                               then
+                                       GET_ENTRY="$entry"
+                                       break
+                               fi
+                               let cnt=$cnt+1
+                       done
+
+                       if test "$GET_ENTRY" = "Back"
+                       then
+                               EXIT_MENU=true
+                               break
+                       else
+                               EXIT_MENU=false
+                       fi
+                       
+                       
+                       # At this point the user has selected a menuitem != "Back"
+                       if test -n "$GET_ENTRY"
+                       then
+                               select_config
+                               ask_pref "$GET_ENTRY"
+                               break
+                       fi
+               done    
+               
+               test "$EXIT_MENU" = true && break               
+       done
+}
+
+select_config() {
+       echo -e "\nChange this setting only for the next reboot or permanently?\n"
+
+       echo -e "Select one of the following:\n"
+
+       echo -e "\t[1] Only for the next reboot"
+       echo -e "\t[2] Permanently"
+       echo ""
+       
+       while true
+       do
+               echo -en "Your Choice: "
+               read junk
+               
+               case "$junk" in
+               2)      CFG="$PERMANENT_CFG"
+                       break ;;
+               1)      CFG="$TEMPORARY_CFG"
+                       break ;;
+               esac            
+       done
+       
+       # Supress error message about missing config
+       ! test -e "$CFG" && touch "$CFG"
+       
+}
+
+go() {
+       build_menu
+       
+       exit 0
+       for setting in $TARGETS
+       do
+               ask_pref "$setting"
+       done
+       
+}
+
+
+! test -e "$CFG" && die "[$CFG] not found, exiting"
+go
diff --git a/packages/altboot/files/altbootctl.conf b/packages/altboot/files/altbootctl.conf
new file mode 100644 (file)
index 0000000..0a358c7
--- /dev/null
@@ -0,0 +1,90 @@
+#! /bin/sh
+#
+# Copyright Matthias Hentges <devel@hentges.net> (c) 2006
+# License: GPL (see http://www.gnu.org/licenses/gpl.txt for a copy of the license)
+#
+# Filename: hentges-setup.conf
+# Date: 04-Jun-06
+
+
+TARGETS="REMEMBER_LAST_SELECTION ENABLE_ALTBOOT FSCK_IMAGES TIMEOUT INIT_RUNLEVEL NO_GUI_RL \
+        USB_HOST_AVAILABLE USB_NETWORKING_AVAILABLE ASK_PW_ON_BOOT SD_DEVICE SD_KERNEL_MODULE \
+        IMAGE_PATH IMAGE_TYPE ENABLE_IMAGECONF USB_STORAGE_MODULES USB_STORAGE_PARTITION \
+        USB_STORAGE_WAIT SD_MOUNTPOINT"
+
+
+REMEMBER_LAST_SELECTION_VALUES="yes no"
+REMEMBER_LAST_SELECTION_TEXT="Remember the last selected menu item for next boot"
+REMEMBER_LAST_SELECTION_MENUPOS="Core"
+
+ENABLE_ALTBOOT_VALUES="yes no"
+ENABLE_ALTBOOT_TEXT="Enable or disable the altboot boot-manager"
+ENABLE_ALTBOOT_MENUPOS="Core"
+
+TIMEOUT_VALUES="<STRING>"
+TIMEOUT_TEXT="Altboot boot-menu timeout in seconds"
+TIMEOUT_MENUPOS="Core"
+
+INIT_RUNLEVEL_VALUES="<STRING>"
+INIT_RUNLEVEL_TEXT="Default runlevel"
+INIT_RUNLEVEL_MENUPOS="Core"
+
+NO_GUI_RL_VALUES="<STRING>"
+NO_GUI_RL_TEXT="GUI-less runlevel"
+NO_GUI_RL_MENUPOS="Core"
+
+ENABLE_DEBUG_VALUES="yes no"
+ENABLE_DEBUG_TEXT="Enable debug output"
+ENABLE_DEBUG_MENUPOS="Core"
+
+FSCK_IMAGES_VALUES="yes no"
+FSCK_IMAGES_TEXT="Automatically fsck loop-images"
+FSCK_IMAGES_MENUPOS="LoopImages"
+
+IMAGE_PATH_VALUES="<STRING>"
+IMAGE_PATH_TEXT="Subdirectory for loop-files"
+IMAGE_PATH_MENUPOS="LoopImages"
+
+IMAGE_TYPE_VALUES="<STRING>"
+IMAGE_TYPE_TEXT="Image FS type"
+IMAGE_TYPE_MENUPOS="LoopImages"
+
+ENABLE_IMAGECONF_VALUES="yes no"
+ENABLE_IMAGECONF_TEXT="Configure new loop-images on 1st boot"
+ENABLE_IMAGECONF_MENUPOS="LoopImages"
+
+USB_HOST_AVAILABLE_VALUES="yes no"
+USB_HOST_AVAILABLE_TEXT="Device supports full USB *HOST* mode"
+USB_HOST_AVAILABLE_MENUPOS="USB"
+
+USB_NETWORKING_AVAILABLE_VALUES="yes no"
+USB_NETWORKING_AVAILABLE_TEXT="USB networking is available"
+USB_NETWORKING_AVAILABLE_MENUPOS="USB"
+
+USB_STORAGE_MODULES_VALUES="<STRING>"
+USB_STORAGE_MODULES_TEXT="Kernelmodules required for USB"
+USB_STORAGE_MODULES_MENUPOS="USB"
+
+USB_STORAGE_PARTITION_VALUES="<STRING>"
+USB_STORAGE_PARTITION_TEXT="USB storage device file"
+USB_STORAGE_PARTITION_MENUPOS="USB"
+
+USB_STORAGE_WAIT_VALUES="<STRING>"
+USB_STORAGE_WAIT_TEXT="Wait x seconds before mount USB storage"
+USB_STORAGE_WAIT_MENUPOS="USB"
+
+ASK_PW_ON_BOOT_VALUES="yes no"
+ASK_PW_ON_BOOT_TEXT="Alway ask altboot password on boot"
+ASK_PW_ON_BOOT_MENUPOS="Core"
+
+SD_DEVICE_VALUES="<STRING>"
+SD_DEVICE_TEXT="The device-file for the SD card"
+SD_DEVICE_MENUPOS="SD_MMC"
+
+SD_KERNEL_MODULE_VALUES="<STRING>"
+SD_KERNEL_MODULE_TEXT="Kernelmodule required for SD operation"
+SD_KERNEL_MODULE_MENUPOS="SD_MMC"
+
+SD_MOUNTPOINT_VALUES="<STRING>"
+SD_MOUNTPOINT_TEXT="Mointpoint for the SD card"
+SD_MOUNTPOINT_MENUPOS="SD_MMC"
index 3bffc2b..e09739c 100644 (file)
@@ -28,6 +28,12 @@ esac
 
 test -e "$ALTBOOT_CFG_FILE" && . "$ALTBOOT_CFG_FILE" || echo "WARNING: No $ALTBOOT_CFG_FILE found! Check your installation of Altboot!" > "$OUT_TTY"
 
+if test -e "${ALTBOOT_CFG_FILE}.next-reboot"
+then
+       . "${ALTBOOT_CFG_FILE}.next-reboot"
+       rm "${ALTBOOT_CFG_FILE}.next-reboot"
+fi
+
 C_RED="\033[31m"
 C_YELLOW="\033[33m"
 C_BLUE="\033[34m"
@@ -66,7 +72,7 @@ show_menu() {
 
        
        m_entry=""
-       # Build "m_entry" for scripts in /etc/altboot-menu
+
        cd $1
 
        cnt=0 ; reset_pref "menu_filelist"
@@ -75,6 +81,8 @@ show_menu() {
                if ! test -d "$1/$file"
                then                    
                        M_TITLE="`$1/$file title`"
+                       FLAGS="`$1/$file flags`"
+                       
                        if ! test -z "$M_TITLE"
                        then
                                let cnt=$cnt+1
@@ -83,6 +91,7 @@ show_menu() {
                                #m_entry="`echo -e "$m_entry\n$cnt:$file\n"`"
                                
                                set_pref "menu_filelist" "$cnt" "$file"
+                               test -n "$FLAGS" && set_pref "menu_fileflags" "$cnt" "$FLAGS"
                                echo -e "\t\t[$cnt] $M_TITLE"                                   
                        fi
                        M_TITLE=""
@@ -101,9 +110,12 @@ show_menu() {
                                let cnt=$cnt+1
                                # Keep a list of existing "modules" together with an index number
                                # This sure is ugly, but Busybox sh doesn't do arrays....
-                               #m_entry="`echo -e "$m_entry\n$cnt:$dir:DIR\n"`"
                                
                                set_pref "menu_filelist" "$cnt" "$dir:DIR"
+                               
+                               # Set noRemember flag for directories
+                               set_pref "menu_fileflags" "$cnt" "noRemember"                           
+                                               
                                echo -e "\t\t[$cnt] $M_TITLE"                                   
 
                                OLD_PWD="$PWD"
@@ -113,15 +125,16 @@ show_menu() {
                                        if ! test -d "$1/$dir/$file"
                                        then                    
                                                M_TITLE="`$1/$dir/$file title`"
+                                               FLAGS="`$1/$dir/$file flags`"
+                                               
                                                if ! test -z "$M_TITLE"
                                                then
                                                        let cnt=$cnt+1
                                                        # Keep a list of existing "modules" together with an index number
                                                        # This sure is ugly, but Busybox sh doesn't do arrays....
-                                                       #m_entry="`echo -e "$m_entry\n$cnt:$dir/$file\n"`"
                                                        
                                                        set_pref "menu_filelist" "$cnt" "$dir/$file"
-                                                       #echo -e "\t\t[$cnt] $M_TITLE"                                  
+                                                       test -n "$FLAGS" && set_pref "menu_fileflags" "$cnt" "$FLAGS"                           
                                                fi
                                                M_TITLE=""
                                        fi
@@ -133,9 +146,11 @@ show_menu() {
                fi
        done
 
-       #echo_pref "menu_filelist"
        echo ""
        
+#      export_pref "$menu_filelist" /tmp/menu_filelist.cache
+#      export_pref "$menu_fileflags" /tmp/menu_fileflags.cache
+       
 }
 
 # This function is used to display the content of directories below
@@ -167,6 +182,33 @@ show_sub_menu() {
        
 }
 
+get_kbd_ints(){
+       if ( uname -r | grep -q ^2.6 )
+       then                            
+               if test -z "$KBD_INT"
+               then            
+                       # find out how the keyboard is called
+                       for kbd in Spitzkbd corgikbd locomokbd tosakbd
+                       do
+                               if ( cat /proc/interrupts | grep -q "$kbd" )
+                               then
+                                       debug_echo "run_timer(): Using [$kbd] as keyboard interrupt"
+                                       KBD_INT="$kbd"  
+                                       break                           
+                               fi
+                       done                            
+               fi
+               key_ints="`cat /proc/interrupts | grep "$KBD_INT"`"
+               #debug_echo "run_timer(): key_ints = [$key_ints]"
+       else
+               KBD_INT="$kbd"
+               debug_echo "\nrun_timer(): Using [keyboard] as keyboard interrupt in kernel-2.4 mode"
+               key_ints="`cat /proc/interrupts | grep keyboard | awk '{print $2}'`"
+       fi
+       
+       test -z "$KBD_INT" && debug_echo "Couldn't read keyboard ints!" 
+}
+
 # Shows the timer and sets $launch_altboot to yes if a keypress was detected
 run_timer() {
        if test "$TIMEOUT" != 0
@@ -174,15 +216,10 @@ run_timer() {
                        
                mount -t proc proc /proc >/dev/null 2>&1
                
-               case "`uname -r`" in
-               2.4*)   key_ints="`cat /proc/interrupts | grep keyboard | awk '{print $2}'`";;
-               2.6*)   key_ints="`cat /proc/interrupts | grep Spitzkbd`"
-                       test -z "$key_ints" && key_ints="`cat /proc/interrupts | grep -i corgikbd`"
-                       test -z "$key_ints" && key_ints="`cat /proc/interrupts | grep -i locomokbd`"
-                       test -z "$key_ints" && key_ints="`cat /proc/interrupts | grep -i tosakbd`";;    
-               esac            
-       
-               test -z "$key_ints" && debug_echo "Couldn't read keyboard ints!"
+               get_kbd_ints                    
+               kbd_ints_old="$key_ints"                                
+               
+               #debug_echo "run_timer() old:`echo $key_ints | md5sum`"
                
                stty -echo  <"$OUT_TTY" >"$OUT_TTY" 2>&1
                echo -en "\n\nPlease press any key to launch altboot." > "$OUT_TTY"
@@ -193,15 +230,11 @@ run_timer() {
                while test "$cnt" != "$TIMEOUT"
                do              
                        sleep 1
-                       case "`uname -r`" in
-                       2.4*)   key_ints_now="`cat /proc/interrupts | grep keyboard | awk '{print $2}'`";;
-                       2.6*)   key_ints_now="`cat /proc/interrupts | grep Spitzkbd`"
-                               test -z "$key_ints_now" && key_ints_now="`cat /proc/interrupts | grep -i corgikbd`"
-                               test -z "$key_ints_now" && key_ints_now="`cat /proc/interrupts | grep -i locomokbd`"
-                               test -z "$key_ints_now" && key_ints_now="`cat /proc/interrupts | grep -i tosakbd`";;    
-                       esac            
                        
-                       if test "$key_ints_now" != "$key_ints" -o -z "$key_ints_now"
+                       get_kbd_ints                    
+                       kbd_ints_new="$key_ints"                                
+
+                       if test "$kbd_ints_new" != "$kbd_ints_old" -o -z "$kbd_ints_new"
                        then                            
                                launch_altboot=yes                              
                                stty echo <"$OUT_TTY" >"$OUT_TTY" 2>&1
@@ -223,6 +256,26 @@ run_timer() {
        fi
 } 
 
+# $1 = ID
+parse_module_flags() {
+       if test -n "$1"
+       then            
+               # Each module can set "flags" to influence handling of the module
+               get_pref "menu_fileflags" "$1" flags
+               
+               test -n "$flags" && debug_echo "parse_module_flags(): [$1] has flags [$flags]"
+               
+               for flag in $flags
+               do
+                       case "$flag" in
+                       noRemember)     REMEMBER_LAST_SELECTION=no;;
+                       esac
+               done
+       else 
+               debug_echo "parse_module_flags(): Empty \$1"
+       fi
+}
+
 # This function launches the selected menu item / script
 # $1: Directory containing the scripts for the menu-items
 launch_selection() {
@@ -235,8 +288,8 @@ launch_selection() {
                type="`echo "$file_" | sed -n "s/\(.*\)\:\(.*\)/\2/p"`"
                file="`echo "$file_" | sed -n "s/\(.*\)\:\(.*\)/\1/p"`"
                test -z "$file" && file="$file_"
-               
-               #echo "[$file_]: [$type] / [$file] ($junk)"
+                               
+               #echo "[$file_]: [$type] : [$flags] / [$file] ($junk)"
                
                # The selected menu-item points to a directory
                if test "$type" = DIR
@@ -291,26 +344,30 @@ wait_for_input() {
                
                # This filters other chars the user may have used
                
-               #echo "junk: [$junk]"
-               junk="`echo "$junk" | sed "s/[a-zA-Z]//g"`"
-               #echo "junk: [$junk]"
+               junk="`echo "$junk" | sed "s/[a-zA-Z]//g"`"     
                                
                if test "$junk" -lt "$cnt" -o "$junk" -eq "$cnt" 
-               then
-                       if test ! -z "$junk"
+               then                    
+                       if test ! -z "$junk" 
                        then
-                               # Don't remount rw if the drive is already mounted rw
-                               # Only helpful for testing / debugging
-                               if test "`mount|sed -n "/\/dev\/root/s/.*(\(.*\))/\1/p"`" != "rw"
-                               then                                    
-                                       mount -o remount,rw / >/dev/null 2>&1
-                                       echo "$junk" > /etc/altboot.conf
-                                       mount -o remount,ro / >/dev/null 2>&1   
-                               else
-                                       echo "$junk" > /etc/altboot.conf
+                               parse_module_flags "$junk"                              
+       
+                               if test "$REMEMBER_LAST_SELECTION" != no
+                               then                                                            
+                                       # Don't remount rw if the drive is already mounted rw
+                                       # Only helpful for testing / debugging
+                                       if test "`mount|sed -n "/\/dev\/root/s/.*(\(.*\))/\1/p"`" != "rw" 
+                                       then                                    
+                                               mount -o remount,rw / >/dev/null 2>&1
+                                               echo "$junk" > /etc/altboot.conf
+                                               mount -o remount,ro / >/dev/null 2>&1   
+                                       else
+                                               echo "$junk" > /etc/altboot.conf
+                                       fi
                                fi
                        else
                                junk="$last_selection"
+                               parse_module_flags "$junk"                              
                                break
                        fi
                        break
@@ -367,7 +424,7 @@ else
                
        echo "" >"$OUT_TTY"
        
-       
+       # launch_altboot is set to "yes" by run_timer when the user presses the button during the timeout
        if test "$launch_altboot" != yes
        then
                # last_selection is the previously selected menu item by the user
@@ -380,7 +437,6 @@ else
                show_menu /etc/altboot-menu >/dev/null
                junk="$last_selection"
                launch_selection /etc/altboot-menu >"$OUT_TTY"
-
        fi
 
        # Anything after this point will never be reached if $launch_altboot != yes