forked from Bananymous/banan-os
				
			
			update main #1
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -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