diff --git a/kernel/arch/i686/boot.S b/kernel/arch/i686/boot.S index 0c9c6c6a..9d003b36 100644 --- a/kernel/arch/i686/boot.S +++ b/kernel/arch/i686/boot.S @@ -36,6 +36,12 @@ multiboot2_start: .long 12 .long V2P(_start) + # page align modules + .align 8 + .short 6 + .short 0 + .long 8 + .align 8 .short 0 .short 0 diff --git a/kernel/arch/x86_64/boot.S b/kernel/arch/x86_64/boot.S index bd897427..c598d943 100644 --- a/kernel/arch/x86_64/boot.S +++ b/kernel/arch/x86_64/boot.S @@ -36,6 +36,12 @@ multiboot2_start: .long 12 .long V2P(_start) + # page align modules + .align 8 + .short 6 + .short 0 + .long 8 + .align 8 .short 0 .short 0 diff --git a/kernel/include/kernel/BootInfo.h b/kernel/include/kernel/BootInfo.h index 9f5b28ce..2d6c8e19 100644 --- a/kernel/include/kernel/BootInfo.h +++ b/kernel/include/kernel/BootInfo.h @@ -41,6 +41,12 @@ namespace Kernel Type type; }; + struct BootModule + { + paddr_t start; + size_t size; + }; + struct BootInfo { BAN::String command_line; @@ -48,6 +54,7 @@ namespace Kernel RSDP rsdp {}; paddr_t kernel_paddr {}; + BAN::Vector modules; BAN::Vector memory_map_entries; }; diff --git a/kernel/include/kernel/multiboot2.h b/kernel/include/kernel/multiboot2.h index 8ae7c9eb..ecc78cbe 100644 --- a/kernel/include/kernel/multiboot2.h +++ b/kernel/include/kernel/multiboot2.h @@ -6,6 +6,7 @@ #define MULTIBOOT2_TAG_END 0 #define MULTIBOOT2_TAG_CMDLINE 1 +#define MULTIBOOT2_TAG_MODULES 3 #define MULTIBOOT2_TAG_MMAP 6 #define MULTIBOOT2_TAG_FRAMEBUFFER 8 #define MULTIBOOT2_TAG_OLD_RSDP 14 @@ -33,6 +34,13 @@ struct multiboot2_cmdline_tag_t : public multiboot2_tag_t char cmdline[]; } __attribute__((packed)); +struct multiboot2_modules_tag_t : public multiboot2_tag_t +{ + uint32_t mod_start; + uint32_t mod_end; + uint8_t string[]; +} __attribute__((packed)); + struct multiboot2_mmap_entry_t { uint64_t base_addr; diff --git a/kernel/kernel/BootInfo.cpp b/kernel/kernel/BootInfo.cpp index 56bd5779..f1a8d6ad 100644 --- a/kernel/kernel/BootInfo.cpp +++ b/kernel/kernel/BootInfo.cpp @@ -26,59 +26,73 @@ namespace Kernel for (const auto* tag = multiboot2_info.tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next()) { - if (tag->type == MULTIBOOT2_TAG_CMDLINE) + switch (tag->type) { - const auto& command_line_tag = *static_cast(tag); - MUST(g_boot_info.command_line.append(command_line_tag.cmdline)); - } - else if (tag->type == MULTIBOOT2_TAG_FRAMEBUFFER) - { - const auto& framebuffer_tag = *static_cast(tag); - g_boot_info.framebuffer.address = framebuffer_tag.framebuffer_addr; - g_boot_info.framebuffer.pitch = framebuffer_tag.framebuffer_pitch; - g_boot_info.framebuffer.width = framebuffer_tag.framebuffer_width; - g_boot_info.framebuffer.height = framebuffer_tag.framebuffer_height; - g_boot_info.framebuffer.bpp = framebuffer_tag.framebuffer_bpp; - if (framebuffer_tag.framebuffer_type == MULTIBOOT2_FRAMEBUFFER_TYPE_RGB) - g_boot_info.framebuffer.type = FramebufferInfo::Type::RGB; - else if (framebuffer_tag.framebuffer_type == MULTIBOOT2_FRAMEBUFFER_TYPE_TEXT) - g_boot_info.framebuffer.type = FramebufferInfo::Type::Text; - else - g_boot_info.framebuffer.type = FramebufferInfo::Type::Unknown; - } - else if (tag->type == MULTIBOOT2_TAG_MMAP) - { - const auto& mmap_tag = *static_cast(tag); - - const size_t entry_count = (mmap_tag.size - sizeof(multiboot2_mmap_tag_t)) / mmap_tag.entry_size; - - MUST(g_boot_info.memory_map_entries.resize(entry_count)); - - for (size_t i = 0; i < entry_count; i++) + case MULTIBOOT2_TAG_CMDLINE: { - const auto& mmap_entry = *reinterpret_cast(reinterpret_cast(tag) + sizeof(multiboot2_mmap_tag_t) + i * mmap_tag.entry_size); - dprintln("entry {16H} {16H} {8H}", - (uint64_t)mmap_entry.base_addr, - (uint64_t)mmap_entry.length, - (uint64_t)mmap_entry.type - ); - g_boot_info.memory_map_entries[i].address = mmap_entry.base_addr; - g_boot_info.memory_map_entries[i].length = mmap_entry.length; - g_boot_info.memory_map_entries[i].type = bios_number_to_memory_type(mmap_entry.type); + const auto& command_line_tag = *static_cast(tag); + MUST(g_boot_info.command_line.append(command_line_tag.cmdline)); + break; } - } - else if (tag->type == MULTIBOOT2_TAG_OLD_RSDP) - { - if (g_boot_info.rsdp.length == 0) + case MULTIBOOT2_TAG_MODULES: { - memcpy(&g_boot_info.rsdp, static_cast(tag)->data, 20); - g_boot_info.rsdp.length = 20; + const auto& modules_tag = *static_cast(tag); + MUST(g_boot_info.modules.emplace_back(modules_tag.mod_start, modules_tag.mod_end - modules_tag.mod_start)); + break; + } + case MULTIBOOT2_TAG_FRAMEBUFFER: + { + const auto& framebuffer_tag = *static_cast(tag); + g_boot_info.framebuffer.address = framebuffer_tag.framebuffer_addr; + g_boot_info.framebuffer.pitch = framebuffer_tag.framebuffer_pitch; + g_boot_info.framebuffer.width = framebuffer_tag.framebuffer_width; + g_boot_info.framebuffer.height = framebuffer_tag.framebuffer_height; + g_boot_info.framebuffer.bpp = framebuffer_tag.framebuffer_bpp; + if (framebuffer_tag.framebuffer_type == MULTIBOOT2_FRAMEBUFFER_TYPE_RGB) + g_boot_info.framebuffer.type = FramebufferInfo::Type::RGB; + else if (framebuffer_tag.framebuffer_type == MULTIBOOT2_FRAMEBUFFER_TYPE_TEXT) + g_boot_info.framebuffer.type = FramebufferInfo::Type::Text; + else + g_boot_info.framebuffer.type = FramebufferInfo::Type::Unknown; + break; + } + case MULTIBOOT2_TAG_MMAP: + { + const auto& mmap_tag = *static_cast(tag); + + const size_t entry_count = (mmap_tag.size - sizeof(multiboot2_mmap_tag_t)) / mmap_tag.entry_size; + + MUST(g_boot_info.memory_map_entries.resize(entry_count)); + + for (size_t i = 0; i < entry_count; i++) + { + const auto& mmap_entry = *reinterpret_cast(reinterpret_cast(tag) + sizeof(multiboot2_mmap_tag_t) + i * mmap_tag.entry_size); + dprintln("entry {16H} {16H} {8H}", + (uint64_t)mmap_entry.base_addr, + (uint64_t)mmap_entry.length, + (uint64_t)mmap_entry.type + ); + g_boot_info.memory_map_entries[i].address = mmap_entry.base_addr; + g_boot_info.memory_map_entries[i].length = mmap_entry.length; + g_boot_info.memory_map_entries[i].type = bios_number_to_memory_type(mmap_entry.type); + } + break; + } + case MULTIBOOT2_TAG_OLD_RSDP: + { + if (g_boot_info.rsdp.length == 0) + { + memcpy(&g_boot_info.rsdp, static_cast(tag)->data, 20); + g_boot_info.rsdp.length = 20; + } + break; + } + case MULTIBOOT2_TAG_NEW_RSDP: + { + const auto& rsdp = *reinterpret_cast(static_cast(tag)->data); + memcpy(&g_boot_info.rsdp, &rsdp, BAN::Math::min(rsdp.length, sizeof(g_boot_info.rsdp))); + break; } - } - else if (tag->type == MULTIBOOT2_TAG_NEW_RSDP) - { - const auto& rsdp = *reinterpret_cast(static_cast(tag)->data); - memcpy(&g_boot_info.rsdp, &rsdp, BAN::Math::min(rsdp.length, sizeof(g_boot_info.rsdp))); } } diff --git a/kernel/kernel/Memory/Heap.cpp b/kernel/kernel/Memory/Heap.cpp index f991c21d..07649603 100644 --- a/kernel/kernel/Memory/Heap.cpp +++ b/kernel/kernel/Memory/Heap.cpp @@ -58,9 +58,13 @@ namespace Kernel if (entry.type != MemoryMapEntry::Type::Available) continue; + // FIXME: only reserve kernel area and modules, not everything from 0 -> kernel end paddr_t start = entry.address; if (start < (vaddr_t)g_kernel_end - KERNEL_OFFSET + g_boot_info.kernel_paddr) start = (vaddr_t)g_kernel_end - KERNEL_OFFSET + g_boot_info.kernel_paddr; + for (const auto& module : g_boot_info.modules) + if (start < module.start + module.size) + start = module.start + module.size; if (auto rem = start % PAGE_SIZE) start += PAGE_SIZE - rem; diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index af1dd4ed..84aae734 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -258,6 +258,9 @@ static void init2(void*) VirtualFileSystem::initialize(cmdline.root); dprintln("VFS initialized"); + // FIXME: release memory used by modules. If modules are used + // they are already loaded in here + TTY::initialize_devices(); auto console_path = MUST(BAN::String::formatted("/dev/{}", cmdline.console));