Le ven. 9 mai 2025, 13:15, khaalid cali <khaliidca...@gmail.com> a écrit :
> From: khaalid <khaliidca...@gmail.com> > > This command is intended to print or dump all UEFI runtime services. > The structure will look like efivar tool, since visually most people are > familiar with it. If the variable content is string then dump it as > string, otherwise for non string variables print them as raw hex; just > the way efivar command does. > > Signed-off-by: khaalid <khaliidca...@gmail.com> > Please use correct legal name in sign off. > --- > grub-core/Makefile.core.def | 6 ++ > grub-core/commands/efi/efivar.c | 150 ++++++++++++++++++++++++++++++++ > 2 files changed, 156 insertions(+) > create mode 100644 grub-core/commands/efi/efivar.c > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index f70e02e69..ef3dc2dd0 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -840,6 +840,12 @@ module = { > enable = efi; > }; > > +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 000000000..8d81e01ab > --- /dev/null > +++ b/grub-core/commands/efi/efivar.c > @@ -0,0 +1,150 @@ > +/* efivar.c - dump runtime uefi variables. */ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2009 Free Software Foundation, Inc. > The date is wrong > > +#include <grub/dl.h> > +#include <grub/misc.h> > +#include <grub/command.h> > +#include <grub/charset.h> > +#include <grub/efi/efi.h> > +#include <grub/efi/api.h> > + > +GRUB_MOD_LICENSE ("GPLv3+"); > + > + > +/* Check if the data looks like UTF-16LE text */ > +static inline int > +is_likely_utf16_string(grub_uint8_t *data, grub_size_t len) > +{ > + if (len < 4) return 0; > + for (grub_size_t i = 0; i < len; i += 2) { > + if (data[i] == 0 && data[i+1] == 0) return 1; // Null terminator > in UTF-16 > + if (data[i+1] != 0 && data[i+1] != 0x20) return 0; // High byte > must be 0 or space-like > + } > + return 1; > +} > This function is weird. What do you mean by space-like? Why null terminator inside the string makes it "UTF-16 like"? An array 00 00 00 00 00 FF FF 00 is clearly non-UTF-16 yet this function returns 1 > + > +static void > +get_variable_data(const char *variable_name, grub_guid_t *variable_guid) > +{ > This is a dump function. Not a getter. > + grub_efi_status_t status; > + grub_efi_uint32_t attributes; > + grub_size_t data_size; > + grub_uint8_t *data; > + > + status = grub_efi_get_variable_with_attributes(variable_name, > variable_guid, > + &data_size, (void > **)&data, &attributes); > + if (status != GRUB_EFI_SUCCESS) > + { > + grub_error(GRUB_ERR_BAD_MODULE, Bad module is for bad grub modules. It's wrong error code "Failed to retrieve variable data 0x%" PRIxGRUB_EFI_UINTN_T, status); > + return; > + } > + > + grub_printf("Attributes:\n"); > Mark as translatable. Here and later. > + if (attributes & GRUB_EFI_VARIABLE_NON_VOLATILE) > + grub_printf("\tNon-Volatile\n"); > + if (attributes & GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS) > + grub_printf("\tBoot Service Access\n"); > + if (attributes & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) > + grub_printf("\tRuntime Service Access\n"); > + > + if (is_likely_utf16_string(data, data_size)) > + { > + grub_printf("Value (as UTF-16 string):\n"); > + for (grub_size_t i = 0; i + 1 < data_size; i += 2) > + { > + grub_uint16_t ch = data[i] | (data[i+1] << 8); > + if (ch == 0) break; > + grub_printf("%c", (char)ch); // crude but works if high > byte is zero > We have a correct UTF-16 to UTF-8 converter. > + } > + grub_printf("\n"); > + } > + else > + { > + grub_printf("Value (hex):\n"); > + for (grub_size_t i = 0; i < data_size; i++) > + { > + grub_printf("%02x ", data[i]); > We have a good hexdump function. > + if ((i + 1) % 16 == 0) > + grub_printf("\n"); > + } > + grub_printf("\n"); > + } > + > + grub_free(data); > +} > + > +static grub_err_t > +dump_efi_variables(void) > +{ > + grub_efi_status_t status; > + grub_efi_runtime_services_t *r; > + grub_efi_uintn_t variable_name_size = 512; > + grub_efi_char16_t *variable_name; > + grub_uint8_t *variable_name_string = NULL; > + grub_guid_t vendor_guid; > + > + r = grub_efi_system_table->runtime_services; > + > + variable_name = grub_malloc(variable_name_size); > + if (!variable_name) > + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "initial malloc > failed"); > Just return grub_errno. > + *variable_name = 0; /* Start with empty string */ > + > + while (1) > + { > + status = r->get_next_variable_name(&variable_name_size, > variable_name, &vendor_guid); > + if (status == GRUB_EFI_NOT_FOUND) > + break; > + variable_name_string = grub_realloc(variable_name_string, > variable_name_size); > Missing error handling. > + grub_utf16_to_utf8(variable_name_string, variable_name, > variable_name_size); > + > grub_printf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x-%s\n", > vendor_guid.data1, > We have %pG qualifier. > + > vendor_guid.data2, > + > vendor_guid.data3, > + > vendor_guid.data4[0], vendor_guid.data4[1], > + > vendor_guid.data4[2], vendor_guid.data4[3], > + > vendor_guid.data4[4], vendor_guid.data4[5], > + > vendor_guid.data4[6], vendor_guid.data4[7], > + > variable_name_string); > + get_variable_data((char*)variable_name_string, > &vendor_guid); > + } > + > + grub_free(variable_name); > + grub_free(variable_name_string); > + return GRUB_ERR_NONE; > +} > + > +static grub_err_t > +grub_cmd_efivar (grub_command_t cmd __attribute__((unused)), > + int argc __attribute__((unused)), char **argv > __attribute__((unused))) > +{ > + return dump_efi_variables(); > +} > + > +static grub_command_t cmd; > + > +GRUB_MOD_INIT(efivar) > +{ > + cmd = grub_register_command("efivar", grub_cmd_efivar, NULL, > N_("Display UEFI variables.")); > I'd rather have function lsefivar [-l] to be consistent with other similar GRUB commands. Without -l it would skip variable contents > +} > +GRUB_MOD_FINI(efivar) > +{ > + grub_unregister_command(cmd); > +} > -- > 2.49.0 > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel >
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel