Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Dec 2018 19:39:37 +0000 (UTC)
From:      Rebecca Cran <bcran@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r342283 - in head: release/amd64 release/arm64 release/i386 release/tools share/man/man8 tools/boot tools/tools/nanobsd/embedded usr.sbin/bsdinstall/partedit usr.sbin/bsdinstall/scripts
Message-ID:  <201812201939.wBKJdbhB015092@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bcran
Date: Thu Dec 20 19:39:37 2018
New Revision: 342283
URL: https://svnweb.freebsd.org/changeset/base/342283

Log:
  Rework UEFI ESP generation
  
  Currently, the installer uses pre-created 800KB FAT12 filesystems that
  it dd's onto the ESP partition.
  This changeset improves that by having the installer generate a FAT32
  filesystem directly onto the ESP using newfs_msdos and then copying
  loader.efi into /EFI/freebsd.
  For live installs it then runs efibootmgr to add a FreeBSD boot entry
  in the BIOS.
  
  Sponsored by:	Netflix
  Differential Revision:	https://reviews.freebsd.org/D17947

Modified:
  head/release/amd64/make-memstick.sh
  head/release/amd64/mkisoimages.sh
  head/release/arm64/make-memstick.sh
  head/release/i386/make-memstick.sh
  head/release/tools/vmimage.subr
  head/share/man/man8/uefi.8
  head/tools/boot/install-boot.sh
  head/tools/boot/rootgen.sh
  head/tools/tools/nanobsd/embedded/common
  head/usr.sbin/bsdinstall/partedit/gpart_ops.c
  head/usr.sbin/bsdinstall/partedit/partedit_arm64.c
  head/usr.sbin/bsdinstall/partedit/partedit_x86.c
  head/usr.sbin/bsdinstall/scripts/bootconfig
  head/usr.sbin/bsdinstall/scripts/zfsboot

Modified: head/release/amd64/make-memstick.sh
==============================================================================
--- head/release/amd64/make-memstick.sh	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/release/amd64/make-memstick.sh	Thu Dec 20 19:39:37 2018	(r342283)
@@ -12,6 +12,9 @@
 
 set -e
 
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../../tools/boot/install-boot.sh
+
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 export PATH
 
@@ -36,11 +39,16 @@ makefs -B little -o label=FreeBSD_Install -o version=2
 rm ${1}/etc/fstab
 rm ${1}/etc/rc.conf.local
 
+# Make an ESP in a file.
+espfilename=$(mktemp /tmp/efiboot.XXXXXX)
+make_esp_file ${espfilename} ${fat32min} ${1}/boot/loader.efi
+
 mkimg -s mbr \
     -b ${1}/boot/mbr \
-    -p efi:=${1}/boot/boot1.efifat \
+    -p efi:=${espfilename} \
     -p freebsd:-"mkimg -s bsd -b ${1}/boot/boot -p freebsd-ufs:=${2}.part" \
     -a 2 \
     -o ${2}
+rm ${espfilename}
 rm ${2}.part
 

Modified: head/release/amd64/mkisoimages.sh
==============================================================================
--- head/release/amd64/mkisoimages.sh	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/release/amd64/mkisoimages.sh	Thu Dec 20 19:39:37 2018	(r342283)
@@ -25,6 +25,9 @@
 
 set -e
 
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../../tools/boot/install-boot.sh
+
 if [ -z $ETDUMP ]; then
 	ETDUMP=etdump
 fi
@@ -43,18 +46,12 @@ if [ "$1" = "-b" ]; then
 	bootable="-o bootimage=i386;$BASEBITSDIR/boot/cdboot -o no-emul-boot"
 
 	# Make EFI system partition (should be done with makefs in the future)
-	dd if=/dev/zero of=efiboot.img bs=4k count=200
-	device=`mdconfig -a -t vnode -f efiboot.img`
-	newfs_msdos -F 12 -m 0xf8 /dev/$device
-	mkdir efi
-	mount -t msdosfs /dev/$device efi
-	mkdir -p efi/efi/boot
-	cp "$BASEBITSDIR/boot/loader.efi" efi/efi/boot/bootx64.efi
-	umount efi
-	rmdir efi
-	mdconfig -d -u $device
-	bootable="$bootable -o bootimage=i386;efiboot.img -o no-emul-boot -o platformid=efi"
-	
+	# The ISO file is a special case, in that it only has a maximum of
+	# 800 KB available for the boot code. So make an 800 KB ESP
+	espfilename=$(mktemp /tmp/efiboot.XXXXXX)
+	make_esp_file ${espfilename} 800 ${BASEBITSDIR}/boot/loader.efi
+	bootable="$bootable -o bootimage=i386;${espfilename} -o no-emul-boot -o platformid=efi"
+
 	shift
 else
 	BASEBITSDIR="$3"
@@ -73,7 +70,7 @@ publisher="The FreeBSD Project.  https://www.FreeBSD.o
 echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$BASEBITSDIR/etc/fstab"
 $MAKEFS -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$@"
 rm -f "$BASEBITSDIR/etc/fstab"
-rm -f efiboot.img
+rm -f ${espfilename}
 
 if [ "$bootable" != "" ]; then
 	# Look for the EFI System Partition image we dropped in the ISO image.

Modified: head/release/arm64/make-memstick.sh
==============================================================================
--- head/release/arm64/make-memstick.sh	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/release/arm64/make-memstick.sh	Thu Dec 20 19:39:37 2018	(r342283)
@@ -15,6 +15,9 @@ set -e
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 export PATH
 
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../../tools/boot/install-boot.sh
+
 if [ $# -ne 2 ]; then
 	echo "make-memstick.sh /path/to/directory /path/to/image/file"
 	exit 1
@@ -36,9 +39,14 @@ makefs -B little -o label=FreeBSD_Install -o version=2
 rm ${1}/etc/fstab
 rm ${1}/etc/rc.conf.local
 
+# Make an ESP in a file.
+espfilename=$(mktemp /tmp/efiboot.XXXXXX)
+make_esp_file ${espfilename} ${fat32min} ${1}/boot/loader.efi
+
 mkimg -s gpt \
-    -p efi:=${1}/boot/boot1.efifat \
+    -p efi:=${espfilename} \
     -p freebsd:=${2}.part \
     -o ${2}
+rm ${espfilename}
 rm ${2}.part
 

Modified: head/release/i386/make-memstick.sh
==============================================================================
--- head/release/i386/make-memstick.sh	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/release/i386/make-memstick.sh	Thu Dec 20 19:39:37 2018	(r342283)
@@ -12,6 +12,9 @@
 
 set -e
 
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../../tools/boot/install-boot.sh
+
 PATH=/bin:/usr/bin:/sbin:/usr/sbin
 export PATH
 
@@ -36,9 +39,15 @@ makefs -B little -o label=FreeBSD_Install -o version=2
 rm ${1}/etc/fstab
 rm ${1}/etc/rc.conf.local
 
+# Make an ESP in a file.
+espfilename=$(mktemp /tmp/efiboot.XXXXXX)
+make_esp_file ${espfilename} ${fat32min} ${1}/boot/loader.efi
+
 mkimg -s mbr \
     -b ${1}/boot/mbr \
+    -p efi:=${espfilename}
     -p freebsd:-"mkimg -s bsd -b ${1}/boot/boot -p freebsd-ufs:=${2}.part" \
     -o ${2}
+rm ${espfilename}
 rm ${2}.part
 

Modified: head/release/tools/vmimage.subr
==============================================================================
--- head/release/tools/vmimage.subr	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/release/tools/vmimage.subr	Thu Dec 20 19:39:37 2018	(r342283)
@@ -6,6 +6,9 @@
 # Common functions for virtual machine image build scripts.
 #
 
+scriptdir=$(dirname $(realpath $0))
+. ${scriptdir}/../../tools/boot/install-boot.sh
+
 export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
 trap "cleanup" INT QUIT TRAP ABRT TERM
 
@@ -29,10 +32,14 @@ write_partition_layout() {
 				-o ${VMIMAGE}
 			;;
 		arm64:aarch64)
+			# Create an ESP
+			espfilename=$(mktemp /tmp/efiboot.XXXXXX)
+			make_esp_file ${espfilename} ${fat32min} ${BOOTFILES}/efi/loader_lua/loader_lua.efi
 			mkimg -s mbr -f ${VMFORMAT} \
-				-p efi:=${BOOTFILES}/efi/boot1/boot1.efifat \
+				-p efi:=${espfilename} \
 				-p freebsd:=${VMBASE} \
 				-o ${VMIMAGE}
+			rm ${espfilename}
 			;;
 		powerpc:powerpc*)
 			mkimg -s apm -f ${VMFORMAT} \

Modified: head/share/man/man8/uefi.8
==============================================================================
--- head/share/man/man8/uefi.8	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/share/man/man8/uefi.8	Thu Dec 20 19:39:37 2018	(r342283)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 25, 2018
+.Dd December 14, 2018
 .Dt UEFI 8
 .Os
 .Sh NAME
@@ -77,20 +77,16 @@ The default
 boot configuration for
 .Fx
 installs
-.Pa boot1.efi
+.Pa loader.efi
 in the default path.
 .It
-.Pa boot1.efi
+.Pa loader.efi
 reads boot configuration from
 .Pa /boot.config
 or
 .Pa /boot/config .
-Unlike other first-stage boot loaders,
-.Pa boot1.efi
-passes the configuration to the next stage boot loader and does not
-itself act on the contents of the file.
 .It
-.Pa boot1.efi
+.Pa loader.efi
 searches partitions of type
 .Li freebsd-ufs
 and
@@ -98,7 +94,7 @@ and
 for
 .Pa loader.efi .
 The search begins with partitions on the device from which
-.Pa boot1.efi
+.Pa loader.efi
 was loaded, and continues with other available partitions.
 If both
 .Li freebsd-ufs
@@ -107,9 +103,6 @@ and
 partitions exist on the same device the
 .Li freebsd-zfs
 partition is preferred.
-.Pa boot1.efi
-then loads and executes
-.Pa loader.efi .
 .It
 .Pa loader.efi
 loads and boots the kernel, as described in
@@ -122,20 +115,8 @@ system console is automatically selected when booting 
 .Nm .
 .Sh FILES
 .Bl -tag -width /boot/loader -compact
-.It Pa /boot/boot1.efi
-First stage
 .Nm
 bootstrap
-.It Pa /boot/boot1.efifat
-.Xr msdosfs 5
-FAT file system image containing
-.Pa boot1.efi
-for use by
-.Xr bsdinstall 8
-and the
-.Ar bootcode
-argument to
-.Xr gpart 8 .
 .It Pa /boot/loader.efi
 Final stage bootstrap
 .It Pa /boot/kernel/kernel

Modified: head/tools/boot/install-boot.sh
==============================================================================
--- head/tools/boot/install-boot.sh	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/tools/boot/install-boot.sh	Thu Dec 20 19:39:37 2018	(r342283)
@@ -10,6 +10,10 @@
 
 # insert code here to guess what you have -- yikes!
 
+# Minimum size of FAT filesystems, in KB.
+fat32min=33292
+fat16min=2100
+
 die() {
     echo $*
     exit 1
@@ -27,21 +31,152 @@ find-part() {
     gpart show $dev | tail +2 | awk '$4 == "'$part'" { print $3; }'
 }
 
-make_esp() {
-    local dev dst mntpt
+get_uefi_bootname() {
 
+    case ${TARGET:-$(uname -m)} in
+        amd64) echo bootx64 ;;
+        arm64) echo bootaa64 ;;
+        i386) echo bootia32 ;;
+        arm) echo bootarm ;;
+        *) die "machine type $(uname -m) doesn't support UEFI" ;;
+    esac
+}
+
+make_esp_file() {
+    local file sizekb loader device mntpt fatbits efibootname
+
+    file=$1
+    sizekb=$2
+    loader=$3
+
+    if [ "$sizekb" -ge "$fat32min" ]; then
+        fatbits=32
+    elif [ "$sizekb" -ge "$fat16min" ]; then
+        fatbits=16
+    else
+        fatbits=12
+    fi
+
+    dd if=/dev/zero of="${file}" bs=1k count="${sizekb}"
+    device=$(mdconfig -a -t vnode -f "${file}")
+    newfs_msdos -F "${fatbits}" -c 1 -L EFISYS "/dev/${device}" > /dev/null 2>&1
+    mntpt=$(mktemp -d /tmp/stand-test.XXXXXX)
+    mount -t msdosfs "/dev/${device}" "${mntpt}"
+    mkdir -p "${mntpt}/EFI/BOOT"
+    efibootname=$(get_uefi_bootname)
+    cp "${loader}" "${mntpt}/EFI/BOOT/${efibootname}.efi"
+    umount "${mntpt}"
+    rmdir "${mntpt}"
+    mdconfig -d -u "${device}"
+}
+
+make_esp_device() {
+    local dev file mntpt fstype efibootname kbfree loadersize efibootfile
+    local isboot1 existingbootentryloaderfile bootorder bootentry
+
+    # ESP device node
     dev=$1
-    dst=$2
+    file=$2
 
-    newfs_msdos -a 32 ${dev}
     mntpt=$(mktemp -d /tmp/stand-test.XXXXXX)
-    mount -t msdos ${dev} ${mntpt}
-    mkdir -p ${mntpt}/efi/boot
-    cp ${dst}/boot/loader.efi ${mntpt}/efi/boot/bootx64.efi
-    umount ${mntpt}
-    rmdir ${mntpt}
+
+    # See if we're using an existing (formatted) ESP
+    fstype=$(fstyp "${dev}")
+
+    if [ "${fstype}" != "msdosfs" ]; then
+        newfs_msdos -F 32 -c 1 -L EFISYS "${dev}" > /dev/null 2>&1
+    fi
+
+    mount -t msdosfs "${dev}" "${mntpt}"
+    if [ $? -ne 0 ]; then
+        die "Failed to mount ${dev} as an msdosfs filesystem"
+    fi
+
+    echo "Mounted ESP ${dev} on ${mntpt}"
+
+    efibootname=$(get_uefi_bootname)
+    kbfree=$(df -k "${mntpt}" | tail -1 | cut -w -f 4)
+    loadersize=$(stat -f %z "${file}")
+    loadersize=$((loadersize / 1024))
+
+    # Check if /EFI/BOOT/BOOTxx.EFI is the FreeBSD boot1.efi
+    # If it is, remove it to avoid leaving stale files around
+    efibootfile="${mntpt}/EFI/BOOT/${efibootname}.efi"
+    if [ -f "${efibootfile}" ]; then
+        isboot1=$(strings "${efibootfile}" | grep "FreeBSD EFI boot block")
+
+        if [ -n "${isboot1}" ] && [ "$kbfree" -lt "${loadersize}" ]; then
+            echo "Only ${kbfree}KB space remaining: removing old FreeBSD boot1.efi file /EFI/BOOT/${efibootname}.efi"
+            rm "${efibootfile}"
+            rmdir "${mntpt}/EFI/BOOT"
+        else
+            echo "${kbfree}KB space remaining on ESP: renaming old boot1.efi file /EFI/BOOT/${efibootname}.efi /EFI/BOOT/${efibootname}-old.efi"
+            mv "${efibootfile}" "${mntpt}/EFI/BOOT/${efibootname}-old.efi"
+        fi
+    fi
+
+    if [ ! -f "${mntpt}/EFI/freebsd/loader.efi" ] && [ "$kbfree" -lt "$loadersize" ]; then
+        umount "${mntpt}"
+	rmdir "${mntpt}"
+        echo "Failed to update the EFI System Partition ${dev}"
+        echo "Insufficient space remaining for ${file}"
+        echo "Run e.g \"mount -t msdosfs ${dev} /mnt\" to inspect it for files that can be removed."
+        die
+    fi
+
+    mkdir -p "${mntpt}/EFI/freebsd"
+
+    # Keep a copy of the existing loader.efi in case there's a problem with the new one
+    if [ -f "${mntpt}/EFI/freebsd/loader.efi" ] && [ "$kbfree" -gt "$((loadersize * 2))" ]; then
+        cp "${mntpt}/EFI/freebsd/loader.efi" "${mntpt}/EFI/freebsd/loader-old.efi"
+    fi
+
+    echo "Copying loader to /EFI/freebsd on ESP"
+    cp "${file}" "${mntpt}/EFI/freebsd/loader.efi"
+
+    existingbootentryloaderfile=$(efibootmgr -v | grep "${mntpt}//EFI/freebsd/loader.efi")
+
+    if [ -z "$existingbootentryloaderfile" ]; then
+        # Try again without the double forward-slash in the path
+        existingbootentryloaderfile=$(efibootmgr -v | grep "${mntpt}/EFI/freebsd/loader.efi")
+    fi
+
+    if [ -z "$existingbootentryloaderfile" ]; then
+        echo "Creating UEFI boot entry for FreeBSD"
+        efibootmgr --create --label FreeBSD --loader "${mntpt}/EFI/freebsd/loader.efi" > /dev/null
+        if [ $? -ne 0 ]; then
+            die "Failed to create new boot entry"
+        fi
+
+        # When creating new entries, efibootmgr doesn't mark them active, so we need to
+        # do so. It doesn't make it easy to find which entry it just added, so rely on
+        # the fact that it places the new entry first in BootOrder.
+        bootorder=$(efivar --name 8be4df61-93ca-11d2-aa0d-00e098032b8c-BootOrder --print --no-name --hex | head -1)
+        bootentry=$(echo "${bootorder}" | cut -w -f 3)$(echo "${bootorder}" | cut -w -f 2)
+        echo "Marking UEFI boot entry ${bootentry} active"
+        efibootmgr --activate "${bootentry}" > /dev/null
+    else
+        echo "Existing UEFI FreeBSD boot entry found: not creating a new one"
+    fi
+
+    umount "${mntpt}"
+    rmdir "${mntpt}"
+    echo "Finished updating ESP"
 }
 
