#!/bin/sh set -e . /usr/share/debconf/confmodule log() { logger -t yaboot-installer "$@" } error() { log "error: $@" } info() { log "info: $@" } debug() { log "debug: $@" } writefile () { cat >>"$1" || die yaboot-installer/conferr "Error writing $2" } findfs () { mount | grep "on /target${1%/} " | tail -n1 | cut -d' ' -f1 } partitions_with_flag () { /usr/lib/partconf/find-partitions --colons --flag "$1" 2>/dev/null || true } db_capb backup db_progress START 0 6 yaboot-installer/progress die() { template="$1" shift error "$@" db_input critical "$template" || [ $? -eq 30 ] db_go || true db_progress STOP exit 1 } ARCH="$(archdetect)" info "architecture: $ARCH" # Install yaboot in /target db_progress INFO yaboot-installer/apt-install PACKAGES=yaboot if [ "$ARCH" = powerpc/powermac_newworld ]; then PACKAGES="$PACKAGES hfsutils" fi if ! apt-install $PACKAGES; then info "Calling 'apt-install $PACKAGES' failed" # Hm, unable to install yaboot into /target/, what should we do? db_input critical yaboot-installer/apt-install-failed || [ $? -eq 30 ] if ! db_go; then db_progress STOP exit 10 # back up to menu fi db_get yaboot-installer/apt-install-failed if [ "$RET" != true ]; then db_progress STOP exit 1 fi fi # Find the boot partition db_progress STEP 1 db_progress INFO yaboot-installer/part # Telling parted to create an Apple_Bootstrap partition doesn't work as well # as we might like: parted's probe function isn't intelligent enough to know # about this, and reports the partition as containing whatever filesystem # was there beforehand. # # As a workaround, we only check for partitions with the boot flag set, and # don't bother checking the filesystem. However, this means that we *must* # ask the user to confirm the bootstrap partition, otherwise we might # mistakenly overwrite some other partition that happened to be flagged as # bootable. PARTITIONS= DEFAULT= bootdev_priority=critical if [ "$ARCH" = powerpc/powermac_newworld ] && \ db_get partman-newworld/boot_partitions && [ "$RET" ]; then OLDIFS="$IFS" IFS=, for part in $RET; do IFS="$OLDIFS" mappart="$(mapdevfs "$part")" if [ -z "$PARTITIONS" ]; then DEFAULT="$mappart" PARTITIONS="$mappart" else PARTITIONS="$PARTITIONS, $mappart" fi IFS=, done IFS="$OLDIFS" info "partman-supplied bootstrap partitions: $PARTITIONS" info "partman-supplied default bootstrap partition: $DEFAULT" if [ "$PARTITIONS" ] && [ "$DEFAULT" = "$PARTITIONS" ]; then # We have explicit information from partman-newworld that only one # bootstrap partition is available, so it's safe to bypass this # question. bootdev_priority=medium fi fi if [ -z "$PARTITIONS" ]; then case $ARCH in powerpc/powermac_newworld) PARTED_FLAGS='boot' ;; powerpc/chrp|powerpc/chrp_rs6k|powerpc/chrp_ibm|powerpc/cell) PARTED_FLAGS='prep prep-boot' ;; powerpc/chrp_pegasos) PARTED_FLAGS= ;; *) error 'unknown subarchitecture; allowing any bootable partition' PARTED_FLAGS='boot' ;; esac for flag in $PARTED_FLAGS; do for part in $(partitions_with_flag "$flag" | cut -d: -f1); do mappart="$(mapdevfs "$part")" if [ -z "$PARTITIONS" ]; then DEFAULT="$mappart" PARTITIONS="$mappart" else PARTITIONS="$PARTITIONS, $mappart" fi done done if [ "$PARTED_FLAGS" ]; then info "guessed bootstrap partitions: $PARTITIONS" info "guessed default bootstrap partition: $DEFAULT" fi fi if [ "$PARTED_FLAGS" ] && [ -z "$PARTITIONS" ]; then # error: no viable boot partitions found; fall over die yaboot-installer/nopart 'No bootstrap partitions found' fi if [ "$PARTITIONS" ]; then db_subst yaboot-installer/bootdev DEVICES "$PARTITIONS" db_set yaboot-installer/bootdev "$DEFAULT" db_input "$bootdev_priority" yaboot-installer/bootdev || [ $? -eq 30 ] if ! db_go; then db_progress STOP exit 10 # back up to menu fi db_get yaboot-installer/bootdev if [ "$RET" = false ]; then die yaboot-installer/nopart 'No bootstrap partition selected (?)' fi # already devfs-mapped boot="$RET" else # no bootstrap partition on Pegasos boot= fi # Find the root partition db_progress STEP 1 db_progress INFO yaboot-installer/root rootdev="$(findfs /)" [ "$rootdev" ] || die yaboot-installer/noroot 'No root partition found' slashbootdev="$(findfs /boot)" [ "$slashbootdev" ] || slashbootdev="$rootdev" mountvirtfs () { fstype="$1" path="$2" if grep -q "[[:space:]]$fstype\$" /proc/filesystems && \ ! grep -q "^[^ ]\+ \+$path " /proc/mounts; then mkdir -p "$path" || \ die yaboot-installer/mounterr "Error creating $path" mount -t "$fstype" "$fstype" "$path" || \ die yaboot-installer/mounterr "Error mounting $path" trap "umount $path" HUP INT QUIT PIPE TERM EXIT fi } # mkofboot needs proc in /target mountvirtfs proc /target/proc # ofpath needs sysfs in /target for 2.6 mountvirtfs sysfs /target/sys # Probe for other OSes. db_progress STEP 1 db_progress INFO yaboot-installer/os-probing os-prober >/tmp/os-probed || true if [ -s /tmp/os-probed ]; then # Other operating systems are installed, so use a longer timeout. timeout=100 else timeout=50 fi extraglobals=/tmp/yaboot.conf.extraglobals rm -f "$extraglobals" extraimages=/tmp/yaboot.conf.extraimages rm -f "$extraimages" writeglobals() { writefile "$extraglobals" 'extra global settings' } writeimages() { writefile "$extraimages" 'extra image records' } map_of_pathname() { # ofpathname does not work correctly on YDL PowerStation Maple board, even # though it is a chrp_ibm platform, but ofpath does. grep -q ': Maple' /proc/cpuinfo && { chroot /target ofpath "$1" || return 1 return } # ofpathname won't handle partition numbers, so we do here. MAP_DEVICE=${1%[0-9]} MAP_PARTNUM=${1#$MAP_DEVICE} MAP_OFPATH="`chroot /target ofpathname "$MAP_DEVICE"`" [ $? -ne 0 ] && return 1 echo "$MAP_OFPATH${MAP_PARTNUM:+:$MAP_PARTNUM}" } # Get the Open Firmware path for a device. Requires non-devfs syntax. map_of_path() { # TODO: look for shorter name using OF aliases? case $ARCH in powerpc/chrp|powerpc/chrp_rs6k|powerpc/chrp_ibm|powerpc/cell) map_of_pathname "$1" || return 1 ;; *) chroot /target ofpath "$1" || return 1 ;; esac } # Get a symlink which always points to the correct block device. # If it does not exist, give the unix block device name back. devsymlink() { [ "$2" != "nobyid" ] && BYID="/dev/disk/by-id/scsi* /dev/disk/by-id/*" for SYMLINK in $BYID /dev/disk/by-uuid/* /dev/disk/by-label/*; do [ "`readlink -f "$SYMLINK"`" = "$1" ] && { echo $SYMLINK return } done echo $1 } # Get UUID= or LABEL= for the given unix partition block device. # If it could not be determined, give the unix partition block device back. uuidlabel() { echo `devsymlink "$1" nobyid` \ | sed -e "s,/dev/disk/by-uuid/,UUID=," \ -e "s,/dev/disk/by-label/,LABEL=," } OLDIFS="$IFS" IFS=: # Note that this creates a subshell, so variables set inside this loop won't # persist outside it. cat /tmp/os-probed | while read partition title label loadertype; do IFS="$OLDIFS" info "probed: $partition:$title:$label:$loadertype" mappedpartition="$(mapdevfs "$partition")" debug "mapped: $mappedpartition" # You only get the first of each non-Linux OS here, as that's all # yaboot supports without painful hacking. Sorry. case $loadertype in linux) IFS=: linux-boot-prober "$partition" | while read \ rootpart bootpart oldlabel kernel initrd params; do IFS="$OLDIFS" info "linux-boot-probed:" \ "$rootpart:$bootpart:$oldlabel:$kernel:$initrd:$params" ofrootpart="$(map_of_path "$mappedpartition")" || continue debug "OF root partition: $ofrootpart" # bootpart may or may not be in devfs syntax. mappedbootpart="$(mapdevfs "$bootpart")" || \ mappedbootpart="$bootpart" debug "mapped boot partition: $mappedbootpart" ofbootpart="$(map_of_path "$mappedbootpart")" || continue debug "OF boot partition: $ofbootpart" if echo "$kernel" | grep -q '^/boot/' && \ [ "$mappedbootpart" != "$mappedpartition" ]; then # separate /boot partition kernel="${kernel#/boot}" initrd="${initrd#/boot}" fi # remove root parameter from params params="`echo $params | sed -e "s,root=[^[:space:]]*,,"`" writeimages <