Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Sep 2025 02:57:18 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 494de51bc007 - main - bsdinstall: Add loader.efi to all ESPs we create
Message-ID:  <202509300257.58U2vIWI017504@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=494de51bc0074472d1b01604f085daea0844f240

commit 494de51bc0074472d1b01604f085daea0844f240
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2025-09-30 02:46:57 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-09-30 02:55:46 +0000

    bsdinstall: Add loader.efi to all ESPs we create
    
    For proper redundancy, add copies of loader.efi to each of the ESPs we
    create when we create multi-volume ZFS datasets. zfsboot creates a list
    of secondary ESPs, while bootpart doesn't create any (it's the UFS
    partitioning tool) because we don't supporg UFS over gmirror. The
    primary ESP is mounted and is what we use efibootmgr to boot from. The
    redundant copies allow the system to boot if the primary disks fails.
    
    Sponsored by:           Netflix
    MFC After:              2 days
    PR:                     208802
    Reviewed by:            cperciva
    Differential Revision:  https://reviews.freebsd.org/D52780
---
 usr.sbin/bsdinstall/scripts/auto       |  3 ++
 usr.sbin/bsdinstall/scripts/bootconfig | 61 ++++++++++++++++++++++------------
 usr.sbin/bsdinstall/scripts/zfsboot    | 28 +++++++++-------
 3 files changed, 59 insertions(+), 33 deletions(-)

diff --git a/usr.sbin/bsdinstall/scripts/auto b/usr.sbin/bsdinstall/scripts/auto
index 0b47d496fdbd..61d52065af2a 100755
--- a/usr.sbin/bsdinstall/scripts/auto
+++ b/usr.sbin/bsdinstall/scripts/auto
@@ -178,6 +178,9 @@ environment_save
 rm -rf $BSDINSTALL_TMPETC
 mkdir $BSDINSTALL_TMPETC
 
+# Reset the ESP list
+: > ${TMPDIR:-"/tmp"}/bsdinstall-esps
+
 # With pkgbase, pkg OOM has been observed with QEMU-default 128 MiB memory size.
 # Ensure we have at least about 256 MiB (with an allowance for rounding etc.).
 physmem=$(($(sysctl -n hw.physmem) / 1048576))
diff --git a/usr.sbin/bsdinstall/scripts/bootconfig b/usr.sbin/bsdinstall/scripts/bootconfig
index 41243ad14b9b..6736e78b450a 100755
--- a/usr.sbin/bsdinstall/scripts/bootconfig
+++ b/usr.sbin/bsdinstall/scripts/bootconfig
@@ -63,6 +63,24 @@ dialog_uefi_entryname()
 		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
 }
 
+# Copy to the normal FreeBSD location. Also copy to the default location if it
+# doesn't exist. This covers setups where UEFI NV variables can't be set and
+# some buggy firmware, while preserving complex UEFI setups for multiple booting
+# (rEFInd, etc).
+uefi_copy_loader()
+{
+    local ldr=$1
+    local freebsd_dir=$2
+    local default_dir=$3
+    local dest=$4
+
+    mkdir -p "${freebsd_dir}" "${default_dir}"
+    cp "${ldr}" "${freebsd_dir}"
+    if [ ! -f "${default_dir}/${dest}" ]; then
+	cp "${ldr}" "${default_dir}/${dest}"
+    fi
+}
+
 update_uefi_bootentry()
 {
 	nentries=$(efibootmgr | grep -c "${EFI_LABEL_NAME}$")
@@ -113,6 +131,7 @@ if [ -n "$(awk '{if ($2=="/boot/efi") printf("%s\n",$1);}' $PATH_FSTAB)" ]; then
 	    *)		die "Unsupported arch $(uname -m) for UEFI install"
 	esac
 
+	# Support the weird 32-bit firmware loading 64-bit kernels
 	if [ `sysctl -n machdep.efi_arch` == i386 ]; then
 		ARCHBOOTNAME=ia32
 		file=loader_ia32.efi