+make_esp() {
+    local file loaderfile
+
+    file=$1
+    loaderfile=$2
+
+    if [ -f "$file" ]; then
+        make_esp_file ${file} ${fat32min} ${loaderfile}
+    else
+        make_esp_device ${file} ${loaderfile}
+    fi
+}
+
 make_esp_mbr() {
     dev=$1
     dst=$2
@@ -53,7 +188,7 @@ make_esp_mbr() {
 	    die "No ESP slice found"
     	fi
     fi
-    make_esp /dev/${dev}s${s} ${dst}
+    make_esp /dev/${dev}s${s} ${dst}/boot/loader.efi
 }
 
 make_esp_gpt() {
@@ -64,7 +199,7 @@ make_esp_gpt() {
     if [ -z "$idx" ] ; then
 	die "No ESP partition found"
     fi
-    make_esp /dev/${dev}p${idx} ${dst}
+    make_esp /dev/${dev}p${idx} ${dst}/boot/loader.efi
 }
 
 boot_nogeli_gpt_ufs_legacy() {
@@ -218,18 +353,32 @@ boot_nogeli_vtoc8_ufs_ofw() {
     doit gpart bootcode -p ${vtoc8} ${dev}
 }
 
-DESTDIR=/
+usage() {
+	printf 'Usage: %s -b bios [-d destdir] -f fs [-g geli] [-h] [-o optargs] -s scheme <bootdev>\n' "$0"
+	printf 'Options:\n'
+	printf ' bootdev       device to install the boot code on\n'
+	printf ' -b bios       bios type: legacy, uefi or both\n'
+	printf ' -d destdir    destination filesystem root\n'
+	printf ' -f fs         filesystem type: ufs or zfs\n'
+	printf ' -g geli       yes or no\n'
+	printf ' -h            this help/usage text\n'
+	printf ' -o optargs    optional arguments\n'
+	printf ' -s scheme     mbr or gpt\n'
+	exit 0
+}
 
+srcroot=/
+
 # Note: we really don't support geli boot in this script yet.
 geli=nogeli
 
-while getopts "b:d:f:g:o:s:" opt; do
+while getopts "b:d:f:g:ho:s:" opt; do
     case "$opt" in
 	b)
 	    bios=${OPTARG}
 	    ;;
 	d)
-	    DESTDIR=${OPTARG}
+	    srcroot=${OPTARG}
 	    ;;
 	f)
 	    fs=${OPTARG}
@@ -246,25 +395,35 @@ while getopts "b:d:f:g:o:s:" opt; do
 	s)
 	    scheme=${OPTARG}
 	    ;;
+
+	?|h)
+            usage
+            ;;
     esac
 done
 
-shift $((OPTIND-1))
-dev=$1
+if [ -n "${scheme}" ] && [ -n "${fs}" ] && [ -n "${bios}" ]; then
+    shift $((OPTIND-1))
+    dev=$1
+fi
 
 # For gpt, we need to install pmbr as the primary boot loader
 # it knows about 
-gpt0=${DESTDIR}/boot/pmbr
-gpt2=${DESTDIR}/boot/gptboot
-gptzfs2=${DESTDIR}/boot/gptzfsboot
+gpt0=${srcroot}/boot/pmbr
+gpt2=${srcroot}/boot/gptboot
+gptzfs2=${srcroot}/boot/gptzfsboot
 
 # For MBR, we have lots of choices, but select mbr, boot0 has issues with UEFI
-mbr0=${DESTDIR}/boot/mbr
-mbr2=${DESTDIR}/boot/boot
+mbr0=${srcroot}/boot/mbr
+mbr2=${srcroot}/boot/boot
 
 # VTOC8
-vtoc8=${DESTDIR}/boot/boot1
+vtoc8=${srcroot}/boot/boot1
 
 # sanity check here
 
-eval boot_${geli}_${scheme}_${fs}_${bios} $dev $DESTDIR $opts || echo "Unsupported boot env: ${geli}-${scheme}-${fs}-${bios}"
+# Check if we've been given arguments. If not, this script is probably being
+# sourced, so we shouldn't run anything.
+if [ -n "${dev}" ]; then
+	eval boot_${geli}_${scheme}_${fs}_${bios} $dev $srcroot $opts || echo "Unsupported boot env: ${geli}-${scheme}-${fs}-${bios}"
+fi

Modified: head/tools/boot/rootgen.sh
==============================================================================
--- head/tools/boot/rootgen.sh	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/tools/boot/rootgen.sh	Thu Dec 20 19:39:37 2018	(r342283)
@@ -5,7 +5,8 @@
 passphrase=passphrase
 iterations=50000
 
-do_boot1_efi=0
+# The smallest FAT32 filesystem is 33292 KB
+espsize=33292
 
 #
 # Builds all the bat-shit crazy combinations we support booting from,
@@ -16,13 +17,13 @@ do_boot1_efi=0
 # Sad panda sez: this runs as root, but could be userland if someone
 # creates userland geli and zfs tools.
 #
-# This assumes an external prograam install-boot.sh which will install
+# This assumes an external program install-boot.sh which will install
 # the appropriate boot files in the appropriate locations.
 #
 # These images assume ada0 will be the root image. We should likely
 # use labels, but we don't.
 #
-# ASsumes you've already rebuilt... maybe bad? Also maybe bad: the env
+# Assumes you've already rebuilt... maybe bad? Also maybe bad: the env
 # vars should likely be conditionally set to allow better automation.
 #
 
@@ -34,29 +35,6 @@ cpsys() {
     (cd $src ; tar cf - .) | (cd $dst; tar xf -)
 }
 
-make_esp()
-{
-    local src dst md mntpt
-    src=$1
-    dst=$2
-
-    if [ "${do_boot1_efi}" -eq 1 ]; then
-	cp ${src}/boot/boot1.efifat ${dst}
-    else
-	dd if=/dev/zero of=${dst} count=1 seek=$((100 * 1024 * 1024 / 512))
-	md=$(mdconfig -f ${dst})
-	newfs_msdos -a 32 /dev/${md}
-	mntpt=$(mktemp -d /tmp/stand-test.XXXXXX)
-	mount -t msdos /dev/${md} ${mntpt}
-#	mkdir -p ${mntpt}/efi/freebsd # not yet
-	mkdir -p ${mntpt}/efi/boot
-	cp ${src}/boot/loader.efi ${mntpt}/efi/boot/bootx64.efi
-	umount ${mntpt}
-	rmdir ${mntpt}
-	mdconfig -d -u ${md}
-    fi
-}
-
 mk_nogeli_gpt_ufs_legacy() {
     src=$1
     img=$2
@@ -78,7 +56,7 @@ mk_nogeli_gpt_ufs_uefi() {
     cat > ${src}/etc/fstab <<EOF
 /dev/ada0p2	/		ufs	rw	1	1
 EOF
-    make_esp ${src} ${img}.p1
+    make_esp_file ${img}.p1 ${espsize} ${src}
     makefs -t ffs -B little -s 200m ${img}.p2 ${src}
     mkimg -s gpt \
 	  -p efi:=${img}.p1 \
@@ -93,7 +71,7 @@ mk_nogeli_gpt_ufs_both() {
     cat > ${src}/etc/fstab <<EOF
 /dev/ada0p3	/		ufs	rw	1	1
 EOF
-    make_esp ${src} ${img}.p1
+    make_esp_file ${img}.p1 ${espsize} ${src}
     makefs -t ffs -B little -s 200m ${img}.p3 ${src}
     # p1 is boot for uefi, p2 is boot for gpt, p3 is /
     mkimg -b ${src}/boot/pmbr -s gpt \
@@ -155,7 +133,7 @@ mk_nogeli_gpt_zfs_uefi() {
     dd if=/dev/zero of=${img} count=1 seek=$((200 * 1024 * 1024 / 512))
     md=$(mdconfig -f ${img})
     gpart create -s gpt ${md}
-    gpart add -t efi -s 800k -a 4k ${md}
+    gpart add -t efi -s ${espsize}k -a 4k ${md}
     gpart add -t freebsd-zfs -l root $md
     # install-boot will make this bootable
     zpool create -O mountpoint=none -R ${mntpt} ${pool} ${md}p2
@@ -193,7 +171,7 @@ mk_nogeli_gpt_zfs_both() {
     dd if=/dev/zero of=${img} count=1 seek=$((200 * 1024 * 1024 / 512))
     md=$(mdconfig -f ${img})
     gpart create -s gpt ${md}
-    gpart add -t efi -s 800k -a 4k ${md}
+    gpart add -t efi -s ${espsize}k -a 4k ${md}
     gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
     gpart add -t freebsd-zfs -l root $md
     # install-boot will make this bootable
@@ -239,7 +217,7 @@ mk_nogeli_mbr_ufs_uefi() {
     cat > ${src}/etc/fstab <<EOF
 /dev/ada0s2a	/		ufs	rw	1	1
 EOF
-    make_esp ${src} ${img}.s1
+    make_esp_file ${img}.s1 ${espsize} ${src}
     makefs -t ffs -B little -s 200m ${img}.s2a ${src}
     mkimg -s bsd -p freebsd-ufs:=${img}.s2a -o ${img}.s2
     mkimg -a 1 -s mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img}
@@ -253,7 +231,7 @@ mk_nogeli_mbr_ufs_both() {
     cat > ${src}/etc/fstab <<EOF
 /dev/ada0s2a	/		ufs	rw	1	1
 EOF
-    make_esp ${src} ${img}.s1
+    make_esp_file ${img}.s1 ${espsize} ${src}
     makefs -t ffs -B little -s 200m ${img}.s2a ${src}
     mkimg -s bsd -b ${src}/boot/boot -p freebsd-ufs:=${img}.s2a -o ${img}.s2
     mkimg -a 2 -s mbr -b ${src}/boot/mbr -p efi:=${img}.s1 -p freebsd:=${img}.s2 -o ${img}
@@ -313,7 +291,7 @@ mk_nogeli_mbr_zfs_uefi() {
     dd if=/dev/zero of=${img} count=1 seek=$((200 * 1024 * 1024 / 512))
     md=$(mdconfig -f ${img})
     gpart create -s mbr ${md}
-    gpart add -t \!239 -s 800k ${md}
+    gpart add -t efi -s ${espsize}k ${md}
     gpart add -t freebsd ${md}
     gpart set -a active -i 2 ${md}
     gpart create -s bsd ${md}s2
@@ -354,7 +332,7 @@ mk_nogeli_mbr_zfs_both() {
     dd if=/dev/zero of=${img} count=1 seek=$((200 * 1024 * 1024 / 512))
     md=$(mdconfig -f ${img})
     gpart create -s mbr ${md}
-    gpart add -t \!239 -s 800k ${md}
+    gpart add -t efi -s  ${espsize}k ${md}
     gpart add -t freebsd ${md}
     gpart set -a active -i 2 ${md}
     gpart create -s bsd ${md}s2
@@ -430,7 +408,7 @@ mk_geli_gpt_ufs_uefi() {
     dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
     md=$(mdconfig -f ${img})
     gpart create -s gpt ${md}
-    gpart add -t efi -s 800k -a 4k ${md}
+    gpart add -t efi -s ${espsize}k -a 4k ${md}
     gpart add -t freebsd-ufs -l root $md
     # install-boot will make this bootable
     echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p2
@@ -466,7 +444,7 @@ mk_geli_gpt_ufs_both() {
     dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
     md=$(mdconfig -f ${img})
     gpart create -s gpt ${md}
-    gpart add -t efi -s 800k -a 4k ${md}
+    gpart add -t efi -s ${espsize}k -a 4k ${md}
     gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
     gpart add -t freebsd-ufs -l root $md
     # install-boot will make this bootable
@@ -547,7 +525,7 @@ mk_geli_gpt_zfs_uefi() {
     dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
     md=$(mdconfig -f ${img})
     gpart create -s gpt ${md}
-    gpart add -t efi -s 800k -a 4k ${md}
+    gpart add -t efi -s ${espsize}k -a 4k ${md}
     gpart add -t freebsd-zfs -l root $md
     # install-boot will make this bootable
     echo ${passphrase} | geli init -bg -e AES-XTS -i ${iterations} -J - -l 256 -s 4096 ${md}p2
@@ -590,7 +568,7 @@ mk_geli_gpt_zfs_both() {
     dd if=/dev/zero of=${img} count=1 seek=$(( 200 * 1024 * 1024 / 512 ))
     md=$(mdconfig -f ${img})
     gpart create -s gpt ${md}
-    gpart add -t efi -s 800k -a 4k ${md}
+    gpart add -t efi -s ${espsize}k -a 4k ${md}
     gpart add -t freebsd-boot -s 400k -a 4k	${md}	# <= ~540k
     gpart add -t freebsd-zfs -l root $md
     # install-boot will make this bootable

Modified: head/tools/tools/nanobsd/embedded/common
==============================================================================
--- head/tools/tools/nanobsd/embedded/common	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/tools/tools/nanobsd/embedded/common	Thu Dec 20 19:39:37 2018	(r342283)
@@ -301,7 +301,7 @@ create_diskimage_mbr ( ) (
 		# s1 is boot, s2 is cfg, s3 is /, not sure how to make that
 		# boot (marked as active) with mkimg yet
 		mkimg -a 2 ${fmtarg} ${bootmbr} -s mbr \
-			-p efi:=${NANO_WORLDDIR}/boot/boot1.efifat \
+			-p efi:=${NANO_WORLDDIR}/boot/efiboot.img \
 			-p ${s2}:=${NANO_LOG}/_.s2 \
 			-p ${s3}:=${NANO_LOG}/_.s3 \
 			-o ${out}
@@ -310,7 +310,7 @@ create_diskimage_mbr ( ) (
 		# p1 is boot for uefi, p2 is boot for gpt, p3 is cfg, p4 is /
 		# and p5 is alt-root (after resize)
 		mkimg -a 2 ${fmtarg} ${bootmbr} -s gpt \
-			-p efi:=${NANO_WORLDDIR}/boot/boot1.efifat \
+			-p efi:=${NANO_WORLDDIR}/boot/efiboot.img \
 			-p freebsd-boot:=${NAANO_WORLDDIR}/boot/gptboot \
 			-p ${p3}:=${NANO_LOG}/_.p3 \
 			-p ${p4}:=${NANO_LOG}/_.p4 \

Modified: head/usr.sbin/bsdinstall/partedit/gpart_ops.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/gpart_ops.c	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/usr.sbin/bsdinstall/partedit/gpart_ops.c	Thu Dec 20 19:39:37 2018	(r342283)
@@ -31,6 +31,7 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <libutil.h>
 #include <inttypes.h>
 
@@ -192,7 +193,9 @@ newfs_command(const char *fstype, char *command, int u
 		for (i = 0; i < (int)nitems(items); i++) {
 			if (items[i].state == 0)
 				continue;
-			if (strcmp(items[i].name, "FAT16") == 0)
+			if (strcmp(items[i].name, "FAT32") == 0)
+				strcat(command, "-F 32 -c 1");
+			else if (strcmp(items[i].name, "FAT16") == 0)
 				strcat(command, "-F 16 ");
 			else if (strcmp(items[i].name, "FAT12") == 0)
 				strcat(command, "-F 12 ");
@@ -400,7 +403,7 @@ gpart_bootcode(struct ggeom *gp)
 		    TRUE);
 		return;
 	}
-		
+
 	bootsize = lseek(bootfd, 0, SEEK_END);
 	boot = malloc(bootsize);
 	lseek(bootfd, 0, SEEK_SET);
@@ -706,8 +709,17 @@ set_default_part_metadata(const char *name, const char
 	if (strcmp(type, "freebsd-swap") == 0)
 		mountpoint = "none";
 	if (strcmp(type, bootpart_type(scheme, &default_bootmount)) == 0) {
-		if (default_bootmount == NULL)
+		if (default_bootmount == NULL) {
+
+			int fd = open("/tmp/bsdinstall-esps", O_CREAT | O_WRONLY | O_APPEND,
+						  0600);
+			if (fd > 0) {
+				write(fd, md->name, strlen(md->name));
+				close(fd);
+			}
+
 			md->bootcode = 1;
+		}
 		else if (mountpoint == NULL || strlen(mountpoint) == 0)
 			mountpoint = default_bootmount;
 	}

Modified: head/usr.sbin/bsdinstall/partedit/partedit_arm64.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit_arm64.c	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/usr.sbin/bsdinstall/partedit/partedit_arm64.c	Thu Dec 20 19:39:37 2018	(r342283)
@@ -35,8 +35,7 @@
 #include "partedit.h"
 
 /* EFI partition size in bytes */
-#define	EFI_BOOTPART_SIZE	(200 * 1024 * 1024)
-#define	EFI_BOOTPART_PATH	"/boot/boot1.efifat"
+#define	EFI_BOOTPART_SIZE	(260 * 1024 * 1024)
 
 const char *
 default_scheme(void)
@@ -95,10 +94,7 @@ const char *
 partcode_path(const char *part_type, const char *fs_type)
 {
 
-	if (strcmp(part_type, "GPT") == 0)
-		return (EFI_BOOTPART_PATH);
-
-	/* No boot partition data for non-GPT */
+	/* No boot partition data for ARM64 */
 	return (NULL);
 }
 

Modified: head/usr.sbin/bsdinstall/partedit/partedit_x86.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit_x86.c	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/usr.sbin/bsdinstall/partedit/partedit_x86.c	Thu Dec 20 19:39:37 2018	(r342283)
@@ -35,8 +35,7 @@
 #include "partedit.h"
 
 /* EFI partition size in bytes */
-#define	EFI_BOOTPART_SIZE	(200 * 1024 * 1024)
-#define	EFI_BOOTPART_PATH	"/boot/boot1.efifat"
+#define	EFI_BOOTPART_SIZE	(260 * 1024 * 1024)
 
 static const char *
 x86_bootmethod(void)
@@ -141,16 +140,14 @@ const char *
 partcode_path(const char *part_type, const char *fs_type)
 {
 
-	if (strcmp(part_type, "GPT") == 0) {
-		if (strcmp(x86_bootmethod(), "UEFI") == 0)
-			return (EFI_BOOTPART_PATH);
-		else if (strcmp(fs_type, "zfs") == 0)
+	if (strcmp(part_type, "GPT") == 0 && strcmp(x86_bootmethod(), "UEFI") != 0) {
+		if (strcmp(fs_type, "zfs") == 0)
 			return ("/boot/gptzfsboot");
 		else
 			return ("/boot/gptboot");
 	}
 	
-	/* No partcode except for GPT */
+	/* No partcode except for non-UEFI GPT */
 	return (NULL);
 }
 

Modified: head/usr.sbin/bsdinstall/scripts/bootconfig
==============================================================================
--- head/usr.sbin/bsdinstall/scripts/bootconfig	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/usr.sbin/bsdinstall/scripts/bootconfig	Thu Dec 20 19:39:37 2018	(r342283)
@@ -1,5 +1,6 @@
 #!/bin/sh
 #-
+# Copyright (c) 2018 Rebecca Cran
 # Copyright (c) 2017 Nathan Whitehorn
 # All rights reserved.
 #
@@ -26,6 +27,11 @@
 #
 # $FreeBSD$
 
+die() {
+	echo $*
+	exit 1
+}
+
 if [ `uname -m` == powerpc ]; then
 	platform=`sysctl -n hw.platform`
 	if [ "$platform" == ps3 -o "$platform" == powernv ]; then
@@ -35,6 +41,115 @@ if [ `uname -m` == powerpc ]; then
 	fi
 fi
 
-# For new-style EFI booting, add code here
-# Add boot0cfg for MBR BIOS booting?
+# Update the ESP (EFI System Partition) with the new bootloader
+if [ "$(uname -m)" = "amd64" ] || [ "$(uname -m)" = "i386" ]; then
+	X86_BOOTMETHOD=$(sysctl -n machdep.bootmethod)
+fi
 
+if [ "$(uname -m)" = "arm64" ] || [ "$X86_BOOTMETHOD" = "UEFI" ]; then
+	UFSBOOT_ESPS=$(cat /tmp/bsdinstall-esps)
+	num_esps=0
+
+	if [ -n "$ZFSBOOT_DISKS" ]; then
+		# We're in a ZFS install environment
+		for disk in $ZFSBOOT_DISKS; do
+			index=$(gpart show "$disk" | cut -w -f 4,5 | grep "efi" | cut -w -f 1)
+			# Check that $index is an integer
+			[ -n "$index" ] && [ "$index" -eq "$index" ] && [ "$index" -ge 0 ] 2> /dev/null
+			if [ $? -ne 0 ]; then
+				continue
+			fi
+
+			if [ -e "/dev/${disk}p${index}" ]; then
+				ESPS="$ESPS ${disk}p${index}"
+			elif [ -e "/dev/${disk}s${index}" ]; then
+				ESPS="$ESPS ${disk}s${index}"
+			else
+				continue
+			fi
+
+			num_esps=$((num_esps + 1))
+		done
+	fi
+
+	if [ -n "$UFSBOOT_ESPS" ]; then
+		# We're in a UFS install environment
+		for partition in $UFSBOOT_ESPS; do
+			ESPS="$ESPS $partition"
+			num_esps=$((num_esps + 1))
+		done
+	fi
+
+	if [ -z "$ESPS" ]; then
+		# The installer hasn't given us any ESPs to use.
+		# Try and figure out which to use by looking for an
+		# unformatted efi partition
+		for disk in $(sysctl -n kern.disks); do
+			hasfreebsd=$(gpart show "$disk" | cut -w -f 4,5 | grep "freebsd")
+			if [ -n "$hasfreebsd" ]; then
+				index=$(gpart show "$disk" | cut -w -f 4,5 | grep "efi" | cut -w -f 1)
+				# Check that $index is a valid integer
+				[ -n "$index" ] && [ "$index" -eq "$index" ] && [ "$index" -ge 0 ] 2> /dev/null 
+				if [ $? -ne 0 ]; then
+					continue
+				fi
+
+				mntpt=$(mktemp -d /tmp/stand-test.XXXXXX)
+				if [ -e "/dev/${disk}p${index}" ]; then
+					dev=${disk}p${index}
+				elif [ -e "/dev/${disk}s${index}" ]; then
+					dev=/${disk}s${index}
+				else
+					continue
+				fi
+
+				# Try and mount it. If it fails, assume it's
+				# unformatted and should be used.
+				mount -t msdosfs "/dev/${dev}" "${mntpt}"
+				if [ $? -ne 0 ]; then
+					ESPS="$ESPS ${dev}"
+					num_esps=$((num_esps + 1))
+				else
+					umount "${mntpt}"
+				fi
+				rmdir "${mntpt}"
+			fi
+		done
+	fi
+
+	for esp in $ESPS; do
+		newfs_msdos -F 32 -c 1 -L EFISYS "/dev/$esp" > /dev/null 2>&1
+		if [ $? -ne 0 ]; then
+			die "Failed to format ESP $esp as FAT32"
+		fi
+
+		mntpt=$(mktemp -d /tmp/stand-test.XXXXXX)
+		mount -t msdosfs "/dev/${esp}" "${mntpt}"
+		if [ $? -ne 0 ]; then
+			die "Failed to mount ESP ${dev} on ${mntpt}"
+		fi
+
+		mkdir -p "$mntpt/EFI/freebsd"
+		cp "$BSDINSTALL_CHROOT/boot/loader.efi" "${mntpt}/EFI/freebsd/loader.efi"
+
+		if [ "$num_esps" -gt 1 ]; then
+			bootlabel="FreeBSD (${esp})"
+		else
+			bootlabel="FreeBSD"
+		fi
+
+		efibootmgr --create --label "$bootlabel" --loader "${mntpt}/EFI/freebsd/loader.efi" > /dev/null
+
+		umount "${mntpt}"
+		rmdir "${mntpt}"
+
+		# When creating new entries, efibootmgr doesn't mark them active, so we need to
+		# do so. It doesn't make it easy to find which entry it just added, so rely on
+		# the fact that it places the new entry first in BootOrder.
+		bootorder=$(efivar --name 8be4df61-93ca-11d2-aa0d-00e098032b8c-BootOrder --print --no-name --hex | head -1)
+		bootentry=$(echo "$bootorder" | cut -w -f 3)$(echo "$bootorder" | cut -w -f 2)
+		efibootmgr --activate "$bootentry" > /dev/null
+	done
+fi
+
+# Add boot0cfg for MBR BIOS booting?

Modified: head/usr.sbin/bsdinstall/scripts/zfsboot
==============================================================================
--- head/usr.sbin/bsdinstall/scripts/zfsboot	Thu Dec 20 19:27:46 2018	(r342282)
+++ head/usr.sbin/bsdinstall/scripts/zfsboot	Thu Dec 20 19:39:37 2018	(r342283)
@@ -213,7 +213,6 @@ KLDLOAD='kldload %s'
 LN_SF='ln -sf "%s" "%s"'
 MKDIR_P='mkdir -p "%s"'
 MOUNT_TYPE='mount -t %s "%s" "%s"'
-NEWFS_ESP='newfs_msdos -F %s -L "%s" "%s"'
 PRINTF_CONF="printf '%s=\"%%s\"\\\n' %s >> \"%s\""
 PRINTF_FSTAB='printf "$FSTAB_FMT" "%s" "%s" "%s" "%s" "%s" "%s" >> "%s"'
 SHELL_TRUNCATE=':> "%s"'
@@ -851,29 +850,7 @@ zfs_create_diskpart()
 			             "$align_small" efiboot$index efi 200M \
 			             $disk || return $FAILURE
 
-			f_eval_catch $funcname mkdir "$MKDIR_P" \
-				     "$BSDINSTALL_TMPETC/esp" ||
-				     return $FAILURE
-			f_eval_catch $funcname newfs_msdos "$NEWFS_ESP" "16" \
-				     "EFISYS" "/dev/${disk}p1" ||
-				     return $FAILURE
-			f_eval_catch $funcname mount "$MOUNT_TYPE" "msdosfs" \
-				     "/dev/${disk}p1" \
-				     "$BSDINSTALL_TMPETC/esp" ||
-				     return $FAILURE
-			f_eval_catch $funcname mkdir "$MKDIR_P" \
-				     "$BSDINSTALL_TMPETC/esp/efi/boot" ||
-				     return $FAILURE
-			f_eval_catch $funcname cp "$COPY" "/boot/loader.efi" \
-				     "$BSDINSTALL_TMPETC/esp/efi/boot/$ZFSBOOT_ESP_NAME" ||
-				     return $FAILURE
-			f_eval_catch $funcname echo "$ECHO_OVERWRITE" \
-				     "$ZFSBOOT_ESP_NAME" \
-				     "$BSDINSTALL_TMPETC/esp/efi/boot/startup.nsh" ||
-				     return $FAILURE
-			f_eval_catch $funcname umount "$UMOUNT" \
-				     "$BSDINSTALL_TMPETC/esp" ||
-				     return $FAILURE
+			# We'll configure the ESP in bootconfig
 		fi
 
 		if [ "$ZFSBOOT_BOOT_TYPE" = "BIOS" -o \
@@ -1593,20 +1570,6 @@ arm64)
 		: ${ZFSBOOT_PARTITION_SCHEME:=GPT}
 	fi
 	;;
-esac
-
-#
-# The EFI loader installed in the ESP (EFI System Partition) must
-# have the expected name in order to load correctly.
-#
-[ "$ZFSBOOT_ESP_NAME" ] || case "${UNAME_m:-$( uname -m )}" in
-	arm64) ZFSBOOT_ESP_NAME=BOOTaa64.efi ;;
-	arm) ZFSBOOT_ESP_NAME=BOOTarm.efi ;;
-	i386) ZFSBOOT_ESP_NAME=BOOTia32.efi ;;
-	amd64) ZFSBOOT_ESP_NAME=BOOTx64.efi ;;
-	*)
-		f_dprintf "Unsupported architecture: %s" $UNAME_m
-		f_die
 esac
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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