Sometimes, using a GRUB boot script (i.e. grub.cfg), it is very important to get/set an EFI variable, especially in embedded systems, to detect some custom BIOS features. For example, based on the content of some EFI variables, a script can decide to boot a special kernel instead of the usual kernel, or add some custom boot parameters to the kernel command line, etc.
This patch add two useful commands: - efivar_get - efivar_set to get/set an EFI variable. The "get" function can display the EFI variable in ASCII or in HEX+ASCII mode (like the Linux command "hexdump"), while the "set" function can set the EFI variable in ASCII mode only. As GUID, the default GUID used is the standard EFI_GLOBAL_VARIABLE_GUID, but it is possible to use any other GUID (standard or custom) using an environment variable. Example: set the EFI variable "Configuration"" to the ASCII value ‘Board_special version 1.0.0’, with the following custom GUID: ‘Configuration-a87cb185-864c-4683-a93e-3666ad3cf6b6’ grub> set guid_used=a87cb185-864c-4683-a93e-3666ad3cf6b6 grub> grub> efivar_set -g guid_used Configuration "Board_special version 1.0.0" grub> grub> efivar_get -g guid_used -xv Configuration Configuration-a87cb185-864c-4683-a93e-3666ad3cf6b6 : 0000 - 42 6f 61 72 64 5f 73 70 65 63 69 61 6c 20 76 65 |Board_special ve| 0010 - 72 73 69 6f 6e 20 31 2e 30 2e 30 00 |rsion 1.0.0. | ----- Usage ----- Usage: efivar_get [OPTIONS] VAR Read EFI VAR variable (if not specified, use EFI_GLOBAL_VARIABLE_GUID as default GUID: {8be4df61-93ca-11d2-aa0d-00e098032b8c}). If --set is specified, the version is set to a variable. -s, --set=VARNAME Assign return value to variable VARNAME. -g, --guid-var=GUIDVARNAME Use the content of GUIDVARNAME as GUID -x, --hexdump Display EFI variable content in hex mode -v, --verbose Display more info about EFI variable. -h, --help Display this help and exit. -u, --usage Display the usage of this command and exit. Usage: efivar_set [OPTIONS] VAR VALUE Write VALUE to EFI variable VAR (if not specified, use EFI_GLOBAL_VARIABLE_GUID as default GUID:{8be4df61-93ca-11d2-aa0d-00e098032b8c}). If --set is specified, the same EFI variable value is set to a variable. If --non-volatile is specified, the non-volatile EFI attribute is set. Note: an existing EFI variable can be changed only maintainig the same volatile/non-volatile attribute. -s, --set=VARNAME Assign the same EFI variable value to variable VARNAME. -g, --guid-var=GUIDVARNAME Use the content of GUIDVARNAME as GUID -n, --non-volatile Set non-volatile attribute. -v, --verbose Display more info about EFI variable -h, --help Display this help and exit. -u, --usage Display the usage of this command and exit. Signed-off-by: Flavio Suligoi <f.suli...@asem.it> --- docs/grub.texi | 137 +++++++++++++++ grub-core/Makefile.core.def | 5 + grub-core/commands/efi/efivar_get_set.c | 288 ++++++++++++++++++++++++++++++++ grub-core/kern/efi/efi.c | 57 +++++++ include/grub/efi/efi.h | 4 + 5 files changed, 491 insertions(+) create mode 100644 grub-core/commands/efi/efivar_get_set.c diff --git a/docs/grub.texi b/docs/grub.texi index d6408d2..ee59079 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -3978,6 +3978,8 @@ you forget a command, you can run the command @command{help} * distrust:: Remove a pubkey from trusted keys * drivemap:: Map a drive to another * echo:: Display a line of text +* efivar_get:: Get EFI variable +* efivar_set:: Set EFI variable * eval:: Evaluate agruments as GRUB commands * export:: Export an environment variable * false:: Do nothing, unsuccessfully @@ -4397,6 +4399,141 @@ character will print that character. @end deffn +@node efivar_get +@subsection efivar_get +@deffn Command efivar_get [@option{--set} var] [@option{--guid-var} guidvarname] [@option{--hexdump}] [@option{--verbose}] efivar +Get and display an EFI variable @var{efivar} in ASCII or hex+ASCII format. + +The EFI GUID can be loaded from an environment variable, using the option +@option{--guid-var @var{guidvarname}}. If this option is not used and +consequently no GUID is specified, the GUID: + + +@center EFI_GLOBAL_VARIABLE_GUID = 8be4df61-93ca-11d2-aa0d-00e098032b8c + +is implicitly assumed. + +If the option @option{--set @var{var}} is specified, store the EFI variable to +the environment variable @var{var} instead of printing it. + +If the option @option{--hexdump} is specified, the output is in hexdecimal +format. + +The option @option{--verbose} improve the data information output. + +@emph{Example:} read the EFI variable: + +@center @samp{PlatformInfo-19ad5244-fd6b-4e5c-826a-414646d6da6a} + +@smallexample +grub> set guid_used=19ad5244-fd6b-4e5c-826a-414646d6da6a +grub> efivar_get -g guid_used -xv PlatformInfo +PlatformInfo-19ad5244-fd6b-4e5c-826a-414646d6da6a : + +0000 - 00 00 e2 00 00 00 00 00 00 00 00 00 f0 5a 0d 00 |.............Z..| +0010 - 00 00 00 00 00 00 00 00 00 a8 ff ff ff df 00 00 |................| +0020 - 00 00 0f 00 00 00 ff ff ff ff 0f 00 00 00 00 00 |................| +0030 - 00 e0 00 00 00 00 00 00 00 04 00 01 24 00 00 00 |............$...| +0040 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0050 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0060 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0070 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0080 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0090 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a8 00 |................| +00a0 - 00 00 a8 00 00 00 00 00 00 c0 a0 ef 7a 00 80 01 |............z...| +00b0 - 00 00 00 f9 ff ff 8b 0d 9c f9 ff ff c1 e9 02 00 |................| +00c0 - 00 00 00 0f 00 00 00 00 00 00 00 10 00 00 00 d0 |................| +00d0 - e6 80 eb 80 05 01 00 00 00 00 00 00 00 00 00 00 |................| +00e0 - 00 00 00 00 00 00 00 00 01 86 80 34 12 00 00 49 |...........4...I| +00f0 - 4e 54 45 4c 20 20 20 45 44 4b 32 20 20 20 20 00 |NTEL EDK2 .| +0100 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0110 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0120 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0130 - 00 00 00 00 00 00 00 00 00 00 30 32 b7 7a c8 3a |..........02.z.:| +0140 - b7 7a b0 34 b7 7a 88 3e b7 7a 00 00 00 00 00 00 |.z.4.z.>.z......| +0150 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0160 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0170 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0180 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +0190 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +01a0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +01b0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +01c0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +01d0 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +01e0 - 00 00 00 00 00 00 00 00 00 fc 8b 3d 98 |...........=. | +grub> +@end smallexample + + +@emph{Note:} in Linux, the dump of any EFI var in +@file{/sys/firmware/efi/efivars} shows, before the variable data, also the +4 bytes of the variable attributes. In GRUB, instead, a dump of any EFI variable +shows the variable data only. + +@end deffn + + +@node efivar_set +@subsection efivar_set +@deffn Command efivar_set [@option{--set} var] [@option{--guid-var} guidvarname] [@option{--non-volatile}] [@option{--verbose}] efivar value +Set an EFI variable @var{efivar} with the value @var{value} in ASCII format. + +The EFI GUID can be loaded from an environment variable, using the option +@option{--guid-var @var{guidvarname}}. If this option is not used and consequently +no GUID is specified, the GUID: + + +@center EFI_GLOBAL_VARIABLE_GUID = 8be4df61-93ca-11d2-aa0d-00e098032b8c + +is implicitly assumed. + +About the EFI variable attributes, the following attributes are set: +@itemize @bullet +@item +GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS +@item +GRUB_EFI_VARIABLE_RUNTIME_ACCESS +@end itemize +If the option @option{--non-volatile} is give, the variable is also set with +the attribute: +@itemize @bullet +@item +GRUB_EFI_VARIABLE_NON_VOLATILE +@end itemize +In this way the variable will be stored in the board NVRAM. + +If the option @option{--set @var{var}} is specified, in addition to set the EFI +variable with the value @var{value}, also store this value to the environment +variable @var{var}. + +The option @option{--verbose} improve the data information output. + +@emph{Example:} set the EFI variable @var{Configuration} to the ASCII value +@samp{Board_special version 1.0.0}, with the following +custom GUID: + +@center @samp{Configuration-a87cb185-864c-4683-a93e-3666ad3cf6b6} + +@smallexample +grub> set guid_used=a87cb185-864c-4683-a93e-3666ad3cf6b6 +grub> efivar_set -g guid_used Configuration "Board_special version 1.0.0" +grub> efivar_get -g guid_used -xv Configuration +Configuration-a87cb185-864c-4683-a93e-3666ad3cf6b6 : + +0000 - 42 6f 61 72 64 5f 73 70 65 63 69 61 6c 20 76 65 |Board_special ve| +0010 - 72 73 69 6f 6e 20 31 2e 30 2e 30 00 |rsion 1.0.0. | +grub> +@end smallexample + + +@emph{Note:} in Linux, the dump of any EFI var in +@file{/sys/firmware/efi/efivars} shows, before the variable data, also the +4 bytes of the variable attributes. In GRUB, instead, a dump of any EFI variable +shows the variable data only. + +@end deffn + + @node eval @subsection eval diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 48b82e7..12535ba 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -2534,3 +2534,8 @@ module = { common = commands/i386/wrmsr.c; enable = x86; }; + +module = { + name = efivar_get_set; + common = commands/efi/efivar_get_set.c; +}; diff --git a/grub-core/commands/efi/efivar_get_set.c b/grub-core/commands/efi/efivar_get_set.c new file mode 100644 index 0000000..f1d1cd9 --- /dev/null +++ b/grub-core/commands/efi/efivar_get_set.c @@ -0,0 +1,288 @@ +/* efivar_get_set.c - command to get/set an EFI variable */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Free Software Foundation, 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/dl.h> +#include <grub/command.h> +#include <grub/misc.h> +#include <grub/mm.h> +#include <grub/env.h> +#include <grub/extcmd.h> +#include <grub/i18n.h> +#include <grub/efi/api.h> +#include <grub/efi/efi.h> + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options_efivar_rd[] = +{ + { "set", 's', 0, N_("Assign return value to variable VARNAME."), + N_("VARNAME"), ARG_TYPE_STRING }, + { "guid-var", 'g', 0, N_("Use the content of GUIDVARNAME as GUID"), + N_("GUIDVARNAME"), ARG_TYPE_STRING }, + {"hexdump", 'x', 0, N_("Display EFI variable content in hex mode"), 0, 0}, + {"verbose", 'v', 0, N_("Display more info about EFI variable."), 0, 0}, + { 0, 0, 0, 0, 0, 0 } +}; + +static const struct grub_arg_option options_efivar_wr[] = +{ + { "set", 's', 0, N_("Assign the same EFI variable value to variable VARNAME."), + N_("VARNAME"), ARG_TYPE_STRING }, + { "guid-var", 'g', 0, N_("Use the content of GUIDVARNAME as GUID"), + N_("GUIDVARNAME"), ARG_TYPE_STRING }, + { "non-volatile", 'n', 0, N_("Set non-volatile attribute."), 0, ARG_TYPE_NONE }, + { "verbose", 'v', 0, N_("Display more info about EFI variable"), 0, 0}, + { 0, 0, 0, 0, 0, 0 } +}; + +static void +dump_efi_var_hex (void *efi_var, grub_size_t efi_var_data_size, + grub_uint8_t verbose) +{ + #define DUMP_EFI_VAR_HEX_ROW_LEN 16 + grub_uint32_t i, j; + grub_uint8_t *val = efi_var; + + grub_printf ("\n"); + for (i = 0; i <= (efi_var_data_size / DUMP_EFI_VAR_HEX_ROW_LEN) ; i++) + { + if (verbose) + grub_printf ("%04x - ", i * DUMP_EFI_VAR_HEX_ROW_LEN); + + /* Print numerical values */ + for (j = 0; j < DUMP_EFI_VAR_HEX_ROW_LEN; j++) + { + if ((i * DUMP_EFI_VAR_HEX_ROW_LEN + j) < efi_var_data_size) + { + grub_printf ("%02x", (unsigned int) val[i * DUMP_EFI_VAR_HEX_ROW_LEN + j]); + } + else + grub_printf (" "); + if (verbose) + grub_printf (" "); + } + + /* If verbose is active, print ASCII chars */ + if (verbose) + { + grub_printf (" |"); + for (j = 0; j < DUMP_EFI_VAR_HEX_ROW_LEN; j++) + { + if ((i * DUMP_EFI_VAR_HEX_ROW_LEN + j) < efi_var_data_size) + { + if (grub_isprint (val[i * DUMP_EFI_VAR_HEX_ROW_LEN + j])) + grub_printf ("%c", (unsigned int) val[i * DUMP_EFI_VAR_HEX_ROW_LEN + j]); + else + grub_printf("."); + } + else + grub_printf(" "); + } + grub_printf ("|\n"); + } + } +} + +static void +dump_efi_guid (char *efi_var_name, grub_efi_guid_t guid) +{ + grub_printf ("%s-%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x :\n", + efi_var_name, + (unsigned) guid.data1, + (unsigned) guid.data2, + (unsigned) guid.data3, + (unsigned) guid.data4[0], + (unsigned) guid.data4[1], + (unsigned) guid.data4[2], + (unsigned) guid.data4[3], + (unsigned) guid.data4[4], + (unsigned) guid.data4[5], + (unsigned) guid.data4[6], + (unsigned) guid.data4[7]); +} + +static grub_err_t +grub_cmd_efivar_get (grub_extcmd_context_t ctxt, int argc, char **args) +{ + void *efi_var = NULL; + grub_size_t efi_var_data_size = 0; + char *buf = 0; + grub_efi_guid_t guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; + const char *guid_str; + grub_err_t err; + + /* One argument required */ + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("one argument required: EFI variable name")); + + /* Get GUID from env variable */ + if (ctxt->state[1].set) + { + guid_str = grub_env_get (ctxt->state[1].arg); + if (guid_str) + { + err = grub_efi_str_to_guid (guid_str, &guid); + if (err) + return err; + } + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("GUID environment variable not found")); + } + else + grub_printf ("No custom GUID provided, use EFI_GLOBAL_VARIABLE_GUID.\n"); + + /* Get EFI variable */ + efi_var = grub_efi_get_variable (args[0], &guid, &efi_var_data_size); + if (!efi_var || !efi_var_data_size) + return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read EFI variable")); + + /* Get EFI var data string */ + buf = grub_malloc (efi_var_data_size * 2 + 1); + if (!buf) + return grub_errno; + + /* Copy EFI variable data */ + grub_strncpy (buf, efi_var, efi_var_data_size); + + /* Set env variable required? */ + if (ctxt->state[0].set) + grub_env_set (ctxt->state[0].arg, buf); + else + { + /* Verbose ? */ + if (ctxt->state[3].set) + { + /* Print GUID */ + dump_efi_guid (args[0], guid); + + /* Hexdump ? */ + if (ctxt->state[2].set) + dump_efi_var_hex(efi_var, efi_var_data_size, 1); + else + grub_printf ("%s", buf); + } + else + /* Hexdump ? */ + if (ctxt->state[2].set) + dump_efi_var_hex(efi_var, efi_var_data_size, 0); + else + grub_printf ("%s", buf); + } + + grub_free (buf); + + return 0; +} + +static grub_err_t +grub_cmd_efivar_set (grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_err_t efi_err; + grub_efi_guid_t guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; + const char *guid_str; + grub_efi_boolean_t non_volatile = 0; + grub_err_t err; + + /* Two arguments required */ + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("two arguments required: EFI variable name and value")); + + /* Get GUID from env variable */ + if (ctxt->state[1].set) + { + guid_str = grub_env_get (ctxt->state[1].arg); + if (guid_str) + { + err = grub_efi_str_to_guid (guid_str, &guid); + if (err) + return err; + } + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("GUID environment variable not found")); + } + else + grub_printf ("No custom GUID provided, use EFI_GLOBAL_VARIABLE_GUID.\n"); + + /* Volatile or non-volatile ? */ + if (ctxt->state[2].set) + non_volatile = 1; + + /* Set EFI variable */ + efi_err = grub_efi_set_variable (args[0], &guid, args[1], + (grub_size_t) grub_strlen(args[1]) + 1, + non_volatile); + if (efi_err != GRUB_ERR_NONE) + return grub_error (GRUB_ERR_WRITE_ERROR, N_("cannot write EFI variable")); + + /* Set env variable required? */ + if (ctxt->state[0].set) + grub_env_set (ctxt->state[0].arg, args[1]); + + /* Verbose ? */ + if (ctxt->state[3].set) + { + /* Print GUID */ + dump_efi_guid (args[0], guid); + + grub_printf("%s EFI variable: %s set to value: %s\n", + non_volatile ? "Non-volatile" : "volatile", + args[0], args[1]); + } + return 0; +} + +static grub_extcmd_t cmd_rd_efi_var, cmd_wr_efi_var; + +GRUB_MOD_INIT(version) +{ + cmd_rd_efi_var = grub_register_extcmd ("efivar_get", + grub_cmd_efivar_get, 0, + N_("[OPTIONS] VAR"), + N_("\nRead EFI VAR variable (if not specified, use " + "EFI_GLOBAL_VARIABLE_GUID as default GUID: " + "{8be4df61-93ca-11d2-aa0d-00e098032b8c}).\n" + "If --set is specified, the version is set to a variable." + ), + options_efivar_rd); + + cmd_wr_efi_var = grub_register_extcmd ("efivar_set", + grub_cmd_efivar_set, 0, + N_("[OPTIONS] VAR VALUE"), + N_("\nWrite VALUE to EFI variable VAR (if not specified, use " + "EFI_GLOBAL_VARIABLE_GUID as default GUID:" + "{8be4df61-93ca-11d2-aa0d-00e098032b8c}).\n" + "If --set is specified, the same EFI variable value " + "is set to a variable.\n" + "If --non-volatile is specified, the non-volatile " + "EFI attribute is set.\n" + "\nNote: an existing EFI variable can be changed only " + "maintainig the same volatile/non-volatile attribute." + ), + options_efivar_wr); +} + +GRUB_MOD_FINI(version) +{ + grub_unregister_extcmd (cmd_rd_efi_var); + grub_unregister_extcmd (cmd_wr_efi_var); +} diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index dcb09b2..5d7a8ed 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -960,3 +960,60 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, return 0; } + +/* Convert a GUID from string format to grub_efi_guid_t format. + * For example: + * + * 8be4df61-93ca-11d2-aa0d-00e098032b8c --> + * + * --> { 0x8BE4DF61, 0x93CA, 0x11d2, \ + * { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }} +*/ +grub_err_t +grub_efi_str_to_guid(const char *guid_str, grub_efi_guid_t *guid) +{ + char guid_str_tmp[32]; + unsigned int i; + union + { + grub_uint64_t octet_64; + grub_uint8_t octet_8[8]; + } guid_octet; + + /* Check string size */ + if (grub_strlen(guid_str) != EFI_GUID_STRING_LENGTH) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("GUID string must be %d chars long\n"), + EFI_GUID_STRING_LENGTH); + + /* Remove dashes for string check */ + grub_snprintf (&guid_str_tmp[0], 9, "%s", guid_str); + grub_snprintf (&guid_str_tmp[8], 5, "%s", guid_str + 9); + grub_snprintf (&guid_str_tmp[12], 5, "%s", guid_str + 14); + grub_snprintf (&guid_str_tmp[16], 5, "%s", guid_str + 19); + grub_snprintf (&guid_str_tmp[20], 13, "%s", guid_str + 24); + + /* Check for hex digit only */ + for (i = 0; i < grub_strlen (guid_str_tmp); i++) + { + guid_str_tmp[i] = grub_tolower(guid_str_tmp[i]); + + if (!(grub_isxdigit (guid_str_tmp[i]))) { + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("GUID string must be like the following: 8be4df61-93ca-11d2-aa0d-00e098032b8c")); + } + } + + /* Convert from string to GUID */ + guid->data1 = grub_strtoul (&guid_str[0], NULL, 16); + guid->data2 = grub_strtoul (&guid_str[9], NULL, 16); + guid->data3 = grub_strtoul (&guid_str[14], NULL, 16); + guid_octet.octet_64 = grub_strtoull (&guid_str_tmp[16], NULL, 16); + for (i = 0; i <= 7; i++) + { + guid->data4[i] = guid_octet.octet_8[7 - i]; + } + + return GRUB_ERR_NONE; +} \ No newline at end of file diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 9b04150..dc87cc2 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -24,6 +24,8 @@ #include <grub/dl.h> #include <grub/efi/api.h> +#define EFI_GUID_STRING_LENGTH 36 + /* Functions. */ void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol, void *registration); @@ -90,6 +92,8 @@ EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, char **device, char **path); +grub_err_t +EXPORT_FUNC(grub_efi_str_to_guid)(const char *guid_str, grub_efi_guid_t *guid); #if defined(__arm__) || defined(__aarch64__) || defined(__riscv) void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); -- 2.7.4 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel