Browse Source

efi_loader: factor out efi_set_load_options()

The bootefi bootmgr command has to set the load options for a loaded image
from the value of BootXXXX variable. If the boot manager is not used, the
value is set from the environment variable bootargs (or efi_selftest).

Factor out a common function efi_set_load_options().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Heinrich Schuchardt 3 years ago
parent
commit
1064d04920
3 changed files with 54 additions and 36 deletions
  1. 19 36
      cmd/bootefi.c
  2. 3 0
      include/efi_loader.h
  3. 32 0
      lib/efi_loader/efi_bootmgr.c

+ 19 - 36
cmd/bootefi.c

@@ -31,55 +31,37 @@ static struct efi_device_path *bootefi_image_path;
 static struct efi_device_path *bootefi_device_path;
 
 /**
- * Set the load options of an image from an environment variable.
+ * efi_env_set_load_options() - set load options from environment variable
  *
  * @handle:		the image handle
  * @env_var:		name of the environment variable
  * @load_options:	pointer to load options (output)
  * Return:		status code
  */
-static efi_status_t set_load_options(efi_handle_t handle, const char *env_var,
-				     u16 **load_options)
+static efi_status_t efi_env_set_load_options(efi_handle_t handle,
+					     const char *env_var,
+					     u16 **load_options)
 {
-	struct efi_loaded_image *loaded_image_info;
-	size_t size;
 	const char *env = env_get(env_var);
+	size_t size;
 	u16 *pos;
 	efi_status_t ret;
 
 	*load_options = NULL;
-	ret = EFI_CALL(systab.boottime->open_protocol(
-					handle,
-					&efi_guid_loaded_image,
-					(void **)&loaded_image_info,
-					efi_root, NULL,
-					EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
-	if (ret != EFI_SUCCESS)
-		return EFI_INVALID_PARAMETER;
-
-	loaded_image_info->load_options = NULL;
-	loaded_image_info->load_options_size = 0;
 	if (!env)
-		goto out;
-
-	size = utf8_utf16_strlen(env) + 1;
-	loaded_image_info->load_options = calloc(size, sizeof(u16));
-	if (!loaded_image_info->load_options) {
-		log_err("ERROR: Out of memory\n");
-		EFI_CALL(systab.boottime->close_protocol(handle,
-							 &efi_guid_loaded_image,
-							 efi_root, NULL));
+		return EFI_SUCCESS;
+	size = sizeof(u16) * (utf8_utf16_strlen(env) + 1);
+	pos = calloc(size, 1);
+	if (!pos)
 		return EFI_OUT_OF_RESOURCES;
-	}
-	pos = loaded_image_info->load_options;
 	*load_options = pos;
 	utf8_utf16_strcpy(&pos, env);
-	loaded_image_info->load_options_size = size * 2;
-
-out:
-	return EFI_CALL(systab.boottime->close_protocol(handle,
-							&efi_guid_loaded_image,
-							efi_root, NULL));
+	ret = efi_set_load_options(handle, size, *load_options);
+	if (ret != EFI_SUCCESS) {
+		free(*load_options);
+		*load_options = NULL;
+	}
+	return ret;
 }
 
 #if !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
@@ -336,7 +318,7 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle)
 	u16 *load_options;
 
 	/* Transfer environment variable as load options */
-	ret = set_load_options(handle, "bootargs", &load_options);
+	ret = efi_env_set_load_options(handle, "bootargs", &load_options);
 	if (ret != EFI_SUCCESS)
 		return ret;
 
@@ -509,8 +491,9 @@ static efi_status_t bootefi_run_prepare(const char *load_options_path,
 		return ret;
 
 	/* Transfer environment variable as load options */
-	return set_load_options((efi_handle_t)*image_objp, load_options_path,
-				&load_options);
+	return efi_env_set_load_options((efi_handle_t)*image_objp,
+					load_options_path,
+					&load_options);
 }
 
 /**

+ 3 - 0
include/efi_loader.h

@@ -717,6 +717,9 @@ struct efi_load_option {
 efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data,
 					 efi_uintn_t *size);
 unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
+efi_status_t efi_set_load_options(efi_handle_t handle,
+				  efi_uintn_t load_options_size,
+				  void *load_options);
 efi_status_t efi_bootmgr_load(efi_handle_t *handle);
 
 /**

+ 32 - 0
lib/efi_loader/efi_bootmgr.c

@@ -30,6 +30,38 @@ static const struct efi_runtime_services *rs;
  * should do normal or recovery boot.
  */
 
+/**
+ * efi_set_load_options() - set the load options of a loaded image
+ *
+ * @handle:		the image handle
+ * @load_options_size:	size of load options
+ * @load_options:	pointer to load options
+ * Return:		status code
+ */
+efi_status_t efi_set_load_options(efi_handle_t handle,
+				  efi_uintn_t load_options_size,
+				  void *load_options)
+{
+	struct efi_loaded_image *loaded_image_info;
+	efi_status_t ret;
+
+	ret = EFI_CALL(systab.boottime->open_protocol(
+					handle,
+					&efi_guid_loaded_image,
+					(void **)&loaded_image_info,
+					efi_root, NULL,
+					EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
+	if (ret != EFI_SUCCESS)
+		return EFI_INVALID_PARAMETER;
+
+	loaded_image_info->load_options = load_options;
+	loaded_image_info->load_options_size = load_options_size;
+
+	return EFI_CALL(systab.boottime->close_protocol(handle,
+							&efi_guid_loaded_image,
+							efi_root, NULL));
+}
+
 
 /**
  * efi_deserialize_load_option() - parse serialized data