Index: release/amd64/make-memstick.sh =================================================================== --- release/amd64/make-memstick.sh +++ release/amd64/make-memstick.sh @@ -36,11 +36,24 @@ rm ${1}/etc/fstab rm ${1}/etc/rc.conf.local + +dd if=/dev/zero of=efiboot.img bs=1k count=33292 +device=`mdconfig -a -t vnode -f efiboot.img` +newfs_msdos -F 32 -c 1 -L EFISYS /dev/$device +mkdir efi +mount -t msdosfs /dev/$device efi +mkdir -p efi/efi/boot +cp -p "${1}/boot/loader.efi" efi/efi/boot/bootx64.efi +umount efi +rmdir efi +mdconfig -d -u $device + mkimg -s mbr \ -b ${1}/boot/mbr \ - -p efi:=${1}/boot/boot1.efifat \ + -p efi:=efiboot.img \ -p freebsd:-"mkimg -s bsd -b ${1}/boot/boot -p freebsd-ufs:=${2}.part" \ -a 2 \ -o ${2} +rm efiboot.img rm ${2}.part Index: release/arm64/make-memstick.sh =================================================================== --- release/arm64/make-memstick.sh +++ release/arm64/make-memstick.sh @@ -36,9 +36,23 @@ rm ${1}/etc/fstab rm ${1}/etc/rc.conf.local + +dd if=/dev/zero of=efiboot.img bs=1k count=33292 +device=`mdconfig -a -t vnode -f efiboot.img` +newfs_msdos -F 32 -c 1 -L EFISYS /dev/$device +mkdir efi +mount -t msdosfs /dev/$device efi +mkdir -p efi/efi/boot +cp -p "${1}/boot/loader.efi" efi/efi/boot/bootaa64.efi +umount efi +rmdir efi +mdconfig -d -u $device + + mkimg -s gpt \ - -p efi:=${1}/boot/boot1.efifat \ + -p efi:=efiboot.img \ -p freebsd:=${2}.part \ -o ${2} +rm efiboot.img rm ${2}.part Index: release/i386/make-memstick.sh =================================================================== --- release/i386/make-memstick.sh +++ release/i386/make-memstick.sh @@ -36,9 +36,23 @@ rm ${1}/etc/fstab rm ${1}/etc/rc.conf.local + +dd if=/dev/zero of=efiboot.img bs=1k count=33292 +device=`mdconfig -a -t vnode -f efiboot.img` +newfs_msdos -F 32 -c 1 -L EFISYS /dev/$device +mkdir efi +mount -t msdosfs /dev/$device efi +mkdir -p efi/efi/boot +cp -p "${1}/boot/loader.efi" efi/efi/boot/bootia32.efi +umount efi +rmdir efi +mdconfig -d -u $device + mkimg -s mbr \ -b ${1}/boot/mbr \ + -p efi:=efiboot.img -p freebsd:-"mkimg -s bsd -b ${1}/boot/boot -p freebsd-ufs:=${2}.part" \ -o ${2} +rm efiboot.img rm ${2}.part Index: stand/efi/boot1/Makefile =================================================================== --- stand/efi/boot1/Makefile +++ stand/efi/boot1/Makefile @@ -51,7 +51,7 @@ .PATH: ${LDRSRC} CFLAGS+= -I${LDRSRC} -FILES= boot1.efi boot1.efifat +FILES= boot1.efi FILESMODE_boot1.efi= ${BINMODE} LDSCRIPT= ${EFISRC}/loader/arch/${MACHINE}/ldscript.${MACHINE} @@ -88,22 +88,7 @@ -j .rela.dyn -j .reloc -j .eh_frame \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} -# The following inserts our objects into a template FAT file system -# created by generate-fat.sh -.include "Makefile.fat" - -boot1.efifat: boot1.efi - @set -- `ls -l ${.ALLSRC}`; \ - x=$$(($$5-${BOOT1_MAXSIZE})); \ - if [ $$x -ge 0 ]; then \ - echo "boot1 $$x bytes too large; regenerate FAT templates?" >&2 ;\ - exit 1; \ - fi - echo ${.OBJDIR} - xz -d -c ${BOOTSRC}/efi/boot1/fat-${MACHINE}.tmpl.xz > ${.TARGET} - ${DD} if=${.ALLSRC} of=${.TARGET} seek=${BOOT1_OFFSET} conv=notrunc - -CLEANFILES+= boot1.efi boot1.efifat +CLEANFILES+= boot1.efi .include Index: stand/efi/boot1/Makefile.fat =================================================================== --- stand/efi/boot1/Makefile.fat +++ stand/efi/boot1/Makefile.fat @@ -1,4 +0,0 @@ -# This file autogenerated by generate-fat.sh - DO NOT EDIT -# $FreeBSD$ -BOOT1_OFFSET=0x2d -BOOT1_MAXSIZE=393216 Index: stand/efi/boot1/generate-fat.sh =================================================================== --- stand/efi/boot1/generate-fat.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -# This script generates the dummy FAT filesystem used for the EFI boot -# blocks. It uses newfs_msdos to generate a template filesystem with the -# relevant interesting files. These are then found by grep, and the offsets -# written to a Makefile snippet. -# -# Because it requires root, and because it is overkill, we do not -# do this as part of the normal build. If makefs(8) grows workable FAT -# support, this should be revisited. - -# $FreeBSD$ - -FAT_SIZE=1600 #Size in 512-byte blocks of the produced image - -BOOT1_OFFSET=2d -BOOT1_SIZE=384k - -if [ $(id -u) != 0 ]; then - echo "${0##*/}: must run as root" >&2 - exit 1 -fi - -# Record maximum boot1 size in bytes -case $BOOT1_SIZE in -*k) - BOOT1_MAXSIZE=$(expr ${BOOT1_SIZE%k} '*' 1024) - ;; -*) - BOOT1_MAXSIZE=$BOOT1_SIZE - ;; -esac - -echo '# This file autogenerated by generate-fat.sh - DO NOT EDIT' > Makefile.fat -echo "# \$FreeBSD\$" >> Makefile.fat -echo "BOOT1_OFFSET=0x$BOOT1_OFFSET" >> Makefile.fat -echo "BOOT1_MAXSIZE=$BOOT1_MAXSIZE" >> Makefile.fat - -while read ARCH FILENAME; do - # Generate 800K FAT image - OUTPUT_FILE=fat-${ARCH}.tmpl - - dd if=/dev/zero of=$OUTPUT_FILE bs=512 count=$FAT_SIZE - DEVICE=`mdconfig -a -f $OUTPUT_FILE` - newfs_msdos -F 12 -L EFISYS $DEVICE - mkdir stub - mount -t msdosfs /dev/$DEVICE stub - - # Create and bless a directory for the boot loader - mkdir -p stub/efi/boot - - # Make a dummy file for boot1 - echo 'Boot1 START' | dd of=stub/efi/boot/$FILENAME cbs=$BOOT1_SIZE count=1 conv=block - # Provide a fallback startup.nsh - echo $FILENAME > stub/efi/boot/startup.nsh - - umount stub - mdconfig -d -u $DEVICE - rmdir stub - - # Locate the offset of the fake file - OFFSET=$(hd $OUTPUT_FILE | grep 'Boot1 START' | cut -f 1 -d ' ') - - # Convert to number of blocks - OFFSET=$(echo 0x$OFFSET | awk '{printf("%x\n",$1/512);}') - - # Validate the offset - if [ $OFFSET != $BOOT1_OFFSET ]; then - echo "Incorrect offset $OFFSET != $BOOT1_OFFSET" >&2 - exit 1 - fi - - xz -f $OUTPUT_FILE -done < #include #include +#include #include #include @@ -192,7 +193,9 @@ 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 @@ TRUE); return; } - + bootsize = lseek(bootfd, 0, SEEK_END); boot = malloc(bootsize); lseek(bootfd, 0, SEEK_SET); @@ -706,8 +709,18 @@ 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, + 0666); + if (fd > 0) { + write(fd, md->name, strlen(md->name)); + write(fd, " ", 1); + close(fd); + } + md->bootcode = 1; + } else if (mountpoint == NULL || strlen(mountpoint) == 0) mountpoint = default_bootmount; } Index: usr.sbin/bsdinstall/partedit/partedit_arm64.c =================================================================== --- usr.sbin/bsdinstall/partedit/partedit_arm64.c +++ usr.sbin/bsdinstall/partedit/partedit_arm64.c @@ -36,7 +36,6 @@ /* EFI partition size in bytes */ #define EFI_BOOTPART_SIZE (200 * 1024 * 1024) -#define EFI_BOOTPART_PATH "/boot/boot1.efifat" const char * default_scheme(void) @@ -95,10 +94,7 @@ 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); } Index: usr.sbin/bsdinstall/partedit/partedit_x86.c =================================================================== --- usr.sbin/bsdinstall/partedit/partedit_x86.c +++ usr.sbin/bsdinstall/partedit/partedit_x86.c @@ -36,7 +36,6 @@ /* EFI partition size in bytes */ #define EFI_BOOTPART_SIZE (200 * 1024 * 1024) -#define EFI_BOOTPART_PATH "/boot/boot1.efifat" static const char * x86_bootmethod(void) @@ -141,16 +140,14 @@ 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); } Index: usr.sbin/bsdinstall/scripts/bootconfig =================================================================== --- usr.sbin/bsdinstall/scripts/bootconfig +++ usr.sbin/bsdinstall/scripts/bootconfig @@ -1,5 +1,6 @@ #!/bin/sh #- +# Copyright (c) 2018 Rebecca Cran # Copyright (c) 2017 Nathan Whitehorn # All rights reserved. # @@ -35,6 +36,45 @@ 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 [ `sysctl -n machdep.bootmethod` == UEFI ]; then + mkdir $BSDINSTALL_TMPETC/esp + UFSBOOT_ESPS=`cat /tmp/bsdinstall-esps` + + if [ "$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` + ESPS="$ESPS $diskp$index" + done + fi + + if [ "$UFSBOOT_ESPS" ]; then + # We're in a UFS install environment + for partition in $UFSBOOT_ESPS; do + ESPS="$ESPS $partition" + done + fi + + for esp in $ESPS; do + newfs_msdos -F 32 -c 1 /dev/$esp + mount_msdosfs /dev/$esp $BSDINSTALL_TMPETC/esp + + mkdir -p $BSDINSTALL_TMPETC/esp/EFI/freebsd + cp $BSDINSTALL_CHROOT/boot/loader.efi $BSDINSTALL_TMPETC/esp/EFI/freebsd/loader.efi + efibootmgr --create --label FreeBSD --loader $BSDINSTALL_TMPETC/esp/EFI/freebsd/loader.efi + + umount $BSDINSTALL_TMPETC/esp + + # When creating new entries, efibootmgr doesn't mark them active, so we need do + # 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` + bootentry=`echo $bootorder | cut -w -f 3``echo $bootorder | cut -w -f 2` + efibootmgr --activate $bootentry + done +fi + +# Add boot0cfg for MBR BIOS booting? Index: usr.sbin/bsdinstall/scripts/zfsboot =================================================================== --- usr.sbin/bsdinstall/scripts/zfsboot +++ usr.sbin/bsdinstall/scripts/zfsboot @@ -213,7 +213,7 @@ 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"' +NEWFS_ESP='newfs_msdos -F %s -c %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 +851,7 @@ "$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 \ @@ -1595,20 +1573,6 @@ ;; 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 - # # Loop over the main menu until we've accomplished what we came here to do #