summaryrefslogtreecommitdiff
path: root/fallback.c
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2013-05-02 14:58:44 -0400
committerPeter Jones <pjones@redhat.com>2013-05-02 14:58:44 -0400
commit8807e36aaecfa2c4c67b33480cf44182518e313c (patch)
treef0aab0de8da8da52fde55913374c5f1133855e4e /fallback.c
parent4f80140b53ba290f3fb2dd4cf9af4637b28f24ed (diff)
downloadefi-boot-shim-8807e36aaecfa2c4c67b33480cf44182518e313c.tar.gz
efi-boot-shim-8807e36aaecfa2c4c67b33480cf44182518e313c.zip
[fallback] Try to execute the first new boot option.
I'm told rebooting is sometimes unreliable when called here, and we'll get bootx64.efi loaded anyway. I'll just assume that's true and try to load the first option, since it's clearly what we'd prefer happens next. Signed-off-by: Peter Jones <pjones@redhat.com>
Diffstat (limited to 'fallback.c')
-rw-r--r--fallback.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/fallback.c b/fallback.c
index dab3d3dc..387c84a8 100644
--- a/fallback.c
+++ b/fallback.c
@@ -114,6 +114,10 @@ make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen)
CHAR16 *bootorder = NULL;
int nbootorder = 0;
+EFI_DEVICE_PATH *first_new_option = NULL;
+VOID *first_new_option_args = NULL;
+UINTN first_new_option_size = 0;
+
EFI_STATUS
add_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
{
@@ -284,6 +288,13 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
CHAR16 *dps = DevicePathToStr(dp);
Print(L"device path: \"%s\"\n", dps);
#endif
+ if (!first_new_option) {
+ CHAR16 *dps = DevicePathToStr(dp);
+ Print(L"device path: \"%s\"\n", dps);
+ first_new_option = DuplicateDevicePath(dp);
+ first_new_option_args = arguments;
+ first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
+ }
add_boot_option(dp, fullpath, label, arguments);
@@ -596,6 +607,33 @@ find_boot_options(EFI_HANDLE device)
uefi_call_wrapper(fh->Close, 1, fh);
return rc;
}
+
+static EFI_STATUS
+try_start_first_option(EFI_HANDLE parent_image_handle)
+{
+ EFI_STATUS rc;
+ EFI_HANDLE image_handle;
+
+ if (!first_new_option) {
+ return EFI_SUCCESS;
+ }
+
+ rc = uefi_call_wrapper(BS->LoadImage, 6, 0, parent_image_handle,
+ first_new_option, NULL, 0,
+ &image_handle);
+ if (EFI_ERROR(rc)) {
+ Print(L"LoadImage failed: %d\n", rc);
+ uefi_call_wrapper(BS->Stall, 1, 2000000);
+ return rc;
+ }
+ rc = uefi_call_wrapper(BS->StartImage, 3, image_handle, NULL, NULL);
+ if (EFI_ERROR(rc)) {
+ Print(L"StartImage failed: %d\n", rc);
+ uefi_call_wrapper(BS->Stall, 1, 2000000);
+ }
+ return rc;
+}
+
EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
@@ -617,8 +655,10 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
return rc;
}
+ try_start_first_option(image);
+
Print(L"Reset System\n");
- uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold,
EFI_SUCCESS, 0, NULL);
return EFI_SUCCESS;