[PATCH 7/8 v2] efi_selftest: Modify self-tests for initrd loading via Loadfile2

Ilias Apalodimas ilias.apalodimas at linaro.org
Wed Dec 30 16:07:19 CET 2020


We changed the logic of the initrd discovery and the installation of the 
protocol in the previous patch.
Instead of a config now option it now resides in an EFI variable. Adjust
the existing tests accordingly and add self-tests which will cover the new 
features.

Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
---
 lib/efi_selftest/efi_selftest_load_initrd.c | 100 +++++++++++++++++++-
 1 file changed, 97 insertions(+), 3 deletions(-)

diff --git a/lib/efi_selftest/efi_selftest_load_initrd.c b/lib/efi_selftest/efi_selftest_load_initrd.c
index fe060a664402..1534c2ba24fa 100644
--- a/lib/efi_selftest/efi_selftest_load_initrd.c
+++ b/lib/efi_selftest/efi_selftest_load_initrd.c
@@ -14,10 +14,12 @@
  *
  *   CONFIG_EFI_SELFTEST=y
  *   CONFIG_EFI_LOAD_FILE2_INITRD=y
- *   CONFIG_EFI_INITRD_FILESPEC="host 0:1 initrd"
  *
- * * Run ./u-boot and execute
+ * * Create files
+ *   mkdir init_test && cp initrd init_test/
+ *   virt-make-fs -t ext4 init_test test.img
  *
+ * * Run ./u-boot and execute
  *   host bind 0 image
  *   setenv efi_selftest load initrd
  *   bootefi selftest
@@ -43,6 +45,7 @@
 #include <efi_load_initrd.h>
 
 static struct efi_boot_services *boottime;
+static struct efi_runtime_services *runtime;
 
 static struct efi_initrd_dp dp = {
 	.vendor = {
@@ -76,10 +79,13 @@ static struct efi_initrd_dp dp_invalid = {
 	}
 };
 
+static efi_handle_t handle;
+
 static int setup(const efi_handle_t handle,
 		 const struct efi_system_table *systable)
 {
 	boottime = systable->boottime;
+	runtime = systable->runtime;
 
 	return EFI_ST_SUCCESS;
 }
@@ -87,16 +93,97 @@ static int setup(const efi_handle_t handle,
 static int execute(void)
 {
 	efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
+	efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
 	struct efi_load_file_protocol *lf2;
 	struct efi_device_path *dp2, *dp2_invalid;
 	efi_status_t status;
-	efi_handle_t handle;
 	char buffer[64];
 	efi_uintn_t buffer_size;
 	void *buf;
 	u32 crc32;
+	u16 boot_current = 0;
+	efi_uintn_t boot_current_size = sizeof(boot_current);
+	char path[] = "host 0 initrd";
+	char invalid_path[] = "host 1 initrd";
+	efi_uintn_t path_size = sizeof(path);
+	efi_uintn_t invalid_path_size = sizeof(invalid_path);
+	u32 attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
 
 	memset(buffer, 0, sizeof(buffer));
+	/* Set variable BootCurrent and Initrd#### to a wrong value */
+	status = runtime->set_variable(L"BootCurrent", &efi_global_variable_guid,
+				       attrs, boot_current_size, &boot_current);
+	if (status != EFI_SUCCESS) {
+		efi_st_error("SetVariable for BootCurrent failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * We don't need NV for Initrd here.
+	 * Set the file to an invalid file path
+	 */
+	status = runtime->set_variable(L"Initrd0010", &efi_global_variable_guid,
+				       attrs, invalid_path_size, invalid_path);
+	if (status != EFI_SUCCESS) {
+		efi_st_error("SetVariable for Initrd failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* We only install the protocol during efibootmgr */
+	status = efi_initrd_register(&handle);
+	if (status != EFI_SUCCESS) {
+		efi_st_error("Failed to install initrd protocol\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * We should only install the protocol if the file's found
+	 * Right now both BootCurrent and file path are invalid
+	 */
+	dp2 = (struct efi_device_path *)&dp;
+	status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle);
+	if (status != EFI_NOT_FOUND) {
+		efi_st_error("Initrd protocol should't be installed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Update BootCurrent to the correct value */
+	boot_current = 0x0010;
+	status = runtime->set_variable(L"BootCurrent", &efi_global_variable_guid,
+				       attrs, boot_current_size, &boot_current);
+	if (status != EFI_SUCCESS) {
+		efi_st_error("SetVariable for BootCurrent failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* re-install with invalid file path */
+	status = efi_initrd_register(&handle);
+	if (status != EFI_SUCCESS) {
+		efi_st_error("Failed to install initrd protocol\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* file path is invalid */
+	dp2 = (struct efi_device_path *)&dp;
+	status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle);
+	if (status != EFI_NOT_FOUND) {
+		efi_st_error("Initrd protocol should't be installed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* re-install with correct values now */
+	status = runtime->set_variable(L"Initrd0010", &efi_global_variable_guid,
+				       attrs, path_size, path);
+	if (status != EFI_SUCCESS) {
+		efi_st_error("SetVariable for Initrd failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	status = efi_initrd_register(&handle);
+	if (status != EFI_SUCCESS) {
+		efi_st_error("Failed to install initrd protocol\n");
+		return EFI_ST_FAILURE;
+	}
 
 	dp2 = (struct efi_device_path *)&dp;
 	status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle);
@@ -211,10 +298,17 @@ static int execute(void)
 	return EFI_ST_SUCCESS;
 }
 
+static int teardown(void)
+{
+	efi_delete_handle(handle);
+	return EFI_ST_SUCCESS;
+}
+
 EFI_UNIT_TEST(load_initrd) = {
 	.name = "load initrd",
 	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
 	.setup = setup,
 	.execute = execute,
+	.teardown = teardown,
 	.on_request = true,
 };
-- 
2.30.0



More information about the U-Boot mailing list