From b68c8c18a5823bfcc3f4849a8e748ceee4c541ed Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 9 May 2023 04:57:17 +0300 Subject: [PATCH] Implement mb2 stub support --- Architecture/aarch64/runtime/crt0.S | 17 - Architecture/aarch64/runtime/crt1.S | 17 - Architecture/aarch64/runtime/crtbegin.c | 1 - Architecture/aarch64/runtime/crtend.c | 1 - Architecture/aarch64/runtime/crti.S | 13 - Architecture/aarch64/runtime/crtn.S | 7 - Architecture/amd64/Bootstrap/Limine/Limine.c | 4 +- .../amd64/Bootstrap/Multiboot/1/Header.asm | 7 - .../amd64/Bootstrap/Multiboot/1/Header.s | 27 ++ .../amd64/Bootstrap/Multiboot/1/Start.asm | 22 + .../amd64/Bootstrap/Multiboot/2/Detect.s | 81 ++++ .../amd64/Bootstrap/Multiboot/2/GDT32.s | 66 +++ .../amd64/Bootstrap/Multiboot/2/GDT64.s | 63 +++ .../amd64/Bootstrap/Multiboot/2/Header.asm | 74 ---- .../amd64/Bootstrap/Multiboot/2/Header.s | 93 ++++ .../amd64/Bootstrap/Multiboot/2/Multiboot.cpp | 313 +++++++++++++ .../Multiboot/2/Multiboot64bitMap.cpp | 301 +++++++++++++ .../Multiboot/2/Multiboot_PageTable.asm | 61 +++ .../Multiboot/2/Multiboot_PageTable.s_fixme | 67 +++ .../amd64/Bootstrap/Multiboot/2/Start.asm | 108 ++++- .../amd64/Bootstrap/Multiboot/2/Start.s_fixme | 117 +++++ .../amd64/Bootstrap/Multiboot/_start.s | 40 ++ Architecture/amd64/runtime/crt0.c | 15 - Architecture/amd64/runtime/crt1.c | 15 - Architecture/amd64/runtime/crtbegin.c | 1 - Architecture/amd64/runtime/crtend.c | 1 - Architecture/amd64/runtime/crti.S | 13 - Architecture/amd64/runtime/crtn.S | 7 - Kernel.cpp | 16 +- KernelThread.cpp | 8 + Makefile | 11 +- Tests/TestSyscalls.c | 5 +- include/boot/protocols/multiboot2.h | 417 ------------------ include/task.hpp | 2 +- 34 files changed, 1397 insertions(+), 614 deletions(-) delete mode 100644 Architecture/aarch64/runtime/crt0.S delete mode 100644 Architecture/aarch64/runtime/crt1.S delete mode 100644 Architecture/aarch64/runtime/crtbegin.c delete mode 100644 Architecture/aarch64/runtime/crtend.c delete mode 100644 Architecture/aarch64/runtime/crti.S delete mode 100644 Architecture/aarch64/runtime/crtn.S delete mode 100644 Architecture/amd64/Bootstrap/Multiboot/1/Header.asm create mode 100644 Architecture/amd64/Bootstrap/Multiboot/1/Header.s create mode 100644 Architecture/amd64/Bootstrap/Multiboot/1/Start.asm create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Detect.s create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/GDT32.s create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/GDT64.s delete mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Header.asm create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Header.s create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Multiboot64bitMap.cpp create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.asm create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.s_fixme create mode 100644 Architecture/amd64/Bootstrap/Multiboot/2/Start.s_fixme create mode 100644 Architecture/amd64/Bootstrap/Multiboot/_start.s delete mode 100644 Architecture/amd64/runtime/crt0.c delete mode 100644 Architecture/amd64/runtime/crt1.c delete mode 100644 Architecture/amd64/runtime/crtbegin.c delete mode 100644 Architecture/amd64/runtime/crtend.c delete mode 100644 Architecture/amd64/runtime/crti.S delete mode 100644 Architecture/amd64/runtime/crtn.S delete mode 100644 include/boot/protocols/multiboot2.h diff --git a/Architecture/aarch64/runtime/crt0.S b/Architecture/aarch64/runtime/crt0.S deleted file mode 100644 index ec4b0f0..0000000 --- a/Architecture/aarch64/runtime/crt0.S +++ /dev/null @@ -1,17 +0,0 @@ -// .section ".text.boot" -// -// .global _start -// .org 0x80000 -// _start: -// ldr x5, =_start -// mov sp, x5 -// ldr x5, =_kernel_rodata_end -// ldr w6, =_bss_size -// 1: cbz w6, 2f -// str xzr, [x5], #8 -// sub w6, w6, #1 -// cbnz w6, 1b -// 2: bl arm64Entry -// Halt: -// wfe -// b Halt diff --git a/Architecture/aarch64/runtime/crt1.S b/Architecture/aarch64/runtime/crt1.S deleted file mode 100644 index d25abc9..0000000 --- a/Architecture/aarch64/runtime/crt1.S +++ /dev/null @@ -1,17 +0,0 @@ -// .section ".text.boot" - -// .global _start -// .org 0x80000 -// _start: -// ldr x5, =_start -// mov sp, x5 -// ldr x5, =_kernel_rodata_end -// ldr w6, =_bss_size -// 1: cbz w6, 2f -// str xzr, [x5], #8 -// sub w6, w6, #1 -// cbnz w6, 1b -// 2: bl arm64Entry -// Halt: -// wfe -// b Halt diff --git a/Architecture/aarch64/runtime/crtbegin.c b/Architecture/aarch64/runtime/crtbegin.c deleted file mode 100644 index 507125b..0000000 --- a/Architecture/aarch64/runtime/crtbegin.c +++ /dev/null @@ -1 +0,0 @@ -// C++ constructor/destructor stuff \ No newline at end of file diff --git a/Architecture/aarch64/runtime/crtend.c b/Architecture/aarch64/runtime/crtend.c deleted file mode 100644 index 507125b..0000000 --- a/Architecture/aarch64/runtime/crtend.c +++ /dev/null @@ -1 +0,0 @@ -// C++ constructor/destructor stuff \ No newline at end of file diff --git a/Architecture/aarch64/runtime/crti.S b/Architecture/aarch64/runtime/crti.S deleted file mode 100644 index d3886db..0000000 --- a/Architecture/aarch64/runtime/crti.S +++ /dev/null @@ -1,13 +0,0 @@ -// .section .init -// .global _init -// .type _init, @function -// _init: -// push %rbp -// movq %rsp, %rbp - -// .section .fini -// .global _fini -// .type _fini, @function -// _fini: -// push %rbp -// movq %rsp, %rbp diff --git a/Architecture/aarch64/runtime/crtn.S b/Architecture/aarch64/runtime/crtn.S deleted file mode 100644 index 21c198b..0000000 --- a/Architecture/aarch64/runtime/crtn.S +++ /dev/null @@ -1,7 +0,0 @@ -.section .init -// popq %rbp - ret - -.section .fini -// popq %rbp - ret diff --git a/Architecture/amd64/Bootstrap/Limine/Limine.c b/Architecture/amd64/Bootstrap/Limine/Limine.c index eceb740..f5f6c5d 100644 --- a/Architecture/amd64/Bootstrap/Limine/Limine.c +++ b/Architecture/amd64/Bootstrap/Limine/Limine.c @@ -20,8 +20,8 @@ #include #include -#include "../../../../tools/limine/limine.h" -#include "../../../kernel.h" +#include "../../../../../tools/limine/limine.h" +#include "../../../../kernel.h" void InitLimine(); diff --git a/Architecture/amd64/Bootstrap/Multiboot/1/Header.asm b/Architecture/amd64/Bootstrap/Multiboot/1/Header.asm deleted file mode 100644 index 4fd7789..0000000 --- a/Architecture/amd64/Bootstrap/Multiboot/1/Header.asm +++ /dev/null @@ -1,7 +0,0 @@ -section .multiboot -align 4 - dd 0x1BADB002 - dd 1 << 0 | 1 << 1 - dd -(0x1BADB002 + (1 << 0 | 1 << 1)) - -; TODO diff --git a/Architecture/amd64/Bootstrap/Multiboot/1/Header.s b/Architecture/amd64/Bootstrap/Multiboot/1/Header.s new file mode 100644 index 0000000..81fce85 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/1/Header.s @@ -0,0 +1,27 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.code32 +.section .multiboot +.align 4 + +MULTIBOOT_HEADER: + .long 0x1BADB002 + .long 1 << 0 | 1 << 1 + .long -(0x1BADB002 + (1 << 0 | 1 << 1)) diff --git a/Architecture/amd64/Bootstrap/Multiboot/1/Start.asm b/Architecture/amd64/Bootstrap/Multiboot/1/Start.asm new file mode 100644 index 0000000..49bc2c2 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/1/Start.asm @@ -0,0 +1,22 @@ +; 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 . + +[bits 32] + +section .bootstrap.text + +global Multiboot1_start +Multiboot1_start: + int3 diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Detect.s b/Architecture/amd64/Bootstrap/Multiboot/2/Detect.s new file mode 100644 index 0000000..319d180 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Detect.s @@ -0,0 +1,81 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.code32 +.section .bootstrap.text + +.global DetectCPUID +DetectCPUID: + pushfd + pop eax + mov ecx, eax + xor eax, 1 << 21 + push eax + popfd + pushfd + pop eax + push ecx + popfd + xor eax, ecx + jz .NoCPUID + mov eax, 1 + ret +.NoCPUID: + xor eax, eax + ret + +.global Detect64Bit +Detect64Bit: + mov eax, 0x80000000 + cpuid + cmp eax, 0x80000001 + jb .NoLongMode + mov eax, 0x80000001 + cpuid + test edx, 1 << 29 + jz .NoLongMode + mov eax, 1 + ret +.NoLongMode: + xor eax, eax + ret + +.global DetectPSE +DetectPSE: + mov eax, 0x00000001 + cpuid + test edx, 0x00000008 + jz .NoPSE + mov eax, 1 + ret +.NoPSE: + xor eax, eax + ret + +.global DetectPAE +DetectPAE: + mov eax, 0x00000001 + cpuid + test edx, 0x00000040 + jz .NoPAE + mov eax, 1 + ret +.NoPAE: + xor eax, eax + ret diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/GDT32.s b/Architecture/amd64/Bootstrap/Multiboot/2/GDT32.s new file mode 100644 index 0000000..30974ac --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/GDT32.s @@ -0,0 +1,66 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.code32 +.section .bootstrap.text + +.align 32 +.global gdtr +gdtr: + .word GDT32_END - GDT32 - 1 + .long GDT32 + +.align 32 +GDT32: + .quad 0x0 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF9A + .byte 0x00 + + .word 0xFFFF + .word 0x0000 + .byte 0x00 + .word 0xCF92 + .byte 0x00 + + .word 0x0100 + .word 0x1000 + .byte 0x00 + .word 0x4092 + .byte 0x00 +GDT32_END: + +.global LoadGDT32 +LoadGDT32: + lgdt [gdtr] + + 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 + + ret diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/GDT64.s b/Architecture/amd64/Bootstrap/Multiboot/2/GDT64.s new file mode 100644 index 0000000..d655c4e --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/GDT64.s @@ -0,0 +1,63 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.code64 +.section .bootstrap.data + +/* Access bits */ +.equ A, 1 << 0 +.equ RW, 1 << 1 +.equ DC, 1 << 2 +.equ E, 1 << 3 +.equ S, 1 << 4 +.equ DPL0, 0 << 5 +.equ DPL1, 1 << 5 +.equ P, 1 << 7 + +/* Flags bits */ +.equ LONG_MODE, 1 << 5 +.equ SZ_32, 1 << 6 +.equ GRAN_4K, 1 << 7 + +.global GDT64.Null +.global GDT64.Code +.global GDT64.Data +.global GDT64.Tss +.global GDT64.Ptr +GDT64: +.equ GDT64.Null, $ - GDT64 + .quad 0 +.equ GDT64.Code, $ - GDT64 + .long 0xFFFF + .byte 0 + .byte P | S | E | RW + .byte GRAN_4K | LONG_MODE | 0xF + .byte 0 +.equ GDT64.Data, $ - GDT64 + .long 0xFFFF + .byte 0 + .byte P | S | RW + .byte GRAN_4K | SZ_32 | 0xF + .byte 0 +.equ GDT64.Tss, $ - GDT64 + .long 0x00000068 + .long 0x00CF8900 +GDT64.Ptr: + .word $ - GDT64 - 1 + .quad GDT64 diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Header.asm b/Architecture/amd64/Bootstrap/Multiboot/2/Header.asm deleted file mode 100644 index 1a10732..0000000 --- a/Architecture/amd64/Bootstrap/Multiboot/2/Header.asm +++ /dev/null @@ -1,74 +0,0 @@ -[bits 32] -extern Multiboot2_start - -; https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html -section .multiboot2 -align 4096 -MULTIBOOT2_HEADER_START: - dd 0xE85250D6 - dd 0 - dd (MULTIBOOT2_HEADER_END - MULTIBOOT2_HEADER_START) - dd 0x100000000 - (MULTIBOOT2_HEADER_END - MULTIBOOT2_HEADER_START) - 0 - 0xE85250D6 -align 8 -InfoRequestTag_Start: - dw 1 - dw 0 - dd InfoRequestTag_End - InfoRequestTag_Start - dd 1 ; Command Line - dd 2 ; Boot Loader Name - dd 3 ; Module - dd 4 ; Basic Memory Information - dd 5 ; BIOS Boot Device - dd 6 ; Memory Map - dd 7 ; VBE - dd 8 ; Framebuffer - dd 9 ; ELF Sections - dd 10 ; APM Table - dd 11 ; EFI 32-bit System Table Pointer - dd 12 ; EFI 64-bit System Table Pointer - ; dd 13 ; SMBIOS - dd 14 ; ACPI Old - dd 15 ; ACPI New - dd 16 ; Network - dd 17 ; EFI Memory Map - dd 18 ; EFI Boot Services Notifier - dd 19 ; EFI 32-bit Image Handle Pointer - dd 20 ; EFI 64-bit Image Handle Pointer - dd 21 ; Load Base Address -InfoRequestTag_End: -align 8 -FramebufferTag_Start: - dw 5 - dw 1 - dd FramebufferTag_End - FramebufferTag_Start - dd 0 - dd 0 - dd 32 -FramebufferTag_End: -align 8 -EGATextSupportTag_Start: - dw 4 - dw 0 - dd EGATextSupportTag_End - EGATextSupportTag_Start - dd 1 ; https://www.gnu.org/software/grub/manual/multiboot2/html_node/Console-header-tags.html -EGATextSupportTag_End: -align 8 -AlignedModulesTag_Start: - dw 6 - dw 0 - dd AlignedModulesTag_End - AlignedModulesTag_Start -AlignedModulesTag_End: -align 8 -EntryAddressTag_Start: - dw 9 - dw 0 - dd EntryAddressTag_End - EntryAddressTag_Start - dd Multiboot2_start -EntryAddressTag_End: -align 8 -EndTag_Start: - dw 0 - dw 0 - dd EndTag_End - EndTag_Start -EndTag_End: -MULTIBOOT2_HEADER_END: diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Header.s b/Architecture/amd64/Bootstrap/Multiboot/2/Header.s new file mode 100644 index 0000000..543bc2a --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Header.s @@ -0,0 +1,93 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.code32 +.extern Multiboot2_start + +/* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */ +.section .multiboot2 +.align 0x1000 +MULTIBOOT2_HEADER_START: + .long 0xE85250D6 + .long 0 + .long (MULTIBOOT2_HEADER_END - MULTIBOOT2_HEADER_START) + .long 0x100000000 - (MULTIBOOT2_HEADER_END - MULTIBOOT2_HEADER_START) - 0 - 0xE85250D6 +.align 8 +InfoRequestTag_Start: + .word 1 + .word 0 + .long InfoRequestTag_End - InfoRequestTag_Start + .long 1 /* Command Line */ + .long 2 /* Boot Loader Name */ + .long 3 /* Module */ + .long 4 /* Basic Memory Information */ + .long 5 /* BIOS Boot Device */ + .long 6 /* Memory Map */ + .long 7 /* VBE */ + .long 8 /* Framebuffer */ + .long 9 /* ELF Sections */ + .long 10 /* APM Table */ + .long 11 /* EFI 32-bit System Table Pointer */ + .long 12 /* EFI 64-bit System Table Pointer */ + /* .long 13 */ /* SMBIOS */ + .long 14 /* ACPI Old */ + .long 15 /* ACPI New */ + .long 16 /* Network */ + .long 17 /* EFI Memory Map */ + .long 18 /* EFI Boot Services Notifier */ + .long 19 /* EFI 32-bit Image Handle Pointer */ + .long 20 /* EFI 64-bit Image Handle Pointer */ + .long 21 /* Load Base Address */ +InfoRequestTag_End: +.align 8 +FramebufferTag_Start: + .word 5 + .word 1 + .long FramebufferTag_End - FramebufferTag_Start + .long 0 + .long 0 + .long 32 +FramebufferTag_End: +.align 8 +EGATextSupportTag_Start: + .word 4 + .word 0 + .long EGATextSupportTag_End - EGATextSupportTag_Start + .long 1 /* https://www.gnu.org/software/grub/manual/multiboot2/html_node/Console-header-tags.html */ +EGATextSupportTag_End: +.align 8 +AlignedModulesTag_Start: + .word 6 + .word 0 + .long AlignedModulesTag_End - AlignedModulesTag_Start +AlignedModulesTag_End: +.align 8 +EntryAddressTag_Start: + .word 3 + .word 0 + .long EntryAddressTag_End - EntryAddressTag_Start + .long Multiboot2_start +EntryAddressTag_End: +.align 8 +EndTag_Start: + .word 0 + .word 0 + .long EndTag_End - EndTag_Start +EndTag_End: +MULTIBOOT2_HEADER_END: diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp new file mode 100644 index 0000000..8167f5f --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot.cpp @@ -0,0 +1,313 @@ +/* + 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 "multiboot2.h" +#include "../../../../../kernel.h" + +EXTERNC void multiboot_main(uint64_t Magic, uint64_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{}; + + { + uint64_t div = 1193180 / 1000; + outb(0x43, 0xB6); + outb(0x42, (uint8_t)div); + outb(0x42, (uint8_t)(div >> 8)); + uint8_t tmp = inb(0x61); + if (tmp != (tmp | 3)) + outb(0x61, tmp | 3); + + int pos = 0; + 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->size; + 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 (EntryCount > 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: %lld\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; + fixme("elf_sections->[num=%d, size=%d, entsize=%d, shndx=%d]", + elf->num, elf->size, elf->entsize, elf->shndx); + 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; + } + } + } + + tmp = inb(0x61) & 0xFC; + outb(0x61, tmp); + } + + Entry(&mb2binfo); +} diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot64bitMap.cpp b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot64bitMap.cpp new file mode 100644 index 0000000..cd5b294 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot64bitMap.cpp @@ -0,0 +1,301 @@ +/* + 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 + +union __attribute__((packed)) PageTableEntry +{ + struct + { + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Dirty : 1; // 6 + bool PageAttributeTable : 1; // 7 + bool Global : 1; // 8 + uint8_t Available0 : 3; // 9-11 + uint64_t Address : 40; // 12-51 + uint32_t Available1 : 7; // 52-58 + uint8_t ProtectionKey : 4; // 59-62 + bool ExecuteDisable : 1; // 63 + }; + uint64_t raw; + + __always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address) + { + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); + } + + __always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; } +}; + +struct __attribute__((packed)) PageTableEntryPtr +{ + PageTableEntry Entries[512]; +}; + +union __attribute__((packed)) PageDirectoryEntry +{ + struct + { + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Available0 : 1; // 6 + bool PageSize : 1; // 7 + uint8_t Available1 : 4; // 8-11 + uint64_t Address : 40; // 12-51 + uint32_t Available2 : 11; // 52-62 + bool ExecuteDisable : 1; // 63 + }; + uint64_t raw; + + __always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address) + { + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); + } + + __always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; } +}; + +struct __attribute__((packed)) PageDirectoryEntryPtr +{ + PageDirectoryEntry Entries[512]; +}; + +union __attribute__((packed)) PageDirectoryPointerTableEntry +{ + struct + { + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Available0 : 1; // 6 + bool PageSize : 1; // 7 + uint8_t Available1 : 4; // 8-11 + uint64_t Address : 40; // 12-51 + uint32_t Available2 : 11; // 52-62 + bool ExecuteDisable : 1; // 63 + }; + uint64_t raw; + + __always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address) + { + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); + } + + __always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; } +}; + +struct __attribute__((packed)) PageDirectoryPointerTableEntryPtr +{ + PageDirectoryPointerTableEntry Entries[512]; +}; + +union __attribute__((packed)) PageMapLevel4 +{ + struct + { + bool Present : 1; // 0 + bool ReadWrite : 1; // 1 + bool UserSupervisor : 1; // 2 + bool WriteThrough : 1; // 3 + bool CacheDisable : 1; // 4 + bool Accessed : 1; // 5 + bool Available0 : 1; // 6 + bool Reserved0 : 1; // 7 + uint8_t Available1 : 4; // 8-11 + uint64_t Address : 40; // 12-51 + uint32_t Available2 : 11; // 52-62 + bool ExecuteDisable : 1; // 63 + }; + uint64_t raw; + + __always_inline inline SafeFunction NIF void SetAddress(uintptr_t _Address) + { + _Address &= 0x000000FFFFFFFFFF; + this->raw &= 0xFFF0000000000FFF; + this->raw |= (_Address << 12); + } + + __always_inline inline SafeFunction NIF uintptr_t GetAddress() { return (this->raw & 0x000FFFFFFFFFF000) >> 12; } +}; + +struct PageTable4 +{ + PageMapLevel4 Entries[512]; +} __attribute__((aligned(0x1000))); + +extern "C" char BootPageTable[]; +extern uintptr_t _kernel_start, _kernel_end; + +__attribute__((section(".bootstrap.data"))) static PageTable4 *BPTable = (PageTable4 *)BootPageTable; +__attribute__((section(".bootstrap.data"))) static size_t BPT_Allocated = 0x4000; + +__always_inline inline SafeFunction NIF void *RequestPage() +{ + void *Page = (void *)(BootPageTable + BPT_Allocated); + BPT_Allocated += 0x1000; + if (BPT_Allocated >= 0x10000) /* The length of BootPageTable */ + { + while (true) + ; + } + return Page; +} + +class PageMapIndexer +{ +public: + uintptr_t PMLIndex = 0; + uintptr_t PDPTEIndex = 0; + uintptr_t PDEIndex = 0; + uintptr_t PTEIndex = 0; + __always_inline inline SafeFunction NIF PageMapIndexer(uintptr_t VirtualAddress) + { + uintptr_t Address = VirtualAddress; + Address >>= 12; + this->PTEIndex = Address & 0x1FF; + Address >>= 9; + this->PDEIndex = Address & 0x1FF; + Address >>= 9; + this->PDPTEIndex = Address & 0x1FF; + Address >>= 9; + this->PMLIndex = Address & 0x1FF; + } +}; + +__attribute__((section(".bootstrap.text"))) SafeFunction NIF void MB2_64_Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags) +{ + PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress); + // Clear any flags that are not 1 << 0 (Present) - 1 << 5 (Accessed) because rest are for page table entries only + uint64_t DirectoryFlags = Flags & 0x3F; + + PageMapLevel4 PML4 = BPTable->Entries[Index.PMLIndex]; + PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr; + if (!PML4.Present) + { + PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)RequestPage(); + if (PDPTEPtr == nullptr) + return; + { + void *ptr = PDPTEPtr; + uint8_t value = 0; + size_t num = 0x1000; + uint8_t *p = (uint8_t *)ptr; + for (size_t i = 0; i < num; i++) + p[i] = value; + } + PML4.Present = true; + PML4.SetAddress((uintptr_t)PDPTEPtr >> 12); + } + else + PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12); + PML4.raw |= DirectoryFlags; + BPTable->Entries[Index.PMLIndex] = PML4; + + PageDirectoryPointerTableEntry PDPTE = PDPTEPtr->Entries[Index.PDPTEIndex]; + PageDirectoryEntryPtr *PDEPtr = nullptr; + if (!PDPTE.Present) + { + PDEPtr = (PageDirectoryEntryPtr *)RequestPage(); + if (PDEPtr == nullptr) + return; + { + void *ptr = PDEPtr; + uint8_t value = 0; + size_t num = 0x1000; + uint8_t *p = (uint8_t *)ptr; + for (size_t i = 0; i < num; i++) + p[i] = value; + } + PDPTE.Present = true; + PDPTE.SetAddress((uintptr_t)PDEPtr >> 12); + } + else + PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE.GetAddress() << 12); + PDPTE.raw |= DirectoryFlags; + PDPTEPtr->Entries[Index.PDPTEIndex] = PDPTE; + + PageDirectoryEntry PDE = PDEPtr->Entries[Index.PDEIndex]; + PageTableEntryPtr *PTEPtr = nullptr; + if (!PDE.Present) + { + PTEPtr = (PageTableEntryPtr *)RequestPage(); + if (PTEPtr == nullptr) + return; + { + void *ptr = PTEPtr; + uint8_t value = 0; + size_t num = 0x1000; + uint8_t *p = (uint8_t *)ptr; + for (size_t i = 0; i < num; i++) + p[i] = value; + } + PDE.Present = true; + PDE.SetAddress((uintptr_t)PTEPtr >> 12); + } + else + PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE.GetAddress() << 12); + PDE.raw |= DirectoryFlags; + PDEPtr->Entries[Index.PDEIndex] = PDE; + + PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex]; + PTE.Present = true; + PTE.raw |= Flags; + PTE.SetAddress((uintptr_t)PhysicalAddress >> 12); + PTEPtr->Entries[Index.PTEIndex] = PTE; + asmv("invlpg (%0)" + : + : "r"(VirtualAddress) + : "memory"); +} + +EXTERNC __attribute__((section(".bootstrap.text"))) SafeFunction NIF __attribute__((section(".bootstrap.text"))) void UpdatePageTable64() +{ + BPTable = (PageTable4 *)BootPageTable; + + uintptr_t KernelStart = (uintptr_t)&_kernel_start; + uintptr_t KernelEnd = (uintptr_t)&_kernel_end; + uintptr_t PhysicalStart = KernelStart - 0xFFFFFFFF80000000; + for (uintptr_t i = KernelStart; i < KernelEnd; i += 0x1000) + { + MB2_64_Map((void *)i, (void *)PhysicalStart, 0x3); + PhysicalStart += 0x1000; + } + + asmv("mov %%cr3, %%rax\n" + "mov %%rax, %%cr3\n" + : + : + : "rax"); +} diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.asm b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.asm new file mode 100644 index 0000000..179233d --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.asm @@ -0,0 +1,61 @@ +; 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 . + +[bits 32] + +PAGE_TABLE_SIZE equ 0x4 + +section .bootstrap.data +align 0x1000 +global BootPageTable +BootPageTable: + times (0x10000) dq 0 ; 0x4000 bytes will be used in UpdatePageTable + +section .bootstrap.text +global UpdatePageTable +UpdatePageTable: + mov edi, (BootPageTable + 0x0000) ; First PML4E + mov eax, (BootPageTable + 0x1000) ; First PDPTE + or eax, 11b ; Bitwise OR on rax (PDPTE) with 11b (Present, Write) + mov dword [edi], eax ; Write 11b to PML4E + + mov edi, (BootPageTable + 0x1000) ; First PDPTE + mov eax, (BootPageTable + 0x2000) ; First PDE + or eax, 11b ; Bitwise OR on rax (PDE) with 11b (Present, Write) + + mov ecx, PAGE_TABLE_SIZE ; For loop instruction + mov ebx, 0x0 ; Value to store in the next 4 bytes + .FillPageTableLevel3: + mov dword [edi], eax ; Store modified PDE in PDPTE + mov dword [edi + 4], ebx ; Store the rbx value in the next 4 bytes + add eax, 0x1000 ; Increment (page size) + adc ebx, 0 ; Add 0 to carry flag + add edi, 8 ; Add 8 to rdi (next PDE) + loop .FillPageTableLevel3 ; Loop until rcx is 0 + + mov edi, (BootPageTable + 0x2000) ; First PDE + mov eax, 10000011b ; Present, Write, Large Page + + mov ecx, (512 * PAGE_TABLE_SIZE) ; For loop instruction + mov ebx, 0x0 ; Value to store in the next 4 bytes + .FillPageTableLevel2: + mov dword [edi], eax ; Store modified PDE in PDPTE + mov dword [edi + 4], ebx ; Store the rbx value in the next 4 bytes + add eax, 1 << 21 ; Increment (page size) + adc ebx, 0 ; Add 0 (carry flag) to rbx to increment if there was a carry + add edi, 8 ; Add 8 to rdi (next PDE) + loop .FillPageTableLevel2 ; Loop until rcx is 0 + + ret diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.s_fixme b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.s_fixme new file mode 100644 index 0000000..6922f1b --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Multiboot_PageTable.s_fixme @@ -0,0 +1,67 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.code32 + +.equ PAGE_TABLE_SIZE, 0x4 + +.section .bootstrap.data +.align 0x1000 +.global BootPageTable +BootPageTable: + .rept 0x10000 /* 0x4000 bytes will be used in UpdatePageTable */ + .long 0 + .endr + +.section .bootstrap.text +.global UpdatePageTable +UpdatePageTable: + mov edi, (BootPageTable + 0x0000) /* First PML4E */ + mov eax, (BootPageTable + 0x1000) /* First PDPTE */ + or eax, 0b11 /* Bitwise OR on rax (PDPTE) with 11b (Present, Write) */ + mov dword [edi], eax /* Write 11b to PML4E */ + + mov edi, (BootPageTable + 0x1000) /* First PDPTE */ + mov eax, (BootPageTable + 0x2000) /* First PDE */ + or eax, 0b11 /* Bitwise OR on rax (PDE) with 11b (Present, Write) */ + + mov ecx, PAGE_TABLE_SIZE /* For loop instruction */ + mov ebx, 0x0 /* Value to store in the next 4 bytes */ + .FillPageTableLevel3: + mov dword [edi], eax /* Store modified PDE in PDPTE */ + mov dword [edi + 4], ebx /* Store the rbx value in the next 4 bytes */ + add eax, 0x1000 /* Increment (page size) */ + adc ebx, 0 /* Add 0 to carry flag */ + add edi, 8 /* Add 8 to rdi (next PDE) */ + loop .FillPageTableLevel3 /* Loop until rcx is 0 */ + + mov edi, (BootPageTable + 0x2000) /* First PDE */ + mov eax, 0b10000011 /* Present, Write, Large Page */ + + mov ecx, (512 * PAGE_TABLE_SIZE) /* For loop instruction */ + mov ebx, 0x0 /* Value to store in the next 4 bytes */ + .FillPageTableLevel2: + mov dword [edi], eax /* Store modified PDE in PDPTE */ + mov dword [edi + 4], ebx /* Store the rbx value in the next 4 bytes */ + add eax, 1 << 21 /* Increment (page size) */ + adc ebx, 0 /* Add 0 (carry flag) to rbx to increment if there was a carry */ + add edi, 8 /* Add 8 to rdi (next PDE) */ + loop .FillPageTableLevel2 /* Loop until rcx is 0 */ + + ret diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Start.asm b/Architecture/amd64/Bootstrap/Multiboot/2/Start.asm index d6e6490..9f28534 100644 --- a/Architecture/amd64/Bootstrap/Multiboot/2/Start.asm +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Start.asm @@ -1,6 +1,112 @@ +; 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 . + [bits 32] +KERNEL_STACK_SIZE equ 0x4000 ; 16KB + +extern DetectCPUID +extern Detect64Bit +extern DetectPSE +extern DetectPAE +extern multiboot_main +extern LoadGDT32 +extern BootPageTable +extern UpdatePageTable +extern GDT64.Ptr +extern GDT64.Code +extern GDT64.Data + +section .bootstrap.data +MB_HeaderMagic: + dq 0 + +MB_HeaderInfo: + dq 0 section .bootstrap.text + global Multiboot2_start Multiboot2_start: - jmp $ + cli + + mov [MB_HeaderMagic], eax + mov [MB_HeaderInfo], ebx + + call DetectCPUID + cmp eax, 0 + je $ + + call Detect64Bit + cmp eax, 0 + je $ + + call DetectPSE + cmp eax, 0 + je $ + + call DetectPAE + cmp eax, 0 + je $ + + mov ecx, cr4 + or ecx, 0x00000010 ; Set PSE in CR4 + or ecx, 0x00000020 ; Set PAE in CR4 + mov cr4, ecx + + call LoadGDT32 + call UpdatePageTable + + mov ecx, BootPageTable + mov cr3, ecx + + mov ecx, 0xC0000080 ; EFER + rdmsr + or eax, 0x800 | 0x100 | 0x1 ; Set LME, LMA, SCE + wrmsr + + mov ecx, cr0 + or ecx, 0x80000001 ; Set PG and PE in CR0 + mov cr0, ecx + + lgdt [GDT64.Ptr] + jmp GDT64.Code:HigherHalfStart + +extern UpdatePageTable64 + +[bits 64] +HigherHalfStart: + mov ax, GDT64.Data + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + call UpdatePageTable64 + + mov rsp, KernelStack + KERNEL_STACK_SIZE + mov rdi, [MB_HeaderMagic] + mov rsi, [MB_HeaderInfo] + push rsi + push rdi + call multiboot_main +.Hang: + hlt + jmp .Hang + +section .bootstrap.bss +align 16 +KernelStack: + resb KERNEL_STACK_SIZE diff --git a/Architecture/amd64/Bootstrap/Multiboot/2/Start.s_fixme b/Architecture/amd64/Bootstrap/Multiboot/2/Start.s_fixme new file mode 100644 index 0000000..8076319 --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/2/Start.s_fixme @@ -0,0 +1,117 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.code32 +.equ KERNEL_STACK_SIZE, 0x4000 /* 16KB */ + +.extern DetectCPUID +.extern Detect64Bit +.extern DetectPSE +.extern DetectPAE +.extern multiboot_main +.extern LoadGDT32 +.extern BootPageTable +.extern UpdatePageTable +.extern GDT64.Ptr +.extern GDT64.Code +.extern GDT64.Data + +.section .bootstrap.data +MB_HeaderMagic: + .quad 0 + +MB_HeaderInfo: + .quad 0 + +.section .bootstrap.text + +.global Multiboot2_start +Multiboot2_start: + cli + + mov [MB_HeaderMagic], eax + mov [MB_HeaderInfo], ebx + + call DetectCPUID + cmp eax, 0 + je $ + + call Detect64Bit + cmp eax, 0 + je $ + + call DetectPSE + cmp eax, 0 + je $ + + call DetectPAE + cmp eax, 0 + je $ + + mov ecx, cr4 + or ecx, 0x00000010 /* Set PSE in CR4 */ + or ecx, 0x00000020 /* Set PAE in CR4 */ + mov cr4, ecx + + call LoadGDT32 + call UpdatePageTable + + mov ecx, BootPageTable + mov cr3, ecx + + mov ecx, 0xC0000080 /* EFER */ + rdmsr + or eax, 0x800 | 0x100 | 0x1 /* Set LME, LMA, SCE */ + wrmsr + + mov ecx, cr0 + or ecx, 0x80000001 /* Set PG and PE in CR0 */ + mov cr0, ecx + + lgdt [GDT64.Ptr] + jmp GDT64.Code:HigherHalfStart + +.extern UpdatePageTable64 + +.code64 +HigherHalfStart: + mov ax, GDT64.Data + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + call UpdatePageTable64 + + mov rsp, KernelStack + KERNEL_STACK_SIZE + mov rbp, 0 + mov rdi, [MB_HeaderMagic] + mov rsi, [MB_HeaderInfo] + push rsi + push rdi + call multiboot_main +.Hang: + hlt + jmp .Hang + +.section .bootstrap.bss +.align 16 +KernelStack: + .space KERNEL_STACK_SIZE diff --git a/Architecture/amd64/Bootstrap/Multiboot/_start.s b/Architecture/amd64/Bootstrap/Multiboot/_start.s new file mode 100644 index 0000000..eac169c --- /dev/null +++ b/Architecture/amd64/Bootstrap/Multiboot/_start.s @@ -0,0 +1,40 @@ +/* + 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 . +*/ + +.intel_syntax noprefix + +.extern Multiboot1_start +.extern Multiboot2_start + +.code32 +.section .bootstrap.text + +.global _start +_start: + cmp eax, 0x36D76289 + je .Multiboot2 + cmp eax, 0x1BADB002 + je .Multiboot1 + int3 + +.Multiboot1: + call Multiboot1_start + jmp . + +.Multiboot2: + call Multiboot2_start + jmp . diff --git a/Architecture/amd64/runtime/crt0.c b/Architecture/amd64/runtime/crt0.c deleted file mode 100644 index 35cf1ab..0000000 --- a/Architecture/amd64/runtime/crt0.c +++ /dev/null @@ -1,15 +0,0 @@ -// #include - -// #include - -// int Entry(void *Info); - -// void _start(void *Raw) -// { -// error("Todo"); -// while (1) -// asmv("hlt"); -// Entry(NULL); -// return; -// } -// C stuff \ No newline at end of file diff --git a/Architecture/amd64/runtime/crt1.c b/Architecture/amd64/runtime/crt1.c deleted file mode 100644 index bcc936a..0000000 --- a/Architecture/amd64/runtime/crt1.c +++ /dev/null @@ -1,15 +0,0 @@ -#include - -#include - -int Entry(void *Info); - -void _start(void *Raw) -{ - UNUSED(Raw); - error("ERROR! INVALID BOOT PROTOCOL!"); - while (1) - asmv("hlt"); - Entry(NULL); - return; -} diff --git a/Architecture/amd64/runtime/crtbegin.c b/Architecture/amd64/runtime/crtbegin.c deleted file mode 100644 index 507125b..0000000 --- a/Architecture/amd64/runtime/crtbegin.c +++ /dev/null @@ -1 +0,0 @@ -// C++ constructor/destructor stuff \ No newline at end of file diff --git a/Architecture/amd64/runtime/crtend.c b/Architecture/amd64/runtime/crtend.c deleted file mode 100644 index 507125b..0000000 --- a/Architecture/amd64/runtime/crtend.c +++ /dev/null @@ -1 +0,0 @@ -// C++ constructor/destructor stuff \ No newline at end of file diff --git a/Architecture/amd64/runtime/crti.S b/Architecture/amd64/runtime/crti.S deleted file mode 100644 index 9385571..0000000 --- a/Architecture/amd64/runtime/crti.S +++ /dev/null @@ -1,13 +0,0 @@ -.section .init -.global _init -.type _init, @function -_init: - push %rbp - movq %rsp, %rbp - -.section .fini -.global _fini -.type _fini, @function -_fini: - push %rbp - movq %rsp, %rbp diff --git a/Architecture/amd64/runtime/crtn.S b/Architecture/amd64/runtime/crtn.S deleted file mode 100644 index 2fe55b4..0000000 --- a/Architecture/amd64/runtime/crtn.S +++ /dev/null @@ -1,7 +0,0 @@ -.section .init - popq %rbp - ret - -.section .fini - popq %rbp - ret diff --git a/Kernel.cpp b/Kernel.cpp index d17867c..d769410 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -17,7 +17,6 @@ #include "kernel.h" -#include #include #include #include @@ -76,6 +75,7 @@ LockClass mExtTrkLock; * - [ ] Vector should have a mutex. * - [ ] Update SMBIOS functions to support newer versions and actually use it. * - [ ] COW (Copy On Write) for the virtual memory. (https://en.wikipedia.org/wiki/Copy-on-write) + * - [ ] Bootstrap should have a separate bss section + PHDR. * * ISSUES: * - [x] Kernel stack is smashed when an interrupt occurs. (this bug it occurs when an interrupt like IRQ1 or IRQ12 occurs) @@ -493,11 +493,25 @@ EXTERNC __no_stack_protector NIF void Entry(BootInfo *Info) void *KernelStackAddress = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); uintptr_t KernelStack = (uintptr_t)KernelStackAddress + STACK_SIZE - 0x10; debug("Kernel stack: %#lx-%#lx", KernelStackAddress, KernelStack); +#if defined(a64) asmv("mov %0, %%rsp" : : "r"(KernelStack) : "memory"); asmv("mov $0, %rbp"); +#elif defined(a32) + asmv("mov %0, %%esp" + : + : "r"(KernelStack) + : "memory"); + asmv("mov $0, %ebp"); +#elif defined(aa64) + asmv("mov %0, %%sp" + : + : "r"(KernelStack) + : "memory"); + asmv("mov $0, %fp"); +#endif #ifdef DEBUG /* I had to do this because KernelAllocator diff --git a/KernelThread.cpp b/KernelThread.cpp index 0772752..5da3501 100644 --- a/KernelThread.cpp +++ b/KernelThread.cpp @@ -179,10 +179,18 @@ void TaskMgr() continue; Status = Thd->Status; uint64_t ThreadCpuUsage = GetUsage(OldSystemTime, &Thd->Info); +#if defined(a64) printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC", Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime, Thd->Info.UserTime, Thd->Registers.rip, Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.rip) : "unknown"); +#elif defined(a32) + printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC", + Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime, + Thd->Info.UserTime, Thd->Registers.eip, + Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.eip) : "unknown"); +#elif defined(aa64) +#endif } } OldSystemTime = TimeManager->GetCounter(); diff --git a/Makefile b/Makefile index fce20b2..6c30374 100644 --- a/Makefile +++ b/Makefile @@ -24,24 +24,27 @@ PSF_SOURCES = $(shell find ./ -type f -name '*.psf') ifeq ($(OSARCH), amd64) ASM_SOURCES = $(shell find ./ -type f -name '*.asm' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") +s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") RS_SOURCES = $(shell find ./ -type f -name '*.rs' -not -path "./Architecture/i386/*" -not -path "./Architecture/aarch64/*") else ifeq ($(OSARCH), i386) ASM_SOURCES = $(shell find ./ -type f -name '*.asm' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") +s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") RS_SOURCES = $(shell find ./ -type f -name '*.rs' -not -path "./Architecture/amd64/*" -not -path "./Architecture/aarch64/*") else ifeq ($(OSARCH), aarch64) ASM_SOURCES = $(shell find ./ -type f -name '*.asm' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") +s_SOURCES = $(shell find ./ -type f -name '*.s' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") RS_SOURCES = $(shell find ./ -type f -name '*.rs' -not -path "./Architecture/amd64/*" -not -path "./Architecture/i386/*") endif HEADERS = $(sort $(dir $(wildcard ./include/*))) $(sort $(dir $(wildcard ./include_std/*))) -OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(RS_SOURCES:.rs=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o) +OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(RS_SOURCES:.rs=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(s_SOURCES:.s=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o) STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su) GCNO_OBJ = $(C_SOURCES:.c=.gcno) $(CPP_SOURCES:.cpp=.gcno) INCLUDE_DIR = -I./include -I./include_std @@ -52,7 +55,7 @@ LDFLAGS := -Wl,-Map kernel.map -shared -nostdlib -nodefaultlibs -nolibc WARNCFLAG = -Wall -Wextra \ -Wfloat-equal -Wpointer-arith -Wcast-align \ -Wredundant-decls -Winit-self -Wswitch-default \ - -Wstrict-overflow=5 -Wconversion + -Wstrict-overflow=5 -Wconversion -w # https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html CFLAGS := \ @@ -172,6 +175,10 @@ endif $(info Compiling $<) $(AS) -c $< -o $@ +%.o: %.s + $(info Compiling $<) + $(AS) -c $< -o $@ + %.o: %.psf ifeq ($(OSARCH), amd64) $(OBJCOPY) -O elf64-x86-64 -I binary $< $@ diff --git a/Tests/TestSyscalls.c b/Tests/TestSyscalls.c index 3eb2c94..65533db 100644 --- a/Tests/TestSyscalls.c +++ b/Tests/TestSyscalls.c @@ -23,6 +23,7 @@ __aligned(0x1000) __no_stack_protector void TestSyscalls() { +#if defined(a64) __asm__ __volatile__("syscall" : : "a"(_Print), "D"('H'), "S"(0) @@ -39,7 +40,9 @@ __aligned(0x1000) __no_stack_protector void TestSyscalls() : : "a"(_Exit), "D"(fork_id) : "rcx", "r11", "memory"); - +#elif defined(a32) +#elif defined(aa64) +#endif while (1) ; } diff --git a/include/boot/protocols/multiboot2.h b/include/boot/protocols/multiboot2.h deleted file mode 100644 index bcc4d25..0000000 --- a/include/boot/protocols/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 */ \ No newline at end of file diff --git a/include/task.hpp b/include/task.hpp index 7635056..f288715 100644 --- a/include/task.hpp +++ b/include/task.hpp @@ -123,7 +123,7 @@ namespace Tasking uint64_t ShadowGSBase, GSBase, FSBase; #elif defined(a32) CPU::x32::TrapFrame Registers; // TODO - uint64_t GSBase, FSBase; + uint64_t ShadowGSBase, GSBase, FSBase; #elif defined(aa64) uint64_t Registers; // TODO #endif