Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Oct 2019 02:53:07 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r353982 - in stable/12/stand/efi: boot1 include libefi loader
Message-ID:  <201910240253.x9O2r7nR099492@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Thu Oct 24 02:53:07 2019
New Revision: 353982
URL: https://svnweb.freebsd.org/changeset/base/353982

Log:
  MFC r346702-r346704, r346879-r346881, r347023, r347059-r347062,
  r347193-r347194, r347201
  
  r346702:
  Add efi_freebsd_delenv
  
  Add a wrapper around efi_delenv akin to efi_freebsd_getenv and
  efi_getenv.
  
  r346703:
  Move initialization of the block device handles earlier (we're just
  snagging them from UEFI BIOS). Call the device type init routines
  earlier as well, as they don't depend on how the console is
  setup. This will allow us to read files earlier in boot, so any rare
  error messages that this might move only to the EFI console will be an
  acceptable price to pay. Also tweak the order of has_kbd so it resides
  next to the rest of the console code. It needs to be after we initialize
  the buffer cache.
  
  r346704:
  Add the proper range of years for Netflix's copyright on this
  file. Note that I wrote it.
  
  r346879:
  Read in and parse /efi/freebsd/loader.env from the boot device's
  partition as if it were on the command line.
  
  Fetch FreeBSD-LoaderEnv UEFI enviornment variable. If set, read in
  loader environment variables from it. Otherwise read in
  /efi/freebsd/loader.env. Both are read relative to the device
  loader.efi loaded from (they aren't full UEFI device paths)
  
  Next fetch FreeBSD-NextLoaderEnv UEFI environment variable. If
  present, read the file it points to in as above and delete the UEFI
  environment variable so it only happens once.
  
  This lets one set environment variables in the bootloader.
  Unfortunately, we don't have all the mechanisms in place to parse the
  file, nor do we have the magic pattern matching in place that
  loader.conf has. Variables are of the form foo=bar. No quotes are
  supported, so spaces aren't allowed, for example. Also, variables like
  foo_load=yes are intercepted when we parse the loader.conf file and
  things are done based on that. Since those aren't done here, variables
  that cause an action to happen won't work.
  
  r346880:
  Implement uefi_rootdev
  
  If uefi_rootdev is set in the environment, then treat it like a device
  path. Convert the string to a device path and see if we can find a
  device that matches. If so, use that device at our root dev no matter
  what. If it's bad in any way, the boot will fail.
  
  r346881:
  Implement uefi_ignore_boot_mgr env variable.
  
  When set, we ignore all the hints that the UEFI boot manager has set
  for us. We also always fail back to the OK prompt when we can't find
  the right thing to boot rather than failing back to the UEFI boot
  manager. This has the side effect of also expanding the cases where we
  fail back to the OK prompt to include when we're booted under UEFI,
  but UEFI::BootCurrent isn't set in the environment and we can't find a
  proper place to boot from.
  
  r347023:
  stand: correct mis-merge from r346879
  
  Small mis-merge from multiple WIP resulted in block io media handles getting
  double-initialized. This resulted in some installations oddly landing at the
  mountroot prompt.
  
  r347059:
  Remove stray '*'
  
  We're storing an EFI_HANDLE, not an pointer to a handle. Since
  EFI_HANDLE is a void * anyway, this has little practical effect since
  the conversion to / from void * and void ** is silent.
  
  r347060:
  When we can't get memory, trying again right away is going to
  fail. Rather than print N failure messages, bail on the first one.
  
  r347061:
  Substitute boot1 with ${BOOT1}
  
  Allow for other names to be built, so parameterize this makefile to
  avoid hard coding boot1.
  
  r347062:
  Use SRC+= rather than SRC=
  
  To allow boot1/Makefile to be included, use SRC+= rathern than SRC=
  so the including Makefile can add additional sources to the build.
  
  r347193:
  Reach over and pull in devpath.c from libefi
  
  This allows us to remove three nearly identical functions because the
  differences don't matter, and the size difference is trivial.
  
  r347194:
  We only ever need one devinfo per handle. So allocate it outside of
  looping over the filesystem modules rather than doing a malloc + free
  each time through the loop. In addition, nothing changes from loop to
  loop, so setup the new devinfo outside the loop as well.
  
  r347201:
  Simplify boot1 allocation of handles.
  
  There's no need to pre-malloc the number of handles. Instead call
  LocateHandles twice, once to get the size, and once to get the
  data.

Modified:
  stable/12/stand/efi/boot1/Makefile
  stable/12/stand/efi/boot1/boot1.c
  stable/12/stand/efi/boot1/boot_module.h
  stable/12/stand/efi/include/efilib.h
  stable/12/stand/efi/libefi/efienv.c
  stable/12/stand/efi/loader/main.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/stand/efi/boot1/Makefile
==============================================================================
--- stable/12/stand/efi/boot1/Makefile	Thu Oct 24 02:49:13 2019	(r353981)
+++ stable/12/stand/efi/boot1/Makefile	Thu Oct 24 02:53:07 2019	(r353982)
@@ -2,7 +2,8 @@
 
 .include <bsd.init.mk>
 
-PROG=		boot1.sym
+BOOT1?=		boot1
+PROG=		${BOOT1}.sym
 INTERNALPROG=
 WARNS?=		6
 
@@ -24,7 +25,7 @@ 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
+SRCS+=	boot1.c self_reloc.c start.S ufs_module.c devpath.c
 .if ${MK_LOADER_ZFS} != "no"
 SRCS+=		zfs_module.c
 CFLAGS.zfs_module.c+=	-I${ZFSSRC}
@@ -51,10 +52,11 @@ CFLAGS+=	-DEFI_DEBUG
 .PATH:		${EFISRC}/loader/arch/${MACHINE}
 .PATH:		${EFISRC}/loader
 .PATH:		${LDRSRC}
+.PATH:		${EFISRC}/libefi
 CFLAGS+=	-I${LDRSRC}
 
-FILES=	boot1.efi boot1.efifat
-FILESMODE_boot1.efi=	${BINMODE}
+FILES=	${BOOT1}.efi ${BOOT1}.efifat
+FILESMODE_${BOOT1}.efi=	${BINMODE}
 
 LDSCRIPT=	${EFISRC}/loader/arch/${MACHINE}/ldscript.${MACHINE}
 LDFLAGS+=	-Wl,-T${LDSCRIPT},-Bsymbolic,-znotext -shared
@@ -79,7 +81,7 @@ LDADD+=		${LIBEFI} ${LIBSA}
 
 DPADD+=		${LDSCRIPT}
 
-boot1.efi: ${PROG}
+${BOOT1}.efi: ${PROG}
 	if ${NM} ${.ALLSRC} | grep ' U '; then \
 		echo "Undefined symbols in ${.ALLSRC}"; \
 		exit 1; \
@@ -95,7 +97,7 @@ boot1.efi: ${PROG}
 
 .include "Makefile.fat"
 
-boot1.efifat: boot1.efi
+${BOOT1}.efifat: ${BOOT1}.efi
 	@set -- `ls -l ${.ALLSRC}`; \
 	x=$$(($$5-${BOOT1_MAXSIZE})); \
 	if [ $$x -ge 0 ]; then \
@@ -106,6 +108,6 @@ boot1.efifat: boot1.efi
 	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 ${BOOT1}.efifat
 
 .include <bsd.prog.mk>

Modified: stable/12/stand/efi/boot1/boot1.c
==============================================================================
--- stable/12/stand/efi/boot1/boot1.c	Thu Oct 24 02:49:13 2019	(r353981)
+++ stable/12/stand/efi/boot1/boot1.c	Thu Oct 24 02:53:07 2019	(r353982)
@@ -47,8 +47,6 @@ static const boot_module_t *boot_modules[] =
 };
 
 #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;
