Kernel: Don't ignore modules passed with multiboot2

This commit is contained in:
Bananymous 2025-06-30 16:07:48 +03:00
parent c67198032f
commit 17f1ac10e3
7 changed files with 96 additions and 48 deletions

View File

@ -36,6 +36,12 @@ multiboot2_start:
.long 12 .long 12
.long V2P(_start) .long V2P(_start)
# page align modules
.align 8
.short 6
.short 0
.long 8
.align 8 .align 8
.short 0 .short 0
.short 0 .short 0

View File

@ -36,6 +36,12 @@ multiboot2_start:
.long 12 .long 12
.long V2P(_start) .long V2P(_start)
# page align modules
.align 8
.short 6
.short 0
.long 8
.align 8 .align 8
.short 0 .short 0
.short 0 .short 0

View File

@ -41,6 +41,12 @@ namespace Kernel
Type type; Type type;
}; };
struct BootModule
{
paddr_t start;
size_t size;
};
struct BootInfo struct BootInfo
{ {
BAN::String command_line; BAN::String command_line;
@ -48,6 +54,7 @@ namespace Kernel
RSDP rsdp {}; RSDP rsdp {};
paddr_t kernel_paddr {}; paddr_t kernel_paddr {};
BAN::Vector<BootModule> modules;
BAN::Vector<MemoryMapEntry> memory_map_entries; BAN::Vector<MemoryMapEntry> memory_map_entries;
}; };

View File

@ -6,6 +6,7 @@
#define MULTIBOOT2_TAG_END 0 #define MULTIBOOT2_TAG_END 0
#define MULTIBOOT2_TAG_CMDLINE 1 #define MULTIBOOT2_TAG_CMDLINE 1
#define MULTIBOOT2_TAG_MODULES 3
#define MULTIBOOT2_TAG_MMAP 6 #define MULTIBOOT2_TAG_MMAP 6
#define MULTIBOOT2_TAG_FRAMEBUFFER 8 #define MULTIBOOT2_TAG_FRAMEBUFFER 8
#define MULTIBOOT2_TAG_OLD_RSDP 14 #define MULTIBOOT2_TAG_OLD_RSDP 14
@ -33,6 +34,13 @@ struct multiboot2_cmdline_tag_t : public multiboot2_tag_t
char cmdline[]; char cmdline[];
} __attribute__((packed)); } __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 struct multiboot2_mmap_entry_t
{ {
uint64_t base_addr; uint64_t base_addr;

View File

@ -26,12 +26,21 @@ namespace Kernel
for (const auto* tag = multiboot2_info.tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next()) for (const auto* tag = multiboot2_info.tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next())
{ {
if (tag->type == MULTIBOOT2_TAG_CMDLINE) switch (tag->type)
{
case MULTIBOOT2_TAG_CMDLINE:
{ {
const auto& command_line_tag = *static_cast<const multiboot2_cmdline_tag_t*>(tag); const auto& command_line_tag = *static_cast<const multiboot2_cmdline_tag_t*>(tag);
MUST(g_boot_info.command_line.append(command_line_tag.cmdline)); MUST(g_boot_info.command_line.append(command_line_tag.cmdline));
break;
} }
else if (tag->type == MULTIBOOT2_TAG_FRAMEBUFFER) case MULTIBOOT2_TAG_MODULES:
{
const auto& modules_tag = *static_cast<const multiboot2_modules_tag_t*>(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<const multiboot2_framebuffer_tag_t*>(tag); const auto& framebuffer_tag = *static_cast<const multiboot2_framebuffer_tag_t*>(tag);
g_boot_info.framebuffer.address = framebuffer_tag.framebuffer_addr; g_boot_info.framebuffer.address = framebuffer_tag.framebuffer_addr;
@ -45,8 +54,9 @@ namespace Kernel
g_boot_info.framebuffer.type = FramebufferInfo::Type::Text; g_boot_info.framebuffer.type = FramebufferInfo::Type::Text;
else else
g_boot_info.framebuffer.type = FramebufferInfo::Type::Unknown; g_boot_info.framebuffer.type = FramebufferInfo::Type::Unknown;
break;
} }
else if (tag->type == MULTIBOOT2_TAG_MMAP) case MULTIBOOT2_TAG_MMAP:
{ {
const auto& mmap_tag = *static_cast<const multiboot2_mmap_tag_t*>(tag); const auto& mmap_tag = *static_cast<const multiboot2_mmap_tag_t*>(tag);
@ -66,19 +76,23 @@ namespace Kernel
g_boot_info.memory_map_entries[i].length = mmap_entry.length; 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); g_boot_info.memory_map_entries[i].type = bios_number_to_memory_type(mmap_entry.type);
} }
break;
} }
else if (tag->type == MULTIBOOT2_TAG_OLD_RSDP) case MULTIBOOT2_TAG_OLD_RSDP:
{ {
if (g_boot_info.rsdp.length == 0) if (g_boot_info.rsdp.length == 0)
{ {
memcpy(&g_boot_info.rsdp, static_cast<const multiboot2_rsdp_tag_t*>(tag)->data, 20); memcpy(&g_boot_info.rsdp, static_cast<const multiboot2_rsdp_tag_t*>(tag)->data, 20);
g_boot_info.rsdp.length = 20; g_boot_info.rsdp.length = 20;
} }
break;
} }
else if (tag->type == MULTIBOOT2_TAG_NEW_RSDP) case MULTIBOOT2_TAG_NEW_RSDP:
{ {
const auto& rsdp = *reinterpret_cast<const RSDP*>(static_cast<const multiboot2_rsdp_tag_t*>(tag)->data); const auto& rsdp = *reinterpret_cast<const RSDP*>(static_cast<const multiboot2_rsdp_tag_t*>(tag)->data);
memcpy(&g_boot_info.rsdp, &rsdp, BAN::Math::min<uint32_t>(rsdp.length, sizeof(g_boot_info.rsdp))); memcpy(&g_boot_info.rsdp, &rsdp, BAN::Math::min<uint32_t>(rsdp.length, sizeof(g_boot_info.rsdp)));
break;
}
} }
} }

View File

@ -58,9 +58,13 @@ namespace Kernel
if (entry.type != MemoryMapEntry::Type::Available) if (entry.type != MemoryMapEntry::Type::Available)
continue; continue;
// FIXME: only reserve kernel area and modules, not everything from 0 -> kernel end
paddr_t start = entry.address; paddr_t start = entry.address;
if (start < (vaddr_t)g_kernel_end - KERNEL_OFFSET + g_boot_info.kernel_paddr) 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; 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) if (auto rem = start % PAGE_SIZE)
start += PAGE_SIZE - rem; start += PAGE_SIZE - rem;

View File

@ -258,6 +258,9 @@ static void init2(void*)
VirtualFileSystem::initialize(cmdline.root); VirtualFileSystem::initialize(cmdline.root);
dprintln("VFS initialized"); dprintln("VFS initialized");
// FIXME: release memory used by modules. If modules are used
// they are already loaded in here
TTY::initialize_devices(); TTY::initialize_devices();
auto console_path = MUST(BAN::String::formatted("/dev/{}", cmdline.console)); auto console_path = MUST(BAN::String::formatted("/dev/{}", cmdline.console));