efi_loader: carve out efi_run_image()
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Sat, 7 Dec 2019 19:51:06 +0000 (20:51 +0100)
committerHeinrich Schuchardt <xypron.glpk@gmx.de>
Tue, 7 Jan 2020 17:08:20 +0000 (18:08 +0100)
Provide public function efi_run_imager() which can be used to run an UEFI
image from memory.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
cmd/bootefi.c
include/efi_loader.h

index a3e2a051263da5a1604926613ccdf880fc3e8ef3..15b4ff95159220f31f6942b5835b6d372da3f07f 100644 (file)
@@ -360,11 +360,8 @@ static int do_efibootmgr(void)
 static int do_bootefi_image(const char *image_opt)
 {
        void *image_buf;
-       struct efi_device_path *device_path, *image_path;
-       struct efi_device_path *file_path = NULL;
        unsigned long addr, size;
        const char *size_str;
-       efi_handle_t mem_handle = NULL, handle;
        efi_status_t ret;
 
 #ifdef CONFIG_CMD_BOOTEFI_HELLO
@@ -382,8 +379,10 @@ static int do_bootefi_image(const char *image_opt)
                image_buf = map_sysmem(addr, size);
                memcpy(image_buf, __efi_helloworld_begin, size);
 
-               device_path = NULL;
-               image_path = NULL;
+               efi_free_pool(bootefi_device_path);
+               efi_free_pool(bootefi_image_path);
+               bootefi_device_path = NULL;
+               bootefi_image_path = NULL;
        } else
 #endif
        {
@@ -399,19 +398,37 @@ static int do_bootefi_image(const char *image_opt)
                        return CMD_RET_USAGE;
 
                image_buf = map_sysmem(addr, size);
-
-               device_path = bootefi_device_path;
-               image_path = bootefi_image_path;
        }
+       ret = efi_run_image(image_buf, size);
+
+       if (ret != EFI_SUCCESS)
+               return CMD_RET_FAILURE;
+
+       return CMD_RET_SUCCESS;
+}
+
+/**
+ * efi_run_image() - run loaded UEFI image
+ *
+ * @source_buffer:     memory address of the UEFI image
+ * @source_size:       size of the UEFI image
+ * Return:             status code
+ */
+efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
+{
+       efi_handle_t mem_handle = NULL, handle;
+       struct efi_device_path *file_path = NULL;
+       efi_status_t ret;
 
-       if (!device_path && !image_path) {
+       if (!bootefi_device_path || !bootefi_image_path) {
                /*
                 * Special case for efi payload not loaded from disk,
                 * such as 'bootefi hello' or for example payload
                 * loaded directly into memory via JTAG, etc:
                 */
                file_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
-                                           (uintptr_t)image_buf, size);
+                                           (uintptr_t)source_buffer,
+                                           source_size);
                /*
                 * Make sure that device for device_path exist
                 * in load_image(). Otherwise, shell and grub will fail.
@@ -425,12 +442,12 @@ static int do_bootefi_image(const char *image_opt)
                if (ret != EFI_SUCCESS)
                        goto out;
        } else {
-               assert(device_path && image_path);
-               file_path = efi_dp_append(device_path, image_path);
+               file_path = efi_dp_append(bootefi_device_path,
+                                         bootefi_image_path);
        }
 
-       ret = EFI_CALL(efi_load_image(false, efi_root,
-                                     file_path, image_buf, size, &handle));
+       ret = EFI_CALL(efi_load_image(false, efi_root, file_path, source_buffer,
+                                     source_size, &handle));
        if (ret != EFI_SUCCESS)
                goto out;
 
@@ -441,11 +458,7 @@ out:
                efi_delete_handle(mem_handle);
        if (file_path)
                efi_free_pool(file_path);
-
-       if (ret != EFI_SUCCESS)
-               return CMD_RET_FAILURE;
-
-       return CMD_RET_SUCCESS;
+       return ret;
 }
 
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
index 3a220893298fe3b68f63011f036e197e5a02e51f..1e1fe52bc0fbe5bd717010391fd63a4be38df305 100644 (file)
@@ -341,6 +341,8 @@ extern struct list_head efi_register_notify_events;
 
 /* Initialize efi execution environment */
 efi_status_t efi_init_obj_list(void);
+/* Run loaded UEFI image */
+efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size);
 /* Initialize variable services */
 efi_status_t efi_init_variables(void);
 /* Notify ExitBootServices() is called */