svn commit: r323065 - in head/sys/boot/efi: boot1 include

Warner Losh imp at FreeBSD.org
Thu Aug 31 17:32:25 UTC 2017


Author: imp
Date: Thu Aug 31 17:32:24 2017
New Revision: 323065
URL: https://svnweb.freebsd.org/changeset/base/323065

Log:
  Save where we're booted from
  
  Record the file path for boot1.efi as the UEFI environemnt variable
  FreeBSDBootVarGUID:Boot1Path. Record the device this came from as
  FreeBSDBootVarGUID:Boot1Dev. While later stages of the boot may be
  able to guess these values by retrieving UEFIGlobal:BootCurrent and
  groveling through the correct UEFIGlobal:BootXXXX, this provides
  certanty in the face of behavior from any part of the boot loader
  chain that might "guess" what to do next. These env variables are
  volatile and will disappear on reboot.
  
  Sponsored by: Netflix

Modified:
  head/sys/boot/efi/boot1/boot1.c
  head/sys/boot/efi/include/efiapi.h

Modified: head/sys/boot/efi/boot1/boot1.c
==============================================================================
--- head/sys/boot/efi/boot1/boot1.c	Thu Aug 31 17:32:19 2017	(r323064)
+++ head/sys/boot/efi/boot1/boot1.c	Thu Aug 31 17:32:24 2017	(r323065)
@@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$");
 
 #include <efi.h>
 #include <eficonsctl.h>
+typedef CHAR16 efi_char;
+#include <efichar.h>
 
 #include "boot_module.h"
 #include "paths.h"
@@ -53,6 +55,7 @@ static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCO
 static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
 static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
 static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID;
 
 /*
  * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
@@ -77,6 +80,34 @@ Free(void *buf, const char *file __unused, int line __
 		(void)BS->FreePool(buf);
 }
 
+static int
+wcslen(const CHAR16 *str)
+{
+	int i;
+
+	i = 0;
+	while (*str++)
+		i++;
+	return i;
+}
+
+static EFI_STATUS
+efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr)
+{
+	CHAR16 *var = NULL;
+	size_t len;
+	EFI_STATUS rv;
+
+	utf8_to_ucs2(varname, &var, &len);
+	if (var == NULL)
+		return (EFI_OUT_OF_RESOURCES);
+	rv = RS->SetVariable(var, &FreeBSDBootVarGUID,
+	    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+	    wcslen(valstr) * 2, valstr);
+	free(var);
+	return (rv);
+}
+
 /*
  * devpath_last returns the last non-path end node in devpath.
  */
@@ -394,6 +425,7 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
 	if (status == EFI_SUCCESS) {
 		text = efi_devpath_name(img->FilePath);
 		printf("   Load Path: %S\n", text);
+		efi_setenv_freebsd_wcs("Boot1Path", text);
 		efi_free_devpath_name(text);
 
 		status = BS->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
@@ -404,6 +436,7 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
 		} else {
 			text = efi_devpath_name(imgpath);
 			printf("   Load Device: %S\n", text);
+			efi_setenv_freebsd_wcs("Boot1Dev", text);
 			efi_free_devpath_name(text);
 		}
 

Modified: head/sys/boot/efi/include/efiapi.h
==============================================================================
--- head/sys/boot/efi/include/efiapi.h	Thu Aug 31 17:32:19 2017	(r323064)
+++ head/sys/boot/efi/include/efiapi.h	Thu Aug 31 17:32:24 2017	(r323065)
@@ -247,7 +247,7 @@ EFI_STATUS
 typedef
 EFI_STATUS
 (EFIAPI *EFI_SET_VARIABLE) (
-    IN CHAR16                       *VariableName,
+    IN const CHAR16                 *VariableName,
     IN EFI_GUID                     *VendorGuid,
     IN UINT32                       Attributes,
     IN UINTN                        DataSize,


More information about the svn-src-all mailing list