mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
211 lines
8.1 KiB
C++
211 lines
8.1 KiB
C++
/*
|
|
This file is part of Fennix Kernel.
|
|
|
|
Fennix Kernel is free software: you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation, either version 3 of
|
|
the License, or (at your option) any later version.
|
|
|
|
Fennix Kernel is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <types.h>
|
|
|
|
#include <boot/protocol/multiboot.h>
|
|
#include <memory.hpp>
|
|
|
|
#include "../../../../kernel.h"
|
|
|
|
void multiboot_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info)
|
|
{
|
|
multiboot_info *InfoAddress = r_cst(multiboot_info *, Info);
|
|
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_MEMORY)
|
|
{
|
|
fixme("mem_lower: %#x, mem_upper: %#x",
|
|
InfoAddress->mem_lower, InfoAddress->mem_upper);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_BOOTDEV)
|
|
{
|
|
fixme("boot_device: %#x",
|
|
InfoAddress->boot_device);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_CMDLINE)
|
|
{
|
|
strncpy(mb2binfo.Kernel.CommandLine,
|
|
r_cst(const char *, InfoAddress->cmdline),
|
|
strlen(r_cst(const char *, InfoAddress->cmdline)));
|
|
debug("Kernel command line: %s", mb2binfo.Kernel.CommandLine);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_MODS)
|
|
{
|
|
multiboot_mod_list *module = r_cst(multiboot_mod_list *, InfoAddress->mods_addr);
|
|
for (size_t i = 0; i < InfoAddress->mods_count; i++)
|
|
{
|
|
if (i > MAX_MODULES)
|
|
{
|
|
warn("Too many modules, skipping the rest...");
|
|
break;
|
|
}
|
|
mb2binfo.Modules[i].Address = (void *)(uint64_t)module[i].mod_start;
|
|
mb2binfo.Modules[i].Size = module[i].mod_end - module[i].mod_start;
|
|
strncpy(mb2binfo.Modules[i].Path, "(null)", 6);
|
|
strncpy(mb2binfo.Modules[i].CommandLine, r_cst(const char *, module[i].cmdline),
|
|
strlen(r_cst(const char *, module[i].cmdline)));
|
|
debug("Module: %s", mb2binfo.Modules[i].Path);
|
|
}
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_AOUT_SYMS)
|
|
{
|
|
fixme("aout_sym: [tabsize: %#x, strsize: %#x, addr: %#x, reserved: %#x]",
|
|
InfoAddress->u.aout_sym.tabsize, InfoAddress->u.aout_sym.strsize,
|
|
InfoAddress->u.aout_sym.addr, InfoAddress->u.aout_sym.reserved);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_ELF_SHDR)
|
|
{
|
|
mb2binfo.Kernel.Symbols.Num = InfoAddress->u.elf_sec.num;
|
|
mb2binfo.Kernel.Symbols.EntSize = InfoAddress->u.elf_sec.size;
|
|
mb2binfo.Kernel.Symbols.Shndx = InfoAddress->u.elf_sec.shndx;
|
|
mb2binfo.Kernel.Symbols.Sections = s_cst(uintptr_t, InfoAddress->u.elf_sec.addr);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_MEM_MAP)
|
|
{
|
|
mb2binfo.Memory.Entries = InfoAddress->mmap_length / sizeof(multiboot_mmap_entry);
|
|
for (uint32_t i = 0; i < mb2binfo.Memory.Entries; i++)
|
|
{
|
|
if (i > MAX_MEMORY_ENTRIES)
|
|
{
|
|
warn("Too many memory entries, skipping the rest...");
|
|
break;
|
|
}
|
|
multiboot_mmap_entry entry = r_cst(multiboot_mmap_entry *, InfoAddress->mmap_addr)[i];
|
|
mb2binfo.Memory.Size += entry.len;
|
|
switch (entry.type)
|
|
{
|
|
case MULTIBOOT_MEMORY_AVAILABLE:
|
|
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
|
mb2binfo.Memory.Entry[i].Length = entry.len;
|
|
mb2binfo.Memory.Entry[i].Type = Usable;
|
|
break;
|
|
case MULTIBOOT_MEMORY_RESERVED:
|
|
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
|
mb2binfo.Memory.Entry[i].Length = entry.len;
|
|
mb2binfo.Memory.Entry[i].Type = Reserved;
|
|
break;
|
|
case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE:
|
|
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
|
mb2binfo.Memory.Entry[i].Length = entry.len;
|
|
mb2binfo.Memory.Entry[i].Type = ACPIReclaimable;
|
|
break;
|
|
case MULTIBOOT_MEMORY_NVS:
|
|
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
|
mb2binfo.Memory.Entry[i].Length = entry.len;
|
|
mb2binfo.Memory.Entry[i].Type = ACPINVS;
|
|
break;
|
|
case MULTIBOOT_MEMORY_BADRAM:
|
|
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
|
mb2binfo.Memory.Entry[i].Length = entry.len;
|
|
mb2binfo.Memory.Entry[i].Type = BadMemory;
|
|
break;
|
|
default:
|
|
mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr;
|
|
mb2binfo.Memory.Entry[i].Length = entry.len;
|
|
mb2binfo.Memory.Entry[i].Type = Unknown;
|
|
break;
|
|
}
|
|
debug("Memory entry: [BaseAddress: %#x, Length: %#x, Type: %d]",
|
|
mb2binfo.Memory.Entry[i].BaseAddress,
|
|
mb2binfo.Memory.Entry[i].Length,
|
|
mb2binfo.Memory.Entry[i].Type);
|
|
}
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_DRIVE_INFO)
|
|
{
|
|
fixme("drives_length: %d, drives_addr: %#x",
|
|
InfoAddress->drives_length, InfoAddress->drives_addr);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_CONFIG_TABLE)
|
|
{
|
|
fixme("config_table: %#x",
|
|
InfoAddress->config_table);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_BOOT_LOADER_NAME)
|
|
{
|
|
strncpy(mb2binfo.Bootloader.Name,
|
|
r_cst(const char *, InfoAddress->boot_loader_name),
|
|
strlen(r_cst(const char *, InfoAddress->boot_loader_name)));
|
|
debug("Bootloader name: %s", mb2binfo.Bootloader.Name);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_APM_TABLE)
|
|
{
|
|
fixme("apm_table: %#x",
|
|
InfoAddress->apm_table);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_VBE_INFO)
|
|
{
|
|
fixme("vbe_control_info: %#x, vbe_mode_info: %#x, vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x",
|
|
InfoAddress->vbe_control_info, InfoAddress->vbe_mode_info,
|
|
InfoAddress->vbe_mode, InfoAddress->vbe_interface_seg,
|
|
InfoAddress->vbe_interface_off, InfoAddress->vbe_interface_len);
|
|
}
|
|
if (InfoAddress->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO)
|
|
{
|
|
static int fb_count = 0;
|
|
mb2binfo.Framebuffer[fb_count].BaseAddress = (void *)InfoAddress->framebuffer_addr;
|
|
mb2binfo.Framebuffer[fb_count].Width = InfoAddress->framebuffer_width;
|
|
mb2binfo.Framebuffer[fb_count].Height = InfoAddress->framebuffer_height;
|
|
mb2binfo.Framebuffer[fb_count].Pitch = InfoAddress->framebuffer_pitch;
|
|
mb2binfo.Framebuffer[fb_count].BitsPerPixel = InfoAddress->framebuffer_bpp;
|
|
switch (InfoAddress->framebuffer_type)
|
|
{
|
|
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
|
|
{
|
|
mb2binfo.Framebuffer[fb_count].Type = Indexed;
|
|
break;
|
|
}
|
|
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
|
|
{
|
|
mb2binfo.Framebuffer[fb_count].Type = RGB;
|
|
mb2binfo.Framebuffer[fb_count].RedMaskSize = InfoAddress->framebuffer_red_mask_size;
|
|
mb2binfo.Framebuffer[fb_count].RedMaskShift = InfoAddress->framebuffer_red_field_position;
|
|
mb2binfo.Framebuffer[fb_count].GreenMaskSize = InfoAddress->framebuffer_green_mask_size;
|
|
mb2binfo.Framebuffer[fb_count].GreenMaskShift = InfoAddress->framebuffer_green_field_position;
|
|
mb2binfo.Framebuffer[fb_count].BlueMaskSize = InfoAddress->framebuffer_blue_mask_size;
|
|
mb2binfo.Framebuffer[fb_count].BlueMaskShift = InfoAddress->framebuffer_blue_field_position;
|
|
break;
|
|
}
|
|
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
|
|
{
|
|
mb2binfo.Framebuffer[fb_count].Type = EGA;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
mb2binfo.Framebuffer[fb_count].Type = Unknown_Framebuffer_Type;
|
|
break;
|
|
}
|
|
}
|
|
debug("Framebuffer %d: %dx%d %d bpp",
|
|
fb_count, InfoAddress->framebuffer_width,
|
|
InfoAddress->framebuffer_height,
|
|
InfoAddress->framebuffer_bpp);
|
|
debug("More info:\nAddress: %p\nPitch: %d\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d",
|
|
InfoAddress->framebuffer_addr, InfoAddress->framebuffer_pitch, InfoAddress->framebuffer_type,
|
|
InfoAddress->framebuffer_red_mask_size, InfoAddress->framebuffer_red_field_position, InfoAddress->framebuffer_green_mask_size,
|
|
InfoAddress->framebuffer_green_field_position, InfoAddress->framebuffer_blue_mask_size, InfoAddress->framebuffer_blue_field_position);
|
|
}
|
|
|
|
mb2binfo.Kernel.PhysicalBase = (void *)&_bootstrap_start;
|
|
mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)((uint64_t)&_bootstrap_start + 0xFFFFFFFF80000000);
|
|
mb2binfo.Kernel.Size = ((uint64_t)&_kernel_end - (uint64_t)&_kernel_start) + ((uint64_t)&_bootstrap_end - (uint64_t)&_bootstrap_start);
|
|
debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase);
|
|
|
|
Entry(&mb2binfo);
|
|
}
|