
Previous patches change the logic of the initrd discovery and the registration of the protocol. Instead of a config now option it now resides in an EFI variable. Adjust the instructions of execution accordingly and add new self-tests which will cover the new functionality.
Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org --- lib/efi_selftest/efi_selftest_load_initrd.c | 90 ++++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-)
diff --git a/lib/efi_selftest/efi_selftest_load_initrd.c b/lib/efi_selftest/efi_selftest_load_initrd.c index fe060a664402..85afed55425f 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 = { @@ -80,6 +83,7 @@ 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,6 +91,7 @@ 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; @@ -95,8 +100,89 @@ static int execute(void) 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 register the protocol during efibootmgr */ + status = efi_initrd_register(); + if (status != EFI_SUCCESS) { + efi_st_error("Failed to register initrd protocol\n"); + return EFI_ST_FAILURE; + } + + /* + * We should only register 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 registered\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-register with invalid file path */ + status = efi_initrd_register(); + if (status != EFI_SUCCESS) { + efi_st_error("Failed to register 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 registered\n"); + return EFI_ST_FAILURE; + } + + /* re-register 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(); + if (status != EFI_SUCCESS) { + efi_st_error("Failed to register initrd protocol\n"); + return EFI_ST_FAILURE; + }
dp2 = (struct efi_device_path *)&dp; status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle);