forked from Bananymous/banan-os
Kernel: Don't use multiboot2 explicitly. Parse it to common structure
This allows support of multiple different bootloaders
This commit is contained in:
parent
07ae1bbf34
commit
ec56e9c6f1
|
@ -12,6 +12,7 @@ set(KERNEL_SOURCES
|
|||
font/prefs.psf.o
|
||||
kernel/ACPI.cpp
|
||||
kernel/APIC.cpp
|
||||
kernel/BootInfo.cpp
|
||||
kernel/CPUID.cpp
|
||||
kernel/Debug.cpp
|
||||
kernel/Device/Device.cpp
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Memory/kmalloc.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
|
||||
extern uint8_t g_kernel_start[];
|
||||
extern uint8_t g_kernel_end[];
|
||||
|
@ -145,6 +144,14 @@ namespace Kernel
|
|||
|
||||
prepare_fast_page();
|
||||
|
||||
// Map main bios area below 1 MiB
|
||||
map_range_at(
|
||||
0x000E0000,
|
||||
P2V(0x000E0000),
|
||||
0x00100000 - 0x000E0000,
|
||||
PageTable::Flags::Present
|
||||
);
|
||||
|
||||
// Map (phys_kernel_start -> phys_kernel_end) to (virt_kernel_start -> virt_kernel_end)
|
||||
ASSERT((vaddr_t)g_kernel_start % PAGE_SIZE == 0);
|
||||
map_range_at(
|
||||
|
@ -169,22 +176,6 @@ namespace Kernel
|
|||
g_userspace_end - g_userspace_start,
|
||||
Flags::Execute | Flags::UserSupervisor | Flags::Present
|
||||
);
|
||||
|
||||
// Map multiboot memory
|
||||
paddr_t multiboot2_data_start = (vaddr_t)g_multiboot2_info & PAGE_ADDR_MASK;
|
||||
paddr_t multiboot2_data_end = (vaddr_t)g_multiboot2_info + g_multiboot2_info->total_size;
|
||||
|
||||
size_t multiboot2_needed_pages = BAN::Math::div_round_up<size_t>(multiboot2_data_end - multiboot2_data_start, PAGE_SIZE);
|
||||
vaddr_t multiboot2_vaddr = reserve_free_contiguous_pages(multiboot2_needed_pages, KERNEL_OFFSET);
|
||||
|
||||
map_range_at(
|
||||
multiboot2_data_start,
|
||||
multiboot2_vaddr,
|
||||
multiboot2_needed_pages * PAGE_SIZE,
|
||||
Flags::ReadWrite | Flags::Present
|
||||
);
|
||||
|
||||
g_multiboot2_info = (multiboot2_info_t*)(multiboot2_vaddr + ((vaddr_t)g_multiboot2_info % PAGE_SIZE));
|
||||
}
|
||||
|
||||
void PageTable::prepare_fast_page()
|
||||
|
@ -371,7 +362,7 @@ namespace Kernel
|
|||
{
|
||||
ASSERT(vaddr);
|
||||
ASSERT(vaddr != fast_page());
|
||||
if (vaddr >= KERNEL_OFFSET)
|
||||
if (vaddr >= KERNEL_OFFSET && s_current)
|
||||
ASSERT_GTE(vaddr, (vaddr_t)g_kernel_start);
|
||||
if ((vaddr >= KERNEL_OFFSET) != (this == s_kernel))
|
||||
Kernel::panic("mapping {8H} to {8H}, kernel: {}", paddr, vaddr, this == s_kernel);
|
||||
|
|
|
@ -21,8 +21,8 @@ multiboot2_start:
|
|||
.short 5
|
||||
.short 0
|
||||
.long 20
|
||||
.long 1920
|
||||
.long 1080
|
||||
.long 800
|
||||
.long 600
|
||||
.long 32
|
||||
|
||||
# legacy start
|
||||
|
@ -50,11 +50,9 @@ multiboot2_end:
|
|||
g_kernel_cmdline:
|
||||
.skip 4096
|
||||
|
||||
.global g_multiboot2_info
|
||||
g_multiboot2_info:
|
||||
bootloader_magic:
|
||||
.skip 8
|
||||
.global g_multiboot2_magic
|
||||
g_multiboot2_magic:
|
||||
bootloader_info:
|
||||
.skip 8
|
||||
|
||||
.section .data
|
||||
|
@ -167,8 +165,8 @@ initialize_paging:
|
|||
_start:
|
||||
# Initialize stack and multiboot info
|
||||
movl $V2P(g_boot_stack_top), %esp
|
||||
movl %eax, V2P(g_multiboot2_magic)
|
||||
movl %ebx, V2P(g_multiboot2_info)
|
||||
movl %eax, V2P(bootloader_magic)
|
||||
movl %ebx, V2P(bootloader_info)
|
||||
|
||||
call check_requirements
|
||||
call enable_sse
|
||||
|
@ -200,8 +198,11 @@ higher_half:
|
|||
# call global constuctors
|
||||
call _init
|
||||
|
||||
# call to the kernel itself (clear ebp for stacktrace)
|
||||
# call to the kernel itself (clear rbp for stacktrace)
|
||||
xorq %rbp, %rbp
|
||||
|
||||
movl V2P(bootloader_magic), %edi
|
||||
movl V2P(bootloader_info), %esi
|
||||
call kernel_main
|
||||
|
||||
# call global destructors
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/String.h>
|
||||
#include <BAN/StringView.h>
|
||||
#include <BAN/Vector.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
enum class FramebufferType
|
||||
{
|
||||
NONE,
|
||||
UNKNOWN,
|
||||
RGB
|
||||
};
|
||||
|
||||
struct FramebufferInfo
|
||||
{
|
||||
paddr_t address;
|
||||
uint32_t pitch;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint8_t bpp;
|
||||
FramebufferType type = FramebufferType::NONE;
|
||||
};
|
||||
|
||||
struct MemoryMapEntry
|
||||
{
|
||||
uint32_t type;
|
||||
paddr_t address;
|
||||
uint64_t length;
|
||||
};
|
||||
|
||||
struct BootInfo
|
||||
{
|
||||
BAN::String command_line;
|
||||
FramebufferInfo framebuffer;
|
||||
BAN::Vector<MemoryMapEntry> memory_map_entries;
|
||||
};
|
||||
|
||||
bool validate_boot_magic(uint32_t magic);
|
||||
void parse_boot_info(uint32_t magic, uint32_t info);
|
||||
BAN::StringView get_early_boot_command_line(uint32_t magic, uint32_t info);
|
||||
|
||||
extern BootInfo g_boot_info;
|
||||
|
||||
}
|
|
@ -13,11 +13,18 @@
|
|||
|
||||
#define MULTIBOOT2_FRAMEBUFFER_TYPE_RGB 1
|
||||
|
||||
#define MULTIBOOT2_MAGIC 0x36d76289
|
||||
|
||||
struct multiboot2_tag_t
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
multiboot2_tag_t* next() { return (multiboot2_tag_t*)((uintptr_t)this + ((size + 7) & ~7)); }
|
||||
const multiboot2_tag_t* next() const
|
||||
{
|
||||
return reinterpret_cast<const multiboot2_tag_t*>(
|
||||
reinterpret_cast<uintptr_t>(this) + ((size + 7) & ~7)
|
||||
);
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
struct multiboot2_cmdline_tag_t : public multiboot2_tag_t
|
||||
|
@ -62,14 +69,3 @@ struct multiboot2_info_t
|
|||
uint32_t reserved;
|
||||
multiboot2_tag_t tags[];
|
||||
} __attribute__((packed));
|
||||
|
||||
extern "C" multiboot2_info_t* g_multiboot2_info;
|
||||
extern "C" uint32_t g_multiboot2_magic;
|
||||
|
||||
inline multiboot2_tag_t* multiboot2_find_tag(uint32_t type)
|
||||
{
|
||||
for (auto* tag = g_multiboot2_info->tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next())
|
||||
if (tag->type == type)
|
||||
return tag;
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include <BAN/StringView.h>
|
||||
#include <kernel/ACPI.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
|
||||
#include <lai/core.h>
|
||||
|
||||
|
@ -85,11 +84,14 @@ namespace Kernel
|
|||
|
||||
static const RSDP* locate_rsdp()
|
||||
{
|
||||
// FIXME: add this back
|
||||
#if 0
|
||||
// Check the multiboot headers
|
||||
if (auto* rsdp_new = (multiboot2_rsdp_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_NEW_RSDP))
|
||||
return (const RSDP*)rsdp_new->data;
|
||||
if (auto* rsdp_old = (multiboot2_rsdp_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_OLD_RSDP))
|
||||
return (const RSDP*)rsdp_old->data;
|
||||
#endif
|
||||
|
||||
// Look in main BIOS area below 1 MB
|
||||
for (uintptr_t addr = P2V(0x000E0000); addr < P2V(0x000FFFFF); addr += 16)
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
#include <kernel/BootInfo.h>
|
||||
|
||||
#include <kernel/multiboot2.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
BootInfo g_boot_info;
|
||||
|
||||
void parse_boot_info_multiboot2(uint32_t info)
|
||||
{
|
||||
const auto& multiboot2_info = *reinterpret_cast<const multiboot2_info_t*>(info);
|
||||
|
||||
for (const auto* tag = multiboot2_info.tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next())
|
||||
{
|
||||
if (tag->type == MULTIBOOT2_TAG_CMDLINE)
|
||||
{
|
||||
const auto& command_line_tag = *reinterpret_cast<const multiboot2_cmdline_tag_t*>(tag);
|
||||
MUST(g_boot_info.command_line.append(command_line_tag.cmdline));
|
||||
}
|
||||
else if (tag->type == MULTIBOOT2_TAG_FRAMEBUFFER)
|
||||
{
|
||||
const auto& framebuffer_tag = *reinterpret_cast<const multiboot2_framebuffer_tag_t*>(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 = FramebufferType::RGB;
|
||||
else
|
||||
g_boot_info.framebuffer.type = FramebufferType::UNKNOWN;
|
||||
}
|
||||
else if (tag->type == MULTIBOOT2_TAG_MMAP)
|
||||
{
|
||||
const auto& mmap_tag = *reinterpret_cast<const multiboot2_mmap_tag_t*>(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<const multiboot2_mmap_entry_t*>(reinterpret_cast<uintptr_t>(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 = mmap_entry.type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BAN::StringView get_early_boot_command_line_multiboot2(uint32_t info)
|
||||
{
|
||||
const auto& multiboot2_info = *reinterpret_cast<const multiboot2_info_t*>(info);
|
||||
for (const auto* tag = multiboot2_info.tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next())
|
||||
if (tag->type == MULTIBOOT2_TAG_CMDLINE)
|
||||
return reinterpret_cast<const multiboot2_cmdline_tag_t*>(tag)->cmdline;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool validate_boot_magic(uint32_t magic)
|
||||
{
|
||||
if (magic == MULTIBOOT2_MAGIC)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void parse_boot_info(uint32_t magic, uint32_t info)
|
||||
{
|
||||
switch (magic)
|
||||
{
|
||||
case MULTIBOOT2_MAGIC:
|
||||
return parse_boot_info_multiboot2(info);
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
BAN::StringView get_early_boot_command_line(uint32_t magic, uint32_t info)
|
||||
{
|
||||
switch (magic)
|
||||
{
|
||||
case MULTIBOOT2_MAGIC:
|
||||
return get_early_boot_command_line_multiboot2(info);
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/BootInfo.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
|
||||
extern uint8_t g_kernel_end[];
|
||||
|
||||
|
@ -26,30 +26,33 @@ namespace Kernel
|
|||
|
||||
void Heap::initialize_impl()
|
||||
{
|
||||
auto* mmap_tag = (multiboot2_mmap_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_MMAP);
|
||||
if (mmap_tag == nullptr)
|
||||
if (g_boot_info.memory_map_entries.empty())
|
||||
Kernel::panic("Bootloader did not provide a memory map");
|
||||
|
||||
for (size_t offset = sizeof(*mmap_tag); offset < mmap_tag->size; offset += mmap_tag->entry_size)
|
||||
for (const auto& entry : g_boot_info.memory_map_entries)
|
||||
{
|
||||
auto* mmap_entry = (multiboot2_mmap_entry_t*)((uintptr_t)mmap_tag + offset);
|
||||
dprintln("{16H}, {16H}, {8H}",
|
||||
entry.address,
|
||||
entry.length,
|
||||
entry.type
|
||||
);
|
||||
|
||||
if (mmap_entry->type == 1)
|
||||
{
|
||||
paddr_t start = mmap_entry->base_addr;
|
||||
if (start < V2P(g_kernel_end))
|
||||
start = V2P(g_kernel_end);
|
||||
if (auto rem = start % PAGE_SIZE)
|
||||
start += PAGE_SIZE - rem;
|
||||
if (entry.type != 1)
|
||||
continue;
|
||||
|
||||
paddr_t start = entry.address;
|
||||
if (start < V2P(g_kernel_end))
|
||||
start = V2P(g_kernel_end);
|
||||
if (auto rem = start % PAGE_SIZE)
|
||||
start += PAGE_SIZE - rem;
|
||||
|
||||
paddr_t end = mmap_entry->base_addr + mmap_entry->length;
|
||||
if (auto rem = end % PAGE_SIZE)
|
||||
end -= rem;
|
||||
paddr_t end = entry.address + entry.length;
|
||||
if (auto rem = end % PAGE_SIZE)
|
||||
end -= rem;
|
||||
|
||||
// Physical pages needs atleast 2 pages
|
||||
if (end > start + PAGE_SIZE)
|
||||
MUST(m_physical_ranges.emplace_back(start, end - start));
|
||||
}
|
||||
// Physical pages needs atleast 2 pages
|
||||
if (end > start + PAGE_SIZE)
|
||||
MUST(m_physical_ranges.emplace_back(start, end - start));
|
||||
}
|
||||
|
||||
size_t total = 0;
|
||||
|
|
|
@ -1,42 +1,41 @@
|
|||
#include <BAN/Errors.h>
|
||||
#include <kernel/BootInfo.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
#include <kernel/Terminal/VesaTerminalDriver.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
VesaTerminalDriver* VesaTerminalDriver::create()
|
||||
{
|
||||
auto* framebuffer_tag = (multiboot2_framebuffer_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_FRAMEBUFFER);
|
||||
if (framebuffer_tag == nullptr)
|
||||
if (g_boot_info.framebuffer.type == FramebufferType::NONE)
|
||||
{
|
||||
dprintln("Bootloader did not provide framebuffer");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (framebuffer_tag->framebuffer_type != MULTIBOOT2_FRAMEBUFFER_TYPE_RGB)
|
||||
if (g_boot_info.framebuffer.type != FramebufferType::RGB)
|
||||
{
|
||||
dprintln("unsupported framebuffer type {}", framebuffer_tag->framebuffer_type);
|
||||
dprintln("unsupported framebuffer type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (framebuffer_tag->framebuffer_bpp != 24 && framebuffer_tag->framebuffer_bpp != 32)
|
||||
if (g_boot_info.framebuffer.bpp != 24 && g_boot_info.framebuffer.bpp != 32)
|
||||
{
|
||||
dprintln("Unsupported bpp {}", framebuffer_tag->framebuffer_bpp);
|
||||
dprintln("Unsupported bpp {}", g_boot_info.framebuffer.bpp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dprintln("Graphics Mode {}x{} ({} bpp)",
|
||||
(uint32_t)framebuffer_tag->framebuffer_width,
|
||||
(uint32_t)framebuffer_tag->framebuffer_height,
|
||||
(uint8_t)framebuffer_tag->framebuffer_bpp
|
||||
g_boot_info.framebuffer.width,
|
||||
g_boot_info.framebuffer.height,
|
||||
g_boot_info.framebuffer.bpp
|
||||
);
|
||||
|
||||
paddr_t paddr = framebuffer_tag->framebuffer_addr & PAGE_ADDR_MASK;
|
||||
paddr_t paddr = g_boot_info.framebuffer.address & PAGE_ADDR_MASK;
|
||||
size_t needed_pages = range_page_count(
|
||||
framebuffer_tag->framebuffer_addr,
|
||||
framebuffer_tag->framebuffer_pitch * framebuffer_tag->framebuffer_height
|
||||
g_boot_info.framebuffer.address,
|
||||
g_boot_info.framebuffer.pitch * g_boot_info.framebuffer.height
|
||||
);
|
||||
|
||||
vaddr_t vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
|
||||
|
@ -45,10 +44,10 @@ VesaTerminalDriver* VesaTerminalDriver::create()
|
|||
PageTable::kernel().map_range_at(paddr, vaddr, needed_pages * PAGE_SIZE, PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
||||
|
||||
auto* driver = new VesaTerminalDriver(
|
||||
framebuffer_tag->framebuffer_width,
|
||||
framebuffer_tag->framebuffer_height,
|
||||
framebuffer_tag->framebuffer_pitch,
|
||||
framebuffer_tag->framebuffer_bpp,
|
||||
g_boot_info.framebuffer.width,
|
||||
g_boot_info.framebuffer.height,
|
||||
g_boot_info.framebuffer.pitch,
|
||||
g_boot_info.framebuffer.bpp,
|
||||
vaddr
|
||||
);
|
||||
driver->set_cursor_position(0, 0);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <kernel/ACPI.h>
|
||||
#include <kernel/Arch.h>
|
||||
#include <kernel/BootInfo.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/FS/ProcFS/FileSystem.h>
|
||||
|
@ -12,7 +13,6 @@
|
|||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Memory/kmalloc.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
#include <kernel/PCI.h>
|
||||
#include <kernel/PIC.h>
|
||||
#include <kernel/Process.h>
|
||||
|
@ -31,13 +31,9 @@ struct ParsedCommandLine
|
|||
BAN::StringView root;
|
||||
};
|
||||
|
||||
static bool should_disable_serial()
|
||||
static bool should_disable_serial(BAN::StringView full_command_line)
|
||||
{
|
||||
auto* cmdline_tag = (multiboot2_cmdline_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_CMDLINE);
|
||||
if (cmdline_tag == nullptr)
|
||||
return false;
|
||||
|
||||
const char* start = cmdline_tag->cmdline;
|
||||
const char* start = full_command_line.data();
|
||||
const char* current = start;
|
||||
while (true)
|
||||
{
|
||||
|
@ -59,13 +55,8 @@ static ParsedCommandLine cmdline;
|
|||
|
||||
static void parse_command_line()
|
||||
{
|
||||
auto* cmdline_tag = (multiboot2_cmdline_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_CMDLINE);
|
||||
if (cmdline_tag == nullptr)
|
||||
return;
|
||||
|
||||
BAN::StringView full_command_line(cmdline_tag->cmdline);
|
||||
auto full_command_line = Kernel::g_boot_info.command_line.sv();
|
||||
auto arguments = MUST(full_command_line.split(' '));
|
||||
|
||||
for (auto argument : arguments)
|
||||
{
|
||||
if (argument == "noapic")
|
||||
|
@ -83,27 +74,31 @@ TerminalDriver* g_terminal_driver = nullptr;
|
|||
|
||||
static void init2(void*);
|
||||
|
||||
extern "C" void kernel_main()
|
||||
extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||
{
|
||||
using namespace Kernel;
|
||||
|
||||
DISABLE_INTERRUPTS();
|
||||
|
||||
if (!should_disable_serial())
|
||||
if (!validate_boot_magic(boot_magic))
|
||||
{
|
||||
Serial::initialize();
|
||||
dprintln("Unrecognized boot magic {8H}", boot_magic);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!should_disable_serial(get_early_boot_command_line(boot_magic, boot_info)))
|
||||
{
|
||||
Serial::initialize();
|
||||
dprintln("Serial output initialized");
|
||||
}
|
||||
|
||||
if (g_multiboot2_magic != 0x36d76289)
|
||||
{
|
||||
dprintln("Invalid multiboot magic number");
|
||||
return;
|
||||
}
|
||||
|
||||
kmalloc_initialize();
|
||||
dprintln("kmalloc initialized");
|
||||
|
||||
parse_boot_info(boot_magic, boot_info);
|
||||
dprintln("boot info parsed");
|
||||
|
||||
GDT::initialize();
|
||||
dprintln("GDT initialized");
|
||||
|
||||
|
|
Loading…
Reference in New Issue