Message ID | 20190115025522.12060-5-takahiro.akashi@linaro.org |
---|---|
State | New |
Headers | show |
Series | cmd: add efitool for efi environment | expand |
On 1/15/19 3:55 AM, AKASHI Takahiro wrote: > "drivers" command prints all the uefi drivers on the system. > > => efi drivers > D > r > v Driver Name Image Path > ================ ==================== ========== > 7ef31d30 EFI block driver <built-in> > > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> > --- > cmd/efitool.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 83 insertions(+), 1 deletion(-) > > diff --git a/cmd/efitool.c b/cmd/efitool.c > index 6b2df1beedb5..4d46721fbf91 100644 > --- a/cmd/efitool.c > +++ b/cmd/efitool.c > @@ -8,6 +8,7 @@ > #include <charset.h> > #include <common.h> > #include <command.h> > +#include <efi_driver.h> > #include <efi_loader.h> > #include <environment.h> > #include <errno.h> > @@ -16,6 +17,7 @@ > #include <malloc.h> > #include <search.h> > #include <linux/ctype.h> > +#include <linux/kernel.h> > #include <asm/global_data.h> > > #define BS systab.boottime > @@ -358,6 +360,82 @@ static int do_efi_show_devices(int argc, char * const argv[]) > return CMD_RET_SUCCESS; > } > > +static int efi_get_driver_handle_info(efi_handle_t handle, u16 **name, > + u16 **devname, u16 **filename) > +{ > + struct efi_handler *handler; > + struct efi_driver_binding_extended_protocol *bp; We can have drivers supplied by U-Boot and drivers supplied by an EFI binary that we recently installed via the bootefi command. A driver installed via the bootefi command will not have allocated memory for the extra fields. So the rest of the code accessing the name field will produce an illegal memory access. Best regards Heinrich > + efi_status_t ret; > + > + ret = efi_search_protocol(handle, &efi_guid_driver_binding_protocol, > + &handler); > + if (ret != EFI_SUCCESS) > + return -1; > + bp = handler->protocol_interface; > + > + *name = malloc((strlen(bp->name) + 1) * sizeof(u16)); > + if (*name) > + ascii2unicode(*name, bp->name); > + > + /* > + * TODO: > + * handle image->device_handle, > + * use append_device_path() > + */ > + *devname = NULL; > + *filename = NULL; > + > + return 0; > +} > + > +static int do_efi_show_drivers(int argc, char * const argv[]) > +{ > + efi_handle_t *handles = NULL, *handle; > + efi_uintn_t size = 0; > + u16 *drvname, *devname, *filename; > + efi_status_t ret; > + int i; > + > + ret = BS->locate_handle(BY_PROTOCOL, &efi_guid_driver_binding_protocol, > + NULL, &size, NULL); > + if (ret == EFI_BUFFER_TOO_SMALL) { > + handles = calloc(1, size); > + if (!handles) > + return CMD_RET_FAILURE; > + > + ret = BS->locate_handle(BY_PROTOCOL, > + &efi_guid_driver_binding_protocol, > + NULL, &size, handles); > + } > + if (ret != EFI_SUCCESS) { > + free(handles); > + return CMD_RET_FAILURE; > + } > + > + printf("D\n"); > + printf("r\n"); > + printf("v Driver Name Image Path\n"); > + printf("================ ==================== ==========\n"); > + handle = handles; > + for (i = 0; i < size / sizeof(*handle); i++) { > + if (!efi_get_driver_handle_info(*handle, &drvname, &devname, > + &filename)) { > + if (filename) > + printf("%16p %-20ls %ls/%ls\n", > + *handle, drvname, devname, filename); > + else > + printf("%16p %-20ls <built-in>\n", > + *handle, drvname); > + free(drvname); > + free(devname); > + free(filename); > + } > + handle++; > + } > + > + return CMD_RET_SUCCESS; > +} > + > static int do_efi_boot_add(int argc, char * const argv[]) > { > int id; > @@ -767,6 +845,8 @@ static int do_efitool(cmd_tbl_t *cmdtp, int flag, > return do_efi_set_var(argc, argv); > else if (!strcmp(command, "devices")) > return do_efi_show_devices(argc, argv); > + else if (!strcmp(command, "drivers")) > + return do_efi_show_drivers(argc, argv); > else > return CMD_RET_USAGE; > } > @@ -793,7 +873,9 @@ static char efitool_help_text[] = > " - set/delete uefi variable's value\n" > " <value> may be \"=\"...\"\", \"=0x...\", \"=H...\", (set) or \"=\" (delete)\n" > "efitool devices\n" > - " - show uefi devices\n"; > + " - show uefi devices\n" > + "efitool drivers\n" > + " - show uefi drivers\n"; > #endif > > U_BOOT_CMD( >
================ ==================== ========== 7ef31d30 EFI block driver <built-in> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> --- cmd/efitool.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/cmd/efitool.c b/cmd/efitool.c index 6b2df1beedb5..4d46721fbf91 100644 --- a/cmd/efitool.c +++ b/cmd/efitool.c @@ -8,6 +8,7 @@ #include <charset.h> #include <common.h> #include <command.h> +#include <efi_driver.h> #include <efi_loader.h> #include <environment.h> #include <errno.h> @@ -16,6 +17,7 @@ #include <malloc.h> #include <search.h> #include <linux/ctype.h> +#include <linux/kernel.h> #include <asm/global_data.h> #define BS systab.boottime @@ -358,6 +360,82 @@ static int do_efi_show_devices(int argc, char * const argv[]) return CMD_RET_SUCCESS; } +static int efi_get_driver_handle_info(efi_handle_t handle, u16 **name, + u16 **devname, u16 **filename) +{ + struct efi_handler *handler; + struct efi_driver_binding_extended_protocol *bp; + efi_status_t ret; + + ret = efi_search_protocol(handle, &efi_guid_driver_binding_protocol, + &handler); + if (ret != EFI_SUCCESS) + return -1; + bp = handler->protocol_interface; + + *name = malloc((strlen(bp->name) + 1) * sizeof(u16)); + if (*name) + ascii2unicode(*name, bp->name); + + /* + * TODO: + * handle image->device_handle, + * use append_device_path() + */ + *devname = NULL; + *filename = NULL; + + return 0; +} + +static int do_efi_show_drivers(int argc, char * const argv[]) +{ + efi_handle_t *handles = NULL, *handle; + efi_uintn_t size = 0; + u16 *drvname, *devname, *filename; + efi_status_t ret; + int i; + + ret = BS->locate_handle(BY_PROTOCOL, &efi_guid_driver_binding_protocol, + NULL, &size, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + handles = calloc(1, size); + if (!handles) + return CMD_RET_FAILURE; + + ret = BS->locate_handle(BY_PROTOCOL, + &efi_guid_driver_binding_protocol, + NULL, &size, handles); + } + if (ret != EFI_SUCCESS) { + free(handles); + return CMD_RET_FAILURE; + } + + printf("D\n"); + printf("r\n"); + printf("v Driver Name Image Path\n"); + printf("================ ==================== ==========\n"); + handle = handles; + for (i = 0; i < size / sizeof(*handle); i++) { + if (!efi_get_driver_handle_info(*handle, &drvname, &devname, + &filename)) { + if (filename) + printf("%16p %-20ls %ls/%ls\n", + *handle, drvname, devname, filename); + else + printf("%16p %-20ls <built-in>\n", + *handle, drvname); + free(drvname); + free(devname); + free(filename); + } + handle++; + } + + return CMD_RET_SUCCESS; +} + static int do_efi_boot_add(int argc, char * const argv[]) { int id; @@ -767,6 +845,8 @@ static int do_efitool(cmd_tbl_t *cmdtp, int flag, return do_efi_set_var(argc, argv); else if (!strcmp(command, "devices")) return do_efi_show_devices(argc, argv); + else if (!strcmp(command, "drivers")) + return do_efi_show_drivers(argc, argv); else return CMD_RET_USAGE; } @@ -793,7 +873,9 @@ static char efitool_help_text[] = " - set/delete uefi variable's value\n" " <value> may be \"=\"...\"\", \"=0x...\", \"=H...\", (set) or \"=\" (delete)\n" "efitool devices\n" - " - show uefi devices\n"; + " - show uefi devices\n" + "efitool drivers\n" + " - show uefi drivers\n"; #endif U_BOOT_CMD(