[syslinux:firmware] efi: implement LOCALBOOT

syslinux-bot for Matt Fleming matt.fleming at intel.com
Fri Aug 2 14:12:06 PDT 2013


Commit-ID:  4f2d3e62b61ebe21498844c0ca346482aca118c9
Gitweb:     http://www.syslinux.org/commit/4f2d3e62b61ebe21498844c0ca346482aca118c9
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Fri, 5 Jul 2013 12:51:12 +0100
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Fri, 2 Aug 2013 20:11:09 +0100

efi: implement LOCALBOOT

Booting the next device is in fact fairly trivial under EFI. We simply
need to return control to the firmware with an error code that indicates
we couldn't execute our OS loader properly.

Unlike under BIOS, we don't take any notice of any integer arguments
passed to LOCALBOOT for EFI, since there is no variation for "boot next
entry".

Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 efi/main.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/efi/main.c b/efi/main.c
index b2debfa..2eeeba3 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -6,6 +6,7 @@
 #include <syslinux/firmware.h>
 #include <syslinux/linux.h>
 #include <sys/ansi.h>
+#include <setjmp.h>
 
 #include "efi.h"
 #include "fio.h"
@@ -24,6 +25,8 @@ uint32_t timer_irq;
 __export uint8_t KbdMap[256];
 char aux_seg[256];
 
+static jmp_buf load_error_buf;
+
 static inline EFI_STATUS
 efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid, EFI_HANDLE agent,
 		   EFI_HANDLE controller)
@@ -119,6 +122,11 @@ void printf_init(void)
 
 __export void local_boot(uint16_t ax)
 {
+    /*
+     * Inform the firmware that we failed to execute correctly, which
+     * will trigger the next entry in the EFI Boot Manager list.
+     */
+    longjmp(load_error_buf, 1);
 }
 
 void bios_timer_cleanup(void)
@@ -1320,7 +1328,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
 		status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key);
 	} while (status != EFI_NOT_READY);
 
-	load_env32(NULL);
+	if (!setjmp(load_error_buf))
+		load_env32(NULL);
 
 	/* load_env32() failed.. cancel timer and bailout */
 	status = cancel_timer(timer_ev);


More information about the Syslinux-commits mailing list