* efi: add a command to read efi variables from shell and configuration files
@ 2015-09-15 9:26 Ignat Korchagin
0 siblings, 0 replies; only message in thread
From: Ignat Korchagin @ 2015-09-15 9:26 UTC (permalink / raw
To: grub-devel
[-- Attachment #1.1: Type: text/plain, Size: 371 bytes --]
Would like to add a command for reading EFI variables from command line or
config files to make following scenario possible in grub.cfg:
# check whether Secure Boot is enabled
get_efivar -t uint8 SecureBoot efi_secure_boot
if [ $efi_secure_boot = 1 ]; then
# secure boot is enabled, boot our secure OS
elif
# secure boot is disabled: enable it, boot insecure OS etc
fi
[-- Attachment #1.2: Type: text/html, Size: 632 bytes --]
[-- Attachment #2: grub2.patch --]
[-- Type: application/octet-stream, Size: 4740 bytes --]
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 9764cd2..49fa3ec 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -728,6 +728,12 @@ module = {
};
module = {
+ name = efivar;
+ efi = commands/efi/efivar.c;
+ enable = efi;
+};
+
+module = {
name = blocklist;
common = commands/blocklist.c;
};
diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.c
new file mode 100644
index 0000000..ca206eb
--- /dev/null
+++ b/grub-core/commands/efi/efivar.c
@@ -0,0 +1,146 @@
+/* efivar.c - Read EFI global variables. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2015 Free Software Foundation, Inc.
+ * Copyright (C) 2015 CloudFlare, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static const struct grub_arg_option options[] = {
+ {"type", 't', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR as specific type (hex, uint8, string). Default: hex."), N_("TYPE"), ARG_TYPE_STRING},
+ {0, 0, 0, 0, 0, 0}
+};
+
+enum efi_var_type
+ {
+ EFI_VAR_STRING = 0,
+ EFI_VAR_UINT8,
+ EFI_VAR_HEX,
+ EFI_VAR_INVALID = -1
+ };
+
+static enum efi_var_type
+parse_efi_var_type (const char *type)
+{
+ if (!grub_strncmp (type, "string", sizeof("string")))
+ return EFI_VAR_STRING;
+
+ if (!grub_strncmp (type, "uint8", sizeof("uint8")))
+ return EFI_VAR_UINT8;
+
+ if (!grub_strncmp (type, "hex", sizeof("hex")))
+ return EFI_VAR_HEX;
+
+ return EFI_VAR_INVALID;
+}
+
+static grub_err_t
+grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt,
+ int argc, char **args)
+{
+ struct grub_arg_list *state = ctxt->state;
+ grub_err_t status;
+ void *efi_var = NULL;
+ grub_size_t efi_var_size = 0;
+ enum efi_var_type efi_type = EFI_VAR_HEX;
+ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ char *env_var = NULL;
+ grub_size_t i;
+
+ if (2 != argc)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
+
+ if (state[0].set)
+ efi_type = parse_efi_var_type (state[0].arg);
+
+ if (EFI_VAR_INVALID == efi_type)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid EFI variable type"));
+
+ efi_var = grub_efi_get_variable (args[0], &global, &efi_var_size);
+ if (!efi_var || !efi_var_size)
+ status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable"));
+
+ switch (efi_type)
+ {
+ case EFI_VAR_STRING:
+ env_var = grub_malloc (efi_var_size + 1);
+ if (!env_var)
+ {
+ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ break;
+ }
+ grub_memcpy(env_var, efi_var, efi_var_size);
+ env_var[efi_var_size] = '\0';
+ break;
+
+ case EFI_VAR_UINT8:
+ env_var = grub_malloc (4);
+ if (!env_var)
+ {
+ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ break;
+ }
+ grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var));
+ break;
+
+ case EFI_VAR_HEX:
+ env_var = grub_malloc (efi_var_size * 2 + 1);
+ if (!env_var)
+ {
+ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ break;
+ }
+ for (i = 0; i < efi_var_size; i++)
+ grub_snprintf (env_var + (i * 2), 3, "%02x", ((grub_uint8_t *)efi_var)[i]);
+ break;
+
+ default:
+ status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)"));
+ }
+
+ status = grub_env_set (args[1], env_var);
+
+ if (env_var)
+ grub_free (env_var);
+
+ if (efi_var)
+ grub_free (efi_var);
+
+ return status;
+}
+
+static grub_extcmd_t cmd = NULL;
+
+GRUB_MOD_INIT (efivar)
+{
+ cmd = grub_register_extcmd ("get_efivar", grub_cmd_get_efi_var, 0, N_("[-t TYPE] EFI_VAR ENV_VAR"),
+ N_("Read EFI variable and put its contents in environment variable."), options);
+}
+
+GRUB_MOD_FINI (efivar)
+{
+ if (cmd)
+ grub_unregister_extcmd (cmd);
+}
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-09-15 9:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-15 9:26 efi: add a command to read efi variables from shell and configuration files Ignat Korchagin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).