initramfs-module-bootmenu: Interactive boot location selection for initramfs-uniboot.
authorPaul Sokolovsky <pmiscml@gmail.com>
Thu, 22 Nov 2007 17:34:24 +0000 (17:34 +0000)
committerPaul Sokolovsky <pmiscml@gmail.com>
Thu, 22 Nov 2007 17:34:24 +0000 (17:34 +0000)
* For now, supports booting from ext2/ext3 partitions and from ext2/ext3 loopback
images placed on vfat partition.

packages/initrdscripts/files/30-bootmenu.sh [new file with mode: 0644]
packages/initrdscripts/initramfs-module-bootmenu_1.0.bb [new file with mode: 0644]

diff --git a/packages/initrdscripts/files/30-bootmenu.sh b/packages/initrdscripts/files/30-bootmenu.sh
new file mode 100644 (file)
index 0000000..5b3e778
--- /dev/null
@@ -0,0 +1,154 @@
+# If root is explicitly specified, skip interactive selection
+if [ -z "$ROOT_DEVICE" ]; then
+##############################
+
+E="\033["
+MOUNTLOC="tmp"
+LOOP_IMG_MASK='*.img'
+
+if ! (echo " " | read -n1 foo) >/dev/null 2>&1; then
+    echo "'read' command lacks -n switch support, aborting" 
+    exit 1
+fi
+
+mkdir -p $MOUNTLOC
+
+list=""
+
+add_menu_item()
+{
+    if [ -n "$list" ]; then
+       list="$list\n"
+    fi
+       
+    list="$list$1"
+}
+
+show_menu() {
+    echo -e -n "${E}3;0H"
+    cnt=0
+    echo -e $list | \
+    while read l; do
+        if [ $cnt == $num ]; then
+           echo -e -n "${E}1m"
+       fi
+        echo -e "$cnt: $l${E}0m"
+       cnt=$((cnt + 1))
+    done
+}
+
+get_menu_selection()
+{
+    cnt=0
+    sel=`echo -e $list | \
+    while read l; do
+    if [ $cnt == $num ]; then
+           echo $l
+           break
+       fi
+       cnt=$((cnt + 1))
+    done`
+}
+
+get_partition_type()
+{
+    fstype=`mount -f --guess-fstype /dev/$dev $MOUNTLOC`
+}
+
+scan_for_loopimgs()
+{
+# Scan a device for loopback images, add to the list if found
+       mount /dev/$dev $MOUNTLOC
+       p=$PWD
+       cd $MOUNTLOC
+       for img in `ls -1 $LOOP_IMG_MASK 2>/dev/null`; do
+           add_menu_item "$dev/$img (loop img on vfat)"
+       done
+       cd $p
+       umount $MOUNTLOC
+}
+
+# Scan all available device/partitions
+while read maj min nblk dev; do
+    if [ -z "$maj" -o "$maj" == "major" ]; then
+       continue;
+    fi
+
+    get_partition_type
+    if [ "$fstype" != "ext2" -a "$fstype" != "ext3" -a "$fstype" != "vfat" ]; then
+#      continue
+       true
+    fi
+    
+    if [ "$fstype" == "vfat" ]; then
+       scan_for_loopimgs
+       continue
+    fi
+    
+    add_menu_item "$dev ($fstype)"
+done < /proc/partitions
+
+add_menu_item "NFS (nfsroot=192.168.2.200:/nfs/image)"
+
+total=`echo -e $list | wc -l`
+num=0
+
+# Draw UI
+stty -echo
+echo -e -n "${E}2J"
+echo -e -n "${E}0;0H"
+echo "Select boot image:"
+
+# Main loop
+show_menu
+while read -n1 i; do
+    case "$i" in
+       "A")
+           num=$((num - 1))
+           if [ $num -lt 0 ]; then
+               num=$(($total - 1))
+           fi
+       ;;
+       ["B"-"Z"])
+           num=$((num + 1))
+           if [ $num -ge $total ]; then
+               num=0
+           fi
+       ;;
+       "q")
+           exec sh
+       ;;
+       "")
+           break
+       ;;
+    esac
+    show_menu
+#    echo "*$esc$i"
+done
+
+stty echo
+
+# Process results of user selection, prepare input arguments
+# for boot modules
+
+get_menu_selection
+echo Selected: $sel
+
+dev=`expr "$sel" : '\([^ /]*\)'`
+path=`expr "$sel" : '[^/]*\([^ ]*\).*'`
+
+if [ "$dev" == "NFS" ]; then
+    ROOT_DEVICE="/dev/nfs"
+    CMDLINE="$CMDLINE nfsroot=192.168.2.200:/nfs/image"
+elif [ -n "$path" ]; then
+    ROOT_DEVICE="/dev/loop"
+    CMDLINE="looproot=/dev/$dev:$path"
+else
+    ROOT_DEVICE="/dev/$dev"
+fi
+
+echo ROOT_DEVICE=$ROOT_DEVICE
+echo CMDLINE=$CMDLINE
+
+##############################
+fi
diff --git a/packages/initrdscripts/initramfs-module-bootmenu_1.0.bb b/packages/initrdscripts/initramfs-module-bootmenu_1.0.bb
new file mode 100644 (file)
index 0000000..3fc8647
--- /dev/null
@@ -0,0 +1,11 @@
+SRC_URI = "file://30-bootmenu.sh"
+PR = "r1"
+RDEPENDS = "util-linux-mount initramfs-uniboot initramfs-module-block initramfs-module-loop"
+DESCRIPTION = "An initramfs module with UI for selection of boot device."
+
+do_install() {
+       install -d ${D}/initrd.d
+        install -m 0755 ${WORKDIR}/30-bootmenu.sh ${D}/initrd.d/
+}
+
+FILES_${PN} += " /initrd.d/* "