From 3dafb1427c5ba7d6f061a864ab0d72a95566cfa6 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 8 Jul 2013 13:09:53 +0100 Subject: 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 --- 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 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; } -- cgit v1.2.1