From 709b1b702a8d9c2b202a0de72c6e6041486366a4 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 21 Jan 2023 16:37:44 +0000 Subject: [PATCH] Allow use on headless EFI systems. A headless EFI system may have no GOP devices. In this case, disable output to the physical display, but continue to write to the shadow buffer. This allows operation via a serial console. --- boot/bootparams.h | 1 + boot/efisetup.c | 15 +++++++-------- system/screen.c | 8 ++++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/boot/bootparams.h b/boot/bootparams.h index 45d95c4..273a562 100644 --- a/boot/bootparams.h +++ b/boot/bootparams.h @@ -58,6 +58,7 @@ typedef struct { #define VIDEO_TYPE_VLFB 0x23 // VESA VGA in graphic mode #define VIDEO_TYPE_EFI 0x70 // EFI graphic mode +#define VIDEO_TYPE_NONE 0xff // no video display (added for Memtest86+) #define LFB_CAPABILITY_64BIT_BASE (1 << 1) diff --git a/boot/efisetup.c b/boot/efisetup.c index 5fc92df..4362215 100644 --- a/boot/efisetup.c +++ b/boot/efisetup.c @@ -334,9 +334,7 @@ static efi_status_t set_screen_info_from_gop(screen_info_t *si, efi_handle_t *ha efi_graphics_output_t *gop = find_gop(handles, handles_size); if (!gop) { -#if DEBUG - print_string("GOP not found\n"); -#endif + print_string("No graphics display found\n"); return EFI_NOT_FOUND; } @@ -365,9 +363,7 @@ static efi_status_t set_screen_info_from_gop(screen_info_t *si, efi_handle_t *ha efi_call_bs(free_pool, info); } if (best_mode == UINT32_MAX) { -#if DEBUG - print_string("No suitable GOP screen resolution\n"); -#endif + print_string("No suitable screen resolution found\n"); return EFI_NOT_FOUND; } @@ -469,9 +465,7 @@ static efi_status_t set_screen_info_from_gop(screen_info_t *si, efi_handle_t *ha status = efi_call_proto(gop, set_mode, best_mode); if (status != EFI_SUCCESS) { -#if DEBUG print_string("Set GOP mode failed\n"); -#endif return status; } @@ -502,6 +496,11 @@ static efi_status_t set_screen_info(boot_params_t *boot_params) if (status == EFI_SUCCESS) { status = set_screen_info_from_gop(&boot_params->screen_info, handles, handles_size); } + if (status == EFI_NOT_FOUND) { + // This may be a headless system. We can still output to a serial console. + boot_params->screen_info.orig_video_isVGA = VIDEO_TYPE_NONE; + status = EFI_SUCCESS; + } efi_call_bs(free_pool, handles); } diff --git a/system/screen.c b/system/screen.c index 4c63513..b745f16 100644 --- a/system/screen.c +++ b/system/screen.c @@ -42,7 +42,7 @@ static const rgb_value_t vga_pallete[16] = { { 255, 255, 255 } // BOLD+WHITE }; -static vga_buffer_t *vga_buffer = (vga_buffer_t *)(0xb8000); +static vga_buffer_t *vga_buffer = NULL; vga_buffer_t shadow_buffer; @@ -64,7 +64,9 @@ static void vga_put_char(int row, int col, uint8_t ch, uint8_t attr) shadow_buffer[row][col].ch = ch; shadow_buffer[row][col].attr = attr; - (*vga_buffer)[row][col].value = shadow_buffer[row][col].value; + if (vga_buffer) { + (*vga_buffer)[row][col].value = shadow_buffer[row][col].value; + } } static void lfb8_put_char(int row, int col, uint8_t ch, uint8_t attr) @@ -239,6 +241,8 @@ void screen_init(void) uint32_t b = ((vga_pallete[i].b * b_max) / 255) << screen_info->blue_pos; lfb_pallete[i] = r | g | b; } + } else if (screen_info->orig_video_isVGA != VIDEO_TYPE_NONE) { + vga_buffer = (vga_buffer_t *)(0xb8000); } }