@@ -93,66 +91,6 @@ Calloc(size_t n1, size_t n2, const char *file, int lin
 }
 
 /*
- * 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,
@@ -239,7 +177,7 @@ try_boot(void)
 		buf = NULL;
 	}
 
-	if ((status = BS->LoadImage(TRUE, IH, devpath_last(dev->devpath),
+	if ((status = BS->LoadImage(TRUE, IH, efi_devpath_last_node(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));
@@ -336,27 +274,27 @@ probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, B
 	if (!blkio->Media->LogicalPartition)
 		return (EFI_UNSUPPORTED);
 
-	*preferred = device_paths_match(imgpath, devpath);
+	*preferred = efi_devpath_match(imgpath, devpath);
 
 	/* Run through each module, see if it can load this partition */
+	devinfo = malloc(sizeof(*devinfo));
+	if (devinfo == NULL) {
+		DPRINTF("\nFailed to allocate devinfo\n");
+		return (EFI_UNSUPPORTED);
+	}
+	devinfo->dev = blkio;
+	devinfo->devpath = devpath;
+	devinfo->devhandle = h;
+	devinfo->preferred = *preferred;
+	devinfo->next = NULL;
+
 	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);
 	}
+	free(devinfo);
 
 	return (EFI_UNSUPPORTED);
 }
@@ -495,32 +433,17 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
 	BS->Exit(IH, EFI_OUT_OF_RESOURCES, 0, NULL);
 #endif
 
-	/* Get all the device handles */
-	hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE);
+	hsize = 0;
+	BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL,
+	    &hsize, NULL);
 	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(EFI_OUT_OF_RESOURCES, "Failed to allocate %d handles\n",
+		    hsize);
+	status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID,
+	    NULL, &hsize, handles);
+	if (status != EFI_SUCCESS)
 		efi_panic(status, "Failed to get device handles\n");
-		break;
-	}
 
 	/* Scan all partitions, probing with all modules. */
 	nhandles = hsize / sizeof(*handles);

Modified: stable/12/stand/efi/boot1/boot_module.h
==============================================================================
--- stable/12/stand/efi/boot1/boot_module.h	Thu Oct 24 02:49:13 2019	(r353981)
+++ stable/12/stand/efi/boot1/boot_module.h	Thu Oct 24 02:53:07 2019	(r353982)
@@ -48,7 +48,7 @@ typedef struct dev_info
 {
 	EFI_BLOCK_IO *dev;
 	EFI_DEVICE_PATH *devpath;
-	EFI_HANDLE *devhandle;
+	EFI_HANDLE devhandle;
 	void *devdata;
 	uint64_t partoff;
 	int preferred;

Modified: stable/12/stand/efi/include/efilib.h
==============================================================================
--- stable/12/stand/efi/include/efilib.h	Thu Oct 24 02:49:13 2019	(r353981)
+++ stable/12/stand/efi/include/efilib.h	Thu Oct 24 02:53:07 2019	(r353982)
@@ -128,6 +128,7 @@ void cpy16to8(const CHAR16 *, char *, size_t);
  */
 
 EFI_STATUS efi_delenv(EFI_GUID *guid, const char *varname);
+EFI_STATUS efi_freebsd_delenv(const char *varname);
 EFI_STATUS efi_freebsd_getenv(const char *v, void *data, __size_t *len);
 EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, __size_t *len);
 EFI_STATUS efi_global_getenv(const char *v, void *data, __size_t *len);

Modified: stable/12/stand/efi/libefi/efienv.c
==============================================================================
--- stable/12/stand/efi/libefi/efienv.c	Thu Oct 24 02:49:13 2019	(r353981)
+++ stable/12/stand/efi/libefi/efienv.c	Thu Oct 24 02:53:07 2019	(r353982)
@@ -119,5 +119,11 @@ efi_delenv(EFI_GUID *guid, const char *name)
 
 	rv = RS->SetVariable(var, guid, 0, 0, NULL);
 	free(var);
-	return rv;
+	return (rv);
+}
+
+EFI_STATUS
+efi_freebsd_delenv(const char *name)
+{
+	return (efi_delenv(&FreeBSDBootVarGUID, name));
 }

Modified: stable/12/stand/efi/loader/main.c
==============================================================================
--- stable/12/stand/efi/loader/main.c	Thu Oct 24 02:49:13 2019	(r353981)
+++ stable/12/stand/efi/loader/main.c	Thu Oct 24 02:53:07 2019	(r353982)
@@ -3,7 +3,7 @@
  * Copyright (c) 2006 Marcel Moolenaar
  * All rights reserved.
  *
- * Copyright (c) 2018 Netflix, Inc.
+ * Copyright (c) 2016-2019 Netflix, Inc. written by M. Warner Losh
  * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -472,13 +472,35 @@ find_currdev(bool do_bootmgr, bool is_last,
 	 */
 	rootdev = getenv("rootdev");
 	if (rootdev != NULL) {
-		printf("Setting currdev to configured rootdev %s\n", rootdev);
+		printf("    Setting currdev to configured rootdev %s\n",
+		    rootdev);
 		set_currdev(rootdev);
 		return (0);
 	}
 
 	/*
-	 * Second choice: If we can find out image boot_info, and there's
+	 * Second choice: If uefi_rootdev is set, translate that UEFI device
+	 * path to the loader's internal name and use that.
+	 */
+	do {
+		rootdev = getenv("uefi_rootdev");
+		if (rootdev == NULL)
+			break;
+		devpath = efi_name_to_devpath(rootdev);
+		if (devpath == NULL)
+			break;
+		dp = efiblk_get_pdinfo_by_device_path(devpath);
+		efi_devpath_free(devpath);
+		if (dp == NULL)
+			break;
+		printf("    Setting currdev to UEFI path %s\n",
+		    rootdev);
+		set_currdev_pdinfo(dp);
+		return (0);
+	} while (0);
+
+	/*
+	 * Third choice: If we can find out image boot_info, and there's
 	 * a follow-on boot image in that boot_info, use that. In this
 	 * case root will be the partition specified in that image and
 	 * we'll load the kernel specified by the file path. Should there
@@ -742,6 +764,80 @@ out:
 	return (how);
 }
 
+void
+parse_loader_efi_config(EFI_HANDLE h, const char *env_fn)
+{
+	pdinfo_t *dp;
+	struct stat st;
+	int fd = -1;
+	char *env = NULL;
+
+	dp = efiblk_get_pdinfo_by_handle(h);
+	if (dp == NULL)
+		return;
+	set_currdev_pdinfo(dp);
+	if (stat(env_fn, &st) != 0)
+		return;
+	fd = open(env_fn, O_RDONLY);
+	if (fd == -1)
+		return;
+	env = malloc(st.st_size + 1);
+	if (env == NULL)
+		goto out;
+	if (read(fd, env, st.st_size) != st.st_size)
+		goto out;
+	env[st.st_size] = '\0';
+	boot_parse_cmdline(env);
+out:
+	free(env);
+	close(fd);
+}
+
+static void
+read_loader_env(const char *name, char *def_fn, bool once)
+{
+	UINTN len;
+	char *fn, *freeme = NULL;
+
+	len = 0;
+	fn = def_fn;
+	if (efi_freebsd_getenv(name, NULL, &len) == EFI_BUFFER_TOO_SMALL) {
+		freeme = fn = malloc(len + 1);
+		if (fn != NULL) {
+			if (efi_freebsd_getenv(name, fn, &len) != EFI_SUCCESS) {
+				free(fn);
+				fn = NULL;
+				printf(
+			    "Can't fetch FreeBSD::%s we know is there\n", name);
+			} else {
+				/*
+				 * if tagged as 'once' delete the env variable so we
+				 * only use it once.
+				 */
+				if (once)
+					efi_freebsd_delenv(name);
+				/*
+				 * We malloced 1 more than len above, then redid the call.
+				 * so now we have room at the end of the string to NUL terminate
+				 * it here, even if the typical idium would have '- 1' here to
+				 * not overflow. len should be the same on return both times.
+				 */
+				fn[len] = '\0';
+			}
+		} else {
+			printf(
+		    "Can't allocate %d bytes to fetch FreeBSD::%s env var\n",
+			    len, name);
+		}
+	}
+	if (fn) {
+		printf("    Reading loader env vars from %s\n", fn);
+		parse_loader_efi_config(boot_img->DeviceHandle, fn);
+	}
+}
+
+
+
 EFI_STATUS
 main(int argc, CHAR16 *argv[])
 {
@@ -783,13 +879,30 @@ main(int argc, CHAR16 *argv[])
 	/* Init the time source */
 	efi_time_init();
 
-	has_kbd = has_keyboard();
-
 	/*
 	 * Initialise the block cache. Set the upper limit.
 	 */
 	bcache_init(32768, 512);
 
+	/*
+	 * Scan the BLOCK IO MEDIA handles then
+	 * march through the device switch probing for things.
+	 */
+	i = efipart_inithandles();
+	if (i != 0 && i != ENOENT) {
+		printf("efipart_inithandles failed with ERRNO %d, expect "
+		    "failures\n", i);
+	}
+
+	for (i = 0; devsw[i] != NULL; i++)
+		if (devsw[i]->dv_init != NULL)
+			(devsw[i]->dv_init)();
+
+	/*
+	 * Detect console settings two different ways: one via the command
+	 * args (eg -h) or via the UEFI ConOut variable.
+	 */
+	has_kbd = has_keyboard();
 	howto = parse_args(argc, argv);
 	if (!has_kbd && (howto & RB_PROBE))
 		howto |= RB_SERIAL | RB_MULTIPLE;
@@ -797,6 +910,24 @@ main(int argc, CHAR16 *argv[])
 	uhowto = parse_uefi_con_out();
 
 	/*
+	 * Read additional environment variables from the boot device's
+	 * "LoaderEnv" file. Any boot loader environment variable may be set
+	 * there, which are subtly different than loader.conf variables. Only
+	 * the 'simple' ones may be set so things like foo_load="YES" won't work
+	 * for two reasons.  First, the parser is simplistic and doesn't grok
+	 * quotes.  Second, because the variables that cause an action to happen
+	 * are parsed by the lua, 4th or whatever code that's not yet
+	 * loaded. This is relative to the root directory when loader.efi is
+	 * loaded off the UFS root drive (when chain booted), or from the ESP
+	 * when directly loaded by the BIOS.
+	 *
+	 * We also read in NextLoaderEnv if it was specified. This allows next boot
+	 * functionality to be implemented and to override anything in LoaderEnv.
+	 */
+	read_loader_env("LoaderEnv", "/efi/freebsd/loader.env", false);
+	read_loader_env("NextLoaderEnv", NULL, true);
+
+	/*
 	 * We now have two notions of console. howto should be viewed as
 	 * overrides. If console is already set, don't set it again.
 	 */
@@ -852,20 +983,6 @@ main(int argc, CHAR16 *argv[])
 	if ((s = getenv("fail_timeout")) != NULL)
 		fail_timeout = strtol(s, NULL, 10);
 
-	/*
-	 * Scan the BLOCK IO MEDIA handles then
-	 * march through the device switch probing for things.
-	 */
-	i = efipart_inithandles();
-	if (i != 0 && i != ENOENT) {
-		printf("efipart_inithandles failed with ERRNO %d, expect "
-		    "failures\n", i);
-	}
-
-	for (i = 0; devsw[i] != NULL; i++)
-		if (devsw[i]->dv_init != NULL)
-			(devsw[i]->dv_init)();
-
 	printf("%s\n", bootprog_info);
 	printf("   Command line arguments:");
 	for (i = 0; i < argc; i++)
@@ -878,8 +995,6 @@ main(int argc, CHAR16 *argv[])
 	    ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
 	printf("   Console: %s (%#x)\n", getenv("console"), howto);
 
-
-
 	/* Determine the devpath of our image so we can prefer it. */
 	text = efi_devpath_name(boot_img->FilePath);
 	if (text != NULL) {
@@ -898,36 +1013,41 @@ main(int argc, CHAR16 *argv[])
 		}
 	}
 
