Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/stand/efiboot Add support for setting environment variab...



details:   https://anonhg.NetBSD.org/src/rev/2afb1fd22bce
branches:  trunk
changeset: 835795:2afb1fd22bce
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Sep 09 17:55:22 2018 +0000

description:
Add support for setting environment variables. Currently the following env
vars are supported: "fdtfile", "initrd", and "rootdev".

diffstat:

 sys/stand/efiboot/Makefile.efiboot |    4 +-
 sys/stand/efiboot/boot.c           |   93 +++++++++++++++++++++++++-
 sys/stand/efiboot/efienv.c         |  134 +++++++++++++++++++++++++++++++++++++
 sys/stand/efiboot/efienv.h         |   33 +++++++++
 sys/stand/efiboot/version          |    3 +-
 5 files changed, 263 insertions(+), 4 deletions(-)

diffs (truncated from 347 to 300 lines):

diff -r b69da79930df -r 2afb1fd22bce sys/stand/efiboot/Makefile.efiboot
--- a/sys/stand/efiboot/Makefile.efiboot        Sun Sep 09 13:40:28 2018 +0000
+++ b/sys/stand/efiboot/Makefile.efiboot        Sun Sep 09 17:55:22 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.efiboot,v 1.3 2018/09/03 00:04:02 jmcneill Exp $
+# $NetBSD: Makefile.efiboot,v 1.4 2018/09/09 17:55:22 jmcneill Exp $
 
 S=             ${.CURDIR}/../../..
 
@@ -22,7 +22,7 @@
 .PATH: ${EFIDIR}/gnuefi
 SOURCES=       crt0-efi-${GNUEFIARCH}.S reloc_${GNUEFIARCH}.c
 SOURCES+=      boot.c conf.c console.c dev_net.c devopen.c exec.c panic.c prompt.c
-SOURCES+=      efiboot.c efichar.c efidev.c efigetsecs.c efifdt.c efifile.c efiblock.c efinet.c efipxe.c
+SOURCES+=      efiboot.c efichar.c efidev.c efienv.c efigetsecs.c efifdt.c efifile.c efiblock.c efinet.c efipxe.c
 
 .PATH: ${S}/external/bsd/libfdt/dist
 CPPFLAGS+=     -I${S}/external/bsd/libfdt/dist
diff -r b69da79930df -r 2afb1fd22bce sys/stand/efiboot/boot.c
--- a/sys/stand/efiboot/boot.c  Sun Sep 09 13:40:28 2018 +0000
+++ b/sys/stand/efiboot/boot.c  Sun Sep 09 17:55:22 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: boot.c,v 1.7 2018/09/09 13:37:54 jmcneill Exp $        */
+/*     $NetBSD: boot.c,v 1.8 2018/09/09 17:55:22 jmcneill Exp $        */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -30,6 +30,7 @@
 #include "efiboot.h"
 #include "efiblock.h"
 #include "efifdt.h"
+#include "efienv.h"
 
 #include <sys/bootblock.h>
 #include <sys/boot_flag.h>
@@ -61,6 +62,10 @@
 void   command_dtb(char *);
 void   command_initrd(char *);
 void   command_ls(char *);
+void   command_printenv(char *);
+void   command_setenv(char *);
+void   command_clearenv(char *);
+void   command_resetenv(char *);
 void   command_reset(char *);
 void   command_version(char *);
 void   command_quit(char *);
@@ -71,6 +76,10 @@
        { "dtb",        command_dtb,            "dtb [dev:][filename]" },
        { "initrd",     command_initrd,         "initrd [dev:][filename]" },
        { "ls",         command_ls,             "ls [hdNn:/path]" },
+       { "printenv",   command_printenv,       "printenv [key]" },
+       { "setenv",     command_setenv,         "setenv <key> <value>" },
+       { "clearenv",   command_clearenv,       "clearenv <key>" },
+       { "resetenv",   command_resetenv,       "resetenv" },
        { "version",    command_version,        "version" },
        { "help",       command_help,           "help|?" },
        { "?",          command_help,           NULL },
@@ -135,6 +144,53 @@
 }
 
 void
+command_printenv(char *arg)
+{
+       char *val;
+
+       if (arg && *arg) {
+               val = efi_env_get(arg);
+               if (val) {
+                       printf("\"%s\" = \"%s\"\n", arg, val);
+                       FreePool(val);
+               }
+       } else {
+               efi_env_print();
+       }
+}
+
+void
+command_setenv(char *arg)
+{
+       char *spc;
+
+       spc = strchr(arg, ' ');
+       if (spc == NULL || spc[1] == '\0') {
+               command_help("");
+               return;
+       }
+
+       *spc = '\0';
+       efi_env_set(arg, spc + 1);
+}
+
+void
+command_clearenv(char *arg)
+{
+       if (*arg == '\0') {
+               command_help("");
+               return;
+       }
+       efi_env_clear(arg);
+}
+
+void
+command_resetenv(char *arg)
+{
+       efi_env_reset();
+}
+
+void
 command_version(char *arg)
 {
        char *ufirmware;
@@ -213,11 +269,46 @@
            bootprog_name, bootprog_rev, bootprog_kernrev);
 }
 
