From a452b9acd132c5def45a511a05b89ab14d253d08 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 6 Sep 2023 22:43:33 +0300 Subject: [PATCH] Add support for legacy Multiboot aka Multiboot1 --- .../amd64/Bootstrap/Multiboot/1/Start.s | 23 - .../amd64/Bootstrap/Multiboot/2/Multiboot.cpp | 302 ------------- .../Bootstrap/Multiboot/Headers/Header1.s} | 19 +- .../{2/Header.s => Headers/Header2.s} | 4 +- .../Multiboot/{2 => Helper}/Detect.s | 0 .../Bootstrap/Multiboot/{2 => Helper}/GDT32.s | 0 .../Bootstrap/Multiboot/{2 => Helper}/GDT64.s | 0 .../amd64/Bootstrap/Multiboot/Multiboot.cpp | 53 +++ .../Bootstrap/Multiboot/Multiboot1Parse.cpp | 210 +++++++++ .../Bootstrap/Multiboot/Multiboot2Parse.cpp | 284 ++++++++++++ .../{2 => Paging}/Multiboot64bitMap.cpp | 0 .../{2 => Paging}/Multiboot_PageTable.s | 0 .../amd64/Bootstrap/Multiboot/{2 => }/Start.s | 25 +- .../amd64/Bootstrap/{Multiboot => }/_start.s | 30 +- .../amd64/MultipleAPICDescriptionTable.cpp | 6 + .../amd64/cpu/SymmetricMultiprocessing.cpp | 12 + .../i386/Bootstrap/Multiboot/1/Start.s | 23 - .../i386/Bootstrap/Multiboot/1/multiboot.h | 274 ------------ .../i386/Bootstrap/Multiboot/2/multiboot2.h | 417 ------------------ .../Bootstrap/Multiboot/Headers/Header1.s} | 0 .../{2/Header.s => Headers/Header2.s} | 4 +- .../Multiboot/{2 => Helper}/Detect.s | 0 .../Bootstrap/Multiboot/{2 => Helper}/GDT32.s | 22 +- .../i386/Bootstrap/Multiboot/Multiboot.cpp | 53 +++ .../Bootstrap/Multiboot/Multiboot1Parse.cpp | 210 +++++++++ .../{2/Multiboot.cpp => Multiboot2Parse.cpp} | 16 +- .../{2 => Paging}/Multiboot_PageTable.s | 0 .../i386/Bootstrap/Multiboot/{2 => }/Start.s | 4 +- .../i386/Bootstrap/Multiboot/_start.s | 30 +- ...AdvancedConfigurationAndPowerInterface.cpp | 6 + Core/Memory/PhysicalMemoryManager.cpp | 1 - Core/Memory/ReserveEssentials.cpp | 92 ++-- Core/PeripheralComponentInterconnect.cpp | 12 + Makefile | 2 +- Tasking/Task.cpp | 23 +- .../1 => include/boot/protocol}/multiboot.h | 0 .../2 => include/boot/protocol}/multiboot2.h | 0 37 files changed, 988 insertions(+), 1169 deletions(-) delete mode 100644 Architecture/amd64/Bootstrap/Multiboot/1/Start.s delete mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp rename Architecture/{i386/Bootstrap/Multiboot/1/Header.s => amd64/Bootstrap/Multiboot/Headers/Header1.s} (79%) rename Architecture/amd64/Bootstrap/Multiboot/{2/Header.s => Headers/Header2.s} (98%) rename Architecture/amd64/Bootstrap/Multiboot/{2 => Helper}/Detect.s (100%) rename Architecture/amd64/Bootstrap/Multiboot/{2 => Helper}/GDT32.s (100%) rename Architecture/amd64/Bootstrap/Multiboot/{2 => Helper}/GDT64.s (100%) create mode 100644 Architecture/amd64/Bootstrap/Multiboot/Multiboot.cpp create mode 100644 Architecture/amd64/Bootstrap/Multiboot/Multiboot1Parse.cpp create mode 100644 Architecture/amd64/Bootstrap/Multiboot/Multiboot2Parse.cpp rename Architecture/amd64/Bootstrap/Multiboot/{2 => Paging}/Multiboot64bitMap.cpp (100%) rename Architecture/amd64/Bootstrap/Multiboot/{2 => Paging}/Multiboot_PageTable.s (100%) rename Architecture/amd64/Bootstrap/Multiboot/{2 => }/Start.s (92%) rename Architecture/amd64/Bootstrap/{Multiboot => }/_start.s (75%) delete mode 100644 Architecture/i386/Bootstrap/Multiboot/1/Start.s delete mode 100644 Architecture/i386/Bootstrap/Multiboot/1/multiboot.h delete mode 100644 Architecture/i386/Bootstrap/Multiboot/2/multiboot2.h rename Architecture/{amd64/Bootstrap/Multiboot/1/Header.s => i386/Bootstrap/Multiboot/Headers/Header1.s} (100%) rename Architecture/i386/Bootstrap/Multiboot/{2/Header.s => Headers/Header2.s} (98%) rename Architecture/i386/Bootstrap/Multiboot/{2 => Helper}/Detect.s (100%) rename Architecture/i386/Bootstrap/Multiboot/{2 => Helper}/GDT32.s (87%) create mode 100644 Architecture/i386/Bootstrap/Multiboot/Multiboot.cpp create mode 100644 Architecture/i386/Bootstrap/Multiboot/Multiboot1Parse.cpp rename Architecture/i386/Bootstrap/Multiboot/{2/Multiboot.cpp => Multiboot2Parse.cpp} (95%) rename Architecture/i386/Bootstrap/Multiboot/{2 => Paging}/Multiboot_PageTable.s (100%) rename Architecture/i386/Bootstrap/Multiboot/{2 => }/Start.s (97%) rename {Architecture/amd64/Bootstrap/Multiboot/1 => include/boot/protocol}/multiboot.h (100%) rename {Architecture/amd64/Bootstrap/Multiboot/2 => include/boot/protocol}/multiboot2.h (100%) diff --git a/Architecture/amd64/Bootstrap/Multiboot/1/Start.s b/Architecture/amd64/Bootstrap/Multiboot/1/Start.s deleted file mode 100644 index 8d2b235..0000000 --- a/Architecture/amd64/Bootstrap/Multiboot/1/Start.s +++ /dev/null @@ -1,23 +0,0 @@ -/* - 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 . -*/ - -.code32 -.section .bootstrap.text, "a" - -.global Multiboot1_start -Multiboot1_start: - jmp . diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp deleted file mode 100644 index 2571499..0000000 --- a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* - 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 . -*/ - -#include - -#include - -#include "multiboot2.h" -#include "../../../../../kernel.h" - -EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info) -{ - if (Info == NULL || Magic == NULL) - { - if (Magic == NULL) - error("Multiboot magic is NULL"); - if (Info == NULL) - error("Multiboot info is NULL"); - CPU::Stop(); - } - else if (Magic != MULTIBOOT2_BOOTLOADER_MAGIC) - { - error("Multiboot magic is invalid (%#x != %#x)", Magic, MULTIBOOT2_BOOTLOADER_MAGIC); - CPU::Stop(); - } - - BootInfo mb2binfo{}; - - { - auto InfoAddress = Info; - for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8); - ; - Tag = (struct multiboot_tag *)((multiboot_uint8_t *)Tag + ((Tag->size + 7) & ~7))) - { - if (Tag->type == MULTIBOOT_TAG_TYPE_END) - { - debug("End of multiboot2 tags"); - break; - } - - switch (Tag->type) - { - case MULTIBOOT_TAG_TYPE_CMDLINE: - { - strncpy(mb2binfo.Kernel.CommandLine, - ((multiboot_tag_string *)Tag)->string, - strlen(((multiboot_tag_string *)Tag)->string)); - debug("Kernel command line: %s", mb2binfo.Kernel.CommandLine); - break; - } - case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: - { - strncpy(mb2binfo.Bootloader.Name, - ((multiboot_tag_string *)Tag)->string, - strlen(((multiboot_tag_string *)Tag)->string)); - debug("Bootloader name: %s", mb2binfo.Bootloader.Name); - break; - } - case MULTIBOOT_TAG_TYPE_MODULE: - { - multiboot_tag_module *module = (multiboot_tag_module *)Tag; - static int module_count = 0; - mb2binfo.Modules[module_count].Address = (void *)(uint64_t)module->mod_start; - mb2binfo.Modules[module_count].Size = module->mod_end - module->mod_start; - strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6); - strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline, - strlen(module->cmdline)); - debug("Module: %s", mb2binfo.Modules[module_count].Path); - module_count++; - break; - } - case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: - { - multiboot_tag_basic_meminfo *meminfo = (multiboot_tag_basic_meminfo *)Tag; - fixme("basic_meminfo->[mem_lower: %#x, mem_upper: %#x]", - meminfo->mem_lower, meminfo->mem_upper); - break; - } - case MULTIBOOT_TAG_TYPE_BOOTDEV: - { - multiboot_tag_bootdev *bootdev = (multiboot_tag_bootdev *)Tag; - fixme("bootdev->[biosdev: %#x, slice: %#x, part: %#x]", - bootdev->biosdev, bootdev->slice, bootdev->part); - break; - } - case MULTIBOOT_TAG_TYPE_MMAP: - { - multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag; - size_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry); - mb2binfo.Memory.Entries = EntryCount; - for (uint32_t i = 0; i < EntryCount; i++) - { - if (i > MAX_MEMORY_ENTRIES) - { - warn("Too many memory entries, skipping the rest..."); - break; - } - multiboot_mmap_entry entry = mmap->entries[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); - } - break; - } - case MULTIBOOT_TAG_TYPE_VBE: - { - multiboot_tag_vbe *vbe = (multiboot_tag_vbe *)Tag; - fixme("vbe->[vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x]", - vbe->vbe_mode, vbe->vbe_interface_seg, vbe->vbe_interface_off, vbe->vbe_interface_len); - break; - } - case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: - { - multiboot_tag_framebuffer *fb = (multiboot_tag_framebuffer *)Tag; - static int fb_count = 0; - mb2binfo.Framebuffer[fb_count].BaseAddress = (void *)fb->common.framebuffer_addr; - mb2binfo.Framebuffer[fb_count].Width = fb->common.framebuffer_width; - mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height; - mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch; - mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp; - switch (fb->common.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 = fb->framebuffer_red_mask_size; - mb2binfo.Framebuffer[fb_count].RedMaskShift = fb->framebuffer_red_field_position; - mb2binfo.Framebuffer[fb_count].GreenMaskSize = fb->framebuffer_green_mask_size; - mb2binfo.Framebuffer[fb_count].GreenMaskShift = fb->framebuffer_green_field_position; - mb2binfo.Framebuffer[fb_count].BlueMaskSize = fb->framebuffer_blue_mask_size; - mb2binfo.Framebuffer[fb_count].BlueMaskShift = fb->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, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp); - debug("More info:\nAddress: %p\nPitch: %d\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d", - fb->common.framebuffer_addr, fb->common.framebuffer_pitch, fb->common.framebuffer_type, - fb->framebuffer_red_mask_size, fb->framebuffer_red_field_position, fb->framebuffer_green_mask_size, - fb->framebuffer_green_field_position, fb->framebuffer_blue_mask_size, fb->framebuffer_blue_field_position); - fb_count++; - break; - } - case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: - { - multiboot_tag_elf_sections *elf = (multiboot_tag_elf_sections *)Tag; - mb2binfo.Kernel.Symbols.Num = elf->num; - mb2binfo.Kernel.Symbols.EntSize = elf->entsize; - mb2binfo.Kernel.Symbols.Shndx = elf->shndx; - mb2binfo.Kernel.Symbols.Sections = r_cst(uintptr_t, elf->sections); - break; - } - case MULTIBOOT_TAG_TYPE_APM: - { - multiboot_tag_apm *apm = (multiboot_tag_apm *)Tag; - fixme("apm->[version: %d, cseg: %d, offset: %d, cseg_16: %d, dseg: %d, flags: %d, cseg_len: %d, cseg_16_len: %d, dseg_len: %d]", - apm->version, apm->cseg, apm->offset, apm->cseg_16, apm->dseg, apm->flags, apm->cseg_len, apm->cseg_16_len, apm->dseg_len); - break; - } - case MULTIBOOT_TAG_TYPE_EFI32: - { - multiboot_tag_efi32 *efi32 = (multiboot_tag_efi32 *)Tag; - fixme("efi32->[pointer: %p, size: %d]", efi32->pointer, efi32->size); - break; - } - case MULTIBOOT_TAG_TYPE_EFI64: - { - multiboot_tag_efi64 *efi64 = (multiboot_tag_efi64 *)Tag; - fixme("efi64->[pointer: %p, size: %d]", efi64->pointer, efi64->size); - break; - } - case MULTIBOOT_TAG_TYPE_SMBIOS: - { - multiboot_tag_smbios *smbios = (multiboot_tag_smbios *)Tag; - fixme("smbios->[major: %d, minor: %d]", smbios->major, smbios->minor); - break; - } - case MULTIBOOT_TAG_TYPE_ACPI_OLD: - { - mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp; - debug("OLD ACPI RSDP: %p", mb2binfo.RSDP); - break; - } - case MULTIBOOT_TAG_TYPE_ACPI_NEW: - { - mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp; - debug("NEW ACPI RSDP: %p", mb2binfo.RSDP); - break; - } - case MULTIBOOT_TAG_TYPE_NETWORK: - { - multiboot_tag_network *net = (multiboot_tag_network *)Tag; - fixme("network->[dhcpack: %p]", net->dhcpack); - break; - } - case MULTIBOOT_TAG_TYPE_EFI_MMAP: - { - multiboot_tag_efi_mmap *efi_mmap = (multiboot_tag_efi_mmap *)Tag; - fixme("efi_mmap->[descr_size: %d, descr_vers: %d, efi_mmap: %p]", - efi_mmap->descr_size, efi_mmap->descr_vers, efi_mmap->efi_mmap); - break; - } - case MULTIBOOT_TAG_TYPE_EFI_BS: - { - fixme("efi_bs->[%p] (unknown structure)", Tag); - break; - } - case MULTIBOOT_TAG_TYPE_EFI32_IH: - { - multiboot_tag_efi32_ih *efi32_ih = (multiboot_tag_efi32_ih *)Tag; - fixme("efi32_ih->[pointer: %p]", efi32_ih->pointer); - break; - } - case MULTIBOOT_TAG_TYPE_EFI64_IH: - { - multiboot_tag_efi64_ih *efi64_ih = (multiboot_tag_efi64_ih *)Tag; - fixme("efi64_ih->[pointer: %p]", efi64_ih->pointer); - break; - } - case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: - { - multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag; - mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr; - mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 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); - break; - } - default: - { - error("Unknown multiboot2 tag type: %d", Tag->type); - break; - } - } - } - } - - Entry(&mb2binfo); -} diff --git a/Architecture/i386/Bootstrap/Multiboot/1/Header.s b/Architecture/amd64/Bootstrap/Multiboot/Headers/Header1.s similarity index 79% rename from Architecture/i386/Bootstrap/Multiboot/1/Header.s rename to Architecture/amd64/Bootstrap/Multiboot/Headers/Header1.s index 56fff32..087ee5f 100644 --- a/Architecture/i386/Bootstrap/Multiboot/1/Header.s +++ b/Architecture/amd64/Bootstrap/Multiboot/Headers/Header1.s @@ -15,13 +15,24 @@ along with Fennix Kernel. If not, see . */ -.intel_syntax noprefix - .code32 +.extern Multiboot_start + .section .multiboot, "a" .align 4 MULTIBOOT_HEADER: .long 0x1BADB002 - .long 1 << 0 | 1 << 1 - .long -(0x1BADB002 + (1 << 0 | 1 << 1)) + .long 0x1 | 0x2 | 0x4 + .long -(0x1BADB002 + (0x1 | 0x2 | 0x4)) + /* KLUDGE */ + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + /* VIDEO MODE */ + .long 0 + .long 0 + .long 0 + .long 0 diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Header.s b/Architecture/amd64/Bootstrap/Multiboot/Headers/Header2.s similarity index 98% rename from Architecture/amd64/Bootstrap/Multiboot/2/Header.s rename to Architecture/amd64/Bootstrap/Multiboot/Headers/Header2.s index 05fb42e..5217f10 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/2/Header.s +++ b/Architecture/amd64/Bootstrap/Multiboot/Headers/Header2.s @@ -16,7 +16,7 @@ */ .code32 -.extern Multiboot2_start +.extern Multiboot_start /* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */ .section .multiboot2, "a" @@ -80,7 +80,7 @@ EntryAddressTag_Start: .word 3 .word 0 .long EntryAddressTag_End - EntryAddressTag_Start - .long Multiboot2_start + .long Multiboot_start EntryAddressTag_End: .align 8 EndTag_Start: diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Detect.s b/Architecture/amd64/Bootstrap/Multiboot/Helper/Detect.s similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/2/Detect.s rename to Architecture/amd64/Bootstrap/Multiboot/Helper/Detect.s diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/GDT32.s b/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT32.s similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/2/GDT32.s rename to Architecture/amd64/Bootstrap/Multiboot/Helper/GDT32.s diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/GDT64.s b/Architecture/amd64/Bootstrap/Multiboot/Helper/GDT64.s similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/2/GDT64.s rename to Architecture/amd64/Bootstrap/Multiboot/Helper/GDT64.s diff --git a/Architecture/amd64/Bootstrap/Multiboot/Multiboot.cpp b/Architecture/amd64/Bootstrap/Multiboot/Multiboot.cpp new file mode 100644 index 0000000..fc67058 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/Multiboot.cpp @@ -0,0 +1,53 @@ +/* + 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 . +*/ + +#include + +#include + +#include "../../../../kernel.h" + +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +void multiboot_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info); +void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info); + +EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info) +{ + BootInfo mb2binfo{}; + + if (Info == NULL || Magic == NULL) + { + if (Magic == NULL) + error("Multiboot magic is NULL"); + if (Info == NULL) + error("Multiboot info is NULL"); + CPU::Stop(); + } + else if (Magic == MULTIBOOT_BOOTLOADER_MAGIC) + multiboot_parse(mb2binfo, Magic, Info); + else if (Magic == MULTIBOOT2_BOOTLOADER_MAGIC) + multiboot2_parse(mb2binfo, Magic, Info); + else + { + error("Unknown multiboot magic %#x", Magic); + CPU::Stop(); + } +} diff --git a/Architecture/amd64/Bootstrap/Multiboot/Multiboot1Parse.cpp b/Architecture/amd64/Bootstrap/Multiboot/Multiboot1Parse.cpp new file mode 100644 index 0000000..4733dd0 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/Multiboot1Parse.cpp @@ -0,0 +1,210 @@ +/* + 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 . +*/ + +#include + +#include +#include + +#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); +} diff --git a/Architecture/amd64/Bootstrap/Multiboot/Multiboot2Parse.cpp b/Architecture/amd64/Bootstrap/Multiboot/Multiboot2Parse.cpp new file mode 100644 index 0000000..83f972c --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/Multiboot2Parse.cpp @@ -0,0 +1,284 @@ +/* + 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 . +*/ + +#include + +#include +#include + +#include "../../../../kernel.h" + +void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info) +{ + auto InfoAddress = Info; + for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8); + ; + Tag = (struct multiboot_tag *)((multiboot_uint8_t *)Tag + ((Tag->size + 7) & ~7))) + { + if (Tag->type == MULTIBOOT_TAG_TYPE_END) + { + debug("End of multiboot2 tags"); + break; + } + + switch (Tag->type) + { + case MULTIBOOT_TAG_TYPE_CMDLINE: + { + strncpy(mb2binfo.Kernel.CommandLine, + ((multiboot_tag_string *)Tag)->string, + strlen(((multiboot_tag_string *)Tag)->string)); + debug("Kernel command line: %s", mb2binfo.Kernel.CommandLine); + break; + } + case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: + { + strncpy(mb2binfo.Bootloader.Name, + ((multiboot_tag_string *)Tag)->string, + strlen(((multiboot_tag_string *)Tag)->string)); + debug("Bootloader name: %s", mb2binfo.Bootloader.Name); + break; + } + case MULTIBOOT_TAG_TYPE_MODULE: + { + multiboot_tag_module *module = (multiboot_tag_module *)Tag; + static int module_count = 0; + mb2binfo.Modules[module_count].Address = (void *)(uint64_t)module->mod_start; + mb2binfo.Modules[module_count].Size = module->mod_end - module->mod_start; + strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6); + strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline, + strlen(module->cmdline)); + debug("Module: %s", mb2binfo.Modules[module_count].Path); + module_count++; + break; + } + case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: + { + multiboot_tag_basic_meminfo *meminfo = (multiboot_tag_basic_meminfo *)Tag; + fixme("basic_meminfo->[mem_lower: %#x, mem_upper: %#x]", + meminfo->mem_lower, meminfo->mem_upper); + break; + } + case MULTIBOOT_TAG_TYPE_BOOTDEV: + { + multiboot_tag_bootdev *bootdev = (multiboot_tag_bootdev *)Tag; + fixme("bootdev->[biosdev: %#x, slice: %#x, part: %#x]", + bootdev->biosdev, bootdev->slice, bootdev->part); + break; + } + case MULTIBOOT_TAG_TYPE_MMAP: + { + multiboot_tag_mmap *mmap = (multiboot_tag_mmap *)Tag; + size_t EntryCount = mmap->size / sizeof(multiboot_mmap_entry); + mb2binfo.Memory.Entries = EntryCount; + for (uint32_t i = 0; i < EntryCount; i++) + { + if (i > MAX_MEMORY_ENTRIES) + { + warn("Too many memory entries, skipping the rest..."); + break; + } + multiboot_mmap_entry entry = mmap->entries[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); + } + break; + } + case MULTIBOOT_TAG_TYPE_VBE: + { + multiboot_tag_vbe *vbe = (multiboot_tag_vbe *)Tag; + fixme("vbe->[vbe_mode: %#x, vbe_interface_seg: %#x, vbe_interface_off: %#x, vbe_interface_len: %#x]", + vbe->vbe_mode, vbe->vbe_interface_seg, vbe->vbe_interface_off, vbe->vbe_interface_len); + break; + } + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + { + multiboot_tag_framebuffer *fb = (multiboot_tag_framebuffer *)Tag; + static int fb_count = 0; + mb2binfo.Framebuffer[fb_count].BaseAddress = (void *)fb->common.framebuffer_addr; + mb2binfo.Framebuffer[fb_count].Width = fb->common.framebuffer_width; + mb2binfo.Framebuffer[fb_count].Height = fb->common.framebuffer_height; + mb2binfo.Framebuffer[fb_count].Pitch = fb->common.framebuffer_pitch; + mb2binfo.Framebuffer[fb_count].BitsPerPixel = fb->common.framebuffer_bpp; + switch (fb->common.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 = fb->framebuffer_red_mask_size; + mb2binfo.Framebuffer[fb_count].RedMaskShift = fb->framebuffer_red_field_position; + mb2binfo.Framebuffer[fb_count].GreenMaskSize = fb->framebuffer_green_mask_size; + mb2binfo.Framebuffer[fb_count].GreenMaskShift = fb->framebuffer_green_field_position; + mb2binfo.Framebuffer[fb_count].BlueMaskSize = fb->framebuffer_blue_mask_size; + mb2binfo.Framebuffer[fb_count].BlueMaskShift = fb->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, fb->common.framebuffer_width, fb->common.framebuffer_height, fb->common.framebuffer_bpp); + debug("More info:\nAddress: %p\nPitch: %d\nMemoryModel: %d\nRedMaskSize: %d\nRedMaskShift: %d\nGreenMaskSize: %d\nGreenMaskShift: %d\nBlueMaskSize: %d\nBlueMaskShift: %d", + fb->common.framebuffer_addr, fb->common.framebuffer_pitch, fb->common.framebuffer_type, + fb->framebuffer_red_mask_size, fb->framebuffer_red_field_position, fb->framebuffer_green_mask_size, + fb->framebuffer_green_field_position, fb->framebuffer_blue_mask_size, fb->framebuffer_blue_field_position); + fb_count++; + break; + } + case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: + { + multiboot_tag_elf_sections *elf = (multiboot_tag_elf_sections *)Tag; + mb2binfo.Kernel.Symbols.Num = elf->num; + mb2binfo.Kernel.Symbols.EntSize = elf->entsize; + mb2binfo.Kernel.Symbols.Shndx = elf->shndx; + mb2binfo.Kernel.Symbols.Sections = r_cst(uintptr_t, elf->sections); + break; + } + case MULTIBOOT_TAG_TYPE_APM: + { + multiboot_tag_apm *apm = (multiboot_tag_apm *)Tag; + fixme("apm->[version: %d, cseg: %d, offset: %d, cseg_16: %d, dseg: %d, flags: %d, cseg_len: %d, cseg_16_len: %d, dseg_len: %d]", + apm->version, apm->cseg, apm->offset, apm->cseg_16, apm->dseg, apm->flags, apm->cseg_len, apm->cseg_16_len, apm->dseg_len); + break; + } + case MULTIBOOT_TAG_TYPE_EFI32: + { + multiboot_tag_efi32 *efi32 = (multiboot_tag_efi32 *)Tag; + fixme("efi32->[pointer: %p, size: %d]", efi32->pointer, efi32->size); + break; + } + case MULTIBOOT_TAG_TYPE_EFI64: + { + multiboot_tag_efi64 *efi64 = (multiboot_tag_efi64 *)Tag; + fixme("efi64->[pointer: %p, size: %d]", efi64->pointer, efi64->size); + break; + } + case MULTIBOOT_TAG_TYPE_SMBIOS: + { + multiboot_tag_smbios *smbios = (multiboot_tag_smbios *)Tag; + fixme("smbios->[major: %d, minor: %d]", smbios->major, smbios->minor); + break; + } + case MULTIBOOT_TAG_TYPE_ACPI_OLD: + { + mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_old_acpi *)Tag)->rsdp; + debug("OLD ACPI RSDP: %p", mb2binfo.RSDP); + break; + } + case MULTIBOOT_TAG_TYPE_ACPI_NEW: + { + mb2binfo.RSDP = (BootInfo::RSDPInfo *)((multiboot_tag_new_acpi *)Tag)->rsdp; + debug("NEW ACPI RSDP: %p", mb2binfo.RSDP); + break; + } + case MULTIBOOT_TAG_TYPE_NETWORK: + { + multiboot_tag_network *net = (multiboot_tag_network *)Tag; + fixme("network->[dhcpack: %p]", net->dhcpack); + break; + } + case MULTIBOOT_TAG_TYPE_EFI_MMAP: + { + multiboot_tag_efi_mmap *efi_mmap = (multiboot_tag_efi_mmap *)Tag; + fixme("efi_mmap->[descr_size: %d, descr_vers: %d, efi_mmap: %p]", + efi_mmap->descr_size, efi_mmap->descr_vers, efi_mmap->efi_mmap); + break; + } + case MULTIBOOT_TAG_TYPE_EFI_BS: + { + fixme("efi_bs->[%p] (unknown structure)", Tag); + break; + } + case MULTIBOOT_TAG_TYPE_EFI32_IH: + { + multiboot_tag_efi32_ih *efi32_ih = (multiboot_tag_efi32_ih *)Tag; + fixme("efi32_ih->[pointer: %p]", efi32_ih->pointer); + break; + } + case MULTIBOOT_TAG_TYPE_EFI64_IH: + { + multiboot_tag_efi64_ih *efi64_ih = (multiboot_tag_efi64_ih *)Tag; + fixme("efi64_ih->[pointer: %p]", efi64_ih->pointer); + break; + } + case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: + { + multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag; + mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr; + mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 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); + break; + } + default: + { + error("Unknown multiboot2 tag type: %d", Tag->type); + break; + } + } + } + + Entry(&mb2binfo); +} diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot64bitMap.cpp b/Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot64bitMap.cpp similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/2/Multiboot64bitMap.cpp rename to Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot64bitMap.cpp diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.s b/Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.s rename to Architecture/amd64/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Start.s b/Architecture/amd64/Bootstrap/Multiboot/Start.s similarity index 92% rename from Architecture/amd64/Bootstrap/Multiboot/2/Start.s rename to Architecture/amd64/Bootstrap/Multiboot/Start.s index 2bfb956..2c2d3ad 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/2/Start.s +++ b/Architecture/amd64/Bootstrap/Multiboot/Start.s @@ -39,8 +39,13 @@ MB_HeaderInfo: .section .bootstrap.text, "a" -.global Multiboot2_start -Multiboot2_start: +x32Hang: + cli + hlt + jmp x32Hang + +.global Multiboot_start +Multiboot_start: cli mov %eax, [MB_HeaderMagic] @@ -48,19 +53,19 @@ Multiboot2_start: call DetectCPUID cmp $0, %eax - je . + je x32Hang call Detect64Bit cmp $0, %eax - je . + je x32Hang call DetectPSE cmp $0, %eax - je . + je x32Hang call DetectPAE cmp $0, %eax - je . + je x32Hang mov %cr4, %ecx or $0x00000010, %ecx /* PSE */ @@ -92,7 +97,7 @@ Multiboot2_start: .code64 HigherHalfStart: - mov GDT64.Data, %ax + mov $GDT64.Data, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs @@ -109,9 +114,9 @@ HigherHalfStart: push %rsi push %rdi call multiboot_main -.Hang: - hlt - jmp .Hang + .Hang: + hlt + jmp .Hang .section .bootstrap.bss, "a" .align 16 diff --git a/Architecture/amd64/Bootstrap/Multiboot/_start.s b/Architecture/amd64/Bootstrap/_start.s similarity index 75% rename from Architecture/amd64/Bootstrap/Multiboot/_start.s rename to Architecture/amd64/Bootstrap/_start.s index 830391e..5e9efa9 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/_start.s +++ b/Architecture/amd64/Bootstrap/_start.s @@ -15,26 +15,24 @@ along with Fennix Kernel. If not, see . */ -.intel_syntax noprefix - -.extern Multiboot1_start -.extern Multiboot2_start - .code32 +.extern Multiboot_start + .section .bootstrap.text, "a" .global _start _start: - cmp eax, 0x36D76289 - je .Multiboot2 - cmp eax, 0x1BADB002 - je .Multiboot1 - int3 + /* Check for multiboot */ + cmp $0x2BADB002, %eax + je .Multiboot -.Multiboot1: - call Multiboot1_start - jmp . + /* Unkown bootloader */ + .Hang: + cli + hlt + jmp .Hang -.Multiboot2: - call Multiboot2_start - jmp . + /* Multiboot */ + .Multiboot: + call Multiboot_start + jmp .Hang diff --git a/Architecture/amd64/MultipleAPICDescriptionTable.cpp b/Architecture/amd64/MultipleAPICDescriptionTable.cpp index f1176ed..5513b75 100644 --- a/Architecture/amd64/MultipleAPICDescriptionTable.cpp +++ b/Architecture/amd64/MultipleAPICDescriptionTable.cpp @@ -27,6 +27,12 @@ namespace ACPI MADT::MADT(ACPI::MADTHeader *madt) { trace("Initializing MADT"); + if (!madt) + { + error("MADT is NULL"); + return; + } + CPUCores = 0; LAPICAddress = (LAPIC *)(uintptr_t)madt->LocalControllerAddress; for (uint8_t *ptr = (uint8_t *)(madt->Entries); diff --git a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp index 83fd80e..89ecdd0 100644 --- a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp +++ b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp @@ -97,8 +97,20 @@ namespace SMP void Initialize(void *_madt) { + if (!_madt) + { + error("MADT is NULL"); + return; + } + ACPI::MADT *madt = (ACPI::MADT *)_madt; + if (madt->lapic.size() < 1) + { + error("No CPUs found!"); + return; + } + int Cores = madt->CPUCores + 1; if (Config.Cores > madt->CPUCores + 1) diff --git a/Architecture/i386/Bootstrap/Multiboot/1/Start.s b/Architecture/i386/Bootstrap/Multiboot/1/Start.s deleted file mode 100644 index 8d2b235..0000000 --- a/Architecture/i386/Bootstrap/Multiboot/1/Start.s +++ /dev/null @@ -1,23 +0,0 @@ -/* - 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 . -*/ - -.code32 -.section .bootstrap.text, "a" - -.global Multiboot1_start -Multiboot1_start: - jmp . diff --git a/Architecture/i386/Bootstrap/Multiboot/1/multiboot.h b/Architecture/i386/Bootstrap/Multiboot/1/multiboot.h deleted file mode 100644 index 42dd7d3..0000000 --- a/Architecture/i386/Bootstrap/Multiboot/1/multiboot.h +++ /dev/null @@ -1,274 +0,0 @@ -/* multiboot.h - Multiboot header file. */ -/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY - * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MULTIBOOT_HEADER -#define MULTIBOOT_HEADER 1 - -/* How many bytes from the start of the file we search for the header. */ -#define MULTIBOOT_SEARCH 8192 -#define MULTIBOOT_HEADER_ALIGN 4 - -/* The magic field should contain this. */ -#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 - -/* This should be in %eax. */ -#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 - -/* Alignment of multiboot modules. */ -#define MULTIBOOT_MOD_ALIGN 0x00001000 - -/* Alignment of the multiboot info structure. */ -#define MULTIBOOT_INFO_ALIGN 0x00000004 - -/* Flags set in the ’flags’ member of the multiboot header. */ - -/* Align all boot modules on i386 page (4KB) boundaries. */ -#define MULTIBOOT_PAGE_ALIGN 0x00000001 - -/* Must pass memory information to OS. */ -#define MULTIBOOT_MEMORY_INFO 0x00000002 - -/* Must pass video information to OS. */ -#define MULTIBOOT_VIDEO_MODE 0x00000004 - -/* This flag indicates the use of the address fields in the header. */ -#define MULTIBOOT_AOUT_KLUDGE 0x00010000 - -/* Flags to be set in the ’flags’ member of the multiboot info structure. */ - -/* is there basic lower/upper memory information? */ -#define MULTIBOOT_INFO_MEMORY 0x00000001 -/* is there a boot device set? */ -#define MULTIBOOT_INFO_BOOTDEV 0x00000002 -/* is the command-line defined? */ -#define MULTIBOOT_INFO_CMDLINE 0x00000004 -/* are there modules to do something with? */ -#define MULTIBOOT_INFO_MODS 0x00000008 - -/* These next two are mutually exclusive */ - -/* is there a symbol table loaded? */ -#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 -/* is there an ELF section header table? */ -#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 - -/* is there a full memory map? */ -#define MULTIBOOT_INFO_MEM_MAP 0x00000040 - -/* Is there drive info? */ -#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 - -/* Is there a config table? */ -#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 - -/* Is there a boot loader name? */ -#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 - -/* Is there a APM table? */ -#define MULTIBOOT_INFO_APM_TABLE 0x00000400 - -/* Is there video information? */ -#define MULTIBOOT_INFO_VBE_INFO 0x00000800 -#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 - -#ifndef ASM_FILE - -typedef unsigned char multiboot_uint8_t; -typedef unsigned short multiboot_uint16_t; -typedef unsigned int multiboot_uint32_t; -typedef unsigned long long multiboot_uint64_t; - -struct multiboot_header -{ - /* Must be MULTIBOOT_MAGIC - see above. */ - multiboot_uint32_t magic; - - /* Feature flags. */ - multiboot_uint32_t flags; - - /* The above fields plus this one must equal 0 mod 2^32. */ - multiboot_uint32_t checksum; - - /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ - multiboot_uint32_t header_addr; - multiboot_uint32_t load_addr; - multiboot_uint32_t load_end_addr; - multiboot_uint32_t bss_end_addr; - multiboot_uint32_t entry_addr; - - /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ - multiboot_uint32_t mode_type; - multiboot_uint32_t width; - multiboot_uint32_t height; - multiboot_uint32_t depth; -}; - -/* The symbol table for a.out. */ -struct multiboot_aout_symbol_table -{ - multiboot_uint32_t tabsize; - multiboot_uint32_t strsize; - multiboot_uint32_t addr; - multiboot_uint32_t reserved; -}; -typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; - -/* The section header table for ELF. */ -struct multiboot_elf_section_header_table -{ - multiboot_uint32_t num; - multiboot_uint32_t size; - multiboot_uint32_t addr; - multiboot_uint32_t shndx; -}; -typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; - -struct multiboot_info -{ - /* Multiboot info version number */ - multiboot_uint32_t flags; - - /* Available memory from BIOS */ - multiboot_uint32_t mem_lower; - multiboot_uint32_t mem_upper; - - /* "root" partition */ - multiboot_uint32_t boot_device; - - /* Kernel command line */ - multiboot_uint32_t cmdline; - - /* Boot-Module list */ - multiboot_uint32_t mods_count; - multiboot_uint32_t mods_addr; - - union - { - multiboot_aout_symbol_table_t aout_sym; - multiboot_elf_section_header_table_t elf_sec; - } u; - - /* Memory Mapping buffer */ - multiboot_uint32_t mmap_length; - multiboot_uint32_t mmap_addr; - - /* Drive Info buffer */ - multiboot_uint32_t drives_length; - multiboot_uint32_t drives_addr; - - /* ROM configuration table */ - multiboot_uint32_t config_table; - - /* Boot Loader Name */ - multiboot_uint32_t boot_loader_name; - - /* APM table */ - multiboot_uint32_t apm_table; - - /* Video */ - multiboot_uint32_t vbe_control_info; - multiboot_uint32_t vbe_mode_info; - multiboot_uint16_t vbe_mode; - multiboot_uint16_t vbe_interface_seg; - multiboot_uint16_t vbe_interface_off; - multiboot_uint16_t vbe_interface_len; - - multiboot_uint64_t framebuffer_addr; - multiboot_uint32_t framebuffer_pitch; - multiboot_uint32_t framebuffer_width; - multiboot_uint32_t framebuffer_height; - multiboot_uint8_t framebuffer_bpp; -#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 -#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - multiboot_uint8_t framebuffer_type; - union - { - struct - { - multiboot_uint32_t framebuffer_palette_addr; - multiboot_uint16_t framebuffer_palette_num_colors; - }; - struct - { - multiboot_uint8_t framebuffer_red_field_position; - multiboot_uint8_t framebuffer_red_mask_size; - multiboot_uint8_t framebuffer_green_field_position; - multiboot_uint8_t framebuffer_green_mask_size; - multiboot_uint8_t framebuffer_blue_field_position; - multiboot_uint8_t framebuffer_blue_mask_size; - }; - }; -}; -typedef struct multiboot_info multiboot_info_t; - -struct multiboot_color -{ - multiboot_uint8_t red; - multiboot_uint8_t green; - multiboot_uint8_t blue; -}; - -struct multiboot_mmap_entry -{ - multiboot_uint32_t size; - multiboot_uint64_t addr; - multiboot_uint64_t len; -#define MULTIBOOT_MEMORY_AVAILABLE 1 -#define MULTIBOOT_MEMORY_RESERVED 2 -#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 -#define MULTIBOOT_MEMORY_NVS 4 -#define MULTIBOOT_MEMORY_BADRAM 5 - multiboot_uint32_t type; -} __attribute__((packed)); -typedef struct multiboot_mmap_entry multiboot_memory_map_t; - -struct multiboot_mod_list -{ - /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ - multiboot_uint32_t mod_start; - multiboot_uint32_t mod_end; - - /* Module command line */ - multiboot_uint32_t cmdline; - - /* padding to take it to 16 bytes (must be zero) */ - multiboot_uint32_t pad; -}; -typedef struct multiboot_mod_list multiboot_module_t; - -/* APM BIOS info. */ -struct multiboot_apm_info -{ - multiboot_uint16_t version; - multiboot_uint16_t cseg; - multiboot_uint32_t offset; - multiboot_uint16_t cseg_16; - multiboot_uint16_t dseg; - multiboot_uint16_t flags; - multiboot_uint16_t cseg_len; - multiboot_uint16_t cseg_16_len; - multiboot_uint16_t dseg_len; -}; - -#endif /* ! ASM_FILE */ - -#endif /* ! MULTIBOOT_HEADER */ diff --git a/Architecture/i386/Bootstrap/Multiboot/2/multiboot2.h b/Architecture/i386/Bootstrap/Multiboot/2/multiboot2.h deleted file mode 100644 index 32f8d99..0000000 --- a/Architecture/i386/Bootstrap/Multiboot/2/multiboot2.h +++ /dev/null @@ -1,417 +0,0 @@ -/* multiboot2.h - Multiboot 2 header file. */ -/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY - * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MULTIBOOT_HEADER -#define MULTIBOOT_HEADER 1 - -/* How many bytes from the start of the file we search for the header. */ -#define MULTIBOOT_SEARCH 32768 -#define MULTIBOOT_HEADER_ALIGN 8 - -/* The magic field should contain this. */ -#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 - -/* This should be in %eax. */ -#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 - -/* Alignment of multiboot modules. */ -#define MULTIBOOT_MOD_ALIGN 0x00001000 - -/* Alignment of the multiboot info structure. */ -#define MULTIBOOT_INFO_ALIGN 0x00000008 - -/* Flags set in the 'flags' member of the multiboot header. */ - -#define MULTIBOOT_TAG_ALIGN 8 -#define MULTIBOOT_TAG_TYPE_END 0 -#define MULTIBOOT_TAG_TYPE_CMDLINE 1 -#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 -#define MULTIBOOT_TAG_TYPE_MODULE 3 -#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 -#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 -#define MULTIBOOT_TAG_TYPE_MMAP 6 -#define MULTIBOOT_TAG_TYPE_VBE 7 -#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 -#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 -#define MULTIBOOT_TAG_TYPE_APM 10 -#define MULTIBOOT_TAG_TYPE_EFI32 11 -#define MULTIBOOT_TAG_TYPE_EFI64 12 -#define MULTIBOOT_TAG_TYPE_SMBIOS 13 -#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 -#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 -#define MULTIBOOT_TAG_TYPE_NETWORK 16 -#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 -#define MULTIBOOT_TAG_TYPE_EFI_BS 18 -#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 -#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 -#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 - -#define MULTIBOOT_HEADER_TAG_END 0 -#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 -#define MULTIBOOT_HEADER_TAG_ADDRESS 2 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 -#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 -#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 -#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 -#define MULTIBOOT_HEADER_TAG_EFI_BS 7 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 -#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 - -#define MULTIBOOT_ARCHITECTURE_I386 0 -#define MULTIBOOT_ARCHITECTURE_MIPS32 4 -#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 - -#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 -#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 -#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 - -#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 -#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 - -#ifndef ASM_FILE - -typedef unsigned char multiboot_uint8_t; -typedef unsigned short multiboot_uint16_t; -typedef unsigned int multiboot_uint32_t; -typedef unsigned long long multiboot_uint64_t; - -struct multiboot_header -{ - /* Must be MULTIBOOT_MAGIC - see above. */ - multiboot_uint32_t magic; - - /* ISA */ - multiboot_uint32_t architecture; - - /* Total header length. */ - multiboot_uint32_t header_length; - - /* The above fields plus this one must equal 0 mod 2^32. */ - multiboot_uint32_t checksum; -}; - -struct multiboot_header_tag -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; -}; - -struct multiboot_header_tag_information_request -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t requests[0]; -}; - -struct multiboot_header_tag_address -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t header_addr; - multiboot_uint32_t load_addr; - multiboot_uint32_t load_end_addr; - multiboot_uint32_t bss_end_addr; -}; - -struct multiboot_header_tag_entry_address -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t entry_addr; -}; - -struct multiboot_header_tag_console_flags -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t console_flags; -}; - -struct multiboot_header_tag_framebuffer -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t width; - multiboot_uint32_t height; - multiboot_uint32_t depth; -}; - -struct multiboot_header_tag_module_align -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; -}; - -struct multiboot_header_tag_relocatable -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t min_addr; - multiboot_uint32_t max_addr; - multiboot_uint32_t align; - multiboot_uint32_t preference; -}; - -struct multiboot_color -{ - multiboot_uint8_t red; - multiboot_uint8_t green; - multiboot_uint8_t blue; -}; - -struct multiboot_mmap_entry -{ - multiboot_uint64_t addr; - multiboot_uint64_t len; -#define MULTIBOOT_MEMORY_AVAILABLE 1 -#define MULTIBOOT_MEMORY_RESERVED 2 -#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 -#define MULTIBOOT_MEMORY_NVS 4 -#define MULTIBOOT_MEMORY_BADRAM 5 - multiboot_uint32_t type; - multiboot_uint32_t zero; -}; -typedef struct multiboot_mmap_entry multiboot_memory_map_t; - -struct multiboot_tag -{ - multiboot_uint32_t type; - multiboot_uint32_t size; -}; - -struct multiboot_tag_string -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - char string[0]; -}; - -struct multiboot_tag_module -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mod_start; - multiboot_uint32_t mod_end; - char cmdline[0]; -}; - -struct multiboot_tag_basic_meminfo -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mem_lower; - multiboot_uint32_t mem_upper; -}; - -struct multiboot_tag_bootdev -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t biosdev; - multiboot_uint32_t slice; - multiboot_uint32_t part; -}; - -struct multiboot_tag_mmap -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t entry_size; - multiboot_uint32_t entry_version; - struct multiboot_mmap_entry entries[0]; -}; - -struct multiboot_vbe_info_block -{ - multiboot_uint8_t external_specification[512]; -}; - -struct multiboot_vbe_mode_info_block -{ - multiboot_uint8_t external_specification[256]; -}; - -struct multiboot_tag_vbe -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - - multiboot_uint16_t vbe_mode; - multiboot_uint16_t vbe_interface_seg; - multiboot_uint16_t vbe_interface_off; - multiboot_uint16_t vbe_interface_len; - - struct multiboot_vbe_info_block vbe_control_info; - struct multiboot_vbe_mode_info_block vbe_mode_info; -}; - -struct multiboot_tag_framebuffer_common -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - - multiboot_uint64_t framebuffer_addr; - multiboot_uint32_t framebuffer_pitch; - multiboot_uint32_t framebuffer_width; - multiboot_uint32_t framebuffer_height; - multiboot_uint8_t framebuffer_bpp; -#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 -#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - multiboot_uint8_t framebuffer_type; - multiboot_uint16_t reserved; -}; - -struct multiboot_tag_framebuffer -{ - struct multiboot_tag_framebuffer_common common; - - union - { - struct - { - multiboot_uint16_t framebuffer_palette_num_colors; - struct multiboot_color framebuffer_palette[0]; - }; - struct - { - multiboot_uint8_t framebuffer_red_field_position; - multiboot_uint8_t framebuffer_red_mask_size; - multiboot_uint8_t framebuffer_green_field_position; - multiboot_uint8_t framebuffer_green_mask_size; - multiboot_uint8_t framebuffer_blue_field_position; - multiboot_uint8_t framebuffer_blue_mask_size; - }; - }; -}; - -struct multiboot_tag_elf_sections -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t num; - multiboot_uint32_t entsize; - multiboot_uint32_t shndx; - char sections[0]; -}; - -struct multiboot_tag_apm -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint16_t version; - multiboot_uint16_t cseg; - multiboot_uint32_t offset; - multiboot_uint16_t cseg_16; - multiboot_uint16_t dseg; - multiboot_uint16_t flags; - multiboot_uint16_t cseg_len; - multiboot_uint16_t cseg_16_len; - multiboot_uint16_t dseg_len; -}; - -struct multiboot_tag_efi32 -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; - -struct multiboot_tag_efi64 -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; - -struct multiboot_tag_smbios -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t major; - multiboot_uint8_t minor; - multiboot_uint8_t reserved[6]; - multiboot_uint8_t tables[0]; -}; - -struct multiboot_tag_old_acpi -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_new_acpi -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_network -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t dhcpack[0]; -}; - -struct multiboot_tag_efi_mmap -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t descr_size; - multiboot_uint32_t descr_vers; - multiboot_uint8_t efi_mmap[0]; -}; - -struct multiboot_tag_efi32_ih -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; - -struct multiboot_tag_efi64_ih -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; - -struct multiboot_tag_load_base_addr -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t load_base_addr; -}; - -#endif /* ! ASM_FILE */ - -#endif /* ! MULTIBOOT_HEADER */ diff --git a/Architecture/amd64/Bootstrap/Multiboot/1/Header.s b/Architecture/i386/Bootstrap/Multiboot/Headers/Header1.s similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/1/Header.s rename to Architecture/i386/Bootstrap/Multiboot/Headers/Header1.s diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Header.s b/Architecture/i386/Bootstrap/Multiboot/Headers/Header2.s similarity index 98% rename from Architecture/i386/Bootstrap/Multiboot/2/Header.s rename to Architecture/i386/Bootstrap/Multiboot/Headers/Header2.s index 5f00e96..41c5168 100644 --- a/Architecture/i386/Bootstrap/Multiboot/2/Header.s +++ b/Architecture/i386/Bootstrap/Multiboot/Headers/Header2.s @@ -18,7 +18,7 @@ .intel_syntax noprefix .code32 -.extern Multiboot2_start +.extern Multiboot_start /* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */ .section .multiboot2, "a" @@ -82,7 +82,7 @@ EntryAddressTag_Start: .word 3 .word 0 .long EntryAddressTag_End - EntryAddressTag_Start - .long Multiboot2_start + .long Multiboot_start EntryAddressTag_End: .align 8 EndTag_Start: diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Detect.s b/Architecture/i386/Bootstrap/Multiboot/Helper/Detect.s similarity index 100% rename from Architecture/i386/Bootstrap/Multiboot/2/Detect.s rename to Architecture/i386/Bootstrap/Multiboot/Helper/Detect.s diff --git a/Architecture/i386/Bootstrap/Multiboot/2/GDT32.s b/Architecture/i386/Bootstrap/Multiboot/Helper/GDT32.s similarity index 87% rename from Architecture/i386/Bootstrap/Multiboot/2/GDT32.s rename to Architecture/i386/Bootstrap/Multiboot/Helper/GDT32.s index 5768dff..2509ccd 100644 --- a/Architecture/i386/Bootstrap/Multiboot/2/GDT32.s +++ b/Architecture/i386/Bootstrap/Multiboot/Helper/GDT32.s @@ -15,8 +15,6 @@ along with Fennix Kernel. If not, see . */ -.intel_syntax noprefix - .code32 .section .bootstrap.text, "a" @@ -48,19 +46,19 @@ GDT32: .word 0x4092 .byte 0x00 GDT32_END: + nop .global LoadGDT32 LoadGDT32: lgdt [gdtr] + ljmp $0x8, $ActivateGDT - jmp 0x8:ActivateGDT - ActivateGDT: - mov cx, 0x10 - mov ss, cx - mov ds, cx - mov es, cx - mov fs, cx - mov cx, 0x18 - mov gs, cx - +ActivateGDT: + mov $0x10, %cx + mov %cx, %ss + mov %cx, %ds + mov %cx, %es + mov %cx, %fs + mov $0x18, %cx + mov %cx, %gs ret diff --git a/Architecture/i386/Bootstrap/Multiboot/Multiboot.cpp b/Architecture/i386/Bootstrap/Multiboot/Multiboot.cpp new file mode 100644 index 0000000..fc67058 --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/Multiboot.cpp @@ -0,0 +1,53 @@ +/* + 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 . +*/ + +#include + +#include + +#include "../../../../kernel.h" + +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +void multiboot_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info); +void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info); + +EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info) +{ + BootInfo mb2binfo{}; + + if (Info == NULL || Magic == NULL) + { + if (Magic == NULL) + error("Multiboot magic is NULL"); + if (Info == NULL) + error("Multiboot info is NULL"); + CPU::Stop(); + } + else if (Magic == MULTIBOOT_BOOTLOADER_MAGIC) + multiboot_parse(mb2binfo, Magic, Info); + else if (Magic == MULTIBOOT2_BOOTLOADER_MAGIC) + multiboot2_parse(mb2binfo, Magic, Info); + else + { + error("Unknown multiboot magic %#x", Magic); + CPU::Stop(); + } +} diff --git a/Architecture/i386/Bootstrap/Multiboot/Multiboot1Parse.cpp b/Architecture/i386/Bootstrap/Multiboot/Multiboot1Parse.cpp new file mode 100644 index 0000000..02e8ded --- /dev/null +++ b/Architecture/i386/Bootstrap/Multiboot/Multiboot1Parse.cpp @@ -0,0 +1,210 @@ +/* + 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 . +*/ + +#include + +#include +#include + +#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 *)(uint32_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 += (__SIZE_TYPE__)entry.len; + switch (entry.type) + { + case MULTIBOOT_MEMORY_AVAILABLE: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)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 = (__SIZE_TYPE__)entry.len; + mb2binfo.Memory.Entry[i].Type = BadMemory; + break; + default: + mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; + mb2binfo.Memory.Entry[i].Length = (__SIZE_TYPE__)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 *)(uint32_t)((uint32_t)&_bootstrap_start + 0xC0000000); + mb2binfo.Kernel.Size = ((uint32_t)&_kernel_end - (uint32_t)&_kernel_start) + ((uint32_t)&_bootstrap_end - (uint32_t)&_bootstrap_start); + debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase); + + Entry(&mb2binfo); +} diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Multiboot.cpp b/Architecture/i386/Bootstrap/Multiboot/Multiboot2Parse.cpp similarity index 95% rename from Architecture/i386/Bootstrap/Multiboot/2/Multiboot.cpp rename to Architecture/i386/Bootstrap/Multiboot/Multiboot2Parse.cpp index da9d92a..1ae8ab8 100644 --- a/Architecture/i386/Bootstrap/Multiboot/2/Multiboot.cpp +++ b/Architecture/i386/Bootstrap/Multiboot/Multiboot2Parse.cpp @@ -19,10 +19,10 @@ #include -#include "multiboot2.h" -#include "../../../../../kernel.h" +#include +#include "../../../../kernel.h" -EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info) +void multiboot2_parse(BootInfo &mb2binfo, uintptr_t Magic, uintptr_t Info) { if (Info == NULL || Magic == NULL) { @@ -38,8 +38,6 @@ EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info) CPU::Stop(); } - BootInfo mb2binfo{}; - { auto InfoAddress = Info; for (auto Tag = (struct multiboot_tag *)((uint8_t *)InfoAddress + 8); @@ -74,7 +72,7 @@ EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info) { multiboot_tag_module *module = (multiboot_tag_module *)Tag; static int module_count = 0; - mb2binfo.Modules[module_count].Address = (void *)(uint64_t)module->mod_start; + mb2binfo.Modules[module_count].Address = (void *)(uint32_t)module->mod_start; mb2binfo.Modules[module_count].Size = module->mod_end - module->mod_start; strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6); strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline, @@ -283,9 +281,9 @@ EXTERNC void multiboot_main(uintptr_t Magic, uintptr_t Info) case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: { multiboot_tag_load_base_addr *load_base_addr = (multiboot_tag_load_base_addr *)Tag; - mb2binfo.Kernel.PhysicalBase = (void *)(uint64_t)load_base_addr->load_base_addr; - mb2binfo.Kernel.VirtualBase = (void *)(uint64_t)(load_base_addr->load_base_addr + 0xFFFFFFFF80000000); - mb2binfo.Kernel.Size = (size_t)(((uint64_t)&_kernel_end - (uint64_t)&_kernel_start) + ((uint64_t)&_bootstrap_end - (uint64_t)&_bootstrap_start)); + mb2binfo.Kernel.PhysicalBase = (void *)(uint32_t)load_base_addr->load_base_addr; + mb2binfo.Kernel.VirtualBase = (void *)(uint32_t)(load_base_addr->load_base_addr + 0xC0000000); + mb2binfo.Kernel.Size = (size_t)(((uint32_t)&_kernel_end - (uint32_t)&_kernel_start) + ((uint32_t)&_bootstrap_end - (uint32_t)&_bootstrap_start)); debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase); break; } diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.s b/Architecture/i386/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s similarity index 100% rename from Architecture/i386/Bootstrap/Multiboot/2/Multiboot_PageTable.s rename to Architecture/i386/Bootstrap/Multiboot/Paging/Multiboot_PageTable.s diff --git a/Architecture/i386/Bootstrap/Multiboot/2/Start.s b/Architecture/i386/Bootstrap/Multiboot/Start.s similarity index 97% rename from Architecture/i386/Bootstrap/Multiboot/2/Start.s rename to Architecture/i386/Bootstrap/Multiboot/Start.s index 7144130..a21aae4 100644 --- a/Architecture/i386/Bootstrap/Multiboot/2/Start.s +++ b/Architecture/i386/Bootstrap/Multiboot/Start.s @@ -33,8 +33,8 @@ MB_HeaderInfo: .section .bootstrap.text, "a" -.global Multiboot2_start -Multiboot2_start: +.global Multiboot_start +Multiboot_start: cli mov %eax, [MB_HeaderMagic] diff --git a/Architecture/i386/Bootstrap/Multiboot/_start.s b/Architecture/i386/Bootstrap/Multiboot/_start.s index 830391e..5e9efa9 100644 --- a/Architecture/i386/Bootstrap/Multiboot/_start.s +++ b/Architecture/i386/Bootstrap/Multiboot/_start.s @@ -15,26 +15,24 @@ along with Fennix Kernel. If not, see . */ -.intel_syntax noprefix - -.extern Multiboot1_start -.extern Multiboot2_start - .code32 +.extern Multiboot_start + .section .bootstrap.text, "a" .global _start _start: - cmp eax, 0x36D76289 - je .Multiboot2 - cmp eax, 0x1BADB002 - je .Multiboot1 - int3 + /* Check for multiboot */ + cmp $0x2BADB002, %eax + je .Multiboot -.Multiboot1: - call Multiboot1_start - jmp . + /* Unkown bootloader */ + .Hang: + cli + hlt + jmp .Hang -.Multiboot2: - call Multiboot2_start - jmp . + /* Multiboot */ + .Multiboot: + call Multiboot_start + jmp .Hang diff --git a/Core/AdvancedConfigurationAndPowerInterface.cpp b/Core/AdvancedConfigurationAndPowerInterface.cpp index 11da60d..5f5cf6e 100644 --- a/Core/AdvancedConfigurationAndPowerInterface.cpp +++ b/Core/AdvancedConfigurationAndPowerInterface.cpp @@ -130,6 +130,12 @@ namespace ACPI ACPI::ACPI() { trace("Initializing ACPI"); + if (!bInfo.RSDP) + { + error("RSDP not found!"); + return; + } + if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress) { debug("XSDT supported"); diff --git a/Core/Memory/PhysicalMemoryManager.cpp b/Core/Memory/PhysicalMemoryManager.cpp index acda70e..e95f84f 100644 --- a/Core/Memory/PhysicalMemoryManager.cpp +++ b/Core/Memory/PhysicalMemoryManager.cpp @@ -188,7 +188,6 @@ namespace Memory if (PageBitmapIndex > Index) PageBitmapIndex = Index; } - } void Physical::FreePages(void *Address, size_t Count) diff --git a/Core/Memory/ReserveEssentials.cpp b/Core/Memory/ReserveEssentials.cpp index 1fc12ae..5813147 100644 --- a/Core/Memory/ReserveEssentials.cpp +++ b/Core/Memory/ReserveEssentials.cpp @@ -141,63 +141,65 @@ namespace Memory } #if defined(a86) - debug("Reserving RSDT region %#lx-%#lx...", bInfo.RSDP, - (void *)((uintptr_t)bInfo.RSDP + sizeof(BootInfo::RSDPInfo))); - - this->ReservePages(bInfo.RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo))); - - ACPI::ACPI::ACPIHeader *ACPIPtr = nullptr; - bool XSDT = false; - - if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress) + if (bInfo.RSDP) { - ACPIPtr = (ACPI::ACPI::ACPIHeader *)(bInfo.RSDP->XSDTAddress); - XSDT = true; - } - else - ACPIPtr = (ACPI::ACPI::ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress; + debug("Reserving RSDT region %#lx-%#lx...", bInfo.RSDP, + (void *)((uintptr_t)bInfo.RSDP + sizeof(BootInfo::RSDPInfo))); - debug("Reserving RSDT..."); - this->ReservePages((void *)bInfo.RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo))); + this->ReservePages(bInfo.RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo))); + + ACPI::ACPI::ACPIHeader *ACPIPtr = nullptr; + bool XSDT = false; + + if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress) + { + ACPIPtr = (ACPI::ACPI::ACPIHeader *)(bInfo.RSDP->XSDTAddress); + XSDT = true; + } + else + ACPIPtr = (ACPI::ACPI::ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress; + + debug("Reserving RSDT..."); + this->ReservePages((void *)bInfo.RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo))); #if defined(a64) - if ((uintptr_t)ACPIPtr > 0x7FE00000) /* FIXME */ - { - error("ACPI table is located above 0x7FE00000, which is not mapped."); - return; - } + if ((uintptr_t)ACPIPtr > 0x7FE00000) /* FIXME */ + { + error("ACPI table is located above 0x7FE00000, which is not mapped."); + return; + } #elif defined(a32) - if ((uintptr_t)ACPIPtr > 0x2800000) /* FIXME */ - { - error("ACPI table is located above 0x2800000, which is not mapped."); - return; - } + if ((uintptr_t)ACPIPtr > 0x2800000) /* FIXME */ + { + error("ACPI table is located above 0x2800000, which is not mapped."); + return; + } #endif - size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / - (XSDT ? 8 : 4)); - debug("Reserving %d ACPI tables...", TableSize); + size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / + (XSDT ? 8 : 4)); + debug("Reserving %d ACPI tables...", TableSize); - for (size_t t = 0; t < TableSize; t++) - { + for (size_t t = 0; t < TableSize; t++) + { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" - // TODO: Should I be concerned about unaligned memory access? - ACPI::ACPI::ACPIHeader *SDTHdr = nullptr; - if (XSDT) - SDTHdr = - (ACPI::ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIPtr + - sizeof(ACPI::ACPI::ACPIHeader) + - (t * 8))); - else - SDTHdr = - (ACPI::ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)ACPIPtr + - sizeof(ACPI::ACPI::ACPIHeader) + - (t * 4))); + // TODO: Should I be concerned about unaligned memory access? + ACPI::ACPI::ACPIHeader *SDTHdr = nullptr; + if (XSDT) + SDTHdr = + (ACPI::ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIPtr + + sizeof(ACPI::ACPI::ACPIHeader) + + (t * 8))); + else + SDTHdr = + (ACPI::ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)ACPIPtr + + sizeof(ACPI::ACPI::ACPIHeader) + + (t * 4))); #pragma GCC diagnostic pop - this->ReservePages(SDTHdr, TO_PAGES(SDTHdr->Length)); + this->ReservePages(SDTHdr, TO_PAGES(SDTHdr->Length)); + } } - #elif defined(aa64) #endif } diff --git a/Core/PeripheralComponentInterconnect.cpp b/Core/PeripheralComponentInterconnect.cpp index 89bb7ab..f1a342a 100644 --- a/Core/PeripheralComponentInterconnect.cpp +++ b/Core/PeripheralComponentInterconnect.cpp @@ -952,6 +952,18 @@ namespace PCI PCI::PCI() { #if defined(a86) + if (!PowerManager->GetACPI()) + { + error("ACPI not found"); + return; + } + + if (!((ACPI::ACPI *)PowerManager->GetACPI())->MCFG) + { + error("MCFG not found"); + return; + } + int Entries = s_cst(int, ((((ACPI::ACPI *)PowerManager->GetACPI())->MCFG->Header.Length) - sizeof(ACPI::ACPI::MCFGHeader)) / sizeof(DeviceConfig)); Memory::Virtual vmm = Memory::Virtual(KernelPageTable); for (int t = 0; t < Entries; t++) diff --git a/Makefile b/Makefile index d68c625..f15df7e 100644 --- a/Makefile +++ b/Makefile @@ -107,7 +107,7 @@ ifneq ($(OSARCH), aarch64) CFLAGS += -fstack-check endif LDFLAGS += -ggdb3 -O0 - ASFLAGS += -g --gstabs --gdwarf-5 -D + ASFLAGS += -g --gstabs+ --gdwarf-5 -D WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable endif diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 6b4b216..12e745e 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -388,17 +388,20 @@ namespace Tasking } debug("Tasking Started"); #if defined(a64) - ((APIC::Timer *)Interrupts::apicTimer[0])->OneShot(CPU::x86::IRQ16, 100); + if (Interrupts::apicTimer[0]) + { + ((APIC::Timer *)Interrupts::apicTimer[0])->OneShot(CPU::x86::IRQ16, 100); - /* FIXME: The kernel is not ready for multi-core tasking. */ - // for (int i = 1; i < SMP::CPUCores; i++) - // { - // ((APIC::Timer *)Interrupts::apicTimer[i])->OneShot(CPU::x86::IRQ16, 100); - // APIC::InterruptCommandRegisterLow icr; - // icr.Vector = CPU::x86::IRQ16; - // icr.Level = APIC::APICLevel::Assert; - // ((APIC::APIC *)Interrupts::apic[0])->IPI(i, icr); - // } + /* FIXME: The kernel is not ready for multi-core tasking. */ + // for (int i = 1; i < SMP::CPUCores; i++) + // { + // ((APIC::Timer *)Interrupts::apicTimer[i])->OneShot(CPU::x86::IRQ16, 100); + // APIC::InterruptCommandRegisterLow icr; + // icr.Vector = CPU::x86::IRQ16; + // icr.Level = APIC::APICLevel::Assert; + // ((APIC::APIC *)Interrupts::apic[0])->IPI(i, icr); + // } + } #elif defined(a32) #elif defined(aa64) #endif diff --git a/Architecture/amd64/Bootstrap/Multiboot/1/multiboot.h b/include/boot/protocol/multiboot.h similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/1/multiboot.h rename to include/boot/protocol/multiboot.h diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/multiboot2.h b/include/boot/protocol/multiboot2.h similarity index 100% rename from Architecture/amd64/Bootstrap/Multiboot/2/multiboot2.h rename to include/boot/protocol/multiboot2.h