From 99858938a08dbdd892cc5438ec49b4262077017d Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 6 Mar 2014 11:58:36 +0800 Subject: [PATCH 1/3] [fallback] Avoid duplicate old BootOrder set_boot_order() already copies the old BootOrder to the variable, bootorder. Besides, we can adjust BootOrder when adding the newly generated boot option. So, we don't have to copy the old one again in update_boot_order(). This avoid the duplicate entries in BootOrder. Signed-off-by: Gary Ching-Pang Lin --- fallback.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/fallback.c b/fallback.c index 44638ec..8aee618 100644 --- a/fallback.c +++ b/fallback.c @@ -204,12 +204,12 @@ add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp, return EFI_OUT_OF_RESOURCES; int j = 0; + newbootorder[0] = i & 0xffff; if (nbootorder) { - for (j = 0; j < nbootorder; j++) - newbootorder[j] = bootorder[j]; + for (j = 1; j < nbootorder + 1; j++) + newbootorder[j] = bootorder[j-1]; FreePool(bootorder); } - newbootorder[j] = i & 0xffff; bootorder = newbootorder; nbootorder += 1; #ifdef DEBUG_FALLBACK @@ -307,28 +307,17 @@ set_boot_order(void) EFI_STATUS update_boot_order(void) { - CHAR16 *oldbootorder; UINTN size; + UINTN len = 0; EFI_GUID global = EFI_GLOBAL_VARIABLE; CHAR16 *newbootorder = NULL; + EFI_STATUS rc; - oldbootorder = LibGetVariableAndSize(L"BootOrder", &global, &size); - if (oldbootorder) { - int n = size / sizeof (CHAR16) + nbootorder; - - newbootorder = AllocateZeroPool(n * sizeof (CHAR16)); - if (!newbootorder) - return EFI_OUT_OF_RESOURCES; - CopyMem(newbootorder, bootorder, nbootorder * sizeof (CHAR16)); - CopyMem(newbootorder + nbootorder, oldbootorder, size); - size = n * sizeof (CHAR16); - } else { - size = nbootorder * sizeof(CHAR16); - newbootorder = AllocateZeroPool(size); - if (!newbootorder) - return EFI_OUT_OF_RESOURCES; - CopyMem(newbootorder, bootorder, size); - } + size = nbootorder * sizeof(CHAR16); + newbootorder = AllocateZeroPool(size); + if (!newbootorder) + return EFI_OUT_OF_RESOURCES; + CopyMem(newbootorder, bootorder, size); #ifdef DEBUG_FALLBACK Print(L"nbootorder: %d\nBootOrder: ", size / sizeof (CHAR16)); @@ -337,13 +326,11 @@ update_boot_order(void) Print(L"%04x ", newbootorder[j]); Print(L"\n"); #endif - - if (oldbootorder) { + rc = uefi_call_wrapper(RT->GetVariable, 5, L"BootOrder", &global, + NULL, &len, NULL); + if (rc == EFI_BUFFER_TOO_SMALL) LibDeleteVariable(L"BootOrder", &global); - FreePool(oldbootorder); - } - EFI_STATUS rc; rc = uefi_call_wrapper(RT->SetVariable, 5, L"BootOrder", &global, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | -- 1.8.4.5 From 80c15a7e90d8f51b09211994895a64ec5e4f5c1e Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 6 Mar 2014 10:57:02 +0800 Subject: [PATCH 2/3] [fallback] Fix the data size for boot option comparison Signed-off-by: Gary Ching-Pang Lin --- fallback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fallback.c b/fallback.c index 8aee618..156115f 100644 --- a/fallback.c +++ b/fallback.c @@ -231,7 +231,7 @@ find_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, { int size = sizeof(UINT32) + sizeof (UINT16) + StrLen(label)*2 + 2 + DevicePathSize(dp) + - StrLen(arguments) * 2 + 2; + StrLen(arguments) * 2; CHAR8 *data = AllocateZeroPool(size); if (!data) -- 1.8.4.5 From 70ffe93b85380a9866ebf3a99b35dde0b332cd65 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Wed, 5 Mar 2014 18:14:09 +0800 Subject: [PATCH 3/3] [fallback] Try to boot the first boot option anyway Some UEFI implementations never care the boot options, so the restored boot options could be just ignored and this results in endless reboot. To avoid this situation, this commit makes fallback.efi to load the first matched boot option even if there is not boot option to be restored. Signed-off-by: Gary Ching-Pang Lin --- fallback.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fallback.c b/fallback.c index 156115f..777e708 100644 --- a/fallback.c +++ b/fallback.c @@ -226,8 +226,9 @@ add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp, } EFI_STATUS -find_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, - CHAR16 *arguments, UINT16 *optnum) +find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp, + CHAR16 *filename, CHAR16 *label, CHAR16 *arguments, + UINT16 *optnum) { int size = sizeof(UINT32) + sizeof (UINT16) + StrLen(label)*2 + 2 + DevicePathSize(dp) + @@ -278,6 +279,12 @@ find_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, continue; /* at this point, we have duplicate data. */ + if (!first_new_option) { + first_new_option = DuplicateDevicePath(fulldp); + first_new_option_args = arguments; + first_new_option_size = StrLen(arguments) * sizeof (CHAR16); + } + *optnum = i; FreePool(candidate); FreePool(data); @@ -403,7 +410,7 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 * #endif UINT16 option; - rc = find_boot_option(dp, fullpath, label, arguments, &option); + rc = find_boot_option(dp, full_device_path, fullpath, label, arguments, &option); if (EFI_ERROR(rc)) { add_boot_option(dp, full_device_path, fullpath, label, arguments); } else if (option != 0) { -- 1.8.4.5