:: commit 986cd6a85efba33ef25469b6b19310b43a477379

mintsuki <mintsuki@protonmail.com> — 2022-06-30 05:25

parents: 0352e3b592

multiboot: Do not panic if unable to set text mode

diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index 16732765..4d64d5ec 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -305,9 +305,40 @@ bool multiboot1_load(char *config, char *cmdline) {
 
             struct fb_info fbinfo;
             if (!fb_init(&fbinfo, req_width, req_height, req_bpp)) {
-                goto nofb;
+#if uefi == 1
+                panic(true, "multiboot1: Failed to set video mode");
+#elif bios == 1
+                size_t rows, cols;
+                init_vga_textmode(&rows, &cols, false);
+
+                multiboot1_info->fb_addr    = 0xb8000;
+                multiboot1_info->fb_width   = cols;
+                multiboot1_info->fb_height  = rows;
+                multiboot1_info->fb_bpp     = 16;
+                multiboot1_info->fb_pitch   = 2 * cols;
+                multiboot1_info->fb_type    = 2;
+#endif
+            } else {
+                multiboot1_info->fb_addr    = (uint64_t)fbinfo.framebuffer_addr;
+                multiboot1_info->fb_width   = fbinfo.framebuffer_width;
+                multiboot1_info->fb_height  = fbinfo.framebuffer_height;
+                multiboot1_info->fb_bpp     = fbinfo.framebuffer_bpp;
+                multiboot1_info->fb_pitch   = fbinfo.framebuffer_pitch;
+                multiboot1_info->fb_type    = 1;
+                multiboot1_info->fb_red_mask_size    = fbinfo.red_mask_size;
+                multiboot1_info->fb_red_mask_shift   = fbinfo.red_mask_shift;
+                multiboot1_info->fb_green_mask_size  = fbinfo.green_mask_size;
+                multiboot1_info->fb_green_mask_shift = fbinfo.green_mask_shift;
+                multiboot1_info->fb_blue_mask_size   = fbinfo.blue_mask_size;
+                multiboot1_info->fb_blue_mask_shift  = fbinfo.blue_mask_shift;
+            }
+        } else {
+#if uefi == 1
+            print("multiboot1: Warning: Cannot use text mode with UEFI\n");
+            struct fb_info fbinfo;
+            if (!fb_init(&fbinfo, 0, 0, 0)) {
+                panic(true, "multiboot1: Failed to set video mode");
             }
-
             multiboot1_info->fb_addr    = (uint64_t)fbinfo.framebuffer_addr;
             multiboot1_info->fb_width   = fbinfo.framebuffer_width;
             multiboot1_info->fb_height  = fbinfo.framebuffer_height;
@@ -320,10 +351,6 @@ bool multiboot1_load(char *config, char *cmdline) {
             multiboot1_info->fb_green_mask_shift = fbinfo.green_mask_shift;
             multiboot1_info->fb_blue_mask_size   = fbinfo.blue_mask_size;
             multiboot1_info->fb_blue_mask_shift  = fbinfo.blue_mask_shift;
-        } else if (header.fb_mode == 1) {
-nofb:;
-#if uefi == 1
-            panic(true, "multiboot1: Cannot use text mode with UEFI.");
 #elif bios == 1
             size_t rows, cols;
             init_vga_textmode(&rows, &cols, false);
@@ -335,8 +362,6 @@ nofb:;
             multiboot1_info->fb_pitch   = 2 * cols;
             multiboot1_info->fb_type    = 2;
 #endif
-        } else {
-            panic(true, "multiboot1: Illegal framebuffer type requested");
         }
 
         multiboot1_info->flags |= (1 << 12);
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 32f22a63..30ff415c 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -482,6 +482,9 @@ bool multiboot2_load(char *config, char* cmdline) {
     {
         struct multiboot_tag_framebuffer *tag = (struct multiboot_tag_framebuffer *)(mb2_info + info_idx);
 
+        tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
+        tag->common.size = sizeof(struct multiboot_tag_framebuffer);
+
         term_deinit();
 
         if (fbtag) {
@@ -506,11 +509,9 @@ bool multiboot2_load(char *config, char* cmdline) {
                 tag->common.framebuffer_bpp = 16;
                 tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
 #elif uefi == 1
-                panic(true, "multiboot2: Cannot use text mode with UEFI");
+                panic(true, "multiboot2: Failed to set video mode");
 #endif
             } else {
-                tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
-                tag->common.size = sizeof(struct multiboot_tag_framebuffer);
                 tag->common.framebuffer_addr = fbinfo.framebuffer_addr;
                 tag->common.framebuffer_pitch = fbinfo.framebuffer_pitch;
                 tag->common.framebuffer_width = fbinfo.framebuffer_width;
@@ -527,7 +528,24 @@ bool multiboot2_load(char *config, char* cmdline) {
             }
         } else {
 #if uefi == 1
-            panic(true, "multiboot2: Cannot use text mode with UEFI");
+            print("multiboot2: Warning: Cannot use text mode with UEFI\n");
+            struct fb_info fbinfo;
+            if (!fb_init(&fbinfo, 0, 0, 0)) {
+                panic(true, "multiboot2: Failed to set video mode");
+            }
+            tag->common.framebuffer_addr = fbinfo.framebuffer_addr;
+            tag->common.framebuffer_pitch = fbinfo.framebuffer_pitch;
+            tag->common.framebuffer_width = fbinfo.framebuffer_width;
+            tag->common.framebuffer_height = fbinfo.framebuffer_height;
+            tag->common.framebuffer_bpp = fbinfo.framebuffer_bpp;
+            tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; // We only support RGB for VBE
+
+            tag->framebuffer_red_field_position = fbinfo.red_mask_shift;
+            tag->framebuffer_red_mask_size = fbinfo.red_mask_size;
+            tag->framebuffer_green_field_position = fbinfo.green_mask_shift;
+            tag->framebuffer_green_mask_size = fbinfo.green_mask_size;
+            tag->framebuffer_blue_field_position = fbinfo.blue_mask_shift;
+            tag->framebuffer_blue_mask_size = fbinfo.blue_mask_size;
 #elif bios == 1
             size_t rows, cols;
             init_vga_textmode(&rows, &cols, false);
tab: 248 wrap: offon