[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