From cf96bb6cc38b50816a9cfcf2fa373bd232c8d9d6 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 5 Aug 2025 02:40:43 +0300 Subject: [PATCH] Kernel: Add support for multiboot I don't know why I did it but it works now :D --- kernel/arch/i686/boot.S | 17 ++++++++ kernel/arch/x86_64/boot.S | 17 ++++++++ kernel/kernel/BootInfo.cpp | 83 +++++++++++++++++++++++++++++++++++--- 3 files changed, 112 insertions(+), 5 deletions(-) diff --git a/kernel/arch/i686/boot.S b/kernel/arch/i686/boot.S index e516a5f7..ba9e0bac 100644 --- a/kernel/arch/i686/boot.S +++ b/kernel/arch/i686/boot.S @@ -14,6 +14,23 @@ # multiboot2 header .section .multiboot, "aw" .align 8 +multiboot_start: + .long 0x1BADB002 + .long (1 << 2) # page align modules + .long -(0x1BADB002 + (1 << 2)) + + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + + .long 0 + .long FB_WIDTH + .long FB_HEIGHT + .long FB_BPP +multiboot_end: + .align 8 multiboot2_start: .long 0xE85250D6 .long 0 diff --git a/kernel/arch/x86_64/boot.S b/kernel/arch/x86_64/boot.S index b6a97c7d..1af0f72b 100644 --- a/kernel/arch/x86_64/boot.S +++ b/kernel/arch/x86_64/boot.S @@ -14,6 +14,23 @@ # multiboot2 header .section .multiboot, "aw" .align 8 +multiboot_start: + .long 0x1BADB002 + .long (1 << 2) # page align modules + .long -(0x1BADB002 + (1 << 2)) + + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + + .long 0 + .long FB_WIDTH + .long FB_HEIGHT + .long FB_BPP +multiboot_end: + .align 8 multiboot2_start: .long 0xE85250D6 .long 0 diff --git a/kernel/kernel/BootInfo.cpp b/kernel/kernel/BootInfo.cpp index f1a8d6ad..8f2c1052 100644 --- a/kernel/kernel/BootInfo.cpp +++ b/kernel/kernel/BootInfo.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace Kernel @@ -20,6 +21,70 @@ namespace Kernel return MemoryMapEntry::Type::Reserved; } + static void parse_boot_info_multiboot(uint32_t info) + { + const auto& multiboot_info = *reinterpret_cast(info); + + if (multiboot_info.flags & MULTIBOOT_FLAGS_CMDLINE) + { + MUST(g_boot_info.command_line.append(reinterpret_cast(multiboot_info.cmdline))); + } + + if (multiboot_info.flags & MULTIBOOT_FLAGS_MODULES) + { + for (size_t i = 0; i < multiboot_info.mods_count; i++) + { + const auto& module = reinterpret_cast(multiboot_info.mods_addr)[i]; + MUST(g_boot_info.modules.emplace_back(module.mod_start, module.mod_end - module.mod_start)); + } + } + + if (multiboot_info.flags & MULTIBOOT_FLAGS_MMAP) + { + uintptr_t address = multiboot_info.mmap_addr; + while (address < multiboot_info.mmap_addr + multiboot_info.mmap_length) + { + const auto& mmap_entry = *reinterpret_cast(address); + dprintln("entry {16H} {16H} {8H}", + (uint64_t)mmap_entry.base_addr, + (uint64_t)mmap_entry.length, + (uint64_t)mmap_entry.type + ); + MUST(g_boot_info.memory_map_entries.push_back({ + .address = mmap_entry.base_addr, + .length = mmap_entry.length, + .type = bios_number_to_memory_type(mmap_entry.type), + })); + address += mmap_entry.size + sizeof(mmap_entry.size); + } + } + + if (multiboot_info.flags & MULTIBOOT_FLAGS_FRAMEBUFFER) + { + g_boot_info.framebuffer.address = multiboot_info.framebuffer_addr; + g_boot_info.framebuffer.pitch = multiboot_info.framebuffer_pitch; + g_boot_info.framebuffer.width = multiboot_info.framebuffer_width; + g_boot_info.framebuffer.height = multiboot_info.framebuffer_height; + g_boot_info.framebuffer.bpp = multiboot_info.framebuffer_bpp; + if (multiboot_info.framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) + g_boot_info.framebuffer.type = FramebufferInfo::Type::RGB; + else if (multiboot_info.framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT) + g_boot_info.framebuffer.type = FramebufferInfo::Type::Text; + else + g_boot_info.framebuffer.type = FramebufferInfo::Type::Unknown; + } + + g_boot_info.kernel_paddr = 0; + } + + static BAN::StringView get_early_boot_command_line_multiboot(uint32_t info) + { + const auto& multiboot_info = *reinterpret_cast(info); + if (!(multiboot_info.flags & MULTIBOOT_FLAGS_CMDLINE)) + return ""_sv; + return BAN::StringView(reinterpret_cast(multiboot_info.cmdline)); + } + static void parse_boot_info_multiboot2(uint32_t info) { const auto& multiboot2_info = *reinterpret_cast(info); @@ -149,17 +214,23 @@ namespace Kernel bool validate_boot_magic(uint32_t magic) { - if (magic == MULTIBOOT2_MAGIC) - return true; - if (magic == BANAN_BOOTLOADER_MAGIC) - return true; - return false; + switch (magic) + { + case MULTIBOOT_MAGIC: + case MULTIBOOT2_MAGIC: + case BANAN_BOOTLOADER_MAGIC: + return true; + default: + return false; + } } void parse_boot_info(uint32_t magic, uint32_t info) { switch (magic) { + case MULTIBOOT_MAGIC: + return parse_boot_info_multiboot(info); case MULTIBOOT2_MAGIC: return parse_boot_info_multiboot2(info); case BANAN_BOOTLOADER_MAGIC: @@ -172,6 +243,8 @@ namespace Kernel { switch (magic) { + case MULTIBOOT_MAGIC: + return get_early_boot_command_line_multiboot(info); case MULTIBOOT2_MAGIC: return get_early_boot_command_line_multiboot2(info); case BANAN_BOOTLOADER_MAGIC: