#!/bin/sh #- # Copyright (c) 2018 Rebecca Cran # Copyright (c) 2017 Nathan Whitehorn # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # BSDCFG_SHARE="/usr/share/bsdconfig" . $BSDCFG_SHARE/common.subr || exit 1 f_dprintf "%s: loading_includes..." "$0" f_include $BSDCFG_SHARE/dialog.subr : ${TMPDIR:="/tmp"} die() { echo $* exit 1 } dialog_uefi_entryname() { local prompt="Please enter a name for the new entry" local hline= local value="$*" local height width f_dialog_inputbox_size height width \ "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$prompt" "$value" "$hline" $DIALOG \ --title "$DIALOG_TITLE" \ --backtitle "$DIALOG_BACKTITLE" \ --hline "$hline" \ --ok-label "Ok" \ --no-cancel \ --inputbox "$prompt" \ $height $width "$value" \ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD } update_uefi_bootentry() { nentries=$(efibootmgr | grep -c "${EFI_LABEL_NAME}$") # No entries so directly create one and return if [ ${nentries} -eq 0 ]; then f_dprintf "Creating UEFI boot entry" efibootmgr --create --activate --label "$EFI_LABEL_NAME" --loader "${mntpt}/${FREEBSD_BOOTNAME}" > /dev/null return fi $DIALOG --backtitle "$OSNAME Installer" --title 'Boot Configuration' \ --yesno "There are multiple \"$OSNAME\" EFI boot entries. Would you like to remove them all and add a new one?" 0 0 if [ $? -eq $DIALOG_OK ]; then for entry in $(efibootmgr | awk "\$NF == \"$EFI_LABEL_NAME\" { sub(/.*Boot/,\"\", \$1); sub(/\*/,\"\", \$1); print \$1 }"); do efibootmgr -B -b ${entry} done efibootmgr --create --activate --label "$EFI_LABEL_NAME" --loader "${mntpt}/${FREEBSD_BOOTNAME}" > /dev/null return fi FREEBSD_BOOTLABEL=$(dialog_uefi_entryname "${EFI_LABEL_NAME}") [ $? -eq $DIALOG_CANCEL ] && exit 1 efibootmgr --create --activate --label "$FREEBSD_BOOTLABEL" --loader "${mntpt}/${FREEBSD_BOOTNAME}" > /dev/null } f_dialog_title "Boot Configuration" f_dialog_backtitle "$OSNAME Installer" if [ `uname -m` == powerpc ]; then platform=`sysctl -n hw.platform` if [ "$platform" == ps3 -o "$platform" == powernv ]; then rootpart=$(awk '{ if($2 == "/") printf("%s:%s\n", $3, $1); }' $PATH_FSTAB) kboot_conf=$BSDINSTALL_CHROOT/boot/etc/kboot.conf mkdir -p $BSDINSTALL_CHROOT/boot/etc/ echo default=$FREEBSD_BOOTLABEL > $kboot_conf echo $FREEBSD_BOOTLABEL=\'/kernel/kernel kernelname=/boot/kernel/kernel vfs.root.mountfrom=${rootpart}\' >> $kboot_conf fi fi # Update the ESP (EFI System Partition) with the new bootloader if we have an ESP if [ -n "$(awk '{if ($2=="/boot/efi") printf("%s\n",$1);}' $PATH_FSTAB)" ]; then case $(uname -m) in arm64) ARCHBOOTNAME=aa64 ;; amd64) ARCHBOOTNAME=x64 ;; riscv) ARCHBOOTNAME=riscv64 ;; # arm) ARCHBOOTNAME=arm ;; # No other support for arm install # i386) ARCHBOOTNAME=ia32 ;; # no support for this in i386 kernels, rare machines *) die "Unsupported arch $(uname -m) for UEFI install" esac if [ `sysctl -n machdep.efi_arch` == i386 ]; then ARCHBOOTNAME=ia32 file=loader_ia32.efi else file=loader.efi fi BOOTDIR="/efi/boot" BOOTNAME="${BOOTDIR}/boot${ARCHBOOTNAME}.efi" FREEBSD_BOOTDIR="/efi/freebsd" FREEBSD_BOOTNAME="${FREEBSD_BOOTDIR}/${file}" mntpt="$BSDINSTALL_CHROOT/boot/efi" f_dprintf "Installing ${file} onto ESP" mkdir -p "${mntpt}/${FREEBSD_BOOTDIR}" "${mntpt}/${BOOTDIR}" cp "$BSDINSTALL_CHROOT/boot/${file}" "${mntpt}/${FREEBSD_BOOTNAME}" # # UEFI defines a way to specifically select what to boot # (which we do via efibootmgr). However, if we booted from an ia32 # UEFI environment, we wouldn't have access to efirt. In addition, # virtual environments often times lack support for the NV variables # efibootmgr sets, and some UEFI implementations have features that # interfere with the setting of these variables. To combat that, we # install the default removable media boot file if it doesn't exist. # We don't install it all the time since that can interfere with other # installations on the drive (like rEFInd). # if [ ! -f "${mntpt}/${BOOTNAME}" ]; then cp "$BSDINSTALL_CHROOT/boot/${file}" "${mntpt}/${BOOTNAME}" fi if [ "$BSDINSTALL_CONFIGCURRENT" ] && [ "$ARCHBOOTNAME" != ia32 ]; then update_uefi_bootentry fi f_dprintf "Finished configuring ESP" fi # Add boot0cfg for MBR BIOS booting?