From 7daa95b7d2019a538854c3d33d7801596f6358a6 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Tue, 27 Sep 2022 05:46:39 +0200 Subject: [PATCH] multiboot: Allow for headless boots --- common/protos/multiboot1.c | 6 ++++-- common/protos/multiboot2.c | 19 +++++++++++++++++-- test/multiboot.c | 16 +++++++--------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c index f006d570..69938773 100644 --- a/common/protos/multiboot1.c +++ b/common/protos/multiboot1.c @@ -312,7 +312,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) { struct fb_info fbinfo; if (!fb_init(&fbinfo, req_width, req_height, req_bpp)) { #if defined (UEFI) - panic(true, "multiboot1: Failed to set video mode"); + goto skip_modeset; #elif defined (BIOS) size_t rows, cols; init_vga_textmode(&rows, &cols, false); @@ -343,7 +343,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) { 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"); + goto skip_modeset; } multiboot1_info->fb_addr = (uint64_t)fbinfo.framebuffer_addr; multiboot1_info->fb_width = fbinfo.framebuffer_width; @@ -371,6 +371,8 @@ noreturn void multiboot1_load(char *config, char *cmdline) { } multiboot1_info->flags |= (1 << 12); + +skip_modeset:; } else { #if defined (UEFI) panic(true, "multiboot1: Cannot use text mode with UEFI."); diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c index b0d5ce59..10ec22af 100644 --- a/common/protos/multiboot2.c +++ b/common/protos/multiboot2.c @@ -107,6 +107,8 @@ noreturn void multiboot2_load(char *config, char* cmdline) { bool is_elf_info_requested = false; + bool is_framebuffer_required = false; + uint64_t entry_point = 0xffffffff; // Iterate through the entries... @@ -141,7 +143,9 @@ noreturn void multiboot2_load(char *config, char* cmdline) { case MULTIBOOT_TAG_TYPE_EFI64_IH: #endif #endif + break; case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + is_framebuffer_required = is_required; break; case MULTIBOOT_TAG_TYPE_ACPI_NEW: is_new_acpi_required = is_required; @@ -516,7 +520,11 @@ noreturn void multiboot2_load(char *config, char* cmdline) { tag->common.framebuffer_bpp = 16; tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; #elif defined (UEFI) - panic(true, "multiboot2: Failed to set video mode"); + if (is_framebuffer_required) { + panic(true, "multiboot2: Failed to set video mode"); + } else { + goto skip_modeset; + } #endif } else { tag->common.framebuffer_addr = fbinfo.framebuffer_addr; @@ -538,8 +546,13 @@ noreturn void multiboot2_load(char *config, char* cmdline) { 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"); + if (is_framebuffer_required) { + panic(true, "multiboot2: Failed to set video mode"); + } else { + goto skip_modeset; + } } + tag->common.framebuffer_addr = fbinfo.framebuffer_addr; tag->common.framebuffer_pitch = fbinfo.framebuffer_pitch; tag->common.framebuffer_width = fbinfo.framebuffer_width; @@ -567,6 +580,8 @@ noreturn void multiboot2_load(char *config, char* cmdline) { } append_tag(info_idx, &tag->common); + +skip_modeset:; } ////////////////////////////////////////////// diff --git a/test/multiboot.c b/test/multiboot.c index f2db28a7..32bfccbc 100644 --- a/test/multiboot.c +++ b/test/multiboot.c @@ -23,7 +23,7 @@ void multiboot_main(uint32_t magic, struct multiboot1_info *info) { { struct multiboot1_module *start = (struct multiboot1_module *)info->mods_addr; struct multiboot1_module *end = (struct multiboot1_module *)(info->mods_addr + info->mods_count); - + e9_printf("\t modules:"); for (struct multiboot1_module* entry = start; entry < end; entry++) { e9_printf("\t\t begin=%x", entry->begin); @@ -32,29 +32,27 @@ void multiboot_main(uint32_t magic, struct multiboot1_info *info) { } } - // TODO(Andy-Python-Programmer): ELF sections are unimplemented - { struct multiboot1_mmap_entry *start = (struct multiboot1_mmap_entry *)info->mmap_addr; struct multiboot1_mmap_entry *end = (struct multiboot1_mmap_entry *)(info->mmap_addr + info->mmap_length); - e9_printf("\t useable_entries_mmap:"); + e9_printf("\t usable_entries_mmap:"); size_t total_mem = 0; - // For now we only print the useable memory map entries since + // For now we only print the usable memory map entries since // printing the whole memory map blows my terminal up. We also // iterate through the avaliable memory map entries and add up - // to find the total amount of useable memory. + // to find the total amount of usable memory. for (struct multiboot1_mmap_entry* entry = start; entry < end; entry++) { - // Check if the memory map entry is marked as useable! + // Check if the memory map entry is marked as usable! if (entry->type != 1) { continue; } e9_printf("\t\t addr=%x", entry->addr); e9_printf("\t\t length=%x", entry->len); - e9_printf("\t\t type=Useable"); + e9_printf("\t\t type=Usable"); // Now this might be a bit confusing since but `entry->size` represents the // is the size of the associated structure in bytes and `entry->len` represents the @@ -91,4 +89,4 @@ void multiboot_main(uint32_t magic, struct multiboot1_info *info) { out: for (;;); -} \ No newline at end of file +}