-	uefi_boot_mgr = true;
-	boot_current = 0;
-	sz = sizeof(boot_current);
-	rv = efi_global_getenv("BootCurrent", &boot_current, &sz);
-	if (rv == EFI_SUCCESS)
-		printf("   BootCurrent: %04x\n", boot_current);
-	else {
-		boot_current = 0xffff;
+	if (getenv("uefi_ignore_boot_mgr") != NULL) {
+		printf("    Ignoring UEFI boot manager\n");
 		uefi_boot_mgr = false;
-	}
+	} else {
+		uefi_boot_mgr = true;
+		boot_current = 0;
+		sz = sizeof(boot_current);
+		rv = efi_global_getenv("BootCurrent", &boot_current, &sz);
+		if (rv == EFI_SUCCESS)
+			printf("   BootCurrent: %04x\n", boot_current);
+		else {
+			boot_current = 0xffff;
+			uefi_boot_mgr = false;
+		}
 
-	sz = sizeof(boot_order);
-	rv = efi_global_getenv("BootOrder", &boot_order, &sz);
-	if (rv == 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");
-		is_last = boot_order[(sz / sizeof(boot_order[0])) - 1] == boot_current;
-		bosz = sz;
-	} else if (uefi_boot_mgr) {
-		/*
-		 * u-boot doesn't set BootOrder, but otherwise participates in the
-		 * boot manager protocol. So we fake it here and don't consider it
-		 * a failure.
-		 */
-		bosz = sizeof(boot_order[0]);
-		boot_order[0] = boot_current;
-		is_last = true;
+		sz = sizeof(boot_order);
+		rv = efi_global_getenv("BootOrder", &boot_order, &sz);
+		if (rv == 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");
+			is_last = boot_order[(sz / sizeof(boot_order[0])) - 1] == boot_current;
+			bosz = sz;
+		} else if (uefi_boot_mgr) {
+			/*
+			 * u-boot doesn't set BootOrder, but otherwise participates in the
+			 * boot manager protocol. So we fake it here and don't consider it
+			 * a failure.
+			 */
+			bosz = sizeof(boot_order[0]);
+			boot_order[0] = boot_current;
+			is_last = true;
+		}
 	}
 
 	/*
@@ -976,7 +1096,8 @@ main(int argc, CHAR16 *argv[])
 	 * to try something different.
 	 */
 	if (find_currdev(uefi_boot_mgr, is_last, boot_info, bisz) != 0)
-		if (!interactive_interrupt("Failed to find bootable partition"))
+		if (uefi_boot_mgr &&
+		    !interactive_interrupt("Failed to find bootable partition"))
 			return (EFI_NOT_FOUND);
 
 	efi_init_environment();



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