+static void
+read_env(void)
+{
+       char *s;
+
+       s = efi_env_get("fdtfile");
+       if (s) {
+#ifdef EFIBOOT_DEBUG
+               printf(">> Setting DTB path to '%s' from environment\n", s);
+#endif
+               set_dtb_path(s);
+               FreePool(s);
+       }
+
+       s = efi_env_get("initrd");
+       if (s) {
+#ifdef EFIBOOT_DEBUG
+               printf(">> Setting initrd path to '%s' from environment\n", s);
+#endif
+               set_initrd_path(s);
+               FreePool(s);
+       }
+
+       s = efi_env_get("rootdev");
+       if (s) {
+#ifdef EFIBOOT_DEBUG
+               printf(">> Setting default device to '%s' from environment\n", s);
+#endif
+               set_default_device(s);
+               FreePool(s);
+       }
+}
+
 void
 boot(void)
 {
        int currname, c;
 
+       read_env();
+
        print_banner();
 
        printf("Press return to boot now, any other key for boot prompt\n");
diff -r b69da79930df -r 2afb1fd22bce sys/stand/efiboot/efienv.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/stand/efiboot/efienv.c        Sun Sep 09 17:55:22 2018 +0000
@@ -0,0 +1,134 @@
+/* $NetBSD: efienv.c,v 1.1 2018/09/09 17:55:22 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
+ * 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 REGENTS 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 REGENTS 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.
+ */
+
+#include "efiboot.h"
+#include "efienv.h"
+
+#define EFIBOOT_VENDOR_GUID \
+       { 0x97cde9bd, 0xac88, 0x4cf9, { 0x84, 0x86, 0x01, 0x33, 0x0f, 0xe1, 0x95, 0xd4 } }
+
+static EFI_GUID EfibootVendorGuid = EFIBOOT_VENDOR_GUID;
+
+void
+efi_env_set(const char *key, char *val)
+{
+       EFI_STATUS status;
+       CHAR16 *ukey;
+       char *data;
+       size_t len;
+
+       data = AllocatePool(strlen(val) + 1);
+       strcpy(data, val);
+
+       utf8_to_ucs2(key, &ukey, &len);
+       status = LibSetNVVariable(ukey, &EfibootVendorGuid, strlen(data) + 1, data);
+       FreePool(ukey);
+       FreePool(data);
+
+       if (EFI_ERROR(status))
+               printf("env: failed to set variable '%s': %#lx\n", key, status);
+}
+
+char *
+efi_env_get(const char *key)
+{
+       CHAR16 *ukey;
+       size_t len;
+       char *ret;
+
+       utf8_to_ucs2(key, &ukey, &len);
+       ret = LibGetVariable(ukey, &EfibootVendorGuid);
+       FreePool(ukey);
+
+       return ret;
+}
+
+void
+efi_env_clear(const char *key)
+{
+       CHAR16 *ukey;
+       size_t len;
+
+       utf8_to_ucs2(key, &ukey, &len);
+       LibDeleteVariable(ukey, &EfibootVendorGuid);
+       FreePool(ukey);
+}
+
+void
+efi_env_reset(void)
+{
+       EFI_STATUS status;
+       CHAR16 ukey[256];
+       EFI_GUID vendor;
+       UINTN size;
+
+retry:
+       ukey[0] = '\0';
+       vendor = NullGuid;
+
+       for (;;) {
+               size = sizeof(ukey);
+               status = uefi_call_wrapper(RT->GetNextVariableName, 3, &size, ukey, &vendor);
+               if (status != EFI_SUCCESS)
+                       break;
+
+               if (CompareGuid(&vendor, &EfibootVendorGuid) == 0) {
+                       LibDeleteVariable(ukey, &vendor);
+                       goto retry;
+               }
+       }
+}
+
+void
+efi_env_print(void)
+{
+       EFI_STATUS status;
+       CHAR16 ukey[256];
+       EFI_GUID vendor;
+       UINTN size;
+       char *val;
+
+       ukey[0] = '\0';
+       vendor = NullGuid;
+
+       for (;;) {
+               size = sizeof(ukey);
+               status = uefi_call_wrapper(RT->GetNextVariableName, 3, &size, ukey, &vendor);
+               if (status != EFI_SUCCESS)
+                       break;
+
+               if (CompareGuid(&vendor, &EfibootVendorGuid) != 0)
+                       continue;
+
+               Print(L"\"%s\" = ", ukey);
+
+               val = LibGetVariable(ukey, &vendor);
+               printf("\"%s\"\n", val);
+               FreePool(val);
+       }
+}
diff -r b69da79930df -r 2afb1fd22bce sys/stand/efiboot/efienv.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/stand/efiboot/efienv.h        Sun Sep 09 17:55:22 2018 +0000
@@ -0,0 +1,33 @@



Home | Main Index | Thread Index | Old Index