diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-07-08 13:09:53 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-07-08 17:03:35 +0100 |
commit | 3dafb1427c5ba7d6f061a864ab0d72a95566cfa6 (patch) | |
tree | 82ca725252dbe18b72c6f2691e45a9cc143abd43 | |
parent | a53c1f05fb750dc02ea555887935031722cf8318 (diff) | |
download | syslinux-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.c | 24 | ||||
-rw-r--r-- | efi/efi.h | 3 | ||||
-rw-r--r-- | efi/main.c | 6 |
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); @@ -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 */ @@ -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; } |