From ae67dca5e61867cda886bdd2943709a19c45d76a Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 11 Dec 2017 09:40:47 +0100 Subject: [PATCH 01/10] efi_loader: helloworld.c: Explicitly use .rodata for loaded_image_guid Commit bbf75dd9345d0b ("efi_loader: output load options in helloworld") introduced a const variable in efi_main() called loaded_image_guid which got populated from a constant struct. While you would usually expect a compiler to realize that this variable should really just be a global pointer to .rodata, gcc disagrees and instead puts it on the stack. Unfortunately in some implementations of gcc it does so my calling memcpy() which we do not implement in our hello world environment. So let's explicitly move it to a global variable which in turn puts it in .rodata reliably and gets rid of the memcpy(). Fixes: bbf75dd9345d0b ("efi_loader: output load options in helloworld") Reported-by: Florian Fainelli Signed-off-by: Alexander Graf Reviewed-by: Heinrich Schuchardt Tested-by: Florian Fainelli --- lib/efi_loader/helloworld.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c index e59c24c788..b8c147d7f2 100644 --- a/lib/efi_loader/helloworld.c +++ b/lib/efi_loader/helloworld.c @@ -13,6 +13,8 @@ #include #include +static const efi_guid_t loaded_image_guid = LOADED_IMAGE_GUID; + /* * Entry point of the EFI application. * @@ -26,7 +28,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, struct efi_simple_text_output_protocol *con_out = systable->con_out; struct efi_boot_services *boottime = systable->boottime; struct efi_loaded_image *loaded_image; - const efi_guid_t loaded_image_guid = LOADED_IMAGE_GUID; efi_status_t ret; con_out->output_string(con_out, L"Hello, world!\n"); From 52a250afa53215190e1714ee2c858ab0bbfa0953 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 11 Dec 2017 09:45:30 +0100 Subject: [PATCH 02/10] efi_loader: helloworld.c: Reduce file size The efi linker script includes sections needed for the dynamic linker. However, in our EFI application environment we don't have a dynamic linker. So let's remove them. That way we save on 4k padding and reduce the file size of the hello world efi binary from ~4k to ~1k. Signed-off-by: Alexander Graf --- arch/arm/lib/elf_arm_efi.lds | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/arm/lib/elf_arm_efi.lds b/arch/arm/lib/elf_arm_efi.lds index 59f66a1d4a..15c9c5c672 100644 --- a/arch/arm/lib/elf_arm_efi.lds +++ b/arch/arm/lib/elf_arm_efi.lds @@ -55,16 +55,13 @@ SECTIONS .rel.data : { *(.rel.data) *(.rel.data*) } _data_size = . - _etext; - . = ALIGN(4096); - .dynsym : { *(.dynsym) } - . = ALIGN(4096); - .dynstr : { *(.dynstr) } - . = ALIGN(4096); - .note.gnu.build-id : { *(.note.gnu.build-id) } /DISCARD/ : { *(.rel.reloc) *(.eh_frame) *(.note.GNU-stack) + *(.dynsym) + *(.dynstr) + *(.note.gnu.build-id) + *(.comment) } - .comment 0 : { *(.comment) } } From 905cb9e1720294d244bc9273c45dc76c33f6034e Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 11 Dec 2017 14:29:46 +0100 Subject: [PATCH 03/10] efi_loader: Ensure efi_dp_find_obj() finds exact matches When calling efi_dp_find_obj(), we usually want to find the *exact* match of an object for a given device path. However, I ran into a nasty corner case where I had the following objects with paths available: Handle 0x9feffa70 /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/EndEntire Handle 0x9feffb58 /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/HD(1,800,32000,2de808cb00000000,1,1)/EndEntire and was searching for /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/HD(1,800,32000,2de808cb00000000,1,1)/EndEntire But because our device path search looked for any substring match, it would return /HardwareVendor(e61d73b9-a384-4acc-aeab-82e828f3628b)[0: ]/USB(6,0)/EndEntire because that path is a full substring of the path we were searching for. So this patch adapts the device path search logic to always look for exact matches first. The way we distinguish between those cases is by looking at whether our caller actually deals with remainders. As a side effect, the code as is from all I can tell now never does a substring match anymore, because it always gets called with rem=NULL, so we always only do exact matches now. Reported-by: Jonathan Gray Signed-off-by: Alexander Graf --- lib/efi_loader/efi_device_path.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index b4e2f933cb..24a4f40c00 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -126,6 +126,7 @@ static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path, struct efi_device_path **rem) { struct efi_object *efiobj; + unsigned int dp_size = efi_dp_size(dp); list_for_each_entry(efiobj, &efi_obj_list, link) { struct efi_handler *handler; @@ -141,10 +142,18 @@ static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path, do { if (efi_dp_match(dp, obj_dp) == 0) { if (rem) { + /* + * Allow partial matches, but inform + * the caller. + */ *rem = ((void *)dp) + efi_dp_size(obj_dp); + return efiobj; + } else { + /* Only return on exact matches */ + if (efi_dp_size(obj_dp) == dp_size) + return efiobj; } - return efiobj; } obj_dp = shorten_path(efi_dp_next(obj_dp)); @@ -164,8 +173,14 @@ struct efi_object *efi_dp_find_obj(struct efi_device_path *dp, { struct efi_object *efiobj; - efiobj = find_obj(dp, false, rem); + /* Search for an exact match first */ + efiobj = find_obj(dp, false, NULL); + /* Then for a fuzzy match */ + if (!efiobj) + efiobj = find_obj(dp, false, rem); + + /* And now for a fuzzy short match */ if (!efiobj) efiobj = find_obj(dp, true, rem); From 56d92888582fe6fba9ba9968ac524f86b4e06389 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 4 Dec 2017 18:03:01 +0100 Subject: [PATCH 04/10] efi_loader: return status from efi_setup_loaded_image() efi_setup_loaded_image() should return an error code indicating if an error has occurred. An error occurs if a protocol cannot be installed. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- include/efi_loader.h | 8 +++++--- lib/efi_loader/efi_boottime.c | 11 +++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index c0caabddb1..78237f14ae 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -249,9 +249,11 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type, int efi_memory_init(void); /* Adds new or overrides configuration table entry to the system table */ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table); -void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, - struct efi_device_path *device_path, - struct efi_device_path *file_path); +/* Sets up a loaded image */ +efi_status_t efi_setup_loaded_image( + struct efi_loaded_image *info, struct efi_object *obj, + struct efi_device_path *device_path, + struct efi_device_path *file_path); efi_status_t efi_load_image_from_path(struct efi_device_path *file_path, void **buffer); diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index a37fb25638..a9ba1ac394 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1170,10 +1170,12 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid, * @obj internal object associated with the loaded image * @device_path device path of the loaded image * @file_path file path of the loaded image + * @return status code */ -void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj, - struct efi_device_path *device_path, - struct efi_device_path *file_path) +efi_status_t efi_setup_loaded_image( + struct efi_loaded_image *info, struct efi_object *obj, + struct efi_device_path *device_path, + struct efi_device_path *file_path) { efi_status_t ret; @@ -1213,9 +1215,10 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob if (ret != EFI_SUCCESS) goto failure; - return; + return ret; failure: printf("ERROR: Failure to install protocols for loaded image\n"); + return ret; } /* From 678e03a00cafc9009f05cbcc3192235f2b8f9a33 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 4 Dec 2017 18:03:02 +0100 Subject: [PATCH 05/10] efi_loader: new function efi_delete_handle() Provide a function to remove a handle from the object list after removing all protocols. To avoid forward declarations other functions have to move up in the coding. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- include/efi_loader.h | 2 + lib/efi_loader/efi_boottime.c | 186 ++++++++++++++++++---------------- 2 files changed, 102 insertions(+), 86 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 78237f14ae..6185055e78 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -190,6 +190,8 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path); void efi_add_handle(struct efi_object *obj); /* Create handle */ efi_status_t efi_create_handle(void **handle); +/* Delete handle */ +void efi_delete_handle(struct efi_object *obj); /* Call this to validate a handle and find the EFI object for it */ struct efi_object *efi_search_obj(const void *handle); /* Find a protocol on a handle */ diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index a9ba1ac394..7c8f3134d1 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -359,6 +359,106 @@ efi_status_t efi_create_handle(void **handle) return r; } +/* + * Find a protocol on a handle. + * + * @handle handle + * @protocol_guid GUID of the protocol + * @handler reference to the protocol + * @return status code + */ +efi_status_t efi_search_protocol(const void *handle, + const efi_guid_t *protocol_guid, + struct efi_handler **handler) +{ + struct efi_object *efiobj; + struct list_head *lhandle; + + if (!handle || !protocol_guid) + return EFI_INVALID_PARAMETER; + efiobj = efi_search_obj(handle); + if (!efiobj) + return EFI_INVALID_PARAMETER; + list_for_each(lhandle, &efiobj->protocols) { + struct efi_handler *protocol; + + protocol = list_entry(lhandle, struct efi_handler, link); + if (!guidcmp(protocol->guid, protocol_guid)) { + if (handler) + *handler = protocol; + return EFI_SUCCESS; + } + } + return EFI_NOT_FOUND; +} + +/* + * Delete protocol from a handle. + * + * @handle handle from which the protocol shall be deleted + * @protocol GUID of the protocol to be deleted + * @protocol_interface interface of the protocol implementation + * @return status code + */ +efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol, + void *protocol_interface) +{ + struct efi_handler *handler; + efi_status_t ret; + + ret = efi_search_protocol(handle, protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + if (guidcmp(handler->guid, protocol)) + return EFI_INVALID_PARAMETER; + list_del(&handler->link); + free(handler); + return EFI_SUCCESS; +} + +/* + * Delete all protocols from a handle. + * + * @handle handle from which the protocols shall be deleted + * @return status code + */ +efi_status_t efi_remove_all_protocols(const void *handle) +{ + struct efi_object *efiobj; + struct list_head *lhandle; + struct list_head *pos; + + efiobj = efi_search_obj(handle); + if (!efiobj) + return EFI_INVALID_PARAMETER; + list_for_each_safe(lhandle, pos, &efiobj->protocols) { + struct efi_handler *protocol; + efi_status_t ret; + + protocol = list_entry(lhandle, struct efi_handler, link); + + ret = efi_remove_protocol(handle, protocol->guid, + protocol->protocol_interface); + if (ret != EFI_SUCCESS) + return ret; + } + return EFI_SUCCESS; +} + +/* + * Delete handle. + * + * @handle handle to delete + */ +void efi_delete_handle(struct efi_object *obj) +{ + if (!obj) + return; + efi_remove_all_protocols(obj->handle); + list_del(&obj->link); + free(obj); +} + /* * Our event capabilities are very limited. Only a small limited * number of events is allowed to coexist. @@ -717,39 +817,6 @@ struct efi_object *efi_search_obj(const void *handle) return NULL; } -/* - * Find a protocol on a handle. - * - * @handle handle - * @protocol_guid GUID of the protocol - * @handler reference to the protocol - * @return status code - */ -efi_status_t efi_search_protocol(const void *handle, - const efi_guid_t *protocol_guid, - struct efi_handler **handler) -{ - struct efi_object *efiobj; - struct list_head *lhandle; - - if (!handle || !protocol_guid) - return EFI_INVALID_PARAMETER; - efiobj = efi_search_obj(handle); - if (!efiobj) - return EFI_INVALID_PARAMETER; - list_for_each(lhandle, &efiobj->protocols) { - struct efi_handler *protocol; - - protocol = list_entry(lhandle, struct efi_handler, link); - if (!guidcmp(protocol->guid, protocol_guid)) { - if (handler) - *handler = protocol; - return EFI_SUCCESS; - } - } - return EFI_NOT_FOUND; -} - /* * Install new protocol on a handle. * @@ -780,59 +847,6 @@ efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol, return EFI_SUCCESS; } -/* - * Delete protocol from a handle. - * - * @handle handle from which the protocol shall be deleted - * @protocol GUID of the protocol to be deleted - * @protocol_interface interface of the protocol implementation - * @return status code - */ -efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol, - void *protocol_interface) -{ - struct efi_handler *handler; - efi_status_t ret; - - ret = efi_search_protocol(handle, protocol, &handler); - if (ret != EFI_SUCCESS) - return ret; - if (guidcmp(handler->guid, protocol)) - return EFI_INVALID_PARAMETER; - list_del(&handler->link); - free(handler); - return EFI_SUCCESS; -} - -/* - * Delete all protocols from a handle. - * - * @handle handle from which the protocols shall be deleted - * @return status code - */ -efi_status_t efi_remove_all_protocols(const void *handle) -{ - struct efi_object *efiobj; - struct list_head *lhandle; - struct list_head *pos; - - efiobj = efi_search_obj(handle); - if (!efiobj) - return EFI_INVALID_PARAMETER; - list_for_each_safe(lhandle, pos, &efiobj->protocols) { - struct efi_handler *protocol; - efi_status_t ret; - - protocol = list_entry(lhandle, struct efi_handler, link); - - ret = efi_remove_protocol(handle, protocol->guid, - protocol->protocol_interface); - if (ret != EFI_SUCCESS) - return ret; - } - return EFI_SUCCESS; -} - /* * Install protocol interface. * From b9b17598f42c29b905a8b4a778e505244a89bd9a Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 4 Dec 2017 18:03:03 +0100 Subject: [PATCH 06/10] efi_loader: error handling in efi_load_image() If a failure occurs when trying to load an image, it is insufficient to free() the EFI object. We must remove it from the object list, too. Otherwise a use after free will occur the next time we iterate over the object list. Furthermore errors in setting up the image should be handled. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- lib/efi_loader/efi_boottime.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 7c8f3134d1..b90bd0b426 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1308,6 +1308,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, { struct efi_loaded_image *info; struct efi_object *obj; + efi_status_t ret; EFI_ENTRY("%d, %p, %p, %p, %ld, %p", boot_policy, parent_image, file_path, source_buffer, source_size, image_handle); @@ -1317,41 +1318,39 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy, if (!source_buffer) { struct efi_device_path *dp, *fp; - efi_status_t ret; ret = efi_load_image_from_path(file_path, &source_buffer); - if (ret != EFI_SUCCESS) { - free(info); - free(obj); - return EFI_EXIT(ret); - } - + if (ret != EFI_SUCCESS) + goto failure; /* * split file_path which contains both the device and * file parts: */ efi_dp_split_file_path(file_path, &dp, &fp); - - efi_setup_loaded_image(info, obj, dp, fp); + ret = efi_setup_loaded_image(info, obj, dp, fp); + if (ret != EFI_SUCCESS) + goto failure; } else { /* In this case, file_path is the "device" path, ie. * something like a HARDWARE_DEVICE:MEMORY_MAPPED */ - efi_setup_loaded_image(info, obj, file_path, NULL); + ret = efi_setup_loaded_image(info, obj, file_path, NULL); + if (ret != EFI_SUCCESS) + goto failure; } - info->reserved = efi_load_pe(source_buffer, info); if (!info->reserved) { - free(info); - free(obj); - return EFI_EXIT(EFI_UNSUPPORTED); + ret = EFI_UNSUPPORTED; + goto failure; } - info->system_table = &systab; info->parent_handle = parent_image; *image_handle = obj->handle; - return EFI_EXIT(EFI_SUCCESS); +failure: + free(info); + efi_delete_handle(obj); + return EFI_EXIT(ret); } /* From 66b051d51f3f35ab48a8e978a2a28a55b4d13208 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 11 Dec 2017 12:56:39 +0100 Subject: [PATCH 07/10] efi_loader: correctly determine if an MMC device is an SD-card The SD cards and eMMC devices have different device nodes. The current coding interpretes all MMC devices as eMMC. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- lib/efi_loader/efi_device_path.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 24a4f40c00..50330ddac7 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -36,6 +36,24 @@ static const struct efi_device_path_vendor ROOT = { .guid = U_BOOT_GUID, }; +#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC) +/* + * Determine if an MMC device is an SD card. + * + * @desc block device descriptor + * @return true if the device is an SD card + */ +static bool is_sd(struct blk_desc *desc) +{ + struct mmc *mmc = find_mmc_device(desc->devnum); + + if (!mmc) + return false; + + return IS_SD(mmc) != 0U; +} +#endif + static void *dp_alloc(size_t sz) { void *buf; @@ -313,9 +331,9 @@ static void *dp_fill(void *buf, struct udevice *dev) struct blk_desc *desc = mmc_get_blk_desc(mmc); sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; - sddp->dp.sub_type = (desc->if_type == IF_TYPE_MMC) ? - DEVICE_PATH_SUB_TYPE_MSG_MMC : - DEVICE_PATH_SUB_TYPE_MSG_SD; + sddp->dp.sub_type = is_sd(desc) ? + DEVICE_PATH_SUB_TYPE_MSG_SD : + DEVICE_PATH_SUB_TYPE_MSG_MMC; sddp->dp.length = sizeof(*sddp); sddp->slot_number = dev->seq; From 7b982f009b2233821bc96d11bec20b433c40e6fa Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 11 Dec 2017 12:56:40 +0100 Subject: [PATCH 08/10] efi_loader: correctly setup device paths for block devices According to the UEFI spec the numbering of partitions has to start with 1. Partion number 0 is reserved for the optional device path for the complete block device. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- lib/efi_loader/efi_device_path.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 50330ddac7..5de2c0388f 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -435,7 +435,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part) if (desc->part_type == PART_TYPE_ISO) { struct efi_device_path_cdrom_path *cddp = buf; - cddp->boot_entry = part - 1; + cddp->boot_entry = part; cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH; cddp->dp.length = sizeof(*cddp); @@ -449,7 +449,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part) hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH; hddp->dp.length = sizeof(*hddp); - hddp->partition_number = part - 1; + hddp->partition_number = part; hddp->partition_start = info.start; hddp->partition_end = info.size; if (desc->part_type == PART_TYPE_EFI) From 6ea8b580f06b9ba9100af1ea5fa4d160e78a4517 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 11 Dec 2017 12:56:41 +0100 Subject: [PATCH 09/10] efi_loader: correct DeviceNodeToText for media types When converting device nodes and paths to text we should stick to the UEFI spec. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- lib/efi_loader/efi_device_path_to_text.c | 43 +++++++++++++++++------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 7159c974d4..50d9e911c0 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -90,7 +90,7 @@ static char *dp_msging(char *s, struct efi_device_path *dp) case DEVICE_PATH_SUB_TYPE_MSG_USB: { struct efi_device_path_usb *udp = (struct efi_device_path_usb *)dp; - s += sprintf(s, "Usb(0x%x,0x%x)", udp->parent_port_number, + s += sprintf(s, "USB(0x%x,0x%x)", udp->parent_port_number, udp->usb_interface); break; } @@ -124,10 +124,10 @@ static char *dp_msging(char *s, struct efi_device_path *dp) case DEVICE_PATH_SUB_TYPE_MSG_MMC: { const char *typename = (dp->sub_type == DEVICE_PATH_SUB_TYPE_MSG_SD) ? - "SDCard" : "MMC"; + "SD" : "eMMC"; struct efi_device_path_sd_mmc_path *sddp = (struct efi_device_path_sd_mmc_path *)dp; - s += sprintf(s, "%s(Slot%u)", typename, sddp->slot_number); + s += sprintf(s, "%s(%u)", typename, sddp->slot_number); break; } default: @@ -137,6 +137,13 @@ static char *dp_msging(char *s, struct efi_device_path *dp) return s; } +/* + * Convert a media device path node to text. + * + * @s output buffer + * @dp device path node + * @return next unused buffer address + */ static char *dp_media(char *s, struct efi_device_path *dp) { switch (dp->sub_type) { @@ -144,21 +151,33 @@ static char *dp_media(char *s, struct efi_device_path *dp) struct efi_device_path_hard_drive_path *hddp = (struct efi_device_path_hard_drive_path *)dp; void *sig = hddp->partition_signature; + u64 start; + u64 end; + + /* Copy from packed structure to aligned memory */ + memcpy(&start, &hddp->partition_start, sizeof(start)); + memcpy(&end, &hddp->partition_end, sizeof(end)); switch (hddp->signature_type) { - case SIG_TYPE_MBR: - s += sprintf(s, "HD(Part%d,Sig%08x)", - hddp->partition_number, - *(uint32_t *)sig); + case SIG_TYPE_MBR: { + u32 signature; + + memcpy(&signature, sig, sizeof(signature)); + s += sprintf( + s, "HD(%d,MBR,0x%08x,0x%llx,0x%llx)", + hddp->partition_number, signature, start, end); break; + } case SIG_TYPE_GUID: - s += sprintf(s, "HD(Part%d,Sig%pUl)", - hddp->partition_number, sig); + s += sprintf( + s, "HD(%d,GPT,%pUl,0x%llx,0x%llx)", + hddp->partition_number, sig, start, end); break; default: - s += sprintf(s, "HD(Part%d,MBRType=%02x,SigType=%02x)", - hddp->partition_number, hddp->partmap_type, - hddp->signature_type); + s += sprintf( + s, "HD(%d,0x%02x,0,0x%llx,0x%llx)", + hddp->partition_number, hddp->partmap_type, + start, end); break; } From bde6bfe4c3234480a0eef3b5bda8cf5fc83d3c79 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 11 Dec 2017 12:56:42 +0100 Subject: [PATCH 10/10] efi_loader: comments for dp_part_fill() Add a description for dp_part_fill(). Reword a comment in the function. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- lib/efi_loader/efi_device_path.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 5de2c0388f..ccb59337f1 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -399,6 +399,13 @@ static unsigned dp_part_size(struct blk_desc *desc, int part) return dpsize; } +/* + * Create a device path for a block device or one of its partitions. + * + * @buf buffer to which the device path is wirtten + * @desc block device descriptor + * @part partition number, 0 identifies a block device + */ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part) { disk_partition_t info; @@ -411,7 +418,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part) * and handling all the different cases like we do for non- * legacy (ie CONFIG_BLK=y) case. But most important thing * is just to have a unique device-path for if_type+devnum. - * So map things to a fictional USB device: + * So map things to a fictitious USB device. */ struct efi_device_path_usb *udp;