]> git.ozlabs.org Git - yaboot.git/blobdiff - ybin/yabootconfig
ybin userland interface for specifying bootonce
[yaboot.git] / ybin / yabootconfig
index e94c4efc5796dbcc684ea40913eb2798342d8483..04a513c1876394bd4cb625e70dfec2e287a6e22d 100755 (executable)
@@ -3,7 +3,7 @@
 ###############################################################################
 ##
 ## yabootconfig generates a simple /etc/yaboot.conf
-## Copyright (C) 2001 Ethan Benson
+## Copyright (C) 2001, 2002, 2003 Ethan Benson
 ##
 ## This program is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License
@@ -27,15 +27,23 @@ if [ -n "$PATH_PREFIX" ] ; then
     PATH="${PATH}:${PATH_PREFIX}/sbin:${PATH_PREFIX}/bin:${PATH_PREFIX}/usr/sbin:${PATH_PREFIX}/usr/bin:${PATH_PREFIX}/usr/local/sbin:${PATH_PREFIX}/usr/local/bin"
 fi
 PRG="${0##*/}"
-VERSION=1.0.3
+VERSION=1.0.8
 CHROOT=/
 ## $CONFIG is relative to $CHROOT
 CONFIG=etc/yaboot.conf
 NOINSTALL=0
 QUIET=0
+DEBUG=0
 SIGINT="$PRG: Interrupt caught ... exiting"
 export LC_COLLATE=C
 
+## avoid older versions of ofpath shipped in debian boot-floppies etc.
+if [ -x "${PATH_PREFIX}/usr/sbin/ofpath" ] ; then
+    OFPATH="${PATH_PREFIX}/usr/sbin/ofpath"
+else
+    OFPATH=ofpath
+fi
+
 ## catch signals, clean up temporary file
 trap "cleanup" 0
 trap "exit 129" 1
@@ -61,7 +69,7 @@ fi
 
 ## make fake `id' if its missing, outputs 0 since if its missing we
 ## are probably running on boot floppies and thus are root.
-if (command -v id > /dev/null 2>&1) ; then 
+if (command -v id > /dev/null 2>&1) ; then
     true
 else
     id()
@@ -77,7 +85,7 @@ echo \
 "$PRG $VERSION
 Written by Ethan Benson
 
-Copyright (C) 2001 Ethan Benson
+Copyright (C) 2001, 2002, 2003 Ethan Benson
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 }
@@ -101,6 +109,12 @@ Generate a working /etc/yaboot.conf.
   -V, --version              output version information and exit"
 }
 
+debug()
+{
+    [ "$DEBUG" = 0 ] && return 0
+    $PRINTF 1>&2 "$PRG: DEBUG: $1"
+}
+
 confirm()
 {
     $PRINTF \
@@ -153,6 +167,7 @@ ckmacfdisk()
        echo 1>&2 "$PRG: `command -v $FDISK`: Permission denied"
        return 1
     fi
+    debug "mac-fdisk is: $FDISK\n"
     return 0
 }
 
@@ -173,6 +188,7 @@ ckfdisk()
        echo 1>&2 "$PRG: `command -v $FDISK`: Permission denied"
        return 1
     fi
+    debug "fdisk is: $FDISK\n"
     return 0
 }
 
@@ -184,12 +200,16 @@ findbootblock()
        ckmacfdisk || return 1
        if [ "$FDISK" = pdisk ] ; then
            ## handle braindamaged pdisk
+           debug "dealing with pdisk deficiency...\n"
            BOOT="$(v=`$FDISK -l "$DISK" 2>/dev/null | grep '\<Apple_Bootstrap\>'` ; echo ${v%%:*})"
+           debug "BOOT before fixup: $BOOT\n"
            if [ -n "$BOOT" ] ; then
                BOOT="${DISK}${BOOT}"
            fi
+           debug "BOOT after fixup: $BOOT\n"
        else
            BOOT="$(v=`$FDISK -l "$DISK" 2>/dev/null | grep '\<Apple_Bootstrap\>'` ; echo ${v%%[ ]*})"
+           debug "BOOT=$BOOT\n"
        fi
        if [ -z "$BOOT" ] ; then
            echo 1>&2 "$PRG: Unable to locate bootstrap partition on $DISK..."
@@ -199,6 +219,7 @@ findbootblock()
     else
        ckfdisk || return 1
        BOOT="$(v=`$FDISK -l "$DISK" 2>/dev/null | grep '\<PPC PReP Boot\>'` ; echo ${v%%[ ]*})"
+       debug "BOOT=$BOOT\n"
        if [ -z "$BOOT" ] ; then
            echo 1>&2 "$PRG: Unable to locate bootstrap partition on $DISK..."
            echo 1>&2 "$PRG: You must create an 800K type: 0x41 PPC PReP Boot partition to make the disk bootable"
@@ -249,7 +270,7 @@ cleanup()
 
 if [ $# != 0 ] ; then
     while true ; do
-        case "$1" in 
+        case "$1" in
             -V|--version)
                 version
                 exit 0
@@ -306,6 +327,10 @@ if [ $# != 0 ] ; then
                NOINSTALL=1
                shift 1
                ;;
+           --debug)
+               DEBUG=1
+               shift 1
+               ;;
             "")
                 break
                 ;;
@@ -357,13 +382,29 @@ fi
 ## find / device
 if [ -z "$ROOT" ] ; then
     ## IMPORTANT! that last substitution is [<space><tab>] thats all ash will grok
-    ROOT="$(v=`grep '[[:blank:]]/[[:blank:]]' ${CHROOT}etc/fstab` ; echo ${v%%[        ]*})"
+    ROOT="$(v=`grep '^[^#].*[[:blank:]]/[[:blank:]]' ${CHROOT}etc/fstab` ; echo ${v%%[         ]*})"
+    debug "ROOT=$ROOT\n"
     if [ -z "$ROOT" ] ; then
        echo 1>&2 "$PRG: Could not determine root partition, aborting..."
        exit 1
     fi
 fi
 
+## dereference label or uuid if necessary
+case "$ROOT" in
+    LABEL=*|UUID=*)
+       if ! (command -v findfs > /dev/null 2>&1) ; then
+           echo 1>&2 "$PRG: Unable to locate findfs, aborting..."
+           exit 1
+       fi
+       ROOT="$(findfs "$ROOT")"
+       if [ -z "$ROOT" -o $? != 0 ] ; then
+           echo 1>&2 "$PRG: Could not determine root partition, aborting..."
+           exit 1
+       fi
+       ;;
+esac
+
 ## make sure root device exists
 if [ ! -e "$ROOT" ] ; then
     echo 1>&2 "$PRG: $ROOT: No such file or directory"
@@ -411,24 +452,52 @@ if [ "$QUIET" = 0 ] ; then
     confirm || exit 2
 fi
 
+READLINKKV=`readlink /usr/src/linux`
 ## find the kernel in the usual places and (if not --quiet) ask the
 ## user if we cannot find one.
-if [ -f "${CHROOT}vmlinux" ] ; then
-    KERNEL="${CHROOT}vmlinux"
-elif [ -f "${CHROOT}boot/vmlinux" ] ; then
-    KERNEL="${CHROOT}boot/vmlinux"
-elif [ -f "${CHROOT}boot/vmlinux-`uname -r`" ] ; then
-    KERNEL="${CHROOT}boot/vmlinux-`uname -r`"
-elif [ -f "${CHROOT}vmlinux-`uname -r`" ] ; then
-    KERNEL="${CHROOT}vmlinux-`uname -r`"
-elif [ "$QUIET" = 0 ] ; then
-    echo 1>&2 "$PRG: Cannot find a kernel, please locate one"
+for k in "vmlinux" "vmlinux-`uname -r`" "vmlinux-`uname -r`" "$READLINKKV" ; do
+       if [ -f "${CHROOT}${k}" ] ; then
+           KERNEL="${CHROOT}${k}"
+           break;
+       elif [ -f "${CHROOT}boot/${k}" ] ; then
+           KERNEL="${CHROOT}boot/${k}"
+           break;
+       fi
+done
+
+for i in "initrd" "initrd-`uname -r`" "`echo $READLINKKV | cut -f1 -d- --complement`" ; do
+    for b in "" "boot/" ; do
+           if [ -f "${CHROOT}${b}${i}" ] ; then
+               INITRD="${CHROOT}${b}${i}"
+           elif [ -f "${CHROOT}${b}${i}.img" ] ; then
+               INITRD="${CHROOT}${b}${i}.img"
+           elif [ -f "${CHROOT}${b}${i}.gz" ] ; then
+               INITRD="${CHROOT}${b}${i}.gz"
+           fi
+    done
+done
+
+if [ ! -f "$KERNEL" ] && [ ${QUIET} == 0 ] ; then
+    echo 1>&2 "$PRG: Cannot find a kernel, please provide one"
     while true ; do
-       $PRINTF 1>&2 "Enter path to a kernel image: "
+       if [ "$CHROOT" == "/" ] ; then
+               $PRINTF 1>&2 "Enter path to a kernel image: "
+       else
+               $PRINTF 1>&2 "Enter path to a kernel image (not including chroot): "
+       fi
        read KERN
