|
|
4210fa |
From f500a8742c19be604d33907b56ab9597fe448b65 Mon Sep 17 00:00:00 2001
|
|
|
4210fa |
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
|
4210fa |
Date: Tue, 27 May 2014 14:12:32 +0800
|
|
|
4210fa |
Subject: [PATCH 29/74] Fetch the netboot image from the same device
|
|
|
4210fa |
|
|
|
4210fa |
The previous strategy is to locate the first available PXE_BASE_CODE
|
|
|
4210fa |
protocol and to fetch the second stage image from it, and this may
|
|
|
4210fa |
cause shim to fetch the wrong second stage image, i.e. grub.efi.
|
|
|
4210fa |
|
|
|
4210fa |
Consider the machine with the following boot order:
|
|
|
4210fa |
1. PXE Boot
|
|
|
4210fa |
2. Hard Drive
|
|
|
4210fa |
|
|
|
4210fa |
Assume that the EFI image, e.g. bootx64.efi, in the PXE server is
|
|
|
4210fa |
broken, then "PXE Boot" will fail and fallback to "Hard Drive". While
|
|
|
4210fa |
shim.efi in "Hard Drive" is loaded, it will find the PXE protocol is
|
|
|
4210fa |
available and fetch grub.efi from the PXE server, not grub.efi in the
|
|
|
4210fa |
disk.
|
|
|
4210fa |
|
|
|
4210fa |
This commit checks the DeviceHandle from Loaded Image. If the device
|
|
|
4210fa |
supports PXE, then shim fetches grub.efi with the PXE protocol. Otherwise,
|
|
|
4210fa |
shim loads grub.efi from the disk.
|
|
|
4210fa |
|
|
|
4210fa |
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
|
|
|
4210fa |
---
|
|
|
4210fa |
netboot.c | 77 +++++++++++++--------------------------------------------------
|
|
|
4210fa |
shim.c | 2 +-
|
|
|
4210fa |
2 files changed, 17 insertions(+), 62 deletions(-)
|
|
|
4210fa |
|
|
|
4210fa |
diff --git a/netboot.c b/netboot.c
|
|
|
4210fa |
index 07e2773..5ef53f7 100644
|
|
|
4210fa |
--- a/netboot.c
|
|
|
4210fa |
+++ b/netboot.c
|
|
|
4210fa |
@@ -85,78 +85,33 @@ translate_slashes(char *str)
|
|
|
4210fa |
* Returns TRUE if we identify a protocol that is enabled and Providing us with
|
|
|
4210fa |
* the needed information to fetch a grubx64.efi image
|
|
|
4210fa |
*/
|
|
|
4210fa |
-BOOLEAN findNetboot(EFI_HANDLE image_handle)
|
|
|
4210fa |
+BOOLEAN findNetboot(EFI_HANDLE device)
|
|
|
4210fa |
{
|
|
|
4210fa |
- UINTN bs = sizeof(EFI_HANDLE);
|
|
|
4210fa |
- EFI_GUID pxe_base_code_protocol = EFI_PXE_BASE_CODE_PROTOCOL;
|
|
|
4210fa |
- EFI_HANDLE *hbuf;
|
|
|
4210fa |
- BOOLEAN rc = FALSE;
|
|
|
4210fa |
- void *buffer = AllocatePool(bs);
|
|
|
4210fa |
- UINTN errcnt = 0;
|
|
|
4210fa |
- UINTN i;
|
|
|
4210fa |
EFI_STATUS status;
|
|
|
4210fa |
|
|
|
4210fa |
- if (!buffer)
|
|
|
4210fa |
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
|
|
|
4210fa |
+ &PxeBaseCodeProtocol, (VOID **)&pxe);
|
|
|
4210fa |
+ if (status != EFI_SUCCESS) {
|
|
|
4210fa |
+ pxe = NULL;
|
|
|
4210fa |
return FALSE;
|
|
|
4210fa |
-
|
|
|
4210fa |
-try_again:
|
|
|
4210fa |
- status = uefi_call_wrapper(BS->LocateHandle,5, ByProtocol,
|
|
|
4210fa |
- &pxe_base_code_protocol, NULL, &bs,
|
|
|
4210fa |
- buffer);
|
|
|
4210fa |
-
|
|
|
4210fa |
- if (status == EFI_BUFFER_TOO_SMALL) {
|
|
|
4210fa |
- errcnt++;
|
|
|
4210fa |
- FreePool(buffer);
|
|
|
4210fa |
- if (errcnt > 1)
|
|
|
4210fa |
- return FALSE;
|
|
|
4210fa |
- buffer = AllocatePool(bs);
|
|
|
4210fa |
- if (!buffer)
|
|
|
4210fa |
- return FALSE;
|
|
|
4210fa |
- goto try_again;
|
|
|
4210fa |
}
|
|
|
4210fa |
|
|
|
4210fa |
- if (status == EFI_NOT_FOUND) {
|
|
|
4210fa |
- FreePool(buffer);
|
|
|
4210fa |
+ if (!pxe || !pxe->Mode) {
|
|
|
4210fa |
+ pxe = NULL;
|
|
|
4210fa |
return FALSE;
|
|
|
4210fa |
}
|
|
|
4210fa |
|
|
|
4210fa |
- /*
|
|
|
4210fa |
- * We have a list of pxe supporting protocols, lets see if any are
|
|
|
4210fa |
- * active
|
|
|
4210fa |
- */
|
|
|
4210fa |
- hbuf = buffer;
|
|
|
4210fa |
- pxe = NULL;
|
|
|
4210fa |
- for (i=0; i < (bs / sizeof(EFI_HANDLE)); i++) {
|
|
|
4210fa |
- status = uefi_call_wrapper(BS->OpenProtocol, 6, hbuf[i],
|
|
|
4210fa |
- &pxe_base_code_protocol,
|
|
|
4210fa |
- (void **)&pxe, image_handle, NULL,
|
|
|
4210fa |
- EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
|
4210fa |
-
|
|
|
4210fa |
- if (status != EFI_SUCCESS) {
|
|
|
4210fa |
- pxe = NULL;
|
|
|
4210fa |
- continue;
|
|
|
4210fa |
- }
|
|
|
4210fa |
-
|
|
|
4210fa |
- if (!pxe || !pxe->Mode) {
|
|
|
4210fa |
- pxe = NULL;
|
|
|
4210fa |
- continue;
|
|
|
4210fa |
- }
|
|
|
4210fa |
-
|
|
|
4210fa |
- if (pxe->Mode->Started && pxe->Mode->DhcpAckReceived) {
|
|
|
4210fa |
- /*
|
|
|
4210fa |
- * We've located a pxe protocol handle thats been
|
|
|
4210fa |
- * started and has received an ACK, meaning its
|
|
|
4210fa |
- * something we'll be able to get tftp server info
|
|
|
4210fa |
- * out of
|
|
|
4210fa |
- */
|
|
|
4210fa |
- rc = TRUE;
|
|
|
4210fa |
- break;
|
|
|
4210fa |
- }
|
|
|
4210fa |
-
|
|
|
4210fa |
+ if (!pxe->Mode->Started || !pxe->Mode->DhcpAckReceived) {
|
|
|
4210fa |
+ pxe = NULL;
|
|
|
4210fa |
+ return FALSE;
|
|
|
4210fa |
}
|
|
|
4210fa |
|
|
|
4210fa |
- FreePool(buffer);
|
|
|
4210fa |
- return rc;
|
|
|
4210fa |
+ /*
|
|
|
4210fa |
+ * We've located a pxe protocol handle thats been started and has
|
|
|
4210fa |
+ * received an ACK, meaning its something we'll be able to get
|
|
|
4210fa |
+ * tftp server info out of
|
|
|
4210fa |
+ */
|
|
|
4210fa |
+ return TRUE;
|
|
|
4210fa |
}
|
|
|
4210fa |
|
|
|
4210fa |
static CHAR8 *get_v6_bootfile_url(EFI_PXE_BASE_CODE_DHCPV6_PACKET *pkt)
|
|
|
4210fa |
diff --git a/shim.c b/shim.c
|
|
|
4210fa |
index 48a6f2f..d8699f9 100644
|
|
|
4210fa |
--- a/shim.c
|
|
|
4210fa |
+++ b/shim.c
|
|
|
4210fa |
@@ -1373,7 +1373,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
|
|
|
4210fa |
goto done;
|
|
|
4210fa |
}
|
|
|
4210fa |
|
|
|
4210fa |
- if (findNetboot(image_handle)) {
|
|
|
4210fa |
+ if (findNetboot(li->DeviceHandle)) {
|
|
|
4210fa |
efi_status = parseNetbootinfo(image_handle);
|
|
|
4210fa |
if (efi_status != EFI_SUCCESS) {
|
|
|
4210fa |
Print(L"Netboot parsing failed: %r\n", efi_status);
|
|
|
4210fa |
--
|
|
|
4210fa |
1.9.3
|
|
|
4210fa |
|