Page MenuHomeFreeBSD

D17947.id51745.diff
No OneTemporary

D17947.id51745.diff

Index: release/amd64/make-memstick.sh
===================================================================
--- release/amd64/make-memstick.sh
+++ release/amd64/make-memstick.sh
@@ -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 @@
rm ${1}/etc/fstab
rm ${1}/etc/rc.conf.local
+# Make a 33292 KB ESP in a file. 33292 KB is the minimum size of a
+# FAT32 filesystem
+make_esp_file /tmp/efiboot.img 33292 ${1}/boot/loader.efi
+
mkimg -s mbr \
-b ${1}/boot/mbr \
- -p efi:=${1}/boot/boot1.efifat \
+ -p efi:=/tmp/efiboot.img \
-p freebsd:-"mkimg -s bsd -b ${1}/boot/boot -p freebsd-ufs:=${2}.part" \
-a 2 \
-o ${2}
+rm /tmp/efiboot.img
rm ${2}.part
Index: release/amd64/mkisoimages.sh
===================================================================
--- release/amd64/mkisoimages.sh
+++ release/amd64/mkisoimages.sh
@@ -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,11 @@
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
+ make_esp_file /tmp/efiboot.img 800 ${BASEBITSDIR}/boot/loader.efi
+ bootable="$bootable -o bootimage=i386;/tmp/efiboot.img -o no-emul-boot -o platformid=efi"
+
shift
else
BASEBITSDIR="$3"
@@ -73,7 +69,7 @@
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 /tmp/efiboot.img
if [ "$bootable" != "" ]; then
# Look for the EFI System Partition image we dropped in the ISO image.
Index: release/arm64/make-memstick.sh
===================================================================
--- release/arm64/make-memstick.sh
+++ release/arm64/make-memstick.sh
@@ -15,6 +15,9 @@
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 @@
rm ${1}/etc/fstab
rm ${1}/etc/rc.conf.local
+# Make a 33292 KB ESP in a file. 33292 KB is the minimum size of a
+# FAT32 filesystem
+make_esp_file /tmp/efiboot.img 33292 ${1}/boot/loader.efi
+
mkimg -s gpt \
- -p efi:=${1}/boot/boot1.efifat \
+ -p efi:=/tmp/efiboot.img \
-p freebsd:=${2}.part \
-o ${2}
+rm /tmp/efiboot.img
rm ${2}.part
Index: release/i386/make-memstick.sh
===================================================================
--- release/i386/make-memstick.sh
+++ release/i386/make-memstick.sh
@@ -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 @@
rm ${1}/etc/fstab
rm ${1}/etc/rc.conf.local
+# Make a 33292 KB ESP in a file. 33292 KB is the minimum size of a
+# FAT32 filesystem
+make_esp_file /tmp/efiboot.img 33292 ${1}/boot/loader.efi
+
mkimg -s mbr \
-b ${1}/boot/mbr \
+ -p efi:=/tmp/efiboot.img
-p freebsd:-"mkimg -s bsd -b ${1}/boot/boot -p freebsd-ufs:=${2}.part" \
-o ${2}
+rm /tmp/efiboot.img
rm ${2}.part
Index: release/tools/vmimage.subr
===================================================================
--- release/tools/vmimage.subr
+++ release/tools/vmimage.subr
@@ -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,8 @@
-o ${VMIMAGE}
;;
arm64:aarch64)
- mkimg -s mbr -f ${VMFORMAT} \
- -p efi:=${BOOTFILES}/efi/boot1/boot1.efifat \
- -p freebsd:=${VMBASE} \
- -o ${VMIMAGE}
+ # Create an ESP (EFI System Partition) of 33292 KB (minimum FAT32 size)
+ make_esp_file ${BOOTFILES}/efi/efiboot.img 33292 ${BOOTFILES}/efi/loader_lua/loader_lua.efi
;;
powerpc:powerpc*)
mkimg -s apm -f ${VMFORMAT} \
Index: share/man/man8/uefi.8
===================================================================
--- share/man/man8/uefi.8
+++ share/man/man8/uefi.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 25, 2018
+.Dd November 28, 2018
.Dt UEFI 8
.Os
.Sh NAME
@@ -77,20 +77,16 @@
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 @@
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 @@
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 @@
.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
Index: stand/efi/Makefile
===================================================================
--- stand/efi/Makefile
+++ stand/efi/Makefile
@@ -9,7 +9,7 @@
.if ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 40500
SUBDIR.${MK_FDT}+= fdt
-SUBDIR.yes+= libefi boot1
+SUBDIR.yes+= libefi
SUBDIR.${MK_FORTH}+= loader_4th
SUBDIR.${MK_LOADER_LUA}+= loader_lua
SUBDIR.yes+= loader_simp
Index: stand/efi/boot1/Makefile
===================================================================
--- stand/efi/boot1/Makefile
+++ /dev/null
@@ -1,109 +0,0 @@
-# $FreeBSD$
-
-.include <bsd.init.mk>
-
-PROG= boot1.sym
-INTERNALPROG=
-WARNS?= 6
-
-CFLAGS+= -DEFI_BOOT1
-# We implement a slightly non-standard %S in that it always takes a
-# CHAR16 that's common in UEFI-land instead of a wchar_t. This only
-# seems to matter on arm64 where wchar_t defaults to an int instead
-# of a short. There's no good cast to use here so just ignore the
-# warnings for now.
-CWARNFLAGS.boot1.c+= -Wno-format
-
-# Disable warnings that are currently incompatible with the zfs boot code
-CWARNFLAGS.zfs_module.c += -Wno-array-bounds
-CWARNFLAGS.zfs_module.c += -Wno-cast-align
-CWARNFLAGS.zfs_module.c += -Wno-cast-qual
-CWARNFLAGS.zfs_module.c += -Wno-missing-prototypes
-CWARNFLAGS.zfs_module.c += -Wno-sign-compare
-CWARNFLAGS.zfs_module.c += -Wno-unused-parameter
-CWARNFLAGS.zfs_module.c += -Wno-unused-function
-
-# architecture-specific loader code
-SRCS= boot1.c self_reloc.c start.S ufs_module.c
-.if ${MK_ZFS} != "no"
-SRCS+= zfs_module.c
-CFLAGS.zfs_module.c+= -I${ZFSSRC}
-CFLAGS.zfs_module.c+= -I${SYSDIR}/cddl/boot/zfs
-CFLAGS.zfs_module.c+= -I${SYSDIR}/crypto/skein
-CFLAGS+= -DEFI_ZFS_BOOT
-.endif
-
-.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} > 40201
-CWARNFLAGS.self_reloc.c+= -Wno-error=maybe-uninitialized
-.endif
-
-CFLAGS+= -I${EFIINC}
-CFLAGS+= -I${EFIINCMD}
-CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include
-CFLAGS+= -DEFI_UFS_BOOT
-.ifdef(EFI_DEBUG)
-CFLAGS+= -DEFI_DEBUG
-.endif
-
-# Always add MI sources and REGULAR efi loader bits
-.PATH: ${EFISRC}/loader/arch/${MACHINE}
-.PATH: ${EFISRC}/loader
-.PATH: ${LDRSRC}
-CFLAGS+= -I${LDRSRC}
-
-FILES= boot1.efi boot1.efifat
-FILESMODE_boot1.efi= ${BINMODE}
-
-LDSCRIPT= ${EFISRC}/loader/arch/${MACHINE}/ldscript.${MACHINE}
-LDFLAGS+= -Wl,-T${LDSCRIPT},-Bsymbolic,-znotext -shared
-
-.if ${MACHINE_CPUARCH} == "aarch64"
-CFLAGS+= -mgeneral-regs-only
-.endif
-.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
-CFLAGS+= -fPIC
-LDFLAGS+= -Wl,-znocombreloc
-.endif
-
-LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a
-
-#
-# Add libstand for the runtime functions used by the compiler - for example
-# __aeabi_* (arm) or __divdi3 (i386).
-# as well as required string and memory functions for all platforms.
-#
-DPADD+= ${LIBEFI} ${LIBSA}
-LDADD+= ${LIBEFI} ${LIBSA}
-
-DPADD+= ${LDSCRIPT}
-
-boot1.efi: ${PROG}
- if ${NM} ${.ALLSRC} | grep ' U '; then \
- echo "Undefined symbols in ${.ALLSRC}"; \
- exit 1; \
- fi
- SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} \
- ${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \
- -j .dynamic -j .dynsym -j .rel.dyn \
- -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
-
-.include <bsd.prog.mk>
Index: stand/efi/boot1/Makefile.depend
===================================================================
--- stand/efi/boot1/Makefile.depend
+++ /dev/null
@@ -1,17 +0,0 @@
-# $FreeBSD$
-# Autogenerated - do NOT edit!
-
-DIRDEPS = \
- include \
- include/xlocale \
- lib/libmd \
- stand/efi/libefi \
- stand/libsa \
- stand/zfs \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
Index: stand/efi/boot1/Makefile.fat
===================================================================
--- stand/efi/boot1/Makefile.fat
+++ /dev/null
@@ -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/boot1.c
===================================================================
--- stand/efi/boot1/boot1.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*-
- * Copyright (c) 1998 Robert Nordier
- * All rights reserved.
- * Copyright (c) 2001 Robert Drehmel
- * All rights reserved.
- * Copyright (c) 2014 Nathan Whitehorn
- * All rights reserved.
- * Copyright (c) 2015 Eric McCorkle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are freely
- * permitted provided that the above copyright notice and this
- * paragraph and the following disclaimer are duplicated in all
- * such forms.
- *
- * This software is provided "AS IS" and without any express or
- * implied warranties, including, without limitation, the implied
- * warranties of merchantability and fitness for a particular
- * purpose.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <machine/elf.h>
-#include <machine/stdarg.h>
-#include <stand.h>
-
-#include <efi.h>
-#include <eficonsctl.h>
-#include <efichar.h>
-
-#include "boot_module.h"
-#include "paths.h"
-
-static void efi_panic(EFI_STATUS s, const char *fmt, ...) __dead2 __printflike(2, 3);
-
-static const boot_module_t *boot_modules[] =
-{
-#ifdef EFI_ZFS_BOOT
- &zfs_module,
-#endif
-#ifdef EFI_UFS_BOOT
- &ufs_module
-#endif
-};
-
-#define NUM_BOOT_MODULES nitems(boot_modules)
-/* The initial number of handles used to query EFI for partitions. */
-#define NUM_HANDLES_INIT 24
-
-static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
-static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
-static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
-static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
-
-/*
- * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
- * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
- * EFI methods.
- */
-void *
-Malloc(size_t len, const char *file __unused, int line __unused)
-{
- void *out;
-
- if (BS->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS)
- return (out);
-
- return (NULL);
-}
-
-void
-Free(void *buf, const char *file __unused, int line __unused)
-{
- if (buf != NULL)
- (void)BS->FreePool(buf);
-}
-
-/*
- * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match,
- * FALSE otherwise.
- */
-static BOOLEAN
-nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
-{
- size_t len;
-
- if (imgpath == NULL || imgpath->Type != devpath->Type ||
- imgpath->SubType != devpath->SubType)
- return (FALSE);
-
- len = DevicePathNodeLength(imgpath);
- if (len != DevicePathNodeLength(devpath))
- return (FALSE);
-
- return (memcmp(imgpath, devpath, (size_t)len) == 0);
-}
-
-/*
- * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes
- * in imgpath and devpath match up to their respective occurrences of a
- * media node, FALSE otherwise.
- */
-static BOOLEAN
-device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
-{
-
- if (imgpath == NULL)
- return (FALSE);
-
- while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) {
- if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) &&
- IsDevicePathType(devpath, MEDIA_DEVICE_PATH))
- return (TRUE);
-
- if (!nodes_match(imgpath, devpath))
- return (FALSE);
-
- imgpath = NextDevicePathNode(imgpath);
- devpath = NextDevicePathNode(devpath);
- }
-
- return (FALSE);
-}
-
-/*
- * devpath_last returns the last non-path end node in devpath.
- */
-static EFI_DEVICE_PATH *
-devpath_last(EFI_DEVICE_PATH *devpath)
-{
-
- while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
- devpath = NextDevicePathNode(devpath);
-
- return (devpath);
-}
-
-/*
- * load_loader attempts to load the loader image data.
- *
- * It tries each module and its respective devices, identified by mod->probe,
- * in order until a successful load occurs at which point it returns EFI_SUCCESS
- * and EFI_NOT_FOUND otherwise.
- *
- * Only devices which have preferred matching the preferred parameter are tried.
- */
-static EFI_STATUS
-load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
- size_t *bufsize, BOOLEAN preferred)
-{
- UINTN i;
- dev_info_t *dev;
- const boot_module_t *mod;
-
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- mod = boot_modules[i];
- for (dev = mod->devices(); dev != NULL; dev = dev->next) {
- if (dev->preferred != preferred)
- continue;
-
- if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) ==
- EFI_SUCCESS) {
- *devinfop = dev;
- *modp = mod;
- return (EFI_SUCCESS);
- }
- }
- }
-
- return (EFI_NOT_FOUND);
-}
-
-/*
- * try_boot only returns if it fails to load the loader. If it succeeds
- * it simply boots, otherwise it returns the status of last EFI call.
- */
-static EFI_STATUS
-try_boot(void)
-{
- size_t bufsize, loadersize, cmdsize;
- void *buf, *loaderbuf;
- char *cmd;
- dev_info_t *dev;
- const boot_module_t *mod;
- EFI_HANDLE loaderhandle;
- EFI_LOADED_IMAGE *loaded_image;
- EFI_STATUS status;
-
- status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE);
- if (status != EFI_SUCCESS) {
- status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
- FALSE);
- if (status != EFI_SUCCESS) {
- printf("Failed to load '%s'\n", PATH_LOADER_EFI);
- return (status);
- }
- }
-
- /*
- * Read in and parse the command line from /boot.config or /boot/config,
- * if present. We'll pass it the next stage via a simple ASCII
- * string. loader.efi has a hack for ASCII strings, so we'll use that to
- * keep the size down here. We only try to read the alternate file if
- * we get EFI_NOT_FOUND because all other errors mean that the boot_module
- * had troubles with the filesystem. We could return early, but we'll let
- * loading the actual kernel sort all that out. Since these files are
- * optional, we don't report errors in trying to read them.
- */
- cmd = NULL;
- cmdsize = 0;
- status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize);
- if (status == EFI_NOT_FOUND)
- status = mod->load(PATH_CONFIG, dev, &buf, &bufsize);
- if (status == EFI_SUCCESS) {
- cmdsize = bufsize + 1;
- cmd = malloc(cmdsize);
- if (cmd == NULL)
- goto errout;
- memcpy(cmd, buf, bufsize);
- cmd[bufsize] = '\0';
- free(buf);
- buf = NULL;
- }
-
- if ((status = BS->LoadImage(TRUE, IH, devpath_last(dev->devpath),
- loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) {
- printf("Failed to load image provided by %s, size: %zu, (%lu)\n",
- mod->name, loadersize, EFI_ERROR_CODE(status));
- goto errout;
- }
-
- if ((status = BS->HandleProtocol(loaderhandle, &LoadedImageGUID,
- (VOID**)&loaded_image)) != EFI_SUCCESS) {
- printf("Failed to query LoadedImage provided by %s (%lu)\n",
- mod->name, EFI_ERROR_CODE(status));
- goto errout;
- }
-
- if (cmd != NULL)
- printf(" command args: %s\n", cmd);
-
- loaded_image->DeviceHandle = dev->devhandle;
- loaded_image->LoadOptionsSize = cmdsize;
- loaded_image->LoadOptions = cmd;
-
- DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
- DSTALL(1000000);
- DPRINTF(".");
- DSTALL(1000000);
- DPRINTF(".");
- DSTALL(1000000);
- DPRINTF(".");
- DSTALL(1000000);
- DPRINTF(".");
- DSTALL(1000000);
- DPRINTF(".\n");
-
- if ((status = BS->StartImage(loaderhandle, NULL, NULL)) !=
- EFI_SUCCESS) {
- printf("Failed to start image provided by %s (%lu)\n",
- mod->name, EFI_ERROR_CODE(status));
- loaded_image->LoadOptionsSize = 0;
- loaded_image->LoadOptions = NULL;
- }
-
-errout:
- if (cmd != NULL)
- free(cmd);
- if (buf != NULL)
- free(buf);
- if (loaderbuf != NULL)
- free(loaderbuf);
-
- return (status);
-}
-
-/*
- * probe_handle determines if the passed handle represents a logical partition
- * if it does it uses each module in order to probe it and if successful it
- * returns EFI_SUCCESS.
- */
-static EFI_STATUS
-probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred)
-{
- dev_info_t *devinfo;
- EFI_BLOCK_IO *blkio;
- EFI_DEVICE_PATH *devpath;
- EFI_STATUS status;
- UINTN i;
-
- /* Figure out if we're dealing with an actual partition. */
- status = BS->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
- if (status == EFI_UNSUPPORTED)
- return (status);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("\nFailed to query DevicePath (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
-#ifdef EFI_DEBUG
- {
- CHAR16 *text = efi_devpath_name(devpath);
- DPRINTF("probing: %S\n", text);
- efi_free_devpath_name(text);
- }
-#endif
- status = BS->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
- if (status == EFI_UNSUPPORTED)
- return (status);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
-
- if (!blkio->Media->LogicalPartition)
- return (EFI_UNSUPPORTED);
-
- *preferred = device_paths_match(imgpath, devpath);
-
- /* Run through each module, see if it can load this partition */
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- devinfo = malloc(sizeof(*devinfo));
- if (devinfo == NULL) {
- DPRINTF("\nFailed to allocate devinfo\n");
- continue;
- }
- devinfo->dev = blkio;
- devinfo->devpath = devpath;
- devinfo->devhandle = h;
- devinfo->devdata = NULL;
- devinfo->preferred = *preferred;
- devinfo->next = NULL;
-
- status = boot_modules[i]->probe(devinfo);
- if (status == EFI_SUCCESS)
- return (EFI_SUCCESS);
- free(devinfo);
- }
-
- return (EFI_UNSUPPORTED);
-}
-
-/*
- * probe_handle_status calls probe_handle and outputs the returned status
- * of the call.
- */
-static void
-probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath)
-{
- EFI_STATUS status;
- BOOLEAN preferred;
-
- preferred = FALSE;
- status = probe_handle(h, imgpath, &preferred);
-
- DPRINTF("probe: ");
- switch (status) {
- case EFI_UNSUPPORTED:
- printf(".");
- DPRINTF(" not supported\n");
- break;
- case EFI_SUCCESS:
- if (preferred) {
- printf("%c", '*');
- DPRINTF(" supported (preferred)\n");
- } else {
- printf("%c", '+');
- DPRINTF(" supported\n");
- }
- break;
- default:
- printf("x");
- DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status));
- break;
- }
- DSTALL(500000);
-}
-
-EFI_STATUS
-efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
-{
- EFI_HANDLE *handles;
- EFI_LOADED_IMAGE *img;
- EFI_DEVICE_PATH *imgpath;
- EFI_STATUS status;
- EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
- SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
- UINTN i, hsize, nhandles;
- CHAR16 *text;
- UINT16 boot_current;
- size_t sz;
- UINT16 boot_order[100];
-
- /* Basic initialization*/
- ST = Xsystab;
- IH = Ximage;
- BS = ST->BootServices;
- RS = ST->RuntimeServices;
-
- /* Set up the console, so printf works. */
- status = BS->LocateProtocol(&ConsoleControlGUID, NULL,
- (VOID **)&ConsoleControl);
- if (status == EFI_SUCCESS)
- (void)ConsoleControl->SetMode(ConsoleControl,
- EfiConsoleControlScreenText);
- /*
- * Reset the console enable the cursor. Later we'll choose a better
- * console size through GOP/UGA.
- */
- conout = ST->ConOut;
- conout->Reset(conout, TRUE);
- /* Explicitly set conout to mode 0, 80x25 */
- conout->SetMode(conout, 0);
- conout->EnableCursor(conout, TRUE);
- conout->ClearScreen(conout);
-
- printf("\n>> FreeBSD EFI boot block\n");
- printf(" Loader path: %s\n\n", PATH_LOADER_EFI);
- printf(" Initializing modules:");
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- printf(" %s", boot_modules[i]->name);
- if (boot_modules[i]->init != NULL)
- boot_modules[i]->init();
- }
- putchar('\n');
-
- /* Determine the devpath of our image so we can prefer it. */
- status = BS->HandleProtocol(IH, &LoadedImageGUID, (VOID**)&img);
- imgpath = NULL;
- if (status == EFI_SUCCESS) {
- text = efi_devpath_name(img->FilePath);
- if (text != NULL) {
- printf(" Load Path: %S\n", text);
- efi_setenv_freebsd_wcs("Boot1Path", text);
- efi_free_devpath_name(text);
- }
-
- status = BS->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
- (void **)&imgpath);
- if (status != EFI_SUCCESS) {
- DPRINTF("Failed to get image DevicePath (%lu)\n",
- EFI_ERROR_CODE(status));
- } else {
- text = efi_devpath_name(imgpath);
- if (text != NULL) {
- printf(" Load Device: %S\n", text);
- efi_setenv_freebsd_wcs("Boot1Dev", text);
- efi_free_devpath_name(text);
- }
- }
- }
-
- boot_current = 0;
- sz = sizeof(boot_current);
- if (efi_global_getenv("BootCurrent", &boot_current, &sz) == EFI_SUCCESS) {
- printf(" BootCurrent: %04x\n", boot_current);
-
- sz = sizeof(boot_order);
- if (efi_global_getenv("BootOrder", &boot_order, &sz) == EFI_SUCCESS) {
- printf(" BootOrder:");
- for (i = 0; i < sz / sizeof(boot_order[0]); i++)
- printf(" %04x%s", boot_order[i],
- boot_order[i] == boot_current ? "[*]" : "");
- printf("\n");
- }
- }
-
-#ifdef TEST_FAILURE
- /*
- * For testing failover scenarios, it's nice to be able to fail fast.
- * Define TEST_FAILURE to create a boot1.efi that always fails after
- * reporting the boot manager protocol details.
- */
- BS->Exit(IH, EFI_OUT_OF_RESOURCES, 0, NULL);
-#endif
-
- /* Get all the device handles */
- hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE);
- handles = malloc(hsize);
- if (handles == NULL)
- printf("Failed to allocate %d handles\n", NUM_HANDLES_INIT);
-
- status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL,
- &hsize, handles);
- switch (status) {
- case EFI_SUCCESS:
- break;
- case EFI_BUFFER_TOO_SMALL:
- free(handles);
- handles = malloc(hsize);
- if (handles == NULL)
- efi_panic(EFI_OUT_OF_RESOURCES, "Failed to allocate %d handles\n",
- NUM_HANDLES_INIT);
- status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID,
- NULL, &hsize, handles);
- if (status != EFI_SUCCESS)
- efi_panic(status, "Failed to get device handles\n");
- break;
- default:
- efi_panic(status, "Failed to get device handles\n");
- break;
- }
-
- /* Scan all partitions, probing with all modules. */
- nhandles = hsize / sizeof(*handles);
- printf(" Probing %zu block devices...", nhandles);
- DPRINTF("\n");
-
- for (i = 0; i < nhandles; i++)
- probe_handle_status(handles[i], imgpath);
- printf(" done\n");
-
- /* Status summary. */
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- printf(" ");
- boot_modules[i]->status();
- }
-
- try_boot();
-
- /* If we get here, we're out of luck... */
- efi_panic(EFI_LOAD_ERROR, "No bootable partitions found!");
-}
-
-/*
- * add_device adds a device to the passed devinfo list.
- */
-void
-add_device(dev_info_t **devinfop, dev_info_t *devinfo)
-{
- dev_info_t *dev;
-
- if (*devinfop == NULL) {
- *devinfop = devinfo;
- return;
- }
-
- for (dev = *devinfop; dev->next != NULL; dev = dev->next)
- ;
-
- dev->next = devinfo;
-}
-
-/*
- * OK. We totally give up. Exit back to EFI with a sensible status so
- * it can try the next option on the list.
- */
-static void
-efi_panic(EFI_STATUS s, const char *fmt, ...)
-{
- va_list ap;
-
- printf("panic: ");
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- printf("\n");
-
- BS->Exit(IH, s, 0, NULL);
-}
-
-void
-putchar(int c)
-{
- CHAR16 buf[2];
-
- if (c == '\n') {
- buf[0] = '\r';
- buf[1] = 0;
- ST->ConOut->OutputString(ST->ConOut, buf);
- }
- buf[0] = c;
- buf[1] = 0;
- ST->ConOut->OutputString(ST->ConOut, buf);
-}
Index: stand/efi/boot1/boot_module.h
===================================================================
--- stand/efi/boot1/boot_module.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*-
- * Copyright (c) 2015 Eric McCorkle
- * 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _BOOT_MODULE_H_
-#define _BOOT_MODULE_H_
-
-#include <stdbool.h>
-
-#include <efi.h>
-#include <efilib.h>
-#include <eficonsctl.h>
-
-#ifdef EFI_DEBUG
-#define DPRINTF(fmt, args...) printf(fmt, ##args)
-#define DSTALL(d) BS->Stall(d)
-#else
-#define DPRINTF(fmt, ...) {}
-#define DSTALL(d) {}
-#endif
-
-/* EFI device info */
-typedef struct dev_info
-{
- EFI_BLOCK_IO *dev;
- EFI_DEVICE_PATH *devpath;
- EFI_HANDLE *devhandle;
- void *devdata;
- uint64_t partoff;
- int preferred;
- struct dev_info *next;
-} dev_info_t;
-
-/*
- * A boot loader module.
- *
- * This is a standard interface for filesystem modules in the EFI system.
- */
-typedef struct boot_module_t
-{
- const char *name;
-
- /* init is the optional initialiser for the module. */
- void (*init)(void);
-
- /*
- * probe checks to see if the module can handle dev.
- *
- * Return codes:
- * EFI_SUCCESS = The module can handle the device.
- * EFI_NOT_FOUND = The module can not handle the device.
- * Other = The module encountered an error.
- */
- EFI_STATUS (*probe)(dev_info_t* dev);
-
- /*
- * load should select the best out of a set of devices that probe
- * indicated were loadable and load the specified file.
- *
- * Return codes:
- * EFI_SUCCESS = The module can handle the device.
- * EFI_NOT_FOUND = The module can not handle the device.
- * Other = The module encountered an error.
- */
- EFI_STATUS (*load)(const char *filepath, dev_info_t *devinfo,
- void **buf, size_t *bufsize);
-
- /* status outputs information about the probed devices. */
- void (*status)(void);
-
- /* valid devices as found by probe. */
- dev_info_t *(*devices)(void);
-} boot_module_t;
-
-/* Standard boot modules. */
-#ifdef EFI_UFS_BOOT
-extern const boot_module_t ufs_module;
-#endif
-#ifdef EFI_ZFS_BOOT
-extern const boot_module_t zfs_module;
-#endif
-
-/* Functions available to modules. */
-extern void add_device(dev_info_t **devinfop, dev_info_t *devinfo);
-extern int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
-#endif
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 <<EOF
- amd64 BOOTx64.efi
- arm64 BOOTaa64.efi
- arm BOOTarm.efi
- i386 BOOTia32.efi
-EOF
Index: stand/efi/boot1/ufs_module.c
===================================================================
--- stand/efi/boot1/ufs_module.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*-
- * Copyright (c) 1998 Robert Nordier
- * All rights reserved.
- * Copyright (c) 2001 Robert Drehmel
- * All rights reserved.
- * Copyright (c) 2014 Nathan Whitehorn
- * All rights reserved.
- * Copyright (c) 2015 Eric McCorkle
- * All rights reverved.
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <sys/disk/bsd.h>
-#include <efi.h>
-
-#include "boot_module.h"
-
-#define BSD_LABEL_BUFFER 8192
-#define BSD_LABEL_OFFSET DEV_BSIZE
-
-static dev_info_t *devinfo;
-static dev_info_t *devices;
-
-static int
-dskread(void *buf, uint64_t lba, int nblk)
-{
- int size;
- EFI_STATUS status;
-
- lba += devinfo->partoff;
- lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE);
- size = nblk * DEV_BSIZE;
-
- status = devinfo->dev->ReadBlocks(devinfo->dev,
- devinfo->dev->Media->MediaId, lba, size, buf);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("dskread: failed dev: %p, id: %u, lba: %ju, size: %d, "
- "status: %lu\n", devinfo->dev,
- devinfo->dev->Media->MediaId, (uintmax_t)lba, size,
- EFI_ERROR_CODE(status));
- return (-1);
- }
-
- return (0);
-}
-
-#include "ufsread.c"
-
-static struct dmadat __dmadat;
-
-static int
-init_dev(dev_info_t* dev)
-{
- char buffer[BSD_LABEL_BUFFER];
- struct disklabel *dl;
- uint64_t bs;
- int ok;
-
- devinfo = dev;
- dmadat = &__dmadat;
-
- /*
- * First try offset 0. This is the typical GPT case where we have no
- * further partitioning (as well as the degenerate MBR case where
- * the bsdlabel has a 0 offset).
- */
- devinfo->partoff = 0;
- ok = fsread(0, NULL, 0);
- if (ok >= 0)
- return (ok);
-
- /*
- * Next, we look for a bsdlabel. This is technically located in sector
- * 1. For 4k sectors, this offset is 4096, for 512b sectors it's
- * 512. However, we have to fall back to 512 here because we create
- * images that assume 512 byte blocks, but these can be put on devices
- * who have 4k (or other) block sizes. If there's a crazy block size, we
- * skip the 'at one sector' and go stright to checking at 512 bytes.
- * There are other offsets that are historic, but we don't probe those
- * since they were never used for MBR disks on FreeBSD on systems that
- * could boot UEFI. UEFI is little endian only, as are BSD labels. We
- * will retry fsread(0) only if there's a label found with a non-zero
- * offset.
- */
- if (dskread(buffer, 0, BSD_LABEL_BUFFER / DEV_BSIZE) != 0)
- return (-1);
- dl = NULL;
- bs = devinfo->dev->Media->BlockSize;
- if (bs != 0 && bs <= BSD_LABEL_BUFFER / 2)
- dl = (struct disklabel *)&buffer[bs];
- if (dl == NULL || dl->d_magic != BSD_MAGIC || dl->d_magic2 != BSD_MAGIC)
- dl = (struct disklabel *)&buffer[BSD_LABEL_OFFSET];
- if (dl->d_magic != BSD_MAGIC || dl->d_magic2 != BSD_MAGIC ||
- dl->d_partitions[0].p_offset == 0)
- return (-1);
- devinfo->partoff = dl->d_partitions[0].p_offset;
- return (fsread(0, NULL, 0));
-}
-
-static EFI_STATUS
-probe(dev_info_t* dev)
-{
-
- if (init_dev(dev) < 0)
- return (EFI_UNSUPPORTED);
-
- add_device(&devices, dev);
-
- return (EFI_SUCCESS);
-}
-
-static EFI_STATUS
-load(const char *filepath, dev_info_t *dev, void **bufp, size_t *bufsize)
-{
- ufs_ino_t ino;
- EFI_STATUS status;
- size_t size;
- ssize_t read;
- void *buf;
-
-#ifdef EFI_DEBUG
- {
- CHAR16 *text = efi_devpath_name(dev->devpath);
- DPRINTF("Loading '%s' from %S\n", filepath, text);
- efi_free_devpath_name(text);
- }
-#endif
- if (init_dev(dev) < 0) {
- DPRINTF("Failed to init device\n");
- return (EFI_UNSUPPORTED);
- }
-
- if ((ino = lookup(filepath)) == 0) {
- DPRINTF("Failed to lookup '%s' (file not found?)\n", filepath);
- return (EFI_NOT_FOUND);
- }
-
- if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
- printf("Failed to read size of '%s' ino: %d\n", filepath, ino);
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((status = BS->AllocatePool(EfiLoaderData, size, &buf)) !=
- EFI_SUCCESS) {
- printf("Failed to allocate read buffer %zu for '%s' (%lu)\n",
- size, filepath, EFI_ERROR_CODE(status));
- return (status);
- }
-
- read = fsread(ino, buf, size);
- if ((size_t)read != size) {
- printf("Failed to read '%s' (%zd != %zu)\n", filepath, read,
- size);
- (void)BS->FreePool(buf);
- return (EFI_INVALID_PARAMETER);
- }
-
- DPRINTF("Load complete\n");
-
- *bufp = buf;
- *bufsize = size;
-
- return (EFI_SUCCESS);
-}
-
-static void
-status(void)
-{
- int i;
- dev_info_t *dev;
-
- for (dev = devices, i = 0; dev != NULL; dev = dev->next, i++)
- ;
-
- printf("%s found ", ufs_module.name);
- switch (i) {
- case 0:
- printf("no partitions\n");
- break;
- case 1:
- printf("%d partition\n", i);
- break;
- default:
- printf("%d partitions\n", i);
- }
-}
-
-static dev_info_t *
-_devices(void)
-{
-
- return (devices);
-}
-
-const boot_module_t ufs_module =
-{
- .name = "UFS",
- .probe = probe,
- .load = load,
- .status = status,
- .devices = _devices
-};
Index: stand/efi/boot1/zfs_module.c
===================================================================
--- stand/efi/boot1/zfs_module.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*-
- * Copyright (c) 2015 Eric McCorkle
- * 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.
- *
- * $FreeBSD$
- */
-#include <stddef.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <efi.h>
-
-#include "boot_module.h"
-
-#include "libzfs.h"
-#include "zfsimpl.c"
-
-static dev_info_t *devices;
-
-uint64_t
-ldi_get_size(void *priv)
-{
- dev_info_t *devinfo = priv;
-
- return (devinfo->dev->Media->BlockSize *
- (devinfo->dev->Media->LastBlock + 1));
-}
-
-static int
-vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
-{
- dev_info_t *devinfo;
- uint64_t lba;
- size_t size, remainder, rb_size, blksz;
- char *bouncebuf = NULL, *rb_buf;
- EFI_STATUS status;
-
- devinfo = (dev_info_t *)priv;
- lba = off / devinfo->dev->Media->BlockSize;
- remainder = off % devinfo->dev->Media->BlockSize;
-
- rb_buf = buf;
- rb_size = bytes;
-
- /*
- * If we have remainder from off, we need to add remainder part.
- * Since buffer must be multiple of the BlockSize, round it all up.
- */
- size = roundup2(bytes + remainder, devinfo->dev->Media->BlockSize);
- blksz = size;
- if (remainder != 0 || size != bytes) {
- rb_size = devinfo->dev->Media->BlockSize;
- bouncebuf = malloc(rb_size);
- if (bouncebuf == NULL) {
- printf("vdev_read: out of memory\n");
- return (-1);
- }
- rb_buf = bouncebuf;
- blksz = rb_size - remainder;
- }
-
- while (bytes > 0) {
- status = devinfo->dev->ReadBlocks(devinfo->dev,
- devinfo->dev->Media->MediaId, lba, rb_size, rb_buf);
- if (EFI_ERROR(status))
- goto error;
- if (bytes < blksz)
- blksz = bytes;
- if (bouncebuf != NULL)
- memcpy(buf, rb_buf + remainder, blksz);
- buf = (void *)((uintptr_t)buf + blksz);
- bytes -= blksz;
- lba++;
- remainder = 0;
- blksz = rb_size;
- }
-
- free(bouncebuf);
- return (0);
-
-error:
- free(bouncebuf);
- DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %ju, size: %zu,"
- " rb_size: %zu, status: %lu\n", devinfo->dev,
- devinfo->dev->Media->MediaId, (uintmax_t)lba, bytes, rb_size,
- EFI_ERROR_CODE(status));
- return (-1);
-}
-
-static EFI_STATUS
-probe(dev_info_t *dev)
-{
- spa_t *spa;
- dev_info_t *tdev;
- EFI_STATUS status;
-
- /* ZFS consumes the dev on success so we need a copy. */
- if ((status = BS->AllocatePool(EfiLoaderData, sizeof(*dev),
- (void**)&tdev)) != EFI_SUCCESS) {
- DPRINTF("Failed to allocate tdev (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
- memcpy(tdev, dev, sizeof(*dev));
-
- if (vdev_probe(vdev_read, tdev, &spa) != 0) {
- (void)BS->FreePool(tdev);
- return (EFI_UNSUPPORTED);
- }
-
- dev->devdata = spa;
- add_device(&devices, dev);
-
- return (EFI_SUCCESS);
-}
-
-static EFI_STATUS
-load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize)
-{
- spa_t *spa;
- struct zfsmount zfsmount;
- dnode_phys_t dn;
- struct stat st;
- int err;
- void *buf;
- EFI_STATUS status;
-
- spa = devinfo->devdata;
-
-#ifdef EFI_DEBUG
- {
- CHAR16 *text = efi_devpath_name(devinfo->devpath);
- DPRINTF("load: '%s' spa: '%s', devpath: %S\n", filepath,
- spa->spa_name, text);
- efi_free_devpath_name(text);
- }
-#endif
- if ((err = zfs_spa_init(spa)) != 0) {
- DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err);
- return (EFI_NOT_FOUND);
- }
-
- if ((err = zfs_mount(spa, 0, &zfsmount)) != 0) {
- DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err);
- return (EFI_NOT_FOUND);
- }
-
- if ((err = zfs_lookup(&zfsmount, filepath, &dn)) != 0) {
- if (err == ENOENT) {
- DPRINTF("Failed to find '%s' on pool '%s' (%d)\n",
- filepath, spa->spa_name, err);
- return (EFI_NOT_FOUND);
- }
- printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath,
- spa->spa_name, err);
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((err = zfs_dnode_stat(spa, &dn, &st)) != 0) {
- printf("Failed to stat '%s' on pool '%s' (%d)\n", filepath,
- spa->spa_name, err);
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((status = BS->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf))
- != EFI_SUCCESS) {
- printf("Failed to allocate load buffer %jd for pool '%s' for '%s' "
- "(%lu)\n", (intmax_t)st.st_size, spa->spa_name, filepath, EFI_ERROR_CODE(status));
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((err = dnode_read(spa, &dn, 0, buf, st.st_size)) != 0) {
- printf("Failed to read node from %s (%d)\n", spa->spa_name,
- err);
- (void)BS->FreePool(buf);
- return (EFI_INVALID_PARAMETER);
- }
-
- *bufsize = st.st_size;
- *bufp = buf;
-
- return (EFI_SUCCESS);
-}
-
-static void
-status(void)
-{
- spa_t *spa;
-
- spa = STAILQ_FIRST(&zfs_pools);
- if (spa == NULL) {
- printf("%s found no pools\n", zfs_module.name);
- return;
- }
-
- printf("%s found the following pools:", zfs_module.name);
- STAILQ_FOREACH(spa, &zfs_pools, spa_link)
- printf(" %s", spa->spa_name);
-
- printf("\n");
-}
-
-static void
-init(void)
-{
-
- zfs_init();
-}
-
-static dev_info_t *
-_devices(void)
-{
-
- return (devices);
-}
-
-const boot_module_t zfs_module =
-{
- .name = "ZFS",
- .init = init,
- .probe = probe,
- .load = load,
- .status = status,
- .devices = _devices
-};
Index: tools/boot/install-boot.sh
===================================================================
--- tools/boot/install-boot.sh
+++ tools/boot/install-boot.sh
@@ -1,5 +1,4 @@
#!/bin/sh
-
# $FreeBSD$
#
@@ -27,19 +26,96 @@
gpart show $dev | tail +2 | awk '$4 == "'$part'" { print $3; }'
}
-make_esp() {
+get_uefi_bootname() {
+
+ if [ "$TARGET" == "" ]; then
+ if [ `uname -m` == amd64 ]; then
+ efibootfile=BOOTx64.EFI
+ elif [ `uname -m` == arm64 ]; then
+ efibootfile=BOOTaa64.EFI
+ elif [ `uname -m` == i386 ]; then
+ efibootfile=BOOTia32.EFI
+ else
+ efibootfile=BOOTarm.EFI
+ fi
+ else
+ if [ $TARGET == amd64 ]; then
+ efibootfile=BOOTx64.EFI
+ elif [ $TARGET == arm64 ]; then
+ efibootfile=BOOTaa64.EFI
+ elif [ $TARGET == i386 ]; then
+ efibootfile=BOOTia32.EFI
+ else
+ efibootfile=BOOTarm.EFI
+ fi
+ fi
+}
+
+make_esp_file() {
+ local file sizekb loader mntpt fatbits
+
+ file=$1
+ sizekb=$2
+ loader=$3
+
+ if [ $sizekb -ge 33292 ]; then
+ fatbits=32
+ elif [ $sizekb -ge 2100 ]; 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}
+ mntpt=$(mktemp -d /tmp/stand-test.XXXXXX)
+ mount -t msdosfs /dev/${device} ${mntpt}
+ mkdir -p ${mntpt}/EFI/BOOT
+ get_uefi_bootname
+ cp "${loader}" ${mntpt}/EFI/BOOT/${efibootfile}
+ umount ${mntpt}
+ rmdir ${mntpt}
+ mdconfig -d -u ${device}
+}
+
+make_esp_device() {
local dev dst mntpt
+ # ESP device node
dev=$1
+ # destdir
dst=$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
+
+ mount -t msdosfs ${dev} ${mntpt}
+ if [ $? -ne 0 ]; then
+ newfs_msdos -F 32 -c 1 -L EFISYS ${dev}
+ mount -t msdosfs ${dev}
+ fi
+
+ mkdir -p ${mntpt}/EFI/freebsd
+ cp ${dst}/boot/loader.efi ${mntpt}/EFI/freebsd/loader.efi
+
+ efibootmgr --create --label FreeBSD --loader ${mntpt}/freebsd/loader.efi
umount ${mntpt}
rmdir ${mntpt}
+
+ 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}
+}
+
+make_esp() {
+ file=$1
+ dst=$2
+
+ if [ -f $file ]; then
+ make_esp_file ${file} 33292 ${dst}/boot/loader.efi
+ else
+ make_esp_device ${file} ${dst}/boot/loader.efi
+ fi
}
make_esp_mbr() {
@@ -53,7 +129,7 @@
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 +140,7 @@
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,12 +294,24 @@
doit gpart bootcode -p ${vtoc8} ${dev}
}
+usage() {
+ printf '%s -b bios [-d destdir] -f fs [-g geli] -h [-o optargs] -s scheme bootdev\n\n' $0
+ printf '\t bootdev: device to install the boot code on\n'
+ printf '\t -b bios bios type: legacy, uefi or both\n'
+ printf '\t -d destdir destination filesystem root\n'
+ printf '\t -f fs filesystem type: ufs or zfs\n'
+ printf '\t -g geli yes or no\n'
+ printf '\t -h help this help/usage text\n'
+ printf '\t -o optargs optional arguments\n'
+ printf '\t -s scheme mbr or gpt\n\n'
+}
+
DESTDIR=/
# 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}
@@ -240,6 +328,10 @@
*) geli=nogeli ;;
esac
;;
+ h)
+ usage
+ exit 0
+ ;;
o)
opts=${OPTARG}
;;
@@ -249,8 +341,7 @@
esac
done
-shift $((OPTIND-1))
-dev=$1
+dev=$((OPTIND-1))
# For gpt, we need to install pmbr as the primary boot loader
# it knows about
@@ -267,4 +358,6 @@
# sanity check here
-eval boot_${geli}_${scheme}_${fs}_${bios} $dev $DESTDIR $opts || echo "Unsupported boot env: ${geli}-${scheme}-${fs}-${bios}"
+if [ "${scheme}" != "" -a "${fs}" != "" -a "${bios}" != "" ]; then
+ eval boot_${geli}_${scheme}_${fs}_${bios} $dev $DESTDIR $opts || echo "Unsupported boot env: ${geli}-${scheme}-${fs}-${bios}"
+fi
Index: tools/boot/rootgen.sh
===================================================================
--- tools/boot/rootgen.sh
+++ tools/boot/rootgen.sh
@@ -5,8 +5,6 @@
passphrase=passphrase
iterations=50000
-do_boot1_efi=0
-
#
# Builds all the bat-shit crazy combinations we support booting from,
# at least for amd64. It assume you have a ~sane kernel in /boot/kernel
@@ -16,13 +14,13 @@
# 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 +32,6 @@
(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 +53,8 @@
cat > ${src}/etc/fstab <<EOF
/dev/ada0p2 / ufs rw 1 1
EOF
- make_esp ${src} ${img}.p1
+ # The smallest ESP (FAT32) filesystem is 33292 KB
+ make_esp_file ${img}.p1 33292 ${src}
makefs -t ffs -B little -s 200m ${img}.p2 ${src}
mkimg -s gpt \
-p efi:=${img}.p1 \
@@ -93,7 +69,7 @@
cat > ${src}/etc/fstab <<EOF
/dev/ada0p3 / ufs rw 1 1
EOF
- make_esp ${src} ${img}.p1
+ make_esp_file ${img}.p1 33292 ${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 +131,7 @@
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 35M -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 +169,7 @@
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 35M -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 +215,7 @@
cat > ${src}/etc/fstab <<EOF
/dev/ada0s2a / ufs rw 1 1
EOF
- make_esp ${src} ${img}.s1
+ make_esp_file ${img}.s1 33292 ${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 +229,7 @@
cat > ${src}/etc/fstab <<EOF
/dev/ada0s2a / ufs rw 1 1
EOF
- make_esp ${src} ${img}.s1
+ make_esp_file ${img}.s1 33292 ${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 +289,7 @@
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 35M ${md}
gpart add -t freebsd ${md}
gpart set -a active -i 2 ${md}
gpart create -s bsd ${md}s2
@@ -354,7 +330,7 @@
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 35M ${md}
gpart add -t freebsd ${md}
gpart set -a active -i 2 ${md}
gpart create -s bsd ${md}s2
@@ -430,7 +406,7 @@
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 35M -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 +442,7 @@
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 35M -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 +523,7 @@
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 35M -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 +566,7 @@
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 35M -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
Index: tools/tools/nanobsd/embedded/common
===================================================================
--- tools/tools/nanobsd/embedded/common
+++ tools/tools/nanobsd/embedded/common
@@ -301,7 +301,7 @@
# 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 @@
# 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 \
Index: usr.sbin/bsdinstall/partedit/gpart_ops.c
===================================================================
--- usr.sbin/bsdinstall/partedit/gpart_ops.c
+++ usr.sbin/bsdinstall/partedit/gpart_ops.c
@@ -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 @@
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,
+ 0600);
+ 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
@@ -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 @@
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
@@ -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 @@
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,50 @@
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 -o `uname -m` == i386 ]; then
+ X86_BOOTMETHOD=`sysctl -n machdep.bootmethod`
+fi
+
+if [ `uname -m` == arm64 -o "$X86_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 -L EFISYS /dev/$esp
+ mount -t 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
+ rmdir $BSDINSTALL_TMPETC/esp
+
+ # 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`
+ 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,6 @@
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 @@
"$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 +1572,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
#

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 25, 12:05 AM (9 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24150644
Default Alt Text
D17947.id51745.diff (62 KB)

Event Timeline