[U-Boot] [PATCH 3/4] efi_loader: implement UnloadImage()
Heinrich Schuchardt
xypron.glpk at gmx.de
Sat May 4 08:36:35 UTC 2019
Implement the UnloadImage() boot service
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
include/efi_api.h | 2 +-
lib/efi_loader/efi_boottime.c | 55 ++++++++++++++++++++++++++++++++---
2 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/include/efi_api.h b/include/efi_api.h
index 4ebb4a5f59..54c6232079 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -348,7 +348,7 @@ struct efi_loaded_image {
aligned_u64 image_size;
unsigned int image_code_type;
unsigned int image_data_type;
- unsigned long unload;
+ efi_status_t (EFIAPI *unload)(efi_handle_t image_handle);
};
#define EFI_DEVICE_PATH_PROTOCOL_GUID \
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 2992af269a..bbcd66caa6 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2669,6 +2669,20 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
return EFI_CALL(systab.boottime->exit(image_handle, ret, 0, NULL));
}
+/**
+ * efi_delete_image() - delete loaded image from memory)
+ *
+ * @image_obj: handle of the loaded image
+ * @loaded_image_protocol: loaded image protocol
+ */
+static void efi_delete_image(struct efi_loaded_image_obj *image_obj,
+ struct efi_loaded_image *loaded_image_protocol)
+{
+ efi_free_pages((uintptr_t)loaded_image_protocol->image_base,
+ efi_size_in_pages(loaded_image_protocol->image_size));
+ efi_delete_handle(&image_obj->header);
+}
+
/**
* efi_unload_image() - unload an EFI image
* @image_handle: handle of the image to be unloaded
@@ -2682,14 +2696,47 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
*/
efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle)
{
+ efi_status_t ret = EFI_SUCCESS;
struct efi_object *efiobj;
+ struct efi_loaded_image *loaded_image_protocol;
EFI_ENTRY("%p", image_handle);
- efiobj = efi_search_obj(image_handle);
- if (efiobj)
- list_del(&efiobj->link);
- return EFI_EXIT(EFI_SUCCESS);
+ efiobj = efi_search_obj(image_handle);
+ if (!efiobj) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ /* Find the loaded image protocol */
+ ret = EFI_CALL(efi_open_protocol(image_handle, &efi_guid_loaded_image,
+ (void **)&loaded_image_protocol,
+ NULL, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (ret != EFI_SUCCESS) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ switch (efiobj->type) {
+ case EFI_OBJECT_TYPE_STARTED_IMAGE:
+ /* Call the unload function */
+ if (!loaded_image_protocol->unload) {
+ ret = EFI_UNSUPPORTED;
+ goto out;
+ }
+ ret = EFI_CALL(loaded_image_protocol->unload(image_handle));
+ if (ret != EFI_SUCCESS)
+ goto out;
+ break;
+ case EFI_OBJECT_TYPE_LOADED_IMAGE:
+ break;
+ default:
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ efi_delete_image((struct efi_loaded_image_obj *)efiobj,
+ loaded_image_protocol);
+out:
+ return EFI_EXIT(ret);
}
/**
--
2.20.1
More information about the U-Boot
mailing list