diff --git a/usr.sbin/bsdinstall/scripts/bootconfig b/usr.sbin/bsdinstall/scripts/bootconfig --- a/usr.sbin/bsdinstall/scripts/bootconfig +++ b/usr.sbin/bsdinstall/scripts/bootconfig @@ -62,6 +62,7 @@ update_uefi_bootentry() { + local mntpt=$1 nentries=$(efibootmgr | grep -c "${EFI_LABEL_NAME}$") # No entries so directly create one and return if [ ${nentries} -eq 0 ]; then @@ -85,7 +86,38 @@ efibootmgr --create --activate --label "$FREEBSD_BOOTLABEL" --loader "${mntpt}/${FREEBSD_BOOTNAME}" > /dev/null } -f_dialog_title "Boot Configuration" +install_uefi_loader() +{ + local dev=$1 + local mntpt=$2 + if ! f_mounted -b "${dev}"; then + mount -t msdosfs "${dev}" "${mntpt}" + if [ $? -ne 0 ]; then + f_dprintf "Failed to mount dev ${dev} on ${mntpt}" + return 1 + fi + fi + + mkdir -p "${mntpt}/${FREEBSD_BOOTDIR}" "${mntpt}/${BOOTDIR}" + cp "$BSDINSTALL_CHROOT/boot/loader.efi" "${mntpt}/${FREEBSD_BOOTNAME}" + # + # The following shouldn't be necessary. UEFI defines a way to + # specifically select what to boot (which we do via + # efibootmgr). However, virtual environments often times lack + # support for the NV variables efibootmgr sets. In addition, + # some UEFI implementations have features that interfere with + # the setting of these variables. To combat that, we install the + # default removable media boot file as a fallback 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/loader.efi" "${mntpt}/${BOOTNAME}" + fi + +} + +f_dialog_title "Boot configuration" f_dialog_backtitle "$OSNAME Installer" if [ `uname -m` == powerpc ]; then @@ -100,7 +132,8 @@ 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 +ESPBOOT=$(awk '{if ($2=="/boot/efi") printf("%s\n",$1);}' $PATH_FSTAB) +if [ -n "$ESPBOOT" ]; then case $(uname -m) in arm64) ARCHBOOTNAME=aa64 ;; amd64) ARCHBOOTNAME=x64 ;; @@ -109,33 +142,41 @@ # i386) ARCHBOOTNAME=ia32 ;; # no support for this in i386 kernels, rare machines *) die "Unsupported arch $(uname -m) for UEFI install" esac + BOOTDIR="/efi/boot" BOOTNAME="${BOOTDIR}/boot${ARCHBOOTNAME}.efi" FREEBSD_BOOTDIR="/efi/freebsd" FREEBSD_BOOTNAME="${FREEBSD_BOOTDIR}/loader.efi" mntpt="$BSDINSTALL_CHROOT/boot/efi" + # zfsboot might've created multiple ESP + if [ -e ${TMPDIR}/bsdinstall-esps ]: then + ESPS=$(cat ${TMPDIR}/bsdinstall-esps 2> /dev/null) + else + ESPS=$ESPBOOT + fi + f_dprintf "Installing loader.efi onto ESP" - mkdir -p "${mntpt}/${FREEBSD_BOOTDIR}" "${mntpt}/${BOOTDIR}" - cp "$BSDINSTALL_CHROOT/boot/loader.efi" "${mntpt}/${FREEBSD_BOOTNAME}" + install_uefi_loader "${ESPBOOT}" "${mntpt}" - # - # The following shouldn't be necessary. UEFI defines a way to - # specifically select what to boot (which we do via - # efibootmgr). However, virtual environments often times lack - # support for the NV variables efibootmgr sets. In addition, - # some UEFI implementations have features that interfere with - # the setting of these variables. To combat that, we install the - # default removable media boot file as a fallback 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/loader.efi" "${mntpt}/${BOOTNAME}" + if [ "$BSDINSTALL_CONFIGCURRENT" ]; then + update_uefi_bootentry "${mntpt}" fi - if [ "$BSDINSTALL_CONFIGCURRENT" ]; then - update_uefi_bootentry + # Place bootloader on all other ESPs that zfsboot created + if [ "$ESPS" != "$ESPBOOT" ] + f_dprintf "Installing loader.efi onto additional ESPs" + for esp in $ESPS; do + if [ "$esp" = "$ESPBOOT" ]; then + continue + fi + mntpt=$(mktemp -d ${TMPDIR}/efiboot.XXX) + install_uefi_loader "${esp}" "${mntpt}" + if [ $? -eq 1 ]; then + umount ${mntpt} + rmdir ${mntpt} + fi + done fi f_dprintf "Finished configuring ESP" diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot --- a/usr.sbin/bsdinstall/scripts/zfsboot +++ b/usr.sbin/bsdinstall/scripts/zfsboot @@ -866,19 +866,24 @@ $disk || return $FAILURE # We'll configure the ESP in bootconfig - if [ -z "$efibootpart" ]; then - efibootpart="/dev/gpt/efiboot$index" - f_dprintf "$funcname: configuring ESP at [%s]" \ - "${efibootpart}" + efibootpart="/dev/gpt/efiboot$index" + f_dprintf "$funcname: configuring ESP at [%s]" \ + "${efibootpart}" - f_eval_catch $funcname newfs_msdos "$NEWFS_ESP"\ - "$efibootpart" \ - || return $FAILURE + f_eval_catch $funcname newfs_msdos "$NEWFS_ESP"\ + "$efibootpart" \ + || return $FAILURE + + if [ "$index" = "0" ]; then f_eval_catch $funcname printf "$PRINTF_FSTAB" \ $efibootpart /boot/efi msdosfs \ rw 2 2 "$BSDINSTALL_TMPETC/fstab" \ || return $FAILURE fi + + # To be reused by bootconfig + echo "$efibootpart" >> ${TMPDIR:-"/tmp"}/bsdinstall-esps + fi if [ "$ZFSBOOT_BOOT_TYPE" = "BIOS" -o \ @@ -1751,9 +1756,6 @@ zfs_create_boot "$ZFSBOOT_POOL_NAME" \ "$vdev_type" $ZFSBOOT_DISKS || continue - # To be reused by bootconfig - echo "$ZFSBOOT_DISKS" > ${TMPDIR:-"/tmp"}/bsdinstall-zfsboot - break # to success ;; ?" $msg_pool_type_disks")