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