[syslinux:firmware] efi, console: save/ restore attributes before exiting

syslinux-bot for Matt Fleming matt.fleming at intel.com
Mon Jul 8 09:30:10 PDT 2013


Commit-ID:  3dafb1427c5ba7d6f061a864ab0d72a95566cfa6
Gitweb:     http://www.syslinux.org/commit/3dafb1427c5ba7d6f061a864ab0d72a95566cfa6
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Mon, 8 Jul 2013 13:09:53 +0100
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Mon, 8 Jul 2013 17:03:35 +0100

efi, console: save/restore attributes before exiting

The Linux kernel doesn't use ANSI attributes when writing to the serial
console, so make sure we restore the default attributes that were set
when we were initially executed by the firmware. Failure to do so can
result in 'invisible' characters being written to the console.

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

---
 efi/console.c | 24 ++++++++++++++++++++++++
 efi/efi.h     |  3 +++
 efi/main.c    |  6 +++++-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/efi/console.c b/efi/console.c
index a938649..a01e14e 100644
--- a/efi/console.c
+++ b/efi/console.c
@@ -4,6 +4,30 @@
 
 extern EFI_GUID GraphicsOutputProtocol;
 
+static uint32_t console_default_attribute;
+static bool console_default_cursor;
+
+/*
+ * We want to restore the console state when we boot a kernel or return
+ * to the firmware.
+ */
+void efi_console_save(void)
+{
+    SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
+    SIMPLE_TEXT_OUTPUT_MODE *mode = out->Mode;
+
+    console_default_attribute = mode->Attribute;
+    console_default_cursor = mode->CursorVisible;
+}
+
+void efi_console_restore(void)
+{
+    SIMPLE_TEXT_OUTPUT_INTERFACE *out = ST->ConOut;
+
+    uefi_call_wrapper(out->SetAttribute, 2, out, console_default_attribute);
+    uefi_call_wrapper(out->EnableCursor, 2, out, console_default_cursor);
+}
+
 __export void writechr(char data)
 {
 	efi_write_char(data, 0);
diff --git a/efi/efi.h b/efi/efi.h
index 3304527..3b202d9 100644
--- a/efi/efi.h
+++ b/efi/efi.h
@@ -69,4 +69,7 @@ handover_func_t efi_handover_32;
 handover_func_t efi_handover_64;
 handover_func_t efi_handover;
 
+extern void efi_console_save(void);
+extern void efi_console_restore(void);
+
 #endif /* _SYSLINUX_EFI_H */
diff --git a/efi/main.c b/efi/main.c
index 16c85b5..91ed735 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -1020,7 +1020,6 @@ static int exit_boot(struct boot_params *bp)
 
 	bp->e820_entries = e - e820buf;
 
-	dprintf("efi_boot_linux: exit boot services\n");
 	status = uefi_call_wrapper(BS->ExitBootServices, 2, image_handle, key);
 	if (status != EFI_SUCCESS) {
 		printf("Failed to exit boot services: 0x%016lx\n", status);
@@ -1141,6 +1140,8 @@ int efi_boot_linux(void *kernel_buf, size_t kernel_size,
 	if (handle_ramdisks(hdr, initramfs))
 		goto free_map;
 
+	efi_console_restore();
+
 	if (exit_boot(bp))
 		goto free_map;
 
@@ -1254,6 +1255,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
 
 	image_handle = image;
 	syslinux_register_efi();
+
+	efi_console_save();
 	init();
 
 	status = uefi_call_wrapper(BS->HandleProtocol, 3, image,
@@ -1321,5 +1324,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
 	 */
 	status = EFI_LOAD_ERROR;
 out:
+	efi_console_restore();
 	return status;
 }


More information about the Syslinux-commits mailing list