+
+       ### Remove leading /
+       case "${KERN}" in
+       /*)     KERN=${CHROOT}${KERN:1} ;;
+       *)      KERN=${CHROOT}${KERN} ;;
+       esac
+
        if [ -f "$KERN" ] ; then
            KERNEL="$KERN"
            break
+       elif [ ${KERN} == ${CHROOT} ] ; then
+           echo 1>&2 "$PRG: You must provide a valid kernel"
        elif [ ! -e "$KERN" ] ; then
            echo 1>&2 "$PRG: $KERN: No such file or directory"
        elif [ -d "$KERN" ] ; then
@@ -437,11 +506,43 @@ elif [ "$QUIET" = 0 ] ; then
            echo 1>&2 "$PRG: $KERN: Is not a regular file"
        fi
     done
-else
+    while true ; do
+       if [ "$CHROOT" == "/" ] ; then
+               $PRINTF 1>&2 "Enter path to an initrd image (hit Enter for none): "
+       else
+               $PRINTF 1>&2 "Enter path to an initrd image (hit Enter for none, don't include the chroot): "
+       fi
+       read IRD
+
+       if [ "$IRD" == "" ]; then
+           break
+       fi
+       
+       ### Remove leading /
+       case "${IRD}" in
+       /*)     IRD=${CHROOT}${IRD:1} ;;
+       *)      IRD=${CHROOT}${IRD} ;;
+       esac
+
+       if [ -f "$IRD" ] ; then
+           INITRD="$IRD"
+           break
+       elif [ ! -e "$IRD" ] ; then
+           echo 1>&2 "$PRG: $IRD: No such file or directory"
+       elif [ -d "$IRD" ] ; then
+           echo 1>&2 "$PRG: $IRD: Is a directory"
+       else
+           echo 1>&2 "$PRG: $IRD: Is not a regular file"
+       fi
+    done
+elif [ ! -f "$KERNEL" ] ; then
     echo 1>&2 "$PRG: Cannot find a kernel, aborting..."
     exit 1
 fi
 
+debug "KERNEL=$KERNEL\n"
+debug "INITRD=$INITRD\n"
+
 ## get partition number the kernel lives on, and the OF device= name
 ## of the whole disk.
 KERNDEV="$(v=`df "$KERNEL" 2> /dev/null | grep ^/dev/` ; echo ${v%%[ ]*})"
@@ -455,14 +556,47 @@ else
     KERNELDISK="${KERNDEV%%[0-9]*}"
 fi
 
+if [ -n "$INITRD" ] ; then
+    ## get partition number the initrd lives on, and the OF device= name
+    ## of the whole disk.
+    IRDDEV="$(v=`df "$INITRD" 2> /dev/null | grep ^/dev/` ; echo ${v%%[ ]*})"
+    IRDDIR="$(v=`df "$INITRD" 2> /dev/null | grep ^/dev/` ; echo ${v##*[ ]})"
+    IRDLINKDEV="$(v=`df "${INITRD%/*}/" 2>/dev/null | grep ^/dev/` ; echo ${v%%[ ]*})"
+    IRDPARTITION="${KERNDEV##*[a-z]}"
+
+    if ckdevfs "$IRDDEV" ; then
+       INITRDDISK="${IRDDEV%/*}/disc"
+    else
+       INITRDDISK="${IRDDEV%%[0-9]*}"
+    fi
+fi
+
+debug "KERNEL=$KERNEL\nKERNDEV=$KERNDEV\nKERNDIR=$KERNDIR\nLINKDEV=$LINKDEV\nPARTITION=$PARTITION\nKERNELDISK=$KERNELDISK\n"
+
+if [ -n "$INITRD" ] ; then
+    debug "INITRD=$INITRD\nIRDDEV=$IRDDEV\nIRDDIR=$IRDDIR\nIRDLINKDEV=$IRDLINKDEV\nIRDPARTITION=$IRDPARTITION\nINITRDDISK=$INITRDDISK\n"
+fi
+
 ## sanity check
 for i in "$KERNDEV" "$KERNDIR" "$LINKDEV" "$PARTITION" "$KERNELDISK" ; do
     if [ -z "$i" ] ; then
        echo 1>&2 "$PRG: Could not determine necessary information, aborting..."
+       echo 1>&2 "$PRG: Are you using chroot $PRG instead of $PRG --chroot ?"
        exit 1
     fi
 done
 
+if [ -n "$INITRD" ] ; then
+    ## sanity check
+    for i in "$IRDDEV" "$IRDDIR" "$IRDLINKDEV" "$IRDPARTITION" "$INITRDDISK" ; do
+       if [ -z "$i" ] ; then
+           echo 1>&2 "$PRG: Could not determine necessary information, aborting..."
+           echo 1>&2 "$PRG: Are you using chroot $PRG instead of $PRG --chroot ?"
+           exit 1
+       fi
+    done
+fi
+
 ## check for cross device symlink
 if [ -L "$KERNEL" ] ; then
     if [ "$KERNDEV" != "$LINKDEV" ] ; then
@@ -475,20 +609,35 @@ if [ -L "$KERNEL" ] ; then
     fi
 fi
 
+if [ -n "$INITRD" ] ; then
+    ## initrd must be on same device as kernel.
+    if [ "$IRDDEV" != "$KERNDEV" -o "$IRDPARTITION" != "$IRDPARTITION" -o "$INITRDDISK" != "$KERNELDISK" ] ; then
+       echo 1>&2 "$PRG: Initrd image must be on same device as kernel image."
+       exit 1
+    fi
+
+    ## check for cross device symlink
+    if [ -L "$INITRD" ] ; then
+       if [ "$IRDDEV" != "$IRDLINKDEV" ] ; then
+           echo 1>&2 "$PRG: Warning: Cross device symlink $INITRD, using it's target instead"
+           INITRD="$(readlink -f "$INITRD" 2>/dev/null)"
+           if [ ! -f "$INITRD" ] ; then
+               echo 1>&2 "$PRG: Unable to canonicalize symlink's target.  Do not create cross device symlinks."
+               exit 1
+           fi
+       fi
+    fi
+fi
+
 ## only powermacs appear to need device=
 if (cat /proc/cpuinfo 2>/dev/null | grep -q pmac-generation 2> /dev/null) ; then
-    DEVICE="\ndevice=$(ofpath $KERNELDISK)"
+    DEVICE="\ndevice=$($OFPATH $KERNELDISK)"
     if [ $? != 0 ] ; then
        echo 1>&2 "$PRG: Unable to determine OpenFirmware device name to $KERNELDISK, aborting..."
        exit 1
     fi
 fi
 
-## IBM hardware needs fstype=raw for ybin
-if (cat /proc/cpuinfo 2>/dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
-    FSTYPE="\nfstype=raw"
-fi
-
 ## if there is a separate /boot partition we must strip off the /boot
 ## mountpoint or else yaboot will not find the kernel.
 if [ "$KERNDIR" != "$CHROOT" ] ; then
@@ -512,6 +661,31 @@ case "$IMAGE" in
     ;;
 esac
 
+if [ -n "$INITRD" ] ; then
+    ## if there is a separate /boot partition we must strip off the /boot
+    ## mountpoint or else yaboot will not find the kernel.
+    if [ "$IRDDIR" != "$CHROOT" ] ; then
+       INITRDIMG="${INITRD##*$IRDDIR}"
+    else
+       INITRDIMG="$INITRD"
+    fi
+
+    ## fix chrooted path
+    if [ "$CHROOT" != / ] ; then
+       INITRDIMG="${INITRDIMG##*$CHROOT}"
+    fi
+
+    ## fix relative path (caused by chroot path fix)
+    case "$INITRDIMG" in
+       /*)
+           true
+           ;;
+       *)
+           INITRDIMG="/${INITRDIMG}"
+           ;;
+    esac
+fi
+
 ## figure out if yaboot is installed in /usr/local or not
 if [ -f /usr/local/lib/yaboot/yaboot ] ; then
     INSTALL=/usr/local/lib/yaboot/yaboot
@@ -532,7 +706,7 @@ if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:}
        echo 1>&2 "$PRG: yaboot is not installed correctly"
        exit 1
     fi
-fi    
+fi
 
 ## check for properly (read debian) packaged yaboot.
 if [ -d ${CHROOT}usr/share/doc/yaboot/examples ] ; then
@@ -544,14 +718,28 @@ if [ -n "$KERNARGS" ] ; then
     APPEND="\tappend=\"${KERNARGS}\"\n"
 fi
 
+## avoid user confusion when they boot an installer with video=ofonly
+## (usually via a install-safe label) and then reboot and have the box
+## not boot properly again.
+if [ -z "$APPEND" ] ; then
+    if (grep -q '\<video=ofonly\>' /proc/cmdline 2> /dev/null) ; then
+       APPEND="\tappend=\"video=ofonly\"\n"
+    fi
+fi
+
+## generate initrd= lines
+if [ -n "$INITRDIMG" ] ; then
+    INITRDIMGS="\tinitrd=$INITRDIMG\n\tinitrd-size=8192\n"
+fi
+
 ## generate global section of yaboot.conf
 GLOBAL="## yaboot.conf generated by $PRG $VERSION
 ##
 ## run: \"man yaboot.conf\" for details. Do not make changes until you have!!
 ${HEADER}##
-## For a dual-boot menu, add one or more of: 
+## For a dual-boot menu, add one or more of:
 ## bsd=/dev/hdaX, macos=/dev/hdaY, macosx=/dev/hdaZ\n
-boot=${BOOT}${FSTYPE:-}${DEVICE:-}
+boot=${BOOT}${DEVICE:-}
 partition=$PARTITION
 root=$ROOT
 timeout=30
@@ -561,7 +749,7 @@ install=${INSTALL}${OFBOOT:-}\n"
 IMAGES="
 image=$IMAGE
 \tlabel=Linux
-\tread-only\n${APPEND:-}"
+\tread-only\n${APPEND:-}${INITRDIMGS:-}"
 
 ## safely create a tmp file then move it into place after we are sure
 ## it was written.