forked from Bananymous/banan-os
Kernel: Start using multiboot2 instead of multiboot
This allows better compatibility with (U)EFI and gives RSDP location instead of me having to scan ram to find it.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include <BAN/StringView.h>
|
||||
#include <kernel/ACPI.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
|
||||
#include <lai/core.h>
|
||||
|
||||
@@ -84,6 +85,12 @@ namespace Kernel
|
||||
|
||||
static const RSDP* locate_rsdp()
|
||||
{
|
||||
// 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;
|
||||
|
||||
// Look in main BIOS area below 1 MB
|
||||
for (uintptr_t addr = P2V(0x000E0000); addr < P2V(0x000FFFFF); addr += 16)
|
||||
if (is_rsdp(addr))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
|
||||
extern uint8_t g_kernel_end[];
|
||||
|
||||
@@ -26,21 +26,23 @@ namespace Kernel
|
||||
|
||||
void Heap::initialize_impl()
|
||||
{
|
||||
if (!(g_multiboot_info->flags & (1 << 6)))
|
||||
auto* mmap_tag = (multiboot2_mmap_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_MMAP);
|
||||
if (mmap_tag == nullptr)
|
||||
Kernel::panic("Bootloader did not provide a memory map");
|
||||
|
||||
for (size_t i = 0; i < g_multiboot_info->mmap_length;)
|
||||
|
||||
for (size_t offset = sizeof(*mmap_tag); offset < mmap_tag->size; offset += mmap_tag->entry_size)
|
||||
{
|
||||
multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)P2V(g_multiboot_info->mmap_addr + i);
|
||||
if (mmmt->type == 1)
|
||||
auto* mmap_entry = (multiboot2_mmap_entry_t*)((uintptr_t)mmap_tag + offset);
|
||||
|
||||
if (mmap_entry->type == 1)
|
||||
{
|
||||
paddr_t start = mmmt->base_addr;
|
||||
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;
|
||||
|
||||
paddr_t end = mmmt->base_addr + mmmt->length;
|
||||
paddr_t end = mmap_entry->base_addr + mmap_entry->length;
|
||||
if (auto rem = end % PAGE_SIZE)
|
||||
end -= rem;
|
||||
|
||||
@@ -48,7 +50,6 @@ namespace Kernel
|
||||
if (end > start + PAGE_SIZE)
|
||||
MUST(m_physical_ranges.emplace_back(start, end - start));
|
||||
}
|
||||
i += mmmt->size + sizeof(uint32_t);
|
||||
}
|
||||
|
||||
size_t total = 0;
|
||||
|
||||
@@ -1,55 +1,54 @@
|
||||
#include <BAN/Errors.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
#include <kernel/Terminal/VesaTerminalDriver.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
VesaTerminalDriver* VesaTerminalDriver::create()
|
||||
{
|
||||
if (!(g_multiboot_info->flags & MULTIBOOT_FLAGS_FRAMEBUFFER))
|
||||
auto* framebuffer_tag = (multiboot2_framebuffer_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_FRAMEBUFFER);
|
||||
if (framebuffer_tag == nullptr)
|
||||
{
|
||||
dprintln("Bootloader did not provide framebuffer");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& framebuffer = g_multiboot_info->framebuffer;
|
||||
|
||||
if (framebuffer.type == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
||||
if (framebuffer_tag->framebuffer_type != MULTIBOOT2_FRAMEBUFFER_TYPE_RGB)
|
||||
{
|
||||
if (framebuffer.bpp != 24 && framebuffer.bpp != 32)
|
||||
{
|
||||
dprintln("Unsupported bpp {}", framebuffer.bpp);
|
||||
return nullptr;
|
||||
}
|
||||
dprintln("Graphics Mode {}x{} ({} bpp)", framebuffer.width, framebuffer.height, framebuffer.bpp);
|
||||
}
|
||||
else if (framebuffer.type == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT)
|
||||
{
|
||||
dprintln("Text Mode is currently not supported");
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintln("Unknown framebuffer type {}", framebuffer.type);
|
||||
dprintln("unsupported framebuffer type {}", framebuffer_tag->framebuffer_type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint64_t first_page = framebuffer.addr / PAGE_SIZE;
|
||||
uint64_t last_page = BAN::Math::div_round_up<uint64_t>(framebuffer.addr + framebuffer.pitch * framebuffer.height, PAGE_SIZE);
|
||||
uint64_t needed_pages = last_page - first_page + 1;
|
||||
if (framebuffer_tag->framebuffer_bpp != 24 && framebuffer_tag->framebuffer_bpp != 32)
|
||||
{
|
||||
dprintln("Unsupported bpp {}", framebuffer_tag->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
|
||||
);
|
||||
|
||||
paddr_t paddr = framebuffer_tag->framebuffer_addr & PAGE_ADDR_MASK;
|
||||
size_t needed_pages = range_page_count(
|
||||
framebuffer_tag->framebuffer_addr,
|
||||
framebuffer_tag->framebuffer_pitch * framebuffer_tag->framebuffer_height
|
||||
);
|
||||
|
||||
vaddr_t vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
|
||||
ASSERT(vaddr);
|
||||
|
||||
PageTable::kernel().map_range_at(framebuffer.addr, vaddr, needed_pages * PAGE_SIZE, PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present);
|
||||
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.width,
|
||||
framebuffer.height,
|
||||
framebuffer.pitch,
|
||||
framebuffer.bpp,
|
||||
framebuffer_tag->framebuffer_width,
|
||||
framebuffer_tag->framebuffer_height,
|
||||
framebuffer_tag->framebuffer_pitch,
|
||||
framebuffer_tag->framebuffer_bpp,
|
||||
vaddr
|
||||
);
|
||||
driver->set_cursor_position(0, 0);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Memory/kmalloc.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/multiboot.h>
|
||||
#include <kernel/multiboot2.h>
|
||||
#include <kernel/PCI.h>
|
||||
#include <kernel/PIC.h>
|
||||
#include <kernel/Process.h>
|
||||
@@ -23,8 +23,6 @@
|
||||
#include <kernel/Terminal/VesaTerminalDriver.h>
|
||||
#include <kernel/Timer/Timer.h>
|
||||
|
||||
extern "C" const char g_kernel_cmdline[];
|
||||
|
||||
struct ParsedCommandLine
|
||||
{
|
||||
bool force_pic = false;
|
||||
@@ -35,11 +33,12 @@ struct ParsedCommandLine
|
||||
|
||||
static bool should_disable_serial()
|
||||
{
|
||||
if (!(g_multiboot_info->flags & 0x02))
|
||||
auto* cmdline_tag = (multiboot2_cmdline_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_CMDLINE);
|
||||
if (cmdline_tag == nullptr)
|
||||
return false;
|
||||
|
||||
const char* start = g_kernel_cmdline;
|
||||
const char* current = g_kernel_cmdline;
|
||||
const char* start = cmdline_tag->cmdline;
|
||||
const char* current = start;
|
||||
while (true)
|
||||
{
|
||||
if (!*current || *current == ' ' || *current == '\t')
|
||||
@@ -60,10 +59,11 @@ static ParsedCommandLine cmdline;
|
||||
|
||||
static void parse_command_line()
|
||||
{
|
||||
if (!(g_multiboot_info->flags & 0x02))
|
||||
auto* cmdline_tag = (multiboot2_cmdline_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_CMDLINE);
|
||||
if (cmdline_tag == nullptr)
|
||||
return;
|
||||
|
||||
BAN::StringView full_command_line(g_kernel_cmdline);
|
||||
BAN::StringView full_command_line(cmdline_tag->cmdline);
|
||||
auto arguments = MUST(full_command_line.split(' '));
|
||||
|
||||
for (auto argument : arguments)
|
||||
@@ -98,7 +98,7 @@ extern "C" void kernel_main()
|
||||
dprintln("Serial output initialized");
|
||||
}
|
||||
|
||||
if (g_multiboot_magic != 0x2BADB002)
|
||||
if (g_multiboot2_magic != 0x36d76289)
|
||||
{
|
||||
dprintln("Invalid multiboot magic number");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user