[osboot] Support setting fb modes from cmdline
bootloader.fbres may be set to have gigaboot set the framebuffer to the
desired resolution, if the framebuffer supports it.
Change-Id: I11aceb8a0065f005ff956e533a94293e07cf6287
diff --git a/src/osboot.c b/src/osboot.c
index 762a6a0..0a4afe9 100644
--- a/src/osboot.c
+++ b/src/osboot.c
@@ -5,6 +5,7 @@
#include <efi.h>
#include <efilib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <cmdline.h>
@@ -114,6 +115,47 @@
return BOOT_DEVICE_NETBOOT;
}
+void set_graphics_mode(EFI_SYSTEM_TABLE* sys, EFI_GRAPHICS_OUTPUT_PROTOCOL* gop, char* cmdline) {
+ if (!gop || !cmdline) return;
+
+ char res[11];
+ if (cmdline_get(cmdline, "bootloader.fbres", res, sizeof(res)) < 0) return;
+
+ uint32_t hres = 0;
+ hres = atol(res);
+
+ char* x = strchr(res, 'x');
+ if (!x) return;
+ x++;
+
+ uint32_t vres = 0;
+ vres = atol(x);
+ if (!hres || !vres) return;
+
+ UINT32 max_mode = gop->Mode->MaxMode;
+
+ for (int i = 0; i < max_mode; i++) {
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* mode_info;
+ UINTN info_size = 0;
+ EFI_STATUS status = gop->QueryMode(gop, i, &info_size, &mode_info);
+ if (EFI_ERROR(status)) {
+ printf("Could not retrieve mode %d: %s\n", i, efi_strerror(status));
+ continue;
+ }
+
+ if (mode_info->HorizontalResolution == hres &&
+ mode_info->VerticalResolution == vres) {
+ gop->SetMode(gop, i);
+ sys->BootServices->Stall(1000);
+ sys->ConOut->ClearScreen(sys->ConOut);
+ return;
+ }
+ }
+ printf("Could not find framebuffer mode %ux%u; using default mode = %ux%u\n",
+ hres, vres, gop->Mode->Info->HorizontalResolution, gop->Mode->Info->VerticalResolution);
+ sys->BootServices->Stall(5000000);
+}
+
void draw_logo(EFI_GRAPHICS_OUTPUT_PROTOCOL* gop) {
if (!gop) return;
@@ -221,7 +263,10 @@
bs->RestoreTPL(prev_tpl);
// maybe it's a kernel image?
- // TODO: process any bootloader.* cmdline args as needed before booting
+ EFI_GRAPHICS_OUTPUT_PROTOCOL* gop;
+ bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
+ set_graphics_mode(sys, gop, cmdline);
+
boot_kernel(img, sys, (void*) nbkernel.data, nbkernel.offset,
(void*) nbramdisk.data, nbramdisk.offset,
cmdline, sizeof(cmdline));
@@ -234,12 +279,6 @@
InitializeLib(img, sys);
InitGoodies(img, sys);
- EFI_GRAPHICS_OUTPUT_PROTOCOL* gop;
- bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
- draw_logo(gop);
-
- printf("\nOSBOOT v0.2\n\n");
- printf("Framebuffer base is at %lx\n\n", gop->Mode->FrameBufferBase);
// Load the cmdline
UINTN csz = 0;
@@ -249,6 +288,14 @@
printf("cmdline: %s\n", cmdline);
}
+ EFI_GRAPHICS_OUTPUT_PROTOCOL* gop;
+ bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
+ set_graphics_mode(sys, gop, cmdline);
+ draw_logo(gop);
+
+ printf("\nOSBOOT v0.2\n\n");
+ printf("Framebuffer base is at %lx\n\n", gop->Mode->FrameBufferBase);
+
// See if there's a network interface
bool have_network = netboot_init() == 0;