aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-07-08 13:09:53 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-07-08 17:03:35 +0100
commit3dafb1427c5ba7d6f061a864ab0d72a95566cfa6 (patch)
tree82ca725252dbe18b72c6f2691e45a9cc143abd43
parenta53c1f05fb750dc02ea555887935031722cf8318 (diff)
downloadsyslinux-3dafb1427c5ba7d6f061a864ab0d72a95566cfa6.tar.gz
syslinux-3dafb1427c5ba7d6f061a864ab0d72a95566cfa6.tar.xz
syslinux-3dafb1427c5ba7d6f061a864ab0d72a95566cfa6.zip
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@intel.com>
-rw-r--r--efi/console.c24
-rw-r--r--efi/efi.h3
-rw-r--r--efi/main.c6
3 files changed, 32 insertions, 1 deletions
diff --git a/efi/console.c b/efi/console.c
index a9386492..a01e14e8 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 3304527b..3b202d9a 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 16c85b5b..91ed735d 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;
}