@@ -120,31 +139,31 @@ if [ -n "$(awk '{if ($2=="/boot/efi") printf("%s\n",$1);}' $PATH_FSTAB)" ]; then
 		file=loader.efi
 	fi
 
-	BOOTDIR="/efi/boot"
-	BOOTNAME="${BOOTDIR}/boot${ARCHBOOTNAME}.efi"
-	FREEBSD_BOOTDIR="/efi/freebsd"
-	FREEBSD_BOOTNAME="${FREEBSD_BOOTDIR}/${file}"
+	# Copy the boot loader
 	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}"
+	uefi_copy_loader "$BSDINSTALL_CHROOT/boot/${file}" \
+		"${mntpt}/efi/freebsd" "${mntpt}/efi/boot" \
+		boot${ARCHBOOTNAME}.efi
+
+	# zfsboot records the extra esp partitions it creates to -esps.  These
+	# are newfs'd at the time of creation. We don't support installing ufs
+	# over gmirror, so we only do this for ZFS.
+	esps=${TMPDIR:-"/tmp"}/bsdinstall-esps
+	if [ -f "$esps" ]; then
+		mntpt=$(mktemp -d -t bsdinstall-esp)
+		for dev in $(cat $esps); do
+			f_dprintf "Installing ${file} onto redundant ESP ${dev}"
+			mount -t msdos "$dev" "$mntpt"
+			uefi_copy_loader "$BSDINSTALL_CHROOT/boot/${file}" \
+				"${mntpt}/efi/freebsd" "${mntpt}/efi/boot" \
+				boot${ARCHBOOTNAME}.efi
+			umount "$mntpt"
+		done
+		rmdir "${mntpt}"
 	fi
 
+	# Try to set the UEFI NV BootXXXX variables to recod the boot location
 	if [ "$BSDINSTALL_CONFIGCURRENT" ] && [ "$ARCHBOOTNAME" != ia32 ]; then
 		update_uefi_bootentry
 	fi
diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot
index 5fbf56ea59ac..95cbba3fa131 100755
--- a/usr.sbin/bsdinstall/scripts/zfsboot
+++ b/usr.sbin/bsdinstall/scripts/zfsboot
@@ -760,6 +760,7 @@ zfs_create_diskpart()
 {
 	local funcname=zfs_create_diskpart
 	local disk="$1" index="$2"
+	local efibootpart
 
 	# Check arguments
 	if [ ! "$disk" ]; then
@@ -867,18 +868,22 @@ zfs_create_diskpart()
 			             $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}"
-
-				f_eval_catch $funcname newfs_msdos "$NEWFS_ESP"\
-				             "$efibootpart" \
-				             || return $FAILURE
+			# Note: This will always be p1
+			efibootpart="/dev/gpt/efiboot$index"
+			f_dprintf "$funcname: configuring ESP at [%s]" \
+			          "${efibootpart}"
+
+			f_eval_catch $funcname newfs_msdos "$NEWFS_ESP"\
+			             "$efibootpart" \
+			             || return $FAILURE
+			if [ $index -eq 0 ]; then
 				f_eval_catch $funcname printf "$PRINTF_FSTAB" \
-					     $efibootpart /boot/efi msdosfs \
-				             rw 2 2 "$BSDINSTALL_TMPETC/fstab" \
-				             || return $FAILURE
+					$efibootpart /boot/efi msdosfs \
+					rw 2 2 "$BSDINSTALL_TMPETC/fstab" \
+					|| return $FAILURE
+			else
+				# Record the extra ones
+				echo "${efibootpart}" >> ${TMPDIR:-"/tmp"}/bsdinstall-esps
 			fi
 		fi
 
@@ -1021,7 +1026,6 @@ zfs_create_boot()
 	local isswapmirror
 	local bootpart targetpart swappart # Set by zfs_create_diskpart() below
 	local create_options
-	local efibootpart
 
 	#
 	# Pedantic checks; should never be seen



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202509300257.58U2vIWI017504>