|
|
4210fa |
From 894a2738d6c843a7b51245fb92bb2f835901e613 Mon Sep 17 00:00:00 2001
|
|
|
4210fa |
From: Peter Jones <pjones@redhat.com>
|
|
|
4210fa |
Date: Fri, 31 Jan 2014 10:31:10 -0500
|
|
|
4210fa |
Subject: [PATCH 19/74] [fallback] Attempt to re-use existing entries when
|
|
|
4210fa |
possible.
|
|
|
4210fa |
|
|
|
4210fa |
Some firmwares seem to ignore our boot entries and put their fallback
|
|
|
4210fa |
entries back on top. Right now that results in a lot of boot entries
|
|
|
4210fa |
for our stuff, a la https://bugzilla.redhat.com/show_bug.cgi?id=995834 .
|
|
|
4210fa |
|
|
|
4210fa |
Instead of that happening, if we simply find existing entries that match
|
|
|
4210fa |
the entry we would create and move them to the top of the boot order,
|
|
|
4210fa |
the machine will continue to operate in failure mode (which we can't
|
|
|
4210fa |
avoid), but at least we won't create thousands of extra entries.
|
|
|
4210fa |
|
|
|
4210fa |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
4210fa |
---
|
|
|
4210fa |
fallback.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
4210fa |
1 file changed, 98 insertions(+), 1 deletion(-)
|
|
|
4210fa |
|
|
|
4210fa |
diff --git a/fallback.c b/fallback.c
|
|
|
4210fa |
index a12bb74..44638ec 100644
|
|
|
4210fa |
--- a/fallback.c
|
|
|
4210fa |
+++ b/fallback.c
|
|
|
4210fa |
@@ -226,6 +226,85 @@ add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp,
|
|
|
4210fa |
}
|
|
|
4210fa |
|
|
|
4210fa |
EFI_STATUS
|
|
|
4210fa |
+find_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label,
|
|
|
4210fa |
+ CHAR16 *arguments, UINT16 *optnum)
|
|
|
4210fa |
+{
|
|
|
4210fa |
+ int size = sizeof(UINT32) + sizeof (UINT16) +
|
|
|
4210fa |
+ StrLen(label)*2 + 2 + DevicePathSize(dp) +
|
|
|
4210fa |
+ StrLen(arguments) * 2 + 2;
|
|
|
4210fa |
+
|
|
|
4210fa |
+ CHAR8 *data = AllocateZeroPool(size);
|
|
|
4210fa |
+ if (!data)
|
|
|
4210fa |
+ return EFI_OUT_OF_RESOURCES;
|
|
|
4210fa |
+ CHAR8 *cursor = data;
|
|
|
4210fa |
+ *(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
|
|
|
4210fa |
+ cursor += sizeof (UINT32);
|
|
|
4210fa |
+ *(UINT16 *)cursor = DevicePathSize(dp);
|
|
|
4210fa |
+ cursor += sizeof (UINT16);
|
|
|
4210fa |
+ StrCpy((CHAR16 *)cursor, label);
|
|
|
4210fa |
+ cursor += StrLen(label)*2 + 2;
|
|
|
4210fa |
+ CopyMem(cursor, dp, DevicePathSize(dp));
|
|
|
4210fa |
+ cursor += DevicePathSize(dp);
|
|
|
4210fa |
+ StrCpy((CHAR16 *)cursor, arguments);
|
|
|
4210fa |
+
|
|
|
4210fa |
+ int i = 0;
|
|
|
4210fa |
+ CHAR16 varname[] = L"Boot0000";
|
|
|
4210fa |
+ CHAR16 hexmap[] = L"0123456789ABCDEF";
|
|
|
4210fa |
+ EFI_GUID global = EFI_GLOBAL_VARIABLE;
|
|
|
4210fa |
+ EFI_STATUS rc;
|
|
|
4210fa |
+
|
|
|
4210fa |
+ CHAR8 *candidate = AllocateZeroPool(size);
|
|
|
4210fa |
+ if (!candidate) {
|
|
|
4210fa |
+ FreePool(data);
|
|
|
4210fa |
+ return EFI_OUT_OF_RESOURCES;
|
|
|
4210fa |
+ }
|
|
|
4210fa |
+
|
|
|
4210fa |
+ for(i = 0; i < nbootorder && i < 0x10000; i++) {
|
|
|
4210fa |
+ varname[4] = hexmap[(bootorder[i] & 0xf000) >> 12];
|
|
|
4210fa |
+ varname[5] = hexmap[(bootorder[i] & 0x0f00) >> 8];
|
|
|
4210fa |
+ varname[6] = hexmap[(bootorder[i] & 0x00f0) >> 4];
|
|
|
4210fa |
+ varname[7] = hexmap[(bootorder[i] & 0x000f) >> 0];
|
|
|
4210fa |
+
|
|
|
4210fa |
+ UINTN candidate_size = size;
|
|
|
4210fa |
+ rc = uefi_call_wrapper(RT->GetVariable, 5, varname, &global,
|
|
|
4210fa |
+ NULL, &candidate_size, candidate);
|
|
|
4210fa |
+ if (EFI_ERROR(rc))
|
|
|
4210fa |
+ continue;
|
|
|
4210fa |
+
|
|
|
4210fa |
+ if (candidate_size != size)
|
|
|
4210fa |
+ continue;
|
|
|
4210fa |
+
|
|
|
4210fa |
+ if (CompareMem(candidate, data, size))
|
|
|
4210fa |
+ continue;
|
|
|
4210fa |
+
|
|
|
4210fa |
+ /* at this point, we have duplicate data. */
|
|
|
4210fa |
+ *optnum = i;
|
|
|
4210fa |
+ FreePool(candidate);
|
|
|
4210fa |
+ FreePool(data);
|
|
|
4210fa |
+ return EFI_SUCCESS;
|
|
|
4210fa |
+ }
|
|
|
4210fa |
+ FreePool(candidate);
|
|
|
4210fa |
+ FreePool(data);
|
|
|
4210fa |
+ return EFI_NOT_FOUND;
|
|
|
4210fa |
+}
|
|
|
4210fa |
+
|
|
|
4210fa |
+EFI_STATUS
|
|
|
4210fa |
+set_boot_order(void)
|
|
|
4210fa |
+{
|
|
|
4210fa |
+ CHAR16 *oldbootorder;
|
|
|
4210fa |
+ UINTN size;
|
|
|
4210fa |
+ EFI_GUID global = EFI_GLOBAL_VARIABLE;
|
|
|
4210fa |
+
|
|
|
4210fa |
+ oldbootorder = LibGetVariableAndSize(L"BootOrder", &global, &size);
|
|
|
4210fa |
+ if (oldbootorder) {
|
|
|
4210fa |
+ nbootorder = size / sizeof (CHAR16);
|
|
|
4210fa |
+ bootorder = oldbootorder;
|
|
|
4210fa |
+ }
|
|
|
4210fa |
+ return EFI_SUCCESS;
|
|
|
4210fa |
+
|
|
|
4210fa |
+}
|
|
|
4210fa |
+
|
|
|
4210fa |
+EFI_STATUS
|
|
|
4210fa |
update_boot_order(void)
|
|
|
4210fa |
{
|
|
|
4210fa |
CHAR16 *oldbootorder;
|
|
|
4210fa |
@@ -336,7 +415,23 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
|
|
|
4210fa |
}
|
|
|
4210fa |
#endif
|
|
|
4210fa |
|
|
|
4210fa |
- add_boot_option(dp, full_device_path, fullpath, label, arguments);
|
|
|
4210fa |
+ UINT16 option;
|
|
|
4210fa |
+ rc = find_boot_option(dp, fullpath, label, arguments, &option);
|
|
|
4210fa |
+ if (EFI_ERROR(rc)) {
|
|
|
4210fa |
+ add_boot_option(dp, full_device_path, fullpath, label, arguments);
|
|
|
4210fa |
+ } else if (option != 0) {
|
|
|
4210fa |
+ CHAR16 *newbootorder;
|
|
|
4210fa |
+ newbootorder = AllocateZeroPool(sizeof (CHAR16) * nbootorder);
|
|
|
4210fa |
+ if (!newbootorder)
|
|
|
4210fa |
+ return EFI_OUT_OF_RESOURCES;
|
|
|
4210fa |
+
|
|
|
4210fa |
+ newbootorder[0] = bootorder[option];
|
|
|
4210fa |
+ CopyMem(newbootorder + 1, bootorder, sizeof (CHAR16) * option);
|
|
|
4210fa |
+ CopyMem(newbootorder + option + 1, bootorder + option + 1,
|
|
|
4210fa |
+ sizeof (CHAR16) * (nbootorder - option - 1));
|
|
|
4210fa |
+ FreePool(bootorder);
|
|
|
4210fa |
+ bootorder = newbootorder;
|
|
|
4210fa |
+ }
|
|
|
4210fa |
|
|
|
4210fa |
err:
|
|
|
4210fa |
if (file)
|
|
|
4210fa |
@@ -717,6 +812,8 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|
|
4210fa |
|
|
|
4210fa |
Print(L"System BootOrder not found. Initializing defaults.\n");
|
|
|
4210fa |
|
|
|
4210fa |
+ set_boot_order();
|
|
|
4210fa |
+
|
|
|
4210fa |
rc = find_boot_options(this_image->DeviceHandle);
|
|
|
4210fa |
if (EFI_ERROR(rc)) {
|
|
|
4210fa |
Print(L"Error: could not find boot options: %d\n", rc);
|
|
|
4210fa |
--
|
|
|
4210fa |
1.9.3
|
|
|
4210fa |
|