#!/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' } # Get the Open Firmware path for a device. Requires non-devfs syntax. map_of_path() { # TODO: look for shorter name using OF aliases? chroot /target ofpath "$1" || return 1 } 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 label kernel initrd params; do IFS="$OLDIFS" info "linux-boot-probed:" \ "$rootpart:$bootpart:$label:$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 [ -z "$label" ]; then label="$title" fi # Prepend the last part of the partition name to the label, # for uniqueness and (I hope) clarity, given that we don't # have a way to display a useful description in yaboot. label="${mappedbootpart##*/}-$label" if echo "$kernel" | grep -q '^/boot/' && \ [ "$mappedbootpart" != "$mappedpartition" ]; then # separate /boot partition kernel="${kernel#/boot}" initrd="${initrd#/boot}" fi writeimages <