diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index b4802d5..a89a799 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -199,145 +199,6 @@ "-fstack-check", "-fsanitize=undefined", - // VSCode flags - "-ffreestanding", - "-nostdinc", - "-nostdinc++" - ] - }, - { - "name": "FennixLoader x64 (Linux, GCC, debug)", - "includePath": [ - "${workspaceFolder}/FennixLoader/include" - ], - "defines": [ - "__debug_vscode__", - "KERNEL_NAME=\"Fennix\"", - "KERNEL_VERSION=\"1.0\"", - "GIT_COMMIT=\"0000000000000000000000000000000000000000\"", - "GIT_COMMIT_SHORT=\"0000000\"", - "DEBUG=\"1\"" - ], - "compilerPath": "${workspaceFolder}/../tools/cross/bin/amd64-elf-gcc", - "cStandard": "c17", - "cppStandard": "c++20", - "intelliSenseMode": "gcc-x64", - "configurationProvider": "ms-vscode.makefile-tools", - "compilerArgs": [ - // Compiler flags - "-fno-pic", - "-fno-pie", - "-mno-red-zone", - "-march=core2", - "-pipe", - "-mcmodel=kernel", - "-fno-builtin", - - // Warnings - "-Wall", - "-Wextra", - "-Wfloat-equal", - "-Wpointer-arith", - "-Wcast-align", - "-Wredundant-decls", - "-Winit-self", - "-Wswitch-default", - "-Wstrict-overflow=5", - "-Wconversion", - - // C++ flags - "-fno-rtti", - "-fexceptions", - - // Linker flags - "-T${workspaceFolder}/Architecture/amd64/linker.ld", - "-Wl,-static,--no-dynamic-linker,-ztext", - "-nostdlib", - "-nodefaultlibs", - "-nolibc", - "-zmax-page-size=0x1000", - "-shared", - - // Debug flags - "-ggdb3", - "-O0", - "-fdiagnostics-color=always", - "-fverbose-asm", - "-fstack-usage", - "-fstack-check", - "-fsanitize=undefined", - - // VSCode flags - "-ffreestanding", - "-nostdinc", - "-nostdinc++" - ] - }, - { - "name": "FennixLoader x32 (Linux, GCC, debug)", - "includePath": [ - "${workspaceFolder}/FennixLoader/include" - ], - "defines": [ - "__debug_vscode__", - "KERNEL_NAME=\"Fennix\"", - "KERNEL_VERSION=\"1.0\"", - "GIT_COMMIT=\"0000000000000000000000000000000000000000\"", - "GIT_COMMIT_SHORT=\"0000000\"", - "DEBUG=\"1\"" - ], - "compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc", - "cStandard": "c17", - "cppStandard": "c++20", - "intelliSenseMode": "gcc-x86", - "configurationProvider": "ms-vscode.makefile-tools", - "compilerArgs": [ - // Compiler flags - "-fno-pic", - "-fno-pie", - "-mno-80387", - "-mno-mmx", - "-mno-3dnow", - "-mno-red-zone", - "-march=pentium", - "-pipe", - "-msoft-float", - "-fno-builtin", - - // Warnings - "-Wall", - "-Wextra", - "-Wfloat-equal", - "-Wpointer-arith", - "-Wcast-align", - "-Wredundant-decls", - "-Winit-self", - "-Wswitch-default", - "-Wstrict-overflow=5", - "-Wconversion", - - // C++ flags - "-fno-rtti", - "-fexceptions", - - // Linker flags - "-T${workspaceFolder}/Architecture/i386/linker.ld", - "-Wl,-static,--no-dynamic-linker,-ztext", - "-nostdlib", - "-nodefaultlibs", - "-nolibc", - "-zmax-page-size=0x1000", - "-shared", - - // Debug flags - "-ggdb3", - "-O0", - "-fdiagnostics-color=always", - "-fverbose-asm", - "-fstack-usage", - "-fstack-check", - "-fsanitize=undefined", - // VSCode flags "-ffreestanding", "-nostdinc", diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 24dcbc4..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "FLDR.elf", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceRoot}/FLDR.elf", - "cwd": "${workspaceRoot}", - "args": [], - "targetArchitecture": "x86", - "MIMode": "gdb", - "miDebuggerPath": "/usr/bin/gdb", - "miDebuggerArgs": "", - "externalConsole": false, - "additionalSOLibSearchPath": "${workspaceRoot}", - "customLaunchSetupCommands": [ - { - "text": "target remote localhost:1234", - "description": "Connect to QEMU remote debugger" - } - ], - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - }, - { - "text": "set breakpoint pending on", - "description": "Make breakpoint pending on future shared library load." - }, - { - "text": "file ${workspaceRoot}/FLDR.elf", - "description": "Load binary." - }, - ] - } - ] -} \ No newline at end of file diff --git a/FennixLoader/ArithmeticOperations.c b/FennixLoader/ArithmeticOperations.c deleted file mode 100644 index 91a9db6..0000000 --- a/FennixLoader/ArithmeticOperations.c +++ /dev/null @@ -1,327 +0,0 @@ -/* Source: https://github.com/glitchub/arith64 */ -#define arith64_u64 unsigned long long int -#define arith64_s64 signed long long int -#define arith64_u32 unsigned int -#define arith64_s32 int - -typedef union -{ - arith64_u64 u64; - arith64_s64 s64; - struct - { -#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - arith64_u32 hi; - arith64_u32 lo; -#else - arith64_u32 lo; - arith64_u32 hi; -#endif - } u32; - struct - { -#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - arith64_s32 hi; - arith64_s32 lo; -#else - arith64_s32 lo; - arith64_s32 hi; -#endif - } s32; -} arith64_word; - -#define arith64_hi(n) (arith64_word){.u64 = n}.u32.hi -#define arith64_lo(n) (arith64_word){.u64 = n}.u32.lo -#define arith64_neg(a, b) (((a) ^ ((((arith64_s64)(b)) >= 0) - 1)) + (((arith64_s64)(b)) < 0)) -#define arith64_abs(a) arith64_neg(a, a) - -arith64_s64 __absvdi2(arith64_s64 a) -{ - return arith64_abs(a); -} - -arith64_s64 __ashldi3(arith64_s64 a, int b) -{ - arith64_word w = {.s64 = a}; - - b &= 63; - - if (b >= 32) - { - w.u32.hi = w.u32.lo << (b - 32); - w.u32.lo = 0; - } - else if (b) - { - w.u32.hi = (w.u32.lo >> (32 - b)) | (w.u32.hi << b); - w.u32.lo <<= b; - } - return w.s64; -} - -arith64_s64 __ashrdi3(arith64_s64 a, int b) -{ - arith64_word w = {.s64 = a}; - - b &= 63; - - if (b >= 32) - { - w.s32.lo = w.s32.hi >> (b - 32); - w.s32.hi >>= 31; // 0xFFFFFFFF or 0 - } - else if (b) - { - w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b); - w.s32.hi >>= b; - } - return w.s64; -} - -int __clzsi2(arith64_u32 a) -{ - int b, n = 0; - b = !(a & 0xffff0000) << 4; - n += b; - a <<= b; - b = !(a & 0xff000000) << 3; - n += b; - a <<= b; - b = !(a & 0xf0000000) << 2; - n += b; - a <<= b; - b = !(a & 0xc0000000) << 1; - n += b; - a <<= b; - return n + !(a & 0x80000000); -} - -int __clzdi2(arith64_u64 a) -{ - int b, n = 0; - b = !(a & 0xffffffff00000000ULL) << 5; - n += b; - a <<= b; - b = !(a & 0xffff000000000000ULL) << 4; - n += b; - a <<= b; - b = !(a & 0xff00000000000000ULL) << 3; - n += b; - a <<= b; - b = !(a & 0xf000000000000000ULL) << 2; - n += b; - a <<= b; - b = !(a & 0xc000000000000000ULL) << 1; - n += b; - a <<= b; - return n + !(a & 0x8000000000000000ULL); -} - -int __ctzsi2(arith64_u32 a) -{ - int b, n = 0; - b = !(a & 0x0000ffff) << 4; - n += b; - a >>= b; - b = !(a & 0x000000ff) << 3; - n += b; - a >>= b; - b = !(a & 0x0000000f) << 2; - n += b; - a >>= b; - b = !(a & 0x00000003) << 1; - n += b; - a >>= b; - return n + !(a & 0x00000001); -} - -int __ctzdi2(arith64_u64 a) -{ - int b, n = 0; - b = !(a & 0x00000000ffffffffULL) << 5; - n += b; - a >>= b; - b = !(a & 0x000000000000ffffULL) << 4; - n += b; - a >>= b; - b = !(a & 0x00000000000000ffULL) << 3; - n += b; - a >>= b; - b = !(a & 0x000000000000000fULL) << 2; - n += b; - a >>= b; - b = !(a & 0x0000000000000003ULL) << 1; - n += b; - a >>= b; - return n + !(a & 0x0000000000000001ULL); -} - -arith64_u64 __divmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c) -{ - if (b > a) - { - if (c) - *c = a; - return 0; - } - if (!arith64_hi(b)) - { - if (b == 0) - { - volatile char x = 0; - x = 1 / x; - } - if (b == 1) - { - if (c) - *c = 0; - return a; - } - if (!arith64_hi(a)) - { - if (c) - *c = arith64_lo(a) % arith64_lo(b); - return arith64_lo(a) / arith64_lo(b); - } - } - - char bits = __clzdi2(b) - __clzdi2(a) + 1; - arith64_u64 rem = a >> bits; - a <<= 64 - bits; - arith64_u64 wrap = 0; - while (bits-- > 0) - { - rem = (rem << 1) | (a >> 63); - a = (a << 1) | (wrap & 1); - wrap = ((arith64_s64)(b - rem - 1) >> 63); - rem -= b & wrap; - } - if (c) - *c = rem; - return (a << 1) | (wrap & 1); -} - -arith64_s64 __divdi3(arith64_s64 a, arith64_s64 b) -{ - arith64_u64 q = __divmoddi4(arith64_abs(a), arith64_abs(b), (void *)0); - return arith64_neg(q, a ^ b); -} - -int __ffsdi2(arith64_u64 a) { return a ? __ctzdi2(a) + 1 : 0; } - -arith64_u64 __lshrdi3(arith64_u64 a, int b) -{ - arith64_word w = {.u64 = a}; - - b &= 63; - - if (b >= 32) - { - w.u32.lo = w.u32.hi >> (b - 32); - w.u32.hi = 0; - } - else if (b) - { - w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b); - w.u32.hi >>= b; - } - return w.u64; -} - -arith64_s64 __moddi3(arith64_s64 a, arith64_s64 b) -{ - arith64_u64 r; - __divmoddi4(arith64_abs(a), arith64_abs(b), &r); - return arith64_neg(r, a); -} - -int __popcountsi2(arith64_u32 a) -{ - - a = a - ((a >> 1) & 0x55555555); - a = ((a >> 2) & 0x33333333) + (a & 0x33333333); - a = (a + (a >> 4)) & 0x0F0F0F0F; - a = (a + (a >> 16)); - - return (a + (a >> 8)) & 63; -} - -int __popcountdi2(arith64_u64 a) -{ - - a = a - ((a >> 1) & 0x5555555555555555ULL); - a = ((a >> 2) & 0x3333333333333333ULL) + (a & 0x3333333333333333ULL); - a = (a + (a >> 4)) & 0x0F0F0F0F0F0F0F0FULL; - a = (a + (a >> 32)); - a = (a + (a >> 16)); - - return (a + (a >> 8)) & 127; -} - -arith64_u64 __udivdi3(arith64_u64 a, arith64_u64 b) { return __divmoddi4(a, b, (void *)0); } - -arith64_u64 __umoddi3(arith64_u64 a, arith64_u64 b) -{ - arith64_u64 r; - __divmoddi4(a, b, &r); - return r; -} - -/* Good documentation: https://splichal.eu/scripts/sphinx/gccint/_build/html/the-gcc-low-level-runtime-library/routines-for-floating-point-emulation.html */ - -double __adddf3(double a, double b) { return a + b; } -double __muldf3(double a, double b) { return a * b; } -double __floatsidf(int i) { return (double)i; } -int __ltdf2(double a, double b) { return a < b; } -int __gtdf2(double a, double b) { return a > b; } -int __nedf2(double a, double b) { return a != b; } -int __eqdf2(double a, double b) { return a == b; } -double __floatdidf(long i) { return (double)i; } -double __divdf3(double a, double b) { return a / b; } -double __subdf3(double a, double b) { return a - b; } -int __gedf2(double a, double b) { return a >= b; } -int __fixdfsi(double a) { return (int)a; } -long __fixdfdi(double a) { return (long)a; } -int __ledf2(double a, double b) { return a <= b; } - -/* FIXME: Check if these functions are implemented correctly */ - -typedef long long int64_t; -typedef unsigned long long uint64_t; -typedef unsigned int uint32_t; -typedef struct -{ - uint64_t value; -} atomic_uint64_t; - -uint64_t __atomic_load_8(const atomic_uint64_t *p) -{ - uint64_t value; - __asm__ volatile("lock cmpxchg8b %1" - : "=A"(value) - : "m"(*p) - : "memory"); - return value; -} - -void __atomic_store_8(atomic_uint64_t *p, uint64_t value) -{ - __asm__ volatile("lock cmpxchg8b %0" - : "=m"(p->value) - : "a"((uint32_t)value), "d"((uint32_t)(value >> 32)), "m"(*p) - : "memory"); -} - -/* FIXME: __fixsfsi is not implemented correctly(?) */ -int __fixsfsi(float a) { return (int)a; } - -int __ltsf2(float a, float b) { return a < b; } -int __eqsf2(float a, float b) { return a == b; } -float __divsf3(float a, float b) { return a / b; } -double __extendsfdf2(float a) { return (double)a; } -float __truncdfsf2(double a) { return (float)a; } -float __subsf3(float a, float b) { return a - b; } -float __floatsisf(int a) { return (float)a; } -int __fixunssfsi(float a) { return (int)a; } -float __mulsf3(float a, float b) { return a * b; } -float __addsf3(float a, float b) { return a + b; } diff --git a/FennixLoader/Bootstrap.asm b/FennixLoader/Bootstrap.asm deleted file mode 100644 index 7b4957e..0000000 --- a/FennixLoader/Bootstrap.asm +++ /dev/null @@ -1,34 +0,0 @@ -[bits 32] - -extern loader_main - -section .text - -MB_HeaderMagic: - dq 0 - -MB_HeaderInfo: - dq 0 - -global _start -_start: - cli - mov [MB_HeaderMagic], eax - mov [MB_HeaderInfo], ebx - mov esp, KernelStack - mov eax, [MB_HeaderMagic] - mov ebx, [MB_HeaderInfo] - push ebx - push eax - call loader_main -.hang: - cli - hlt - jmp .hang - -STACK_SIZE equ 0x4000 ; 16KB - -section .bss -align 16 -KernelStack: - resb STACK_SIZE diff --git a/FennixLoader/Debugger.cpp b/FennixLoader/Debugger.cpp deleted file mode 100644 index 40a63ab..0000000 --- a/FennixLoader/Debugger.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include - -enum vga_color -{ - VGA_COLOR_BLACK = 0, - VGA_COLOR_BLUE = 1, - VGA_COLOR_GREEN = 2, - VGA_COLOR_CYAN = 3, - VGA_COLOR_RED = 4, - VGA_COLOR_MAGENTA = 5, - VGA_COLOR_BROWN = 6, - VGA_COLOR_LIGHT_GREY = 7, - VGA_COLOR_DARK_GREY = 8, - VGA_COLOR_LIGHT_BLUE = 9, - VGA_COLOR_LIGHT_GREEN = 10, - VGA_COLOR_LIGHT_CYAN = 11, - VGA_COLOR_LIGHT_RED = 12, - VGA_COLOR_LIGHT_MAGENTA = 13, - VGA_COLOR_LIGHT_BROWN = 14, - VGA_COLOR_WHITE = 15, -}; - -extern "C" void terminal_setcolor(uint8_t color); -extern "C" void putchar(char c); -extern bool DoNotWriteOnScreen; - -static inline void WritePrefix(DebugLevel Level, const char *File, int Line, const char *Function) -{ - const char *DbgLvlString; - switch (Level) - { - case DebugLevelError: - DbgLvlString = "ERROR"; - terminal_setcolor(VGA_COLOR_RED); - break; - case DebugLevelWarning: - DbgLvlString = "WARN "; - terminal_setcolor(VGA_COLOR_BROWN); - break; - case DebugLevelInfo: - DbgLvlString = "INFO "; - terminal_setcolor(VGA_COLOR_LIGHT_GREY); - break; - case DebugLevelDebug: - DbgLvlString = "DEBUG"; - terminal_setcolor(VGA_COLOR_GREEN); - break; - case DebugLevelTrace: - DbgLvlString = "TRACE"; - terminal_setcolor(VGA_COLOR_DARK_GREY); - break; - case DebugLevelFixme: - DbgLvlString = "FIXME"; - terminal_setcolor(VGA_COLOR_LIGHT_RED); - break; - case DebugLevelUbsan: - { - DbgLvlString = "UBSAN"; - printf("%s|%s: ", DbgLvlString, Function); - terminal_setcolor(VGA_COLOR_LIGHT_RED); - return; - } - default: - DbgLvlString = "UNKNW"; - terminal_setcolor(VGA_COLOR_WHITE); - break; - } - DoNotWriteOnScreen = true; - printf("%s|%s->%s:%d: ", DbgLvlString, File, Function, Line); - DoNotWriteOnScreen = false; -} - -namespace SysDbg -{ - void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) - { - WritePrefix(Level, File, Line, Function); - va_list args; - va_start(args, Format); - vprintf(Format, args); - va_end(args); - } - - void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) - { - WritePrefix(Level, File, Line, Function); - va_list args; - va_start(args, Format); - vprintf(Format, args); - va_end(args); - putchar('\n'); - } -} - -// C compatibility -extern "C" void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) -{ - WritePrefix(Level, File, Line, Function); - va_list args; - va_start(args, Format); - vprintf(Format, args); - va_end(args); -} - -// C compatibility -extern "C" void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...) -{ - WritePrefix(Level, File, Line, Function); - va_list args; - va_start(args, Format); - vprintf(Format, args); - va_end(args); - putchar('\n'); -} diff --git a/FennixLoader/Detect/Detect64.asm b/FennixLoader/Detect/Detect64.asm deleted file mode 100644 index 9c6273e..0000000 --- a/FennixLoader/Detect/Detect64.asm +++ /dev/null @@ -1,16 +0,0 @@ -[bits 32] -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 diff --git a/FennixLoader/Detect/DetectCPUID.asm b/FennixLoader/Detect/DetectCPUID.asm deleted file mode 100644 index eaa23e9..0000000 --- a/FennixLoader/Detect/DetectCPUID.asm +++ /dev/null @@ -1,20 +0,0 @@ -[bits 32] -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 diff --git a/FennixLoader/LoadElf.cpp b/FennixLoader/LoadElf.cpp deleted file mode 100644 index 6f89959..0000000 --- a/FennixLoader/LoadElf.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "loadelf.hpp" - -#include -#include -#include - -static uint64_t KernelJumpAddress = 0x0; - -bool LoadElfInMemory(void *Address, size_t Length, bool Allow64) -{ - Elf32_Ehdr *Header32 = (Elf32_Ehdr *)Address; - Elf64_Ehdr *Header64 = (Elf64_Ehdr *)Address; - - bool Is64Bit = false; - - if (Header32->e_ident[EI_MAG0] == ELFMAG0 && - Header32->e_ident[EI_MAG1] == ELFMAG1 && - Header32->e_ident[EI_MAG2] == ELFMAG2 && - Header32->e_ident[EI_MAG3] == ELFMAG3) - { - debug("Elf magic is correct"); - if (Header32->e_machine == EM_X86_64) - { - if (!Allow64) - { - error("64 bit elf not allowed"); - return false; - } - Is64Bit = true; - debug("Elf is 64 bit"); - } - else if (Header32->e_machine == EM_386) - { - if (Allow64) - { - error("32 bit elf not allowed"); - return false; - } - debug("Elf is 32 bit"); - } - else - { - error("Elf is neither 32 nor 64 bit"); - return false; - } - - if (Is64Bit) - { - fixme("64 bit elf not implemented"); - } - else - { - if (Header32->e_phentsize != sizeof(Elf32_Phdr)) - { - error("Elf program header size is not correct"); - return false; - } - - Elf32_Phdr *ProgramHeader = (Elf32_Phdr *)((uintptr_t)Address + Header32->e_phoff); - for (size_t i = 0; i < Header32->e_phnum; i++) - { - if (ProgramHeader[i].p_type != PT_LOAD) - continue; - - if (ProgramHeader[i].p_filesz > ProgramHeader[i].p_memsz) - { - error("File size is greater than memory size"); - return false; - } - - size_t SegmentSize = ProgramHeader[i].p_memsz; - void *VirtualAddress = (void *)ProgramHeader[i].p_vaddr; - void *PhysicalAddress = KernelAllocator32.RequestPages(TO_PAGES(SegmentSize)); - debug("- Segment: %p (physical allocated at: %p) (%#x bytes)", VirtualAddress, PhysicalAddress, SegmentSize); - - debug(" Mapping %d pages at %p (%p-%p)", TO_PAGES(SegmentSize), VirtualAddress, PhysicalAddress, (void *)((uintptr_t)PhysicalAddress + TO_PAGES(SegmentSize) * PAGE_SIZE)); - Memory32::Virtual().Map(VirtualAddress, PhysicalAddress, SegmentSize, P | RW); - - void *memcpy_Dest = (void *)((uintptr_t)PhysicalAddress + (ProgramHeader[i].p_vaddr - 0xC0000000)); - void *memcpy_Src = (void *)((uintptr_t)Address + ProgramHeader[i].p_offset); - debug(" memcpy(%p, %p, %#x)", memcpy_Dest, memcpy_Src, ProgramHeader[i].p_filesz); - memcpy(memcpy_Dest, memcpy_Src, ProgramHeader[i].p_filesz); - - if (ProgramHeader[i].p_filesz < ProgramHeader[i].p_memsz) - { - debug(" Zeroing %#x bytes at %p", ProgramHeader[i].p_memsz - ProgramHeader[i].p_filesz, (void *)((uintptr_t)PhysicalAddress + ProgramHeader[i].p_filesz)); - memset((void *)((uintptr_t)PhysicalAddress + ProgramHeader[i].p_filesz), 0, ProgramHeader[i].p_memsz - ProgramHeader[i].p_filesz); - } - } - - void *Stack = KernelAllocator32.RequestPage(); - memset(Stack, 0, PAGE_SIZE - 1); - debug("Stack allocated at: %p", Stack); - - void *StackTop = (void *)((uintptr_t)Stack + PAGE_SIZE - 0x10); - debug("Stack top at: %p", StackTop); - - debug("Memory Info: %lldMB / %lldMB (%lldMB reserved)", - TO_MB(KernelAllocator32.UsedMemory), - TO_MB(KernelAllocator32.TotalMemory), - TO_MB(KernelAllocator32.ReservedMemory)); - - debug("Kernel Entry Point: %p", (void *)Header32->e_entry); - KernelJumpAddress = (uint64_t)Header32->e_entry; - - asmv("cli"); - asmv("mov %0, %%esp" - : - : "r"(StackTop)); - asmv("pushf\n" - "orl $0x46, (%esp)\n" - "popf"); - asmv("mov $0x80000011, %eax"); - asmv("mov %eax, %cr0"); - asmv("mov $0, %eax"); - asmv("mov %eax, %cr4"); - asmv("mov $0, %eax\n" - "mov $0, %ebx\n" - "mov $0, %ecx\n" - "mov $0, %edx\n" - "mov $0, %esi\n" - "mov $0, %edi\n" - "mov $0, %ebp\n"); - asmv("call %0" - : - : "r"(KernelJumpAddress)); - // asmv("jmp %0" - // : - // : "r"(KernelJumpAddress)); - - - // asmv("call *%0" - // : - // : "r"(KernelJumpAddress)); - - // void (*EntryPoint)() = (void (*)())KernelJumpAddress; - // EntryPoint(); - } - } - - return false; -} diff --git a/FennixLoader/Loader.cpp b/FennixLoader/Loader.cpp deleted file mode 100644 index c68a1e7..0000000 --- a/FennixLoader/Loader.cpp +++ /dev/null @@ -1,371 +0,0 @@ -#include -#include -#include -#include -#include - -#include "loadelf.hpp" - -using namespace UniversalAsynchronousReceiverTransmitter; - -BootInfo mb2binfo; - -bool DoNotWriteOnScreen = false; -extern "C" void terminal_initialize(void); -extern "C" void terminal_putchar(char c); - -extern "C" int DetectCPUID(); -extern "C" int Detect64Bit(); -extern "C" void EnablePaging(); - -char *strncpy(char *destination, const char *source, unsigned long num) -{ - if (destination == NULL) - return NULL; - char *ptr = destination; - while (*source && num--) - { - *destination = *source; - destination++; - source++; - } - *destination = '\0'; - return ptr; -} - -long unsigned strlen(const char s[]) -{ - long unsigned i = 0; - if (s) - while (s[i] != '\0') - ++i; - return i; -} - -int strcmp(const char *l, const char *r) -{ - for (; *l == *r && *l; l++, r++) - ; - return *(unsigned char *)l - *(unsigned char *)r; -} - -extern "C" void putchar(char c) -{ - if (mb2binfo.Framebuffer[0].Type == FramebufferType::EGA && !DoNotWriteOnScreen) - terminal_putchar(c); - UART(COM1).Write(c); -} - -void ProcessMB2(uint32_t Info) -{ - auto InfoAddress = Info; - for (auto Tag = (struct multiboot_tag *)((uint8_t *)(uint64_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 = (uint64_t)module->size; - strncpy(mb2binfo.Modules[module_count].Path, "(null)", 6); - strncpy(mb2binfo.Modules[module_count].CommandLine, module->cmdline, - strlen(module->cmdline)); - debug("Module: %s %s %p %lld", mb2binfo.Modules[module_count].Path, - mb2binfo.Modules[module_count].CommandLine, - mb2binfo.Modules[module_count].Address, - mb2binfo.Modules[module_count].Size); - 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; - uint32_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; - debug("Available memory: %#llx - %#llx", entry.addr, entry.addr + entry.len); - 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; - debug("Reserved memory: %#llx - %#llx", entry.addr, entry.addr + entry.len); - 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; - debug("ACPI reclaimable memory: %#llx - %#llx", entry.addr, entry.addr + entry.len); - 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; - debug("ACPI NVS memory: %#llx - %#llx", entry.addr, entry.addr + entry.len); - 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; - debug("Bad memory: %#llx - %#llx", entry.addr, entry.addr + entry.len); - break; - default: - mb2binfo.Memory.Entry[i].BaseAddress = (void *)entry.addr; - mb2binfo.Memory.Entry[i].Length = entry.len; - mb2binfo.Memory.Entry[i].Type = Unknown; - debug("Unknown memory: %#llx - %#llx", entry.addr, entry.addr + entry.len); - break; - } - } - 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 = FramebufferType::Indexed; - break; - } - case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: - { - mb2binfo.Framebuffer[fb_count].Type = FramebufferType::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 = FramebufferType::EGA; - break; - } - } - debug("Framebuffer %d: %dx%d %d bpp", Tag, 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 *)load_base_addr->load_base_addr; - mb2binfo.Kernel.VirtualBase = (void *)(load_base_addr->load_base_addr + 0xC0000000); - debug("Kernel base: %p (physical) %p (virtual)", mb2binfo.Kernel.PhysicalBase, mb2binfo.Kernel.VirtualBase); - break; - } - default: - { - error("Unknown multiboot2 tag type: %d", Tag->type); - break; - } - } - } -} - -typedef void (*CallPtr)(void); -extern CallPtr __init_array_start[0], __init_array_end[0]; -extern CallPtr __fini_array_start[0], __fini_array_end[0]; - -extern "C" int loader_main(uint32_t magic, uint32_t addr) -{ - if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) - { - error("Multiboot magic is invalid (%#x != %#x)", magic, MULTIBOOT2_BOOTLOADER_MAGIC); - while (1) - asmv("cli; hlt"); - } - - for (CallPtr *func = __init_array_start; func != __init_array_end; func++) - (*func)(); - - ProcessMB2(addr); - if (mb2binfo.Framebuffer[0].Type == FramebufferType::EGA) - terminal_initialize(); - debug("Multiboot2 tags processed"); - InitializeMemoryManagement(&mb2binfo, true); - EnablePaging(); - - bool Load64Bit = false; - - if (DetectCPUID()) - { - debug("CPUID supported"); - if (Detect64Bit()) - { - info("64-bit CPU detected"); - if (strcmp(mb2binfo.Kernel.CommandLine, "no64bit") == 0) - info("64-bit kernel disabled"); - else - Load64Bit = true; - } - else - { - info("32-bit CPU detected"); - } - } - else - { - error("CPUID not supported"); - while (1) - asmv("cli; hlt"); - } - if (!LoadElfInMemory(mb2binfo.Modules[0].Address, mb2binfo.Modules[0].Size, Load64Bit)) - { - error("Kernel not loaded"); - while (1) - asmv("cli; hlt"); - } - error("Unwanted reach"); - while (1) - asmv("cli; hlt"); -} diff --git a/FennixLoader/MB2Header.asm b/FennixLoader/MB2Header.asm deleted file mode 100644 index a0a9a71..0000000 --- a/FennixLoader/MB2Header.asm +++ /dev/null @@ -1,41 +0,0 @@ -section .multiboot2 -align 4096 -HEADER_START: - dd 0xE85250D6 - dd 0 - dd (HEADER_END - HEADER_START) - dd 0x100000000 - (HEADER_END - HEADER_START) - 0 - 0xE85250D6 -align 8 -MB2_INFO_REQUEST_TAG_START: - dw 1 - dw 0 - dd MB2_INFO_REQUEST_TAG_END - MB2_INFO_REQUEST_TAG_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 -MB2_INFO_REQUEST_TAG_END: -align 8 -MB2_TAG_START: - dw 0 - dw 0 - dd MB2_TAG_END - MB2_TAG_START -MB2_TAG_END: -HEADER_END: diff --git a/FennixLoader/MBHeader.asm b/FennixLoader/MBHeader.asm deleted file mode 100644 index 71a6efe..0000000 --- a/FennixLoader/MBHeader.asm +++ /dev/null @@ -1,5 +0,0 @@ -section .multiboot -align 4 - dd 0x1BADB002 - dd 1 << 0 | 1 << 1 - dd -(0x1BADB002 + (1 << 0 | 1 << 1)) diff --git a/FennixLoader/Makefile b/FennixLoader/Makefile deleted file mode 100644 index dff2107..0000000 --- a/FennixLoader/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# Config file -include ../../Makefile.conf - -NASM_ARCH = - -CC = ../../$(COMPILER_PATH)/i386-elf-gcc -CPP = ../../$(COMPILER_PATH)/i386-elf-g++ -NASM = /usr/bin/nasm - -ASM_SOURCES = $(shell find ./ -type f -name '*.asm') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CPP_SOURCES = $(shell find ./ -type f -name '*.cpp') - -OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) - -LDFLAGS = -shared -nostdlib -nodefaultlibs -nolibc -Tlinker.ld - -CFLAGS = -fno-pic -fno-pie \ - -mno-red-zone -pipe \ - -fno-builtin -Wno-main \ - -march=pentium -I./include -Wall -Wextra - -ifeq ($(DEBUG), 1) - CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fsanitize=undefined - NASM_ARCH += -F dwarf -g -endif - -build: $(OBJ) - $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) -o FLDR.elf - mv FLDR.elf ../FLDR.elf - -%.o: %.c - $(info Compiling $<) - $(CC) $(CFLAGS) -std=c17 -c $< -o $@ - -%.o: %.cpp - $(info Compiling $<) - $(CPP) $(CFLAGS) -std=c++20 -fexceptions -c $< -o $@ -fno-rtti - -%.o: %.asm - $(info Compiling $<) - $(NASM) $< $(NASM_ARCH) -f elf32 -o $@ - -clean_only_obj: - $(info Removing objects $(OBJ)) - rm -f $(OBJ) - -clean: - rm -f $(OBJ) diff --git a/FennixLoader/Memory/Bitmap.cpp b/FennixLoader/Memory/Bitmap.cpp deleted file mode 100644 index 32ce047..0000000 --- a/FennixLoader/Memory/Bitmap.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include - -bool Bitmap::operator[](uint64_t index) { return Get(index); } - -bool Bitmap::Get(uint64_t index) -{ - if (index > Size * 8) - return false; - uint64_t byteIndex = index / 8; - uint8_t bitIndex = index % 8; - uint8_t bitIndexer = 0b10000000 >> bitIndex; - if ((Buffer[byteIndex] & bitIndexer) > 0) - return true; - return false; -} - -bool Bitmap::Set(uint64_t index, bool value) -{ - if (index > Size * 8) - return false; - uint64_t byteIndex = index / 8; - uint8_t bitIndex = index % 8; - uint8_t bitIndexer = 0b10000000 >> bitIndex; - Buffer[byteIndex] &= ~bitIndexer; - if (value) - Buffer[byteIndex] |= bitIndexer; - return true; -} diff --git a/FennixLoader/Memory/Memory.cpp b/FennixLoader/Memory/Memory.cpp deleted file mode 100644 index b1b3458..0000000 --- a/FennixLoader/Memory/Memory.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include - -Memory32::Physical KernelAllocator32{}; -Memory32::PageTable *KernelPageTable32 = nullptr; - -Memory64::Physical KernelAllocator64{}; -Memory64::PageTable *KernelPageTable64 = nullptr; - -void InitializeMemoryManagement(BootInfo *Info, bool is32) -{ - if (is32) - { - trace("Initializing Physical Memory Manager"); - // KernelAllocator32 = Physical(); <- Already called in the constructor - KernelAllocator32.Init(Info); - info("Memory Info: %lldMB / %lldMB (%lldMB reserved)", - TO_MB(KernelAllocator32.UsedMemory), - TO_MB(KernelAllocator32.TotalMemory), - TO_MB(KernelAllocator32.ReservedMemory)); - - trace("Initializing Virtual Memory Manager"); - - KernelPageTable32 = (Memory32::PageTable *)KernelAllocator32.RequestPages(TO_PAGES(PAGE_SIZE + 1)); - memset(KernelPageTable32, 0, PAGE_SIZE); - - { - Memory32::Virtual va = Memory32::Virtual(KernelPageTable32); - debug("Mapping from 0x0 to %#llx", Info->Memory.Size); - size_t MemSize = Info->Memory.Size; - va.Map((void *)0, (void *)0, MemSize, PTFlag::RW); - - debug("Mapping Framebuffer"); - int itrfb = 0; - while (true) - { - if (!Info->Framebuffer[itrfb].BaseAddress) - break; - - va.Map((void *)Info->Framebuffer[itrfb].BaseAddress, - (void *)Info->Framebuffer[itrfb].BaseAddress, - Info->Framebuffer[itrfb].Pitch * Info->Framebuffer[itrfb].Height, - PTFlag::RW | PTFlag::US | PTFlag::G); - itrfb++; - } - } - - trace("Applying new page table from address %#lx", KernelPageTable32); - asmv("mov %0, %%cr3" ::"r"(KernelPageTable32)); - } -} diff --git a/FennixLoader/Memory/PhysicalMemoryManager.cpp b/FennixLoader/Memory/PhysicalMemoryManager.cpp deleted file mode 100644 index 89c9d03..0000000 --- a/FennixLoader/Memory/PhysicalMemoryManager.cpp +++ /dev/null @@ -1,583 +0,0 @@ -#include -namespace Memory32 -{ - void *Physical::RequestPage() - { - for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) - { - if (PageBitmap[PageBitmapIndex] == true) - continue; - - this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE)); - return (void *)(PageBitmapIndex * PAGE_SIZE); - } - - error("Out of memory! (Free: %ldMB; Used: %ldMB; Reserved: %ldMB)", TO_MB(FreeMemory), TO_MB(UsedMemory), TO_MB(ReservedMemory)); - while (1) - asmv("cli; hlt"); - __builtin_unreachable(); - } - - void *Physical::RequestPages(size_t Count) - { - for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) - { - if (PageBitmap[PageBitmapIndex] == true) - continue; - - for (uint64_t Index = PageBitmapIndex; Index < PageBitmap.Size * 8; Index++) - { - if (PageBitmap[Index] == true) - continue; - - for (size_t i = 0; i < Count; i++) - { - if (PageBitmap[Index + i] == true) - goto NextPage; - } - - this->LockPages((void *)(Index * PAGE_SIZE), Count); - return (void *)(Index * PAGE_SIZE); - - NextPage: - Index += Count; - continue; - } - } - - error("Out of memory! (Free: %ldMB; Used: %ldMB; Reserved: %ldMB)", TO_MB(FreeMemory), TO_MB(UsedMemory), TO_MB(ReservedMemory)); - while (1) - asmv("cli; hlt"); - __builtin_unreachable(); - } - - void Physical::FreePage(void *Address) - { - if (unlikely(Address == nullptr)) - { - warn("Null pointer passed to FreePage."); - return; - } - - size_t Index = (size_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == false)) - { - warn("Tried to free an already free page. (%p)", Address); - return; - } - - if (PageBitmap.Set(Index, false)) - { - FreeMemory += PAGE_SIZE; - UsedMemory -= PAGE_SIZE; - if (PageBitmapIndex > Index) - PageBitmapIndex = Index; - } - } - - void Physical::FreePages(void *Address, size_t Count) - { - if (unlikely(Address == nullptr || Count == 0)) - { - warn("%s%s%s passed to FreePages.", Address == nullptr ? "Null pointer " : "", Address == nullptr && Count == 0 ? "and " : "", Count == 0 ? "Zero count" : ""); - return; - } - for (size_t t = 0; t < Count; t++) - this->FreePage((void *)((uintptr_t)Address + (t * PAGE_SIZE))); - } - - void Physical::LockPage(void *Address) - { - if (unlikely(Address == nullptr)) - warn("Trying to lock null address."); - - uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == true)) - return; - - if (PageBitmap.Set(Index, true)) - { - FreeMemory -= PAGE_SIZE; - UsedMemory += PAGE_SIZE; - } - } - - void Physical::LockPages(void *Address, size_t PageCount) - { - if (unlikely(Address == nullptr || PageCount == 0)) - warn("Trying to lock %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); - - for (size_t i = 0; i < PageCount; i++) - this->LockPage((void *)((uintptr_t)Address + (i * PAGE_SIZE))); - } - - void Physical::ReservePage(void *Address) - { - if (unlikely(Address == nullptr)) - warn("Trying to reserve null address."); - - uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == true)) - return; - - if (PageBitmap.Set(Index, true)) - { - FreeMemory -= PAGE_SIZE; - ReservedMemory += PAGE_SIZE; - } - } - - void Physical::ReservePages(void *Address, size_t PageCount) - { - if (unlikely(Address == nullptr || PageCount == 0)) - warn("Trying to reserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); - - for (size_t t = 0; t < PageCount; t++) - { - uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == true)) - return; - - if (PageBitmap.Set(Index, true)) - { - FreeMemory -= PAGE_SIZE; - ReservedMemory += PAGE_SIZE; - } - } - } - - void Physical::UnreservePage(void *Address) - { - if (unlikely(Address == nullptr)) - warn("Trying to unreserve null address."); - - uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == false)) - return; - - if (PageBitmap.Set(Index, false)) - { - FreeMemory += PAGE_SIZE; - ReservedMemory -= PAGE_SIZE; - if (PageBitmapIndex > Index) - PageBitmapIndex = Index; - } - } - - void Physical::UnreservePages(void *Address, size_t PageCount) - { - if (unlikely(Address == nullptr || PageCount == 0)) - warn("Trying to unreserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); - - for (size_t t = 0; t < PageCount; t++) - { - uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == false)) - return; - - if (PageBitmap.Set(Index, false)) - { - FreeMemory += PAGE_SIZE; - ReservedMemory -= PAGE_SIZE; - if (PageBitmapIndex > Index) - PageBitmapIndex = Index; - } - } - } - - void Physical::Init(BootInfo *Info) - { - uint64_t MemorySize = Info->Memory.Size; - debug("Memory size: %lld bytes (%ld pages)", MemorySize, TO_PAGES(MemorySize)); - UsedMemory = 0; - ReservedMemory = 0; - TotalMemory = MemorySize; - FreeMemory = MemorySize; - - void *LargestFreeMemorySegment = nullptr; - uint64_t LargestFreeMemorySegmentSize = 0; - - for (uint64_t i = 0; i < Info->Memory.Entries; i++) - { - if (Info->Memory.Entry[i].Type == Usable) - { - if (Info->Memory.Entry[i].Length > LargestFreeMemorySegmentSize) - { - /* We don't want to use 0 as a memory address. */ - if (Info->Memory.Entry[i].BaseAddress == 0x0) - continue; - - LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress; - LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length; - - debug("Largest free memory segment: %llp (%lldMB)", - (void *)Info->Memory.Entry[i].BaseAddress, - TO_MB(Info->Memory.Entry[i].Length)); - } - } - } - - if (LargestFreeMemorySegment == nullptr) - { - error("No free memory found!"); - while (1) - asmv("cli; hlt"); - } - - size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1; - void *LargestFreeMemorySegmentNoKernel = nullptr; - - if ((uintptr_t)LargestFreeMemorySegment >= (uintptr_t)&_kernel_start && - (uintptr_t)LargestFreeMemorySegment <= (uintptr_t)&_kernel_end) - { - LargestFreeMemorySegmentNoKernel = (void *)((uintptr_t)LargestFreeMemorySegment + (uintptr_t)&_kernel_end); - if ((uintptr_t)LargestFreeMemorySegmentNoKernel > ((uintptr_t)LargestFreeMemorySegment + LargestFreeMemorySegmentSize)) - { - error("No free memory found!"); - while (1) - asmv("cli; hlt"); - } - } - else - { - LargestFreeMemorySegmentNoKernel = LargestFreeMemorySegment; - } - - debug("Initializing Bitmap at %llp-%llp (%lld Bytes)", - LargestFreeMemorySegmentNoKernel, - (void *)((uintptr_t)LargestFreeMemorySegmentNoKernel + BitmapSize), - BitmapSize); - - PageBitmap.Size = BitmapSize; - PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegmentNoKernel; - for (size_t i = 0; i < BitmapSize; i++) - *(uint8_t *)(PageBitmap.Buffer + i) = 0; - - debug("Reserving pages..."); - this->ReservePages(0, TO_PAGES(Info->Memory.Size)); - debug("Unreserving usable pages..."); - - for (uint64_t i = 0; i < Info->Memory.Entries; i++) - { - if (Info->Memory.Entry[i].Type == Usable) - this->UnreservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length)); - } - - debug("Reserving bitmap pages..."); - this->ReservePages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size)); - debug("Reserving kernel..."); - this->ReservePages(&_kernel_start, TO_PAGES((uintptr_t)&_kernel_end - (uintptr_t)&_kernel_start)); - debug("Reserving kernel and its modules..."); - - BootInfo::ModuleInfo *Module = &Info->Modules[0]; - int ModuleIndex = 0; - do - { - debug("Reserving %s (%p-%p)", Module->CommandLine, Module->Address, (void *)((uintptr_t)Module->Address + Module->Size)); - this->ReservePages(Module->Address, TO_PAGES(Module->Size)); - Module = &Info->Modules[++ModuleIndex]; - } while (Module->Address); - - this->ReservePages(0, 16); - } - - Physical::Physical() {} - Physical::~Physical() {} -} - -namespace Memory64 -{ - void *Physical::RequestPage() - { - for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) - { - if (PageBitmap[PageBitmapIndex] == true) - continue; - - this->LockPage((void *)(PageBitmapIndex * PAGE_SIZE)); - return (void *)(PageBitmapIndex * PAGE_SIZE); - } - - error("Out of memory! (Free: %ldMB; Used: %ldMB; Reserved: %ldMB)", TO_MB(FreeMemory), TO_MB(UsedMemory), TO_MB(ReservedMemory)); - while (1) - asmv("cli; hlt"); - __builtin_unreachable(); - } - - void *Physical::RequestPages(size_t Count) - { - for (; PageBitmapIndex < PageBitmap.Size * 8; PageBitmapIndex++) - { - if (PageBitmap[PageBitmapIndex] == true) - continue; - - for (uint64_t Index = PageBitmapIndex; Index < PageBitmap.Size * 8; Index++) - { - if (PageBitmap[Index] == true) - continue; - - for (size_t i = 0; i < Count; i++) - { - if (PageBitmap[Index + i] == true) - goto NextPage; - } - - this->LockPages((void *)(Index * PAGE_SIZE), Count); - return (void *)(Index * PAGE_SIZE); - - NextPage: - Index += Count; - continue; - } - } - - error("Out of memory! (Free: %ldMB; Used: %ldMB; Reserved: %ldMB)", TO_MB(FreeMemory), TO_MB(UsedMemory), TO_MB(ReservedMemory)); - while (1) - asmv("cli; hlt"); - __builtin_unreachable(); - } - - void Physical::FreePage(void *Address) - { - if (unlikely(Address == nullptr)) - { - warn("Null pointer passed to FreePage."); - return; - } - - size_t Index = (size_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == false)) - { - warn("Tried to free an already free page. (%p)", Address); - return; - } - - if (PageBitmap.Set(Index, false)) - { - FreeMemory += PAGE_SIZE; - UsedMemory -= PAGE_SIZE; - if (PageBitmapIndex > Index) - PageBitmapIndex = Index; - } - } - - void Physical::FreePages(void *Address, size_t Count) - { - if (unlikely(Address == nullptr || Count == 0)) - { - warn("%s%s%s passed to FreePages.", Address == nullptr ? "Null pointer " : "", Address == nullptr && Count == 0 ? "and " : "", Count == 0 ? "Zero count" : ""); - return; - } - for (size_t t = 0; t < Count; t++) - this->FreePage((void *)((uintptr_t)Address + (t * PAGE_SIZE))); - } - - void Physical::LockPage(void *Address) - { - if (unlikely(Address == nullptr)) - warn("Trying to lock null address."); - - uintptr_t Index = (uintptr_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == true)) - return; - - if (PageBitmap.Set(Index, true)) - { - FreeMemory -= PAGE_SIZE; - UsedMemory += PAGE_SIZE; - } - } - - void Physical::LockPages(void *Address, size_t PageCount) - { - if (unlikely(Address == nullptr || PageCount == 0)) - warn("Trying to lock %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); - - for (size_t i = 0; i < PageCount; i++) - this->LockPage((void *)((uintptr_t)Address + (i * PAGE_SIZE))); - } - - void Physical::ReservePage(void *Address) - { - if (unlikely(Address == nullptr)) - warn("Trying to reserve null address."); - - uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == true)) - return; - - if (PageBitmap.Set(Index, true)) - { - FreeMemory -= PAGE_SIZE; - ReservedMemory += PAGE_SIZE; - } - } - - void Physical::ReservePages(void *Address, size_t PageCount) - { - if (unlikely(Address == nullptr || PageCount == 0)) - warn("Trying to reserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); - - for (size_t t = 0; t < PageCount; t++) - { - uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == true)) - return; - - if (PageBitmap.Set(Index, true)) - { - FreeMemory -= PAGE_SIZE; - ReservedMemory += PAGE_SIZE; - } - } - } - - void Physical::UnreservePage(void *Address) - { - if (unlikely(Address == nullptr)) - warn("Trying to unreserve null address."); - - uintptr_t Index = (Address == NULL) ? 0 : (uintptr_t)Address / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == false)) - return; - - if (PageBitmap.Set(Index, false)) - { - FreeMemory += PAGE_SIZE; - ReservedMemory -= PAGE_SIZE; - if (PageBitmapIndex > Index) - PageBitmapIndex = Index; - } - } - - void Physical::UnreservePages(void *Address, size_t PageCount) - { - if (unlikely(Address == nullptr || PageCount == 0)) - warn("Trying to unreserve %s%s.", Address ? "null address" : "", PageCount ? "0 pages" : ""); - - for (size_t t = 0; t < PageCount; t++) - { - uintptr_t Index = ((uintptr_t)Address + (t * PAGE_SIZE)) / PAGE_SIZE; - - if (unlikely(PageBitmap[Index] == false)) - return; - - if (PageBitmap.Set(Index, false)) - { - FreeMemory += PAGE_SIZE; - ReservedMemory -= PAGE_SIZE; - if (PageBitmapIndex > Index) - PageBitmapIndex = Index; - } - } - } - - void Physical::Init(BootInfo *Info) - { - uint64_t MemorySize = Info->Memory.Size; - debug("Memory size: %lld bytes (%ld pages)", MemorySize, TO_PAGES(MemorySize)); - UsedMemory = 0; - ReservedMemory = 0; - TotalMemory = MemorySize; - FreeMemory = MemorySize; - - void *LargestFreeMemorySegment = nullptr; - uint64_t LargestFreeMemorySegmentSize = 0; - - for (uint64_t i = 0; i < Info->Memory.Entries; i++) - { - if (Info->Memory.Entry[i].Type == Usable) - { - if (Info->Memory.Entry[i].Length > LargestFreeMemorySegmentSize) - { - /* We don't want to use 0 as a memory address. */ - if (Info->Memory.Entry[i].BaseAddress == 0x0) - continue; - - LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress; - LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length; - - debug("Largest free memory segment: %llp (%lldMB)", - (void *)Info->Memory.Entry[i].BaseAddress, - TO_MB(Info->Memory.Entry[i].Length)); - } - } - } - - if (LargestFreeMemorySegment == nullptr) - { - error("No free memory found!"); - while (1) - asmv("cli; hlt"); - } - - size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1; - void *LargestFreeMemorySegmentNoKernel = nullptr; - - if ((uintptr_t)LargestFreeMemorySegment >= (uintptr_t)&_kernel_start && - (uintptr_t)LargestFreeMemorySegment <= (uintptr_t)&_kernel_end) - { - LargestFreeMemorySegmentNoKernel = (void *)((uintptr_t)LargestFreeMemorySegment + (uintptr_t)&_kernel_end); - if ((uintptr_t)LargestFreeMemorySegmentNoKernel > ((uintptr_t)LargestFreeMemorySegment + LargestFreeMemorySegmentSize)) - { - error("No free memory found!"); - while (1) - asmv("cli; hlt"); - } - } - else - { - LargestFreeMemorySegmentNoKernel = LargestFreeMemorySegment; - } - - debug("Initializing Bitmap at %llp-%llp (%lld Bytes)", - LargestFreeMemorySegmentNoKernel, - (void *)((uintptr_t)LargestFreeMemorySegmentNoKernel + BitmapSize), - BitmapSize); - - PageBitmap.Size = BitmapSize; - PageBitmap.Buffer = (uint8_t *)LargestFreeMemorySegmentNoKernel; - for (size_t i = 0; i < BitmapSize; i++) - *(uint8_t *)(PageBitmap.Buffer + i) = 0; - - debug("Reserving pages..."); - this->ReservePages(0, TO_PAGES(Info->Memory.Size)); - debug("Unreserving usable pages..."); - - for (uint64_t i = 0; i < Info->Memory.Entries; i++) - { - if (Info->Memory.Entry[i].Type == Usable) - this->UnreservePages(Info->Memory.Entry[i].BaseAddress, TO_PAGES(Info->Memory.Entry[i].Length)); - } - - debug("Reserving bitmap pages..."); - this->ReservePages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size)); - debug("Reserving fennix loader..."); - this->ReservePages(&_kernel_start, TO_PAGES((uintptr_t)&_kernel_end - (uintptr_t)&_kernel_start)); - debug("Reserving kernel and its modules..."); - - BootInfo::ModuleInfo *Module = &Info->Modules[0]; - int ModuleIndex = 0; - do - { - debug("Reserving %s (%p-%p)", Module->CommandLine, Module->Address, (void *)((uintptr_t)Module->Address + Module->Size)); - this->ReservePages(Module->Address, TO_PAGES(Module->Size)); - Module = &Info->Modules[++ModuleIndex]; - } while (Module->Address); - this->ReservePages(0, 16); - } - - Physical::Physical() {} - Physical::~Physical() {} -} diff --git a/FennixLoader/Memory/Setup.asm b/FennixLoader/Memory/Setup.asm deleted file mode 100644 index 5390768..0000000 --- a/FennixLoader/Memory/Setup.asm +++ /dev/null @@ -1,8 +0,0 @@ -[bits 32] -section .text -global EnablePaging -EnablePaging: - mov ecx, cr0 - or ecx, 0x80000000 ; Set PG in CR0 - mov cr0, ecx - ret diff --git a/FennixLoader/Memory/VirtualMemoryManager.cpp b/FennixLoader/Memory/VirtualMemoryManager.cpp deleted file mode 100644 index c990c9e..0000000 --- a/FennixLoader/Memory/VirtualMemoryManager.cpp +++ /dev/null @@ -1,316 +0,0 @@ -#include -#include - -namespace Memory32 -{ - void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags) - { - if (unlikely(!this->Table)) - { - error("No page table"); - return; - } - - Flags |= PTFlag::P; - - 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; - - PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex]; - PageTableEntryPtr *PTEPtr = nullptr; - if (!PDE->Present) - { - PTEPtr = (PageTableEntryPtr *)KernelAllocator32.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr) + 1)); - memset(PTEPtr, 0, sizeof(PageTableEntryPtr)); - PDE->Present = true; - PDE->SetAddress((uintptr_t)PTEPtr >> 12); - } - else - PTEPtr = (PageTableEntryPtr *)(PDE->GetAddress() << 12); - PDE->raw |= DirectoryFlags; - - PageTableEntry *PTE = &PTEPtr->Entries[Index.PTEIndex]; - PTE->Present = true; - PTE->raw |= Flags; - PTE->SetAddress((uintptr_t)PhysicalAddress >> 12); - - asmv("invlpg (%0)" ::"r"(VirtualAddress) - : "memory"); - } - - Virtual::Virtual(PageTable *Table) - { - if (Table) - this->Table = Table; - else - { - asmv("movl %%cr3, %0" - : "=r"(this->Table)); - } - } - - Virtual::~Virtual() {} -} - -namespace Memory64 -{ - bool Virtual::Check(void *VirtualAddress, PTFlag Flag, MapType Type) - { - // 0x1000 aligned - uintptr_t Address = (uintptr_t)VirtualAddress; - Address &= 0xFFFFFFFFFFFFF000; - - PageMapIndexer Index = PageMapIndexer(Address); - PageMapLevel4 PML4 = this->Table->Entries[Index.PMLIndex]; - - PageDirectoryPointerTableEntryPtr *PDPTE = nullptr; - PageDirectoryEntryPtr *PDE = nullptr; - PageTableEntryPtr *PTE = nullptr; - - if ((PML4.raw & Flag) > 0) - { - PDPTE = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12); - if (PDPTE) - { - if ((PDPTE->Entries[Index.PDPTEIndex].Present)) - { - if (Type == MapType::OneGB && PDPTE->Entries[Index.PDPTEIndex].PageSize) - return true; - - PDE = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12); - if (PDE) - { - if (Type == MapType::TwoMB && PDE->Entries[Index.PDEIndex].PageSize) - return true; - - if ((PDE->Entries[Index.PDEIndex].Present)) - { - PTE = (PageTableEntryPtr *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12); - if (PTE) - { - if ((PTE->Entries[Index.PTEIndex].Present)) - return true; - } - } - } - } - } - } - return false; - } - - void *Virtual::GetPhysical(void *VirtualAddress) - { - // 0x1000 aligned - uintptr_t Address = (uintptr_t)VirtualAddress; - Address &= 0xFFFFFFFFFFFFF000; - - PageMapIndexer Index = PageMapIndexer(Address); - PageMapLevel4 PML4 = this->Table->Entries[Index.PMLIndex]; - - PageDirectoryPointerTableEntryPtr *PDPTE = nullptr; - PageDirectoryEntryPtr *PDE = nullptr; - PageTableEntryPtr *PTE = nullptr; - - if (PML4.Present) - { - PDPTE = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4.GetAddress() << 12); - if (PDPTE) - { - if (PDPTE->Entries[Index.PDPTEIndex].Present) - { - if (PDPTE->Entries[Index.PDPTEIndex].PageSize) - return (void *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12); - - PDE = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Entries[Index.PDPTEIndex].GetAddress() << 12); - if (PDE) - { - if (PDE->Entries[Index.PDEIndex].Present) - { - if (PDE->Entries[Index.PDEIndex].PageSize) - return (void *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12); - - PTE = (PageTableEntryPtr *)((uintptr_t)PDE->Entries[Index.PDEIndex].GetAddress() << 12); - if (PTE) - { - if (PTE->Entries[Index.PTEIndex].Present) - return (void *)((uintptr_t)PTE->Entries[Index.PTEIndex].GetAddress() << 12); - } - } - } - } - } - } - return nullptr; - } - - void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type) - { - if (unlikely(!this->Table)) - { - error("No page table"); - return; - } - - Flags |= PTFlag::P; - - 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 = &this->Table->Entries[Index.PMLIndex]; - PageDirectoryPointerTableEntryPtr *PDPTEPtr = nullptr; - if (!PML4->Present) - { - PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)KernelAllocator64.RequestPages(TO_PAGES(sizeof(PageDirectoryPointerTableEntryPtr) + 1)); - memset(PDPTEPtr, 0, sizeof(PageDirectoryPointerTableEntryPtr)); - PML4->Present = true; - PML4->SetAddress((uintptr_t)PDPTEPtr >> 12); - } - else - PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)(PML4->GetAddress() << 12); - PML4->raw |= DirectoryFlags; - - PageDirectoryPointerTableEntry *PDPTE = &PDPTEPtr->Entries[Index.PDPTEIndex]; - if (Type == MapType::OneGB) - { - PDPTE->raw |= Flags; - PDPTE->PageSize = true; - PDPTE->SetAddress((uintptr_t)PhysicalAddress >> 12); - debug("Mapped 1GB page at %p to %p", VirtualAddress, PhysicalAddress); - return; - } - - PageDirectoryEntryPtr *PDEPtr = nullptr; - if (!PDPTE->Present) - { - PDEPtr = (PageDirectoryEntryPtr *)KernelAllocator64.RequestPages(TO_PAGES(sizeof(PageDirectoryEntryPtr) + 1)); - memset(PDEPtr, 0, sizeof(PageDirectoryEntryPtr)); - PDPTE->Present = true; - PDPTE->SetAddress((uintptr_t)PDEPtr >> 12); - } - else - PDEPtr = (PageDirectoryEntryPtr *)(PDPTE->GetAddress() << 12); - PDPTE->raw |= DirectoryFlags; - - PageDirectoryEntry *PDE = &PDEPtr->Entries[Index.PDEIndex]; - if (Type == MapType::TwoMB) - { - PDE->raw |= Flags; - PDE->PageSize = true; - PDE->SetAddress((uintptr_t)PhysicalAddress >> 12); - debug("Mapped 2MB page at %p to %p", VirtualAddress, PhysicalAddress); - return; - } - - PageTableEntryPtr *PTEPtr = nullptr; - if (!PDE->Present) - { - PTEPtr = (PageTableEntryPtr *)KernelAllocator64.RequestPages(TO_PAGES(sizeof(PageTableEntryPtr) + 1)); - memset(PTEPtr, 0, sizeof(PageTableEntryPtr)); - PDE->Present = true; - PDE->SetAddress((uintptr_t)PTEPtr >> 12); - } - else - PTEPtr = (PageTableEntryPtr *)(PDE->GetAddress() << 12); - PDE->raw |= DirectoryFlags; - - PageTableEntry *PTE = &PTEPtr->Entries[Index.PTEIndex]; - PTE->Present = true; - PTE->raw |= Flags; - PTE->SetAddress((uintptr_t)PhysicalAddress >> 12); - - asmv("invlpg (%0)" ::"r"(VirtualAddress) - : "memory"); - -#ifdef DEBUG -/* https://stackoverflow.com/a/3208376/9352057 */ -#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" -#define BYTE_TO_BINARY(byte) \ - (byte & 0x80 ? '1' : '0'), \ - (byte & 0x40 ? '1' : '0'), \ - (byte & 0x20 ? '1' : '0'), \ - (byte & 0x10 ? '1' : '0'), \ - (byte & 0x08 ? '1' : '0'), \ - (byte & 0x04 ? '1' : '0'), \ - (byte & 0x02 ? '1' : '0'), \ - (byte & 0x01 ? '1' : '0') - - if (!this->Check(VirtualAddress, (PTFlag)Flags, Type)) // quick workaround just to see where it fails - warn("Failed to map v:%#lx p:%#lx with flags: " BYTE_TO_BINARY_PATTERN, VirtualAddress, PhysicalAddress, BYTE_TO_BINARY(Flags)); -#endif - } - - void Virtual::Unmap(void *VirtualAddress, MapType Type) - { - if (!this->Table) - { - error("No page table"); - return; - } - - PageMapIndexer Index = PageMapIndexer((uintptr_t)VirtualAddress); - PageMapLevel4 *PML4 = &this->Table->Entries[Index.PMLIndex]; - if (!PML4->Present) - { - error("Page %#lx not present", PML4->GetAddress()); - return; - } - - PageDirectoryPointerTableEntryPtr *PDPTEPtr = (PageDirectoryPointerTableEntryPtr *)((uintptr_t)PML4->Address << 12); - PageDirectoryPointerTableEntry *PDPTE = &PDPTEPtr->Entries[Index.PDPTEIndex]; - if (!PDPTE->Present) - { - error("Page %#lx not present", PDPTE->GetAddress()); - return; - } - - if (Type == MapType::OneGB && PDPTE->PageSize) - { - PDPTE->Present = false; - return; - } - - PageDirectoryEntryPtr *PDEPtr = (PageDirectoryEntryPtr *)((uintptr_t)PDPTE->Address << 12); - PageDirectoryEntry *PDE = &PDEPtr->Entries[Index.PDEIndex]; - if (!PDE->Present) - { - error("Page %#lx not present", PDE->GetAddress()); - return; - } - - if (Type == MapType::TwoMB && PDE->PageSize) - { - PDE->Present = false; - return; - } - - PageTableEntryPtr *PTEPtr = (PageTableEntryPtr *)((uintptr_t)PDE->Address << 12); - PageTableEntry PTE = PTEPtr->Entries[Index.PTEIndex]; - if (!PTE.Present) - { - error("Page %#lx not present", PTE.GetAddress()); - return; - } - - PTE.Present = false; - PTEPtr->Entries[Index.PTEIndex] = PTE; - - asmv("invlpg (%0)" ::"r"(VirtualAddress) - : "memory"); - } - - Virtual::Virtual(PageTable *Table) - { - if (Table) - this->Table = Table; - else - { - asmv("movl %%cr3, %0" // FIXME: movq - : "=r"(this->Table)); - } - } - - Virtual::~Virtual() {} -} diff --git a/FennixLoader/Memory/memop.cpp b/FennixLoader/Memory/memop.cpp deleted file mode 100644 index 393fa85..0000000 --- a/FennixLoader/Memory/memop.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include - -void *memcpy(void *dest, const void *src, size_t n) -{ - unsigned char *d = (unsigned char *)dest; - const unsigned char *s = (const unsigned char *)src; - while (n--) - *d++ = *s++; - return dest; -} - -void *memset(void *s, int c, size_t n) -{ - unsigned char *p = (unsigned char *)s; - while (n--) - *p++ = (unsigned char)c; - return s; -} diff --git a/FennixLoader/UndefinedBehaviorSanitization.c b/FennixLoader/UndefinedBehaviorSanitization.c deleted file mode 100644 index 8052522..0000000 --- a/FennixLoader/UndefinedBehaviorSanitization.c +++ /dev/null @@ -1,513 +0,0 @@ -#include "ubsan.h" -#include - -extern void __asan_report_load1(void *unknown) -{ - ubsan("load1"); - UNUSED(unknown); -} - -extern void __asan_report_load2(void *unknown) -{ - ubsan("load2"); - UNUSED(unknown); -} - -extern void __asan_report_load4(void *unknown) -{ - ubsan("load4"); - UNUSED(unknown); -} - -extern void __asan_report_load8(void *unknown) -{ - ubsan("load8"); - UNUSED(unknown); -} - -extern void __asan_report_load16(void *unknown) -{ - ubsan("load16"); - UNUSED(unknown); -} - -extern void __asan_report_load_n(void *unknown, uintptr_t size) -{ - ubsan("loadn"); - UNUSED(unknown); - UNUSED(size); -} - -extern void __asan_report_store1(void *unknown) -{ - ubsan("store1"); - UNUSED(unknown); -} - -extern void __asan_report_store2(void *unknown) -{ - ubsan("store2"); - UNUSED(unknown); -} - -extern void __asan_report_store4(void *unknown) -{ - ubsan("store4"); - UNUSED(unknown); -} - -extern void __asan_report_store8(void *unknown) -{ - ubsan("store8"); - UNUSED(unknown); -} - -extern void __asan_report_store16(void *unknown) -{ - ubsan("store16"); - UNUSED(unknown); -} - -extern void __asan_report_store_n(void *unknown, uintptr_t size) -{ - ubsan("storen"); - UNUSED(unknown); - UNUSED(size); -} - -extern void __asan_report_load1_noabort(void *unknown) -{ - ubsan("load1"); - UNUSED(unknown); -} - -extern void __asan_report_load2_noabort(void *unknown) -{ - ubsan("load2"); - UNUSED(unknown); -} - -extern void __asan_report_load4_noabort(void *unknown) -{ - ubsan("load4"); - UNUSED(unknown); -} - -extern void __asan_report_load8_noabort(void *unknown) -{ - ubsan("load8"); - UNUSED(unknown); -} - -extern void __asan_report_load16_noabort(void *unknown) -{ - ubsan("load16"); - UNUSED(unknown); -} - -extern void __asan_report_load_n_noabort(void *unknown, uintptr_t size) -{ - ubsan("loadn"); - UNUSED(unknown); - UNUSED(size); -} - -extern void __asan_report_store1_noabort(void *unknown) -{ - ubsan("store1"); - UNUSED(unknown); -} - -extern void __asan_report_store2_noabort(void *unknown) -{ - ubsan("store2"); - UNUSED(unknown); -} - -extern void __asan_report_store4_noabort(void *unknown) -{ - ubsan("store4"); - UNUSED(unknown); -} - -extern void __asan_report_store8_noabort(void *unknown) -{ - ubsan("store8"); - UNUSED(unknown); -} - -extern void __asan_report_store16_noabort(void *unknown) -{ - ubsan("store16"); - UNUSED(unknown); -} - -extern void __asan_report_store_n_noabort(void *unknown, uintptr_t size) -{ - ubsan("storen"); - UNUSED(unknown); - UNUSED(size); -} - -extern void __asan_stack_malloc_0(uintptr_t size) -{ - ubsan("stack malloc 0"); - UNUSED(size); -} - -extern void __asan_stack_malloc_1(uintptr_t size) -{ - ubsan("stack malloc 1"); - UNUSED(size); -} - -extern void __asan_stack_malloc_2(uintptr_t size) -{ - ubsan("stack malloc 2"); - UNUSED(size); -} - -extern void __asan_stack_malloc_3(uintptr_t size) -{ - ubsan("stack malloc 3"); - UNUSED(size); -} - -extern void __asan_stack_malloc_4(uintptr_t size) -{ - ubsan("stack malloc 4"); - UNUSED(size); -} - -extern void __asan_stack_malloc_5(uintptr_t size) -{ - ubsan("stack malloc 5"); - UNUSED(size); -} - -extern void __asan_stack_malloc_6(uintptr_t size) -{ - ubsan("stack malloc 6"); - UNUSED(size); -} - -extern void __asan_stack_malloc_7(uintptr_t size) -{ - ubsan("stack malloc 7"); - UNUSED(size); -} - -extern void __asan_stack_malloc_8(uintptr_t size) -{ - ubsan("stack malloc 8"); - UNUSED(size); -} - -extern void __asan_stack_malloc_9(uintptr_t size) -{ - ubsan("stack malloc 9"); - UNUSED(size); -} - -extern void __asan_stack_free_0(void *ptr, uintptr_t size) -{ - ubsan("stack free 0"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_1(void *ptr, uintptr_t size) -{ - ubsan("stack free 1"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_2(void *ptr, uintptr_t size) -{ - ubsan("stack free 2"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_3(void *ptr, uintptr_t size) -{ - ubsan("stack free 3"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_4(void *ptr, uintptr_t size) -{ - ubsan("stack free 4"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_5(void *ptr, uintptr_t size) -{ - ubsan("stack free 5"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_6(void *ptr, uintptr_t size) -{ - ubsan("stack free 6"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_7(void *ptr, uintptr_t size) -{ - ubsan("stack free 7"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_8(void *ptr, uintptr_t size) -{ - ubsan("stack free 8"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_stack_free_9(void *ptr, uintptr_t size) -{ - ubsan("stack free 9"); - UNUSED(ptr); - UNUSED(size); -} - -extern void __asan_poison_stack_memory(void *addr, uintptr_t size) -{ - ubsan("poison stack memory"); - UNUSED(addr); - UNUSED(size); -} - -extern void __asan_unpoison_stack_memory(void *addr, uintptr_t size) -{ - ubsan("unpoison stack memory"); - UNUSED(addr); - UNUSED(size); -} - -extern void __asan_before_dynamic_init(const char *module_name) -{ - ubsan("before dynamic init"); - UNUSED(module_name); -} - -extern void __asan_after_dynamic_init(void) { ubsan("after dynamic init"); } - -extern void __asan_register_globals(void *unknown, size_t size) -{ - ubsan("register_globals"); - UNUSED(unknown); - UNUSED(size); -} - -extern void __asan_unregister_globals(void) { ubsan("unregister_globals"); } - -extern void __asan_init(void) { ubsan("init"); } -extern void __asan_version_mismatch_check_v8(void) { ubsan("version_mismatch_check_v8"); } -extern void __asan_option_detect_stack_use_after_return(void) { ubsan("stack use after return"); } - -extern __noreturn void __asan_handle_no_return(void) -{ - ubsan("no_return"); - while (1) - asmv("cli; hlt"); -} - -#define is_aligned(value, alignment) !(value & (alignment - 1)) - -const char *Type_Check_Kinds[] = { - "Load of", - "Store to", - "Reference binding to", - "Member access within", - "Member call on", - "Constructor call on", - "Downcast of", - "Downcast of", - "Upcast of", - "Cast to virtual base of", -}; - -bool UBSANMsg(const char *file, uint32_t line, uint32_t column) -{ - ubsan("\t\tIn File: %s:%i:%i", file, line, column); - return true; -} - -void __ubsan_handle_type_mismatch_v1(struct type_mismatch_v1_data *type_mismatch, uintptr_t pointer) -{ - struct source_location *location = &type_mismatch->location; - if (pointer == 0) - { - if (UBSANMsg(location->file, location->line, location->column)) - { - ubsan("Null pointer access."); - } - } - else if (type_mismatch->alignment != 0 && is_aligned(pointer, type_mismatch->alignment)) - { - if (UBSANMsg(location->file, location->line, location->column)) - { - ubsan("Unaligned memory access %#llx.", pointer); - } - } - else - { - if (UBSANMsg(location->file, location->line, location->column)) - { - ubsan("%s address %#llx with insufficient space for object of type %s", - Type_Check_Kinds[type_mismatch->type_check_kind], (void *)pointer, type_mismatch->type->name); - } - } -} - -void __ubsan_handle_add_overflow(struct overflow_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Addition overflow."); - } -} - -void __ubsan_handle_sub_overflow(struct overflow_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Subtraction overflow."); - } -} - -void __ubsan_handle_mul_overflow(struct overflow_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Multiplication overflow."); - } -} - -void __ubsan_handle_divrem_overflow(struct overflow_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Division overflow."); - } -} - -void __ubsan_handle_negate_overflow(struct overflow_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Negation overflow."); - } -} - -void __ubsan_handle_pointer_overflow(struct overflow_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Pointer overflow."); - } -} - -void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Shift out of bounds."); - } -} - -void __ubsan_handle_load_invalid_value(struct invalid_value_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Invalid load value."); - } -} - -void __ubsan_handle_out_of_bounds(struct array_out_of_bounds_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Array out of bounds."); - } -} - -void __ubsan_handle_vla_bound_not_positive(struct negative_vla_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Variable-length argument is negative."); - } -} - -void __ubsan_handle_nonnull_return(struct nonnull_return_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Non-null return is null."); - } -} - -void __ubsan_handle_nonnull_return_v1(struct nonnull_return_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Non-null return is null."); - } -} - -void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Non-null argument is null."); - } -} - -void __ubsan_handle_builtin_unreachable(struct unreachable_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Unreachable code reached."); - } -} - -void __ubsan_handle_invalid_builtin(struct invalid_builtin_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Invalid builtin."); - } -} - -void __ubsan_handle_missing_return(struct unreachable_data *data) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Missing return."); - } -} - -void __ubsan_vptr_type_cache(uintptr_t *cache, uintptr_t ptr) -{ - ubsan("Vptr type cache."); - *cache = ptr; -} - -void __ubsan_handle_dynamic_type_cache_miss(struct dynamic_type_cache_miss_data *data, uintptr_t ptr) -{ - if (UBSANMsg(data->location.file, data->location.line, data->location.column)) - { - ubsan("Dynamic type cache miss."); - } - UNUSED(ptr); -} diff --git a/FennixLoader/UniversalAsynchronousReceiverTransmitter.cpp b/FennixLoader/UniversalAsynchronousReceiverTransmitter.cpp deleted file mode 100644 index 7010ed8..0000000 --- a/FennixLoader/UniversalAsynchronousReceiverTransmitter.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include - -volatile bool serialports[8] = {false, false, false, false, false, false, false, false}; - - -__always_inline inline uint8_t inportb(uint16_t Port) -{ - uint8_t Result; - asm("in %%dx, %%al" - : "=a"(Result) - : "d"(Port)); - return Result; -} - -__always_inline inline void outportb(uint16_t Port, uint8_t Data) -{ - asmv("out %%al, %%dx" - : - : "a"(Data), "d"(Port)); -} - -namespace UniversalAsynchronousReceiverTransmitter -{ -#define SERIAL_ENABLE_DLAB 0x80 -#define SERIAL_RATE_115200_LO 0x01 -#define SERIAL_RATE_115200_HI 0x00 -#define SERIAL_RATE_57600_LO 0x02 -#define SERIAL_RATE_57600_HI 0x00 -#define SERIAL_RATE_38400_LO 0x03 -#define SERIAL_RATE_38400_HI 0x00 -#define SERIAL_BUFFER_EMPTY 0x20 - - /* TODO: Serial Port implementation needs reword. https://wiki.osdev.org/Serial_Ports */ - - SafeFunction UART::UART(SerialPorts Port) - { - if (Port == COMNULL) - return; - - this->Port = Port; - int PortNumber = 0; - - switch (Port) - { - case COM1: - PortNumber = 0; - break; - case COM2: - PortNumber = 1; - break; - case COM3: - PortNumber = 2; - break; - case COM4: - PortNumber = 3; - break; - case COM5: - PortNumber = 4; - break; - case COM6: - PortNumber = 5; - break; - case COM7: - PortNumber = 6; - break; - case COM8: - PortNumber = 7; - break; - default: - return; - } - - if (serialports[PortNumber]) - return; - - // Initialize the serial port - outportb(s_cst(uint16_t, Port + 1), 0x00); // Disable all interrupts - outportb(s_cst(uint16_t, Port + 3), SERIAL_ENABLE_DLAB); // Enable DLAB (set baud rate divisor) - outportb(s_cst(uint16_t, Port + 0), SERIAL_RATE_115200_LO); // Set divisor to 1 (lo byte) 115200 baud - outportb(s_cst(uint16_t, Port + 1), SERIAL_RATE_115200_HI); // (hi byte) - outportb(s_cst(uint16_t, Port + 3), 0x03); // 8 bits, no parity, one stop bit - outportb(s_cst(uint16_t, Port + 2), 0xC7); // Enable FIFO, clear them, with 14-byte threshold - outportb(s_cst(uint16_t, Port + 4), 0x0B); // IRQs enabled, RTS/DSR set - - // Check if the serial port is faulty. - if (inportb(s_cst(uint16_t, Port + 0)) != 0xAE) - { - static int once = 0; - if (!once++) - warn("Serial port %#llx is faulty.", Port); - // serialports[Port] = false; // ignore for now - // return; - } - - // Set to normal operation mode. - outportb(s_cst(uint16_t, Port + 4), 0x0F); - serialports[PortNumber] = true; - } - - SafeFunction UART::~UART() {} - - SafeFunction void UART::Write(uint8_t Char) - { - while ((inportb(s_cst(uint16_t, Port + 5)) & SERIAL_BUFFER_EMPTY) == 0) - ; - outportb(Port, Char); - } - - SafeFunction uint8_t UART::Read() - { - while ((inportb(s_cst(uint16_t, Port + 5)) & 1) == 0) - ; - return inportb(Port); - } -} diff --git a/FennixLoader/cxxabi.cpp b/FennixLoader/cxxabi.cpp deleted file mode 100644 index 7591c16..0000000 --- a/FennixLoader/cxxabi.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#include - -#include -#include - -// TODO: complete implementation for everything -// TODO: https://wiki.osdev.org/C%2B%2B - -#define ATEXIT_MAX_FUNCS 128 - -typedef unsigned uarch_t; - -struct atexit_func_entry_t -{ - /* - * Each member is at least 4 bytes large. Such that each entry is 12bytes. - * 128 * 12 = 1.5KB exact. - **/ - void (*destructor_func)(void *); - void *obj_ptr; - void *dso_handle; -}; - -typedef enum -{ - _URC_NO_REASON = 0, - _URC_FOREIGN_EXCEPTION_CAUGHT = 1, - _URC_FATAL_PHASE2_ERROR = 2, - _URC_FATAL_PHASE1_ERROR = 3, - _URC_NORMAL_STOP = 4, - _URC_END_OF_STACK = 5, - _URC_HANDLER_FOUND = 6, - _URC_INSTALL_CONTEXT = 7, - _URC_CONTINUE_UNWIND = 8 -} _Unwind_Reason_Code; - -struct _Unwind_Context; -typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); -typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); -typedef unsigned _Unwind_Word __attribute__((__mode__(__unwind_word__))); -typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code, struct _Unwind_Exception *); -typedef int _Unwind_Action; - -struct type_info -{ - const char *name; -}; - -struct unexpected_handler -{ - void (*unexpected)(); -}; - -struct terminate_handler -{ - void (*handler)(); -}; - -struct _Unwind_Exception -{ - _Unwind_Exception_Class exception_class; - _Unwind_Exception_Cleanup_Fn exception_cleanup; -#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__SEH__) - _Unwind_Word private_[6]; -#else - _Unwind_Word private_1; - _Unwind_Word private_2; -#endif -} __attribute__((__aligned__)); - -struct __cxa_exception -{ -#if __LP64__ - size_t referenceCount; -#endif - type_info *exceptionType; - void (*exceptionDestructor)(void *); - unexpected_handler unexpectedHandler; - terminate_handler terminateHandler; - __cxa_exception *nextException; - int handlerCount; - -#ifdef __ARM_EABI_UNWINDER__ - __cxa_exception *nextPropagatingException; - int propagationCount; -#else - int handlerSwitchValue; - const unsigned char *actionRecord; - const unsigned char *languageSpecificData; - _Unwind_Ptr catchTemp; - void *adjustedPtr; -#endif -#if !__LP64__ - size_t referenceCount; -#endif - _Unwind_Exception unwindHeader; -}; - -/* extern */ void *__dso_handle = 0; -atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS]; -uarch_t __atexit_func_count = 0; - -extern "C" int __cxa_atexit(void (*f)(void *), void *objptr, void *dso) -{ - fixme("__cxa_atexit( %p %p %p ) triggered.", f, objptr, dso); - if (__atexit_func_count >= ATEXIT_MAX_FUNCS) - return -1; - __atexit_funcs[__atexit_func_count].destructor_func = f; - __atexit_funcs[__atexit_func_count].obj_ptr = objptr; - __atexit_funcs[__atexit_func_count].dso_handle = dso; - __atexit_func_count++; - return 0; -} - -extern "C" void __cxa_finalize(void *f) -{ - fixme("__cxa_finalize( %p ) triggered.", f); - uarch_t i = __atexit_func_count; - if (!f) - { - while (i--) - if (__atexit_funcs[i].destructor_func) - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - - return; - } - - while (i--) - if (__atexit_funcs[i].destructor_func == f) - { - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - __atexit_funcs[i].destructor_func = 0; - } -} - -extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action actions, _Unwind_Exception_Class exception_class, _Unwind_Exception *ue_header, _Unwind_Context *context) -{ - fixme("__gxx_personality_v0( %d %p %p %p %p ) triggered.", version, actions, exception_class, ue_header, context); - return _URC_NO_REASON; -} - -extern "C" void _Unwind_Resume(struct _Unwind_Exception *exc) { fixme("_Unwind_Resume( %p ) triggered.", exc); } - -static inline size_t align_exception_allocation_size(size_t s, size_t a) { return (s + a - 1) & ~(a - 1); } - -void unexpected_header_stub() { fixme("unexpected() called."); } -void terminate_header_stub() { fixme("terminate() called."); } - -extern "C" void *__cxa_allocate_exception(size_t thrown_size) throw() -{ - fixme("__cxa_allocate_exception( %d ) triggered.", thrown_size); - - size_t real_size = align_exception_allocation_size(thrown_size + sizeof(__cxa_exception), alignof(__cxa_exception)); - - __cxa_exception *header = (__cxa_exception *)KernelAllocator32.RequestPages(TO_PAGES(real_size)); - if (!header) - { - error("Failed to allocate exception."); - return nullptr; - } - - header->referenceCount = 1; - header->exceptionType = nullptr; - header->exceptionDestructor = nullptr; - header->unexpectedHandler = {.unexpected = unexpected_header_stub}; - header->terminateHandler = {.handler = terminate_header_stub}; - header->nextException = nullptr; - header->handlerCount = -1; - header->handlerSwitchValue = 0; - header->actionRecord = nullptr; - header->languageSpecificData = nullptr; - header->catchTemp = 0; - header->adjustedPtr = nullptr; - - return header + 1; -} - -extern "C" void _Unwind_RaiseException(_Unwind_Exception *exc) -{ - fixme("_Unwind_RaiseException( %p ) triggered.", exc); - - __cxa_exception *header = ((__cxa_exception *)exc) - 1; - if (header->terminateHandler.handler) - { - debug("Calling terminate handler."); - header->terminateHandler.handler(); - } - else - { - error("Unhandled exception."); - } - - while (1) - asmv("cli; hlt"); -} - -extern "C" void __cxa_throw(void *thrown_object, void *tinfo, void (*dest)(void *)) -{ - fixme("__cxa_throw( %p %p %p ) triggered.", thrown_object, tinfo, dest); - - __cxa_exception *header = ((__cxa_exception *)thrown_object) - 1; - header->exceptionType = (type_info *)tinfo; - header->exceptionDestructor = dest; - - _Unwind_RaiseException(&header->unwindHeader); -} - -extern "C" void __cxa_rethrow() { fixme("__cxa_rethrow() triggered."); } - -extern "C" void __cxa_pure_virtual() { fixme("__cxa_pure_virtual() triggered."); } - -extern "C" void __cxa_throw_bad_array_new_length() { fixme("__cxa_throw_bad_array_new_length() triggered."); } - -extern "C" void __cxa_free_exception(void *thrown_exception) { fixme("__cxa_free_exception( %p ) triggered.", thrown_exception); } - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -extern "C" void *__cxa_begin_catch(void *e) throw() -#else -extern "C" void *__cxa_begin_catch(void *e) -#endif -{ - fixme("__cxa_begin_catch( %p ) triggered.", e); - return (void *)0; -} - -extern "C" void __cxa_end_catch() { fixme("__cxa_end_catch() triggered."); } - -__extension__ typedef int __guard __attribute__((mode(__DI__))); - -extern "C" int __cxa_guard_acquire(__guard *g) -{ - fixme("__cxa_guard_acquire( %p ) triggered.", g); - return !*(char *)(g); -} - -extern "C" void __cxa_guard_release(__guard *g) -{ - fixme("__cxa_guard_release( %p ) triggered.", g); - *(char *)g = 1; -} - -extern "C" void __cxa_guard_abort(__guard *g) { fixme("__cxa_guard_abort( %p ) triggered.", g); } - -// vtable for __cxxabiv1::__class_type_info -extern "C" void *_ZTVN10__cxxabiv117__class_type_infoE(void) -{ - fixme("_ZTVN10__cxxabiv117__class_type_infoE() triggered."); - return (void *)0; -} - -// vtable for __cxxabiv1::__si_class_type_info -extern "C" void *_ZTVN10__cxxabiv120__si_class_type_infoE(void) -{ - fixme("_ZTVN10__cxxabiv120__si_class_type_infoE() triggered."); - return (void *)0; -} - -// typeinfo for int -extern "C" void *_ZTIi(void) -{ - fixme("_ZTIi() triggered."); - return (void *)0; -} - -// typeinfo for unsigned char* -extern "C" void *_ZTIPh(void) -{ - fixme("_ZTIPh() triggered."); - return (void *)0; -} - -// typeinfo for char const* -extern "C" void *_ZTIPKc(void) -{ - fixme("_ZTIPKc() triggered."); - return (void *)0; -} diff --git a/FennixLoader/ega.c b/FennixLoader/ega.c deleted file mode 100644 index 91af888..0000000 --- a/FennixLoader/ega.c +++ /dev/null @@ -1,166 +0,0 @@ -/* https://wiki.osdev.org/Bare_Bones */ -#include - -enum vga_color -{ - VGA_COLOR_BLACK = 0, - VGA_COLOR_BLUE = 1, - VGA_COLOR_GREEN = 2, - VGA_COLOR_CYAN = 3, - VGA_COLOR_RED = 4, - VGA_COLOR_MAGENTA = 5, - VGA_COLOR_BROWN = 6, - VGA_COLOR_LIGHT_GREY = 7, - VGA_COLOR_DARK_GREY = 8, - VGA_COLOR_LIGHT_BLUE = 9, - VGA_COLOR_LIGHT_GREEN = 10, - VGA_COLOR_LIGHT_CYAN = 11, - VGA_COLOR_LIGHT_RED = 12, - VGA_COLOR_LIGHT_MAGENTA = 13, - VGA_COLOR_LIGHT_BROWN = 14, - VGA_COLOR_WHITE = 15, -}; - -void outb(uint16_t port, uint8_t val) -{ - asm volatile("outb %0, %1" - : - : "a"(val), "Nd"(port)); -} - -static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) -{ - return fg | bg << 4; -} - -static inline uint16_t vga_entry(unsigned char uc, uint8_t color) -{ - return (uint16_t)uc | (uint16_t)color << 8; -} - -size_t ega_strlen(const char *str) -{ - size_t len = 0; - while (str[len]) - len++; - return len; -} - -static const size_t VGA_WIDTH = 80; -static const size_t VGA_HEIGHT = 25; - -int terminal_initialized; -size_t terminal_row; -size_t terminal_column; -uint8_t terminal_color; -uint16_t *terminal_buffer; - -void terminal_initialize(void) -{ - terminal_initialized = 1; - terminal_row = 0; - terminal_column = 0; - terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - terminal_buffer = (uint16_t *)0xB8000; - for (size_t y = 0; y < VGA_HEIGHT; y++) - { - for (size_t x = 0; x < VGA_WIDTH; x++) - { - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(' ', terminal_color); - } - } -} - -void terminal_setcolor(uint8_t color) -{ - terminal_color = color; -} - -void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) -{ - if (!terminal_initialized) - return; - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(c, color); -} - -void terminal_putchar(char c) -{ - if (!terminal_initialized) - return; - - switch (c) - { - case '\n': - case '\r': - terminal_column = 0; - if (++terminal_row >= VGA_HEIGHT) - { - // terminal_row = 0; - // scroll the screen - for (size_t y = 0; y < VGA_HEIGHT - 1; y++) - { - for (size_t x = 0; x < VGA_WIDTH; x++) - { - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = terminal_buffer[index + VGA_WIDTH]; - } - } - for (size_t x = 0; x < VGA_WIDTH; x++) - { - const size_t index = (VGA_HEIGHT - 1) * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(' ', terminal_color); - } - terminal_row = VGA_HEIGHT - 1; - } - // Update the cursor - uint16_t cursorLocation = terminal_row * 80 + terminal_column; - outb(0x3D4, 14); // Tell the VGA board we are setting the high cursor byte. - outb(0x3D5, cursorLocation >> 8); // Send the high cursor byte. - outb(0x3D4, 15); // Tell the VGA board we are setting the low cursor byte. - outb(0x3D5, cursorLocation); // Send the low cursor byte. - return; - case '\t': - terminal_column += 4; - if (terminal_column >= VGA_WIDTH) - { - terminal_column = 0; - if (++terminal_row == VGA_HEIGHT) - terminal_row = 0; - } - return; - } - - terminal_putentryat(c, terminal_color, terminal_column, terminal_row); - if (++terminal_column >= VGA_WIDTH) - { - terminal_column = 0; - if (++terminal_row >= VGA_HEIGHT) - { - // terminal_row = 0; - // scroll the screen - for (size_t y = 0; y < VGA_HEIGHT - 1; y++) - { - for (size_t x = 0; x < VGA_WIDTH; x++) - { - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = terminal_buffer[index + VGA_WIDTH]; - } - } - for (size_t x = 0; x < VGA_WIDTH; x++) - { - const size_t index = (VGA_HEIGHT - 1) * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(' ', terminal_color); - } - terminal_row = VGA_HEIGHT - 1; - } - } - - // Update the cursor - uint16_t cursorLocation = terminal_row * 80 + terminal_column; - outb(0x3D4, 14); // Tell the VGA board we are setting the high cursor byte. - outb(0x3D5, cursorLocation >> 8); // Send the high cursor byte. - outb(0x3D4, 15); // Tell the VGA board we are setting the low cursor byte. - outb(0x3D5, cursorLocation); // Send the low cursor byte. -} diff --git a/FennixLoader/include/binfo.h b/FennixLoader/include/binfo.h deleted file mode 100644 index eb40b0f..0000000 --- a/FennixLoader/include/binfo.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef __FENNIX_KERNEL_BOOT_INFO_H__ -#define __FENNIX_KERNEL_BOOT_INFO_H__ - -enum MemoryType -{ - Unknown_Memory_Type, - Usable, - Reserved, - ACPIReclaimable, - ACPINVS, - BadMemory, - BootloaderReclaimable, - KernelAndModules, - Framebuffer, - Unknown -}; - -enum FramebufferType -{ - Unknown_Framebuffer_Type, - Indexed, - RGB, - EGA -}; - -#define MAX_FRAMEBUFFERS 16 -#define MAX_MEMORY_ENTRIES 256 -#define MAX_MODULES 16 - -struct BootInfo -{ - struct FramebufferInfo - { - enum FramebufferType Type; - void *BaseAddress; - __UINT32_TYPE__ Width; - __UINT32_TYPE__ Height; - __UINT64_TYPE__ Pitch; - __UINT16_TYPE__ BitsPerPixel; - __UINT8_TYPE__ RedMaskSize; - __UINT8_TYPE__ RedMaskShift; - __UINT8_TYPE__ GreenMaskSize; - __UINT8_TYPE__ GreenMaskShift; - __UINT8_TYPE__ BlueMaskSize; - __UINT8_TYPE__ BlueMaskShift; - void *ExtendedDisplayIdentificationData; - __UINT64_TYPE__ EDIDSize; - } Framebuffer[MAX_FRAMEBUFFERS]; - - struct MemoryInfo - { - struct MemoryEntryInfo - { - void *BaseAddress; - __UINT64_TYPE__ Length; - enum MemoryType Type; - } Entry[MAX_MEMORY_ENTRIES]; - __UINT64_TYPE__ Entries; - __UINT64_TYPE__ Size; - } Memory; - - struct ModuleInfo - { - void *Address; - char Path[256]; - char CommandLine[256]; - __UINT64_TYPE__ Size; - } Modules[MAX_MODULES]; - - struct RSDPInfo - { - /** - * @brief Signature - */ - __UINT8_TYPE__ Signature[8]; - /** - * @brief Checksum - */ - __UINT8_TYPE__ Checksum; - /** - * @brief OEM ID - */ - __UINT8_TYPE__ OEMID[6]; - /** - * @brief Revision - */ - __UINT8_TYPE__ Revision; - /** - * @brief Address of the Root System Description Table - */ - __UINT32_TYPE__ RSDTAddress; - /* END OF RSDP 1.0 */ - - /** - * @brief Length - */ - __UINT32_TYPE__ Length; - /** - * @brief Extended System Descriptor Table - */ - __UINT64_TYPE__ XSDTAddress; - /** - * @brief Extended checksum - */ - __UINT8_TYPE__ ExtendedChecksum; - /** - * @brief Reserved - */ - __UINT8_TYPE__ Reserved[3]; - } __attribute__((packed)) * RSDP; - - struct KernelInfo - { - void *PhysicalBase; - void *VirtualBase; - void *FileBase; - char CommandLine[256]; - __UINT64_TYPE__ Size; - } Kernel; - - struct BootloaderInfo - { - char Name[256]; - char Version[64]; - } Bootloader; - - void *SMBIOSPtr; -}; - -#endif // !__FENNIX_KERNEL_BOOT_INFO_H__ diff --git a/FennixLoader/include/bitmap.hpp b/FennixLoader/include/bitmap.hpp deleted file mode 100644 index b34d5be..0000000 --- a/FennixLoader/include/bitmap.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include - -class Bitmap -{ -public: - size_t Size; - uint8_t *Buffer; - bool operator[](uint64_t index); - bool Set(uint64_t index, bool value); - bool Get(uint64_t index); -}; diff --git a/FennixLoader/include/debug.h b/FennixLoader/include/debug.h deleted file mode 100644 index d68ef3c..0000000 --- a/FennixLoader/include/debug.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef __FENNIX_KERNEL_DEBUGGER_H__ -#define __FENNIX_KERNEL_DEBUGGER_H__ - -#include - -enum DebugLevel -{ - DebugLevelNone = 0, - DebugLevelError = 1, - DebugLevelWarning = 2, - DebugLevelInfo = 3, - DebugLevelDebug = 4, - DebugLevelTrace = 5, - DebugLevelFixme = 6, - DebugLevelUbsan = 7 -}; - -#ifdef __cplusplus - -namespace SysDbg -{ - void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); - void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); - void LockedWrite(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); - void LockedWriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); -} - -#define error(Format, ...) SysDbg::WriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define warn(Format, ...) SysDbg::WriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define info(Format, ...) SysDbg::WriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#ifdef DEBUG -#define debug(Format, ...) SysDbg::WriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define ubsan(Format, ...) SysDbg::WriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#else -#define debug(Format, ...) -#define ubsan(Format, ...) -#endif -#define trace(Format, ...) SysDbg::WriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define fixme(Format, ...) SysDbg::WriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) - -#define locked_error(Format, ...) SysDbg::LockedWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_warn(Format, ...) SysDbg::LockedWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_info(Format, ...) SysDbg::LockedWriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#ifdef DEBUG -#define locked_debug(Format, ...) SysDbg::LockedWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_ubsan(Format, ...) SysDbg::LockedWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#else -#define locked_debug(Format, ...) -#define locked_ubsan(Format, ...) -#endif -#define locked_trace(Format, ...) SysDbg::LockedWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_fixme(Format, ...) SysDbg::LockedWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) - -#else - -void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); -void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); -void SysDbgLockedWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); -void SysDbgLockedWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...); - -#define error(Format, ...) SysDbgWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define warn(Format, ...) SysDbgWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define info(Format, ...) SysDbgWriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#ifdef DEBUG -#define debug(Format, ...) SysDbgWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define ubsan(Format, ...) SysDbgWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#else -#define debug(Format, ...) -#define ubsan(Format, ...) -#endif -#define trace(Format, ...) SysDbgWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define fixme(Format, ...) SysDbgWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) - -#define locked_error(Format, ...) SysDbgLockedWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_warn(Format, ...) SysDbgLockedWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_info(Format, ...) SysDbgLockedWriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#ifdef DEBUG -#define locked_debug(Format, ...) SysDbgLockedWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_ubsan(Format, ...) SysDbgLockedWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#else -#define locked_debug(Format, ...) -#define locked_ubsan(Format, ...) -#endif -#define locked_trace(Format, ...) SysDbgLockedWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) -#define locked_fixme(Format, ...) SysDbgLockedWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__) - -#endif // __cplusplus - -#endif // !__FENNIX_KERNEL_DEBUGGER_H__ diff --git a/FennixLoader/include/elf.h b/FennixLoader/include/elf.h deleted file mode 100644 index 24818eb..0000000 --- a/FennixLoader/include/elf.h +++ /dev/null @@ -1,476 +0,0 @@ -#ifndef __FENNIX_KERNEL_ELF_H__ -#define __FENNIX_KERNEL_ELF_H__ - -#include - -// https://wiki.osdev.org/ELF_Tutorial -// https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h - -/* 32-bit ELF base types. */ -typedef uint32_t Elf32_Addr; -typedef uint16_t Elf32_Half; -typedef uint32_t Elf32_Off; -typedef int32_t Elf32_Sword; -typedef uint32_t Elf32_Word; - -/* 64-bit ELF base types. */ -typedef uint64_t Elf64_Addr; -typedef uint16_t Elf64_Half; -typedef int16_t Elf64_SHalf; -typedef uint64_t Elf64_Off; -typedef int32_t Elf64_Sword; -typedef uint32_t Elf64_Word; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; - -#define EI_NIDENT 16 - -typedef struct elf32_hdr -{ - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -} Elf32_Ehdr; - -typedef struct elf64_hdr -{ - unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ - Elf64_Half e_type; - Elf64_Half e_machine; - Elf64_Word e_version; - Elf64_Addr e_entry; /* Entry point virtual address */ - Elf64_Off e_phoff; /* Program header table file offset */ - Elf64_Off e_shoff; /* Section header table file offset */ - Elf64_Word e_flags; - Elf64_Half e_ehsize; - Elf64_Half e_phentsize; - Elf64_Half e_phnum; - Elf64_Half e_shentsize; - Elf64_Half e_shnum; - Elf64_Half e_shstrndx; -} Elf64_Ehdr; - -typedef struct elf32_shdr -{ - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -} Elf32_Shdr; - -typedef struct elf64_shdr -{ - Elf64_Word sh_name; /* Section name, index in string tbl */ - Elf64_Word sh_type; /* Type of section */ - Elf64_Xword sh_flags; /* Miscellaneous section attributes */ - Elf64_Addr sh_addr; /* Section virtual addr at execution */ - Elf64_Off sh_offset; /* Section file offset */ - Elf64_Xword sh_size; /* Size of section in bytes */ - Elf64_Word sh_link; /* Index of another section */ - Elf64_Word sh_info; /* Additional section information */ - Elf64_Xword sh_addralign; /* Section alignment */ - Elf64_Xword sh_entsize; /* Entry size if section holds table */ -} Elf64_Shdr; - -typedef struct { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - -typedef struct -{ - Elf64_Word p_type; - Elf64_Word p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; - Elf64_Xword p_filesz; - Elf64_Xword p_memsz; - Elf64_Xword p_align; -} Elf64_Phdr; - -typedef struct elf32_rel -{ - Elf32_Addr r_offset; - Elf32_Word r_info; -} Elf32_Rel; - -typedef struct elf64_rel -{ - Elf64_Addr r_offset; /* Location at which to apply the action */ - Elf64_Xword r_info; /* index and type of relocation */ -} Elf64_Rel; - -typedef struct elf32_sym -{ - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; -} Elf32_Sym; - -typedef struct elf64_sym -{ - Elf64_Word st_name; /* Symbol name, index in string tbl */ - unsigned char st_info; /* Type and binding attributes */ - unsigned char st_other; /* No defined meaning, 0 */ - Elf64_Half st_shndx; /* Associated section index */ - Elf64_Addr st_value; /* Value of the symbol */ - Elf64_Xword st_size; /* Associated symbol size */ -} Elf64_Sym; - -struct Elf32_Dyn -{ - Elf32_Sword d_tag; /* Type of dynamic table entry. */ - union - { - Elf32_Word d_val; /* Integer value of entry. */ - Elf32_Addr d_ptr; /* Pointer value of entry. */ - } d_un; -}; - -struct Elf64_Dyn -{ - Elf64_Sxword d_tag; /* Type of dynamic table entry. */ - union - { - Elf64_Xword d_val; /* Integer value of entry. */ - Elf64_Addr d_ptr; /* Pointer value of entry. */ - } d_un; -}; - -typedef struct -{ - Elf64_Addr r_offset; - Elf64_Xword r_info; - Elf64_Sxword r_addend; -} Elf64_Rela; - -enum Elf_Ident -{ - EI_MAG0 = 0, // 0x7F - EI_MAG1 = 1, // 'E' - EI_MAG2 = 2, // 'L' - EI_MAG3 = 3, // 'F' - EI_CLASS = 4, // Architecture (32/64) - EI_DATA = 5, // Byte Order - EI_VERSION = 6, // ELF Version - EI_OSABI = 7, // OS Specific - EI_ABIVERSION = 8, // OS Specific - EI_PAD = 9 // Padding -}; - -enum Elf_OSABI -{ - ELFOSABI_NONE = 0, - ELFOSABI_HPUX = 1, - ELFOSABI_NETBSD = 2, - ELFOSABI_LINUX = 3, - ELFOSABI_HURD = 4, - ELFOSABI_SOLARIS = 6, - ELFOSABI_AIX = 7, - ELFOSABI_IRIX = 8, - ELFOSABI_FREEBSD = 9, - ELFOSABI_TRU64 = 10, - ELFOSABI_MODESTO = 11, - ELFOSABI_OPENBSD = 12, - ELFOSABI_OPENVMS = 13, - ELFOSABI_NSK = 14, - ELFOSABI_AROS = 15, - ELFOSABI_FENIXOS = 16, - ELFOSABI_CLOUDABI = 17, - ELFOSABI_OPENVOS = 18, - ELFOSABI_C6000_ELFABI = 64, - ELFOSABI_C6000_LINUX = 65, - ELFOSABI_ARM = 97, - ELFOSABI_STANDALONE = 255 -}; - -enum Elf_Type -{ - ET_NONE = 0, // Unknown Type - ET_REL = 1, // Relocatable File - ET_EXEC = 2, // Executable File - ET_DYN = 3, // Shared Object File - ET_CORE = 4, // Core File - ET_LOPROC = 0xff00, // Processor Specific - ET_HIPROC = 0xffff // Processor Specific -}; - -enum RtT_Types -{ - R_386_NONE = 0, // No relocation - R_386_32 = 1, // Symbol + Offset - R_386_PC32 = 2, // Symbol + Offset - Section Offset - - R_X86_64_NONE = 0, - R_X86_64_64 = 1, - R_X86_64_PC32 = 2, - R_X86_64_GOT32 = 3, - R_X86_64_PLT32 = 4, - R_X86_64_COPY = 5, - R_X86_64_GLOB_DAT = 6, - R_X86_64_JUMP_SLOT = 7, - R_X86_64_RELATIVE = 8, - R_X86_64_GOTPCREL = 9, - R_X86_64_32 = 10, - R_X86_64_32S = 11, - R_X86_64_16 = 12, -}; - -enum ProgFlags_Types -{ - PF_X = 1, - PF_W = 2, - PF_R = 4 -}; - -enum StT_Bindings -{ - /** - * @brief Local symbol. Symbol is not visible outside the object file. - */ - STB_LOCAL = 0, - /** - * @brief Global symbol. These symbols are visible to all object files being combined. - */ - STB_GLOBAL = 1, - /** - * @brief Weak symbols. These symbols are like global symbols, but their definitions are not required. Weak symbols are not visible outside the object file containing their definition. - */ - STB_WEAK = 2, - /** - * @brief Values in this inclusive range are reserved for operating system-specific semantics. - */ - STB_LOOS = 10, - /** - * @brief Values in this inclusive range are reserved for operating system-specific semantics. - */ - STB_HIOS = 12, - /** - * @brief Values in this inclusive range are reserved for processor-specific semantics. - */ - STB_LOPROC = 13, - /** - * @brief Values in this inclusive range are reserved for processor-specific semantics. - */ - STB_HIPROC = 15 -}; - -enum StT_Types -{ - STT_NOTYPE = 0, // No type - STT_OBJECT = 1, // Variables, arrays, etc. - STT_FUNC = 2 // Methods or functions -}; - -enum SegmentTypes -{ - PT_NULL = 0, - PT_LOAD = 1, - PT_DYNAMIC = 2, - PT_INTERP = 3, - PT_NOTE = 4, - PT_SHLIB = 5, - PT_PHDR = 6, - PT_TLS = 7, - PT_LOSUNW = 0x6ffffffa, - PT_SUNWBSS = 0x6ffffffb, - PT_SUNWSTACK = 0x6ffffffa, - PT_HISUNW = 0x6fffffff, - PT_LOPROC = 0x70000000, - PT_HIPROC = 0x7fffffff -}; - -/* https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html */ -enum DynamicArrayTags -{ - DT_NULL = 0, - DT_NEEDED = 1, - DT_PLTRELSZ = 2, - DT_PLTGOT = 3, - DT_HASH = 4, - DT_STRTAB = 5, - DT_SYMTAB = 6, - DT_RELA = 7, - DT_RELASZ = 8, - DT_RELAENT = 9, - DT_STRSZ = 10, - DT_SYMENT = 11, - DT_INIT = 12, - DT_FINI = 13, - DT_SONAME = 14, - DT_RPATH = 15, - DT_SYMBOLIC = 16, - DT_REL = 17, - DT_RELSZ = 18, - DT_RELENT = 19, - DT_PLTREL = 20, - DT_DEBUG = 21, - DT_TEXTREL = 22, - DT_JMPREL = 23, - DT_BIND_NOW = 24, - DT_INIT_ARRAY = 25, - DT_FINI_ARRAY = 26, - DT_INIT_ARRAYSZ = 27, - DT_FINI_ARRAYSZ = 28, - DT_RUNPATH = 29, - DT_FLAGS = 30, - DT_ENCODING = 32, - DT_PREINIT_ARRAY = 32, - DT_PREINIT_ARRAYSZ = 33, - DT_LOOS = 0x6000000d, - DT_SUNW_RTLDINF = 0x6000000e, - DT_HIOS = 0x6ffff000, - DT_VALRNGLO = 0x6ffffd00, - DT_CHECKSUM = 0x6ffffdf8, - DT_PLTPADSZ = 0x6ffffdf9, - DT_MOVEENT = 0x6ffffdfa, - DT_MOVESZ = 0x6ffffdfb, - DT_FEATURE_1 = 0x6ffffdfc, - DT_POSFLAG_1 = 0x6ffffdfd, - DT_SYMINSZ = 0x6ffffdfe, - DT_SYMINENT = 0x6ffffdff, - DT_VALRNGHI = 0x6ffffdff, - DT_ADDRRNGLO = 0x6ffffe00, - DT_CONFIG = 0x6ffffefa, - DT_DEPAUDIT = 0x6ffffefb, - DT_AUDIT = 0x6ffffefc, - DT_PLTPAD = 0x6ffffefd, - DT_MOVETAB = 0x6ffffefe, - DT_SYMINFO = 0x6ffffeff, - DT_ADDRRNGHI = 0x6ffffeff, - DT_RELACOUNT = 0x6ffffff9, - DT_RELCOUNT = 0x6ffffffa, - DT_FLAGS_1 = 0x6ffffffb, - DT_VERDEF = 0x6ffffffc, - DT_VERDEFNUM = 0x6ffffffd, - DT_VERNEED = 0x6ffffffe, - DT_VERNEEDNUM = 0x6fffffff, - DT_LOPROC = 0x70000000, - DT_SPARC_REGISTER = 0x70000001, - DT_AUXILIARY = 0x7ffffffd, - DT_USED = 0x7ffffffe, - DT_FILTER = 0x7fffffff, - DT_HIPROC = 0x7fffffff -}; - -// used for Elf64_Sym st_info -#define ELF32_ST_BIND(info) ((info) >> 4) -#define ELF32_ST_TYPE(info) ((info)&0xf) -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type)&0xf)) -#define ELF64_ST_BIND(info) ((info) >> 4) -#define ELF64_ST_TYPE(info) ((info)&0xf) -#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type)&0xf)) - -// used for Elf64_Sym st_other -#define ELF32_ST_VISIBILITY(o) ((o)&0x3) -#define ELF64_ST_VISIBILITY(o) ((o)&0x3) - -#define DO_386_32(S, A) ((S) + (A)) -#define DO_386_PC32(S, A, P) ((S) + (A) - (P)) - -#define DO_64_64(S, A) ((S) + (A)) -#define DO_64_PC32(S, A, P) ((S) + (A) - (P)) - -#define ELF32_R_SYM(i) ((i) >> 8) -#define ELF32_R_TYPE(i) ((unsigned char)(i)) -#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t)) - -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i)&0xffffffffL) -#define ELF64_R_INFO(s, t) (((s) << 32) + ((t)&0xffffffffL)) - -#define SHN_UNDEF 0 -#define SHN_ABS 0xfff1 - -#define SHT_NOBITS 8 -#define SHT_REL 9 - -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 - -#define EM_386 0x3 // x86 Machine Type -#define EM_X86_64 0x3E // 64bit -#define EM_ARM 0x28 // ARM -#define EM_AARCH64 0xb7 // ARM64 - -#define EV_CURRENT 0x1 // ELF Current Version - -#define ELFMAG0 0x7F // e_ident[EI_MAG0] -#define ELFMAG1 'E' // e_ident[EI_MAG1] -#define ELFMAG2 'L' // e_ident[EI_MAG2] -#define ELFMAG3 'F' // e_ident[EI_MAG3] - -#define ELFDATANONE 0 /* e_ident[EI_DATA] */ -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 - -#define ELFCLASSNONE 0 /* EI_CLASS */ -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFCLASSNUM 3 - -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program data */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Dynamic linking information */ -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_INIT_ARRAY 14 /* Array of constructors */ -#define SHT_FINI_ARRAY 15 /* Array of destructors */ -#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -#define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -#define SHT_NUM 19 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -#define SHT_HIUSER 0x8fffffff /* End of application-specific */ - -#endif // !__FENNIX_KERNEL_ELF_H__ diff --git a/FennixLoader/include/memory.hpp b/FennixLoader/include/memory.hpp deleted file mode 100644 index a0f5aa7..0000000 --- a/FennixLoader/include/memory.hpp +++ /dev/null @@ -1,618 +0,0 @@ -#pragma once -#include -#include -#include -#include - -extern uintptr_t _kernel_start, _kernel_end; - -// kilobyte -#define TO_KB(d) ((d) / 1024) -// megabyte -#define TO_MB(d) ((d) / 1024 / 1024) -// gigabyte -#define TO_GB(d) ((d) / 1024 / 1024 / 1024) - -#define PAGE_SIZE 0x1000 // 4KB -#define PAGE_SIZE_4K PAGE_SIZE // 4KB -#define PAGE_SIZE_2M 0x200000 // 2MB -#define PAGE_SIZE_4M 0x400000 // 4MB -#define PAGE_SIZE_1G 0x40000000 // 1GB - -// To pages -#define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE) -// From pages -#define FROM_PAGES(d) ((d)*PAGE_SIZE) - -enum PTFlag -{ - /** @brief Present */ - P = 1 << 0, - - /** @brief Read/Write */ - RW = 1 << 1, - - /** @brief User/Supervisor */ - US = 1 << 2, - - /** @brief Write-Through */ - PWT = 1 << 3, - - /** @brief Cache Disable */ - PCD = 1 << 4, - - /** @brief Accessed */ - A = 1 << 5, - - /** @brief Dirty */ - D = 1 << 6, - - /** @brief Page Size */ - PS = 1 << 7, - - /** @brief Global */ - G = 1 << 8, - - /** @brief Available 0 */ - AVL0 = 1 << 9, - - /** @brief Available 1 */ - AVL1 = 1 << 10, - - /** @brief Available 2 */ - AVL2 = 1 << 11, - - /** @brief Page Attribute Table */ - PAT = 1 << 12, - - /** @brief Available 3 */ - AVL3 = (uint64_t)1 << 52, - - /** @brief Available 4 */ - AVL4 = (uint64_t)1 << 53, - - /** @brief Available 5 */ - AVL5 = (uint64_t)1 << 54, - - /** @brief Available 6 */ - AVL6 = (uint64_t)1 << 55, - - /** @brief Available 7 */ - AVL7 = (uint64_t)1 << 56, - - /** @brief Available 8 */ - AVL8 = (uint64_t)1 << 57, - - /** @brief Available 9 */ - AVL9 = (uint64_t)1 << 58, - - /** @brief Protection Key 0 */ - PK0 = (uint64_t)1 << 59, - - /** @brief Protection Key 1 */ - PK1 = (uint64_t)1 << 60, - - /** @brief Protection Key 2 */ - PK2 = (uint64_t)1 << 61, - - /** @brief Protection Key 3 */ - PK3 = (uint64_t)1 << 62, - - /** @brief Execute Disable */ - XD = (uint64_t)1 << 63 -}; - -namespace Memory32 -{ - union __packed PageTableEntry - { - struct - { - uint32_t Present : 1; // 0 - uint32_t ReadWrite : 1; // 1 - uint32_t UserSupervisor : 1; // 2 - uint32_t WriteThrough : 1; // 3 - uint32_t CacheDisable : 1; // 4 - uint32_t Accessed : 1; // 5 - uint32_t Dirty : 1; // 6 - uint32_t PageAttributeTable : 1; // 7 - uint32_t Global : 1; // 8 - uint32_t Available0 : 3; // 9-11 - uint32_t Address : 20; // 12-31 - }; - uint32_t raw; - - void SetAddress(uintptr_t _Address) - { - _Address &= 0x000FFFFF; - this->raw &= 0xFFC00003; - this->raw |= (_Address << 12); - } - - uintptr_t GetAddress() - { - return (this->raw & 0x003FFFFF000) >> 12; - } - }; - - struct __packed PageTableEntryPtr - { - PageTableEntry Entries[1024]; - }; - - union __packed PageDirectoryEntry - { - struct - { - uint32_t Present : 1; // 0 - uint32_t ReadWrite : 1; // 1 - uint32_t UserSupervisor : 1; // 2 - uint32_t WriteThrough : 1; // 3 - uint32_t CacheDisable : 1; // 4 - uint32_t Accessed : 1; // 5 - uint32_t Available0 : 1; // 6 - uint32_t PageSize : 1; // 7 - uint32_t Available1 : 4; // 8-11 - uint32_t Address : 20; // 12-31 - }; - uint32_t raw; - - void SetAddress(uintptr_t _Address) - { - _Address &= 0x000FFFFF; - this->raw &= 0xFFC00003; - this->raw |= (_Address << 12); - } - - uintptr_t GetAddress() - { - return (this->raw & 0x003FFFFF000) >> 12; - } - }; - - struct PageTable - { - PageDirectoryEntry Entries[1024]; - } __aligned(0x1000); - - class Physical - { - private: - uint64_t PageBitmapIndex = 0; - Bitmap PageBitmap; - - public: - uint64_t TotalMemory = 0; - uint64_t FreeMemory = 0; - uint64_t ReservedMemory = 0; - uint64_t UsedMemory = 0; - void LockPage(void *Address); - void LockPages(void *Address, size_t PageCount); - void ReservePage(void *Address); - void ReservePages(void *Address, size_t PageCount); - void UnreservePage(void *Address); - void UnreservePages(void *Address, size_t PageCount); - void *RequestPage(); - void *RequestPages(size_t Count); - void FreePage(void *Address); - void FreePages(void *Address, size_t Count); - void Init(BootInfo *Info); - Physical(); - ~Physical(); - }; - - class Virtual - { - private: - PageTable *Table = nullptr; - - public: - class PageMapIndexer - { - public: - uintptr_t PDEIndex = 0; - uintptr_t PTEIndex = 0; - PageMapIndexer(uintptr_t VirtualAddress) - { - uintptr_t Address = VirtualAddress; - Address >>= 12; - this->PTEIndex = Address & 0x3FF; - Address >>= 10; - this->PDEIndex = Address & 0x3FF; - } - }; - - void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flag = PTFlag::P); - - __always_inline inline void Map(void *VirtualAddress, void *PhysicalAddress, size_t Length, uint64_t Flags) - { - for (uintptr_t i = 0; i < Length; i += PAGE_SIZE_4K) - this->Map((void *)((uintptr_t)VirtualAddress + i), (void *)((uintptr_t)PhysicalAddress + i), Flags); - } - - Virtual(PageTable *Table = nullptr); - ~Virtual(); - }; -} - -namespace Memory64 -{ - union __packed PageTableEntry - { - struct - { - uint64_t Present : 1; // 0 - uint64_t ReadWrite : 1; // 1 - uint64_t UserSupervisor : 1; // 2 - uint64_t WriteThrough : 1; // 3 - uint64_t CacheDisable : 1; // 4 - uint64_t Accessed : 1; // 5 - uint64_t Dirty : 1; // 6 - uint64_t PageAttributeTable : 1; // 7 - uint64_t Global : 1; // 8 - uint64_t Available0 : 3; // 9-11 - uint64_t Address : 40; // 12-51 - uint64_t Available1 : 7; // 52-58 - uint64_t ProtectionKey : 4; // 59-62 - uint64_t ExecuteDisable : 1; // 63 - }; - uint64_t raw; - - /** @brief Set Address */ - void SetAddress(uintptr_t _Address) - { - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); - } - - /** @brief Get Address */ - uintptr_t GetAddress() - { - return (this->raw & 0x000FFFFFFFFFF000) >> 12; - } - }; - - struct __packed PageTableEntryPtr - { - PageTableEntry Entries[511]; - }; - - union __packed PageDirectoryEntry - { - struct - { - uint64_t Present : 1; // 0 - uint64_t ReadWrite : 1; // 1 - uint64_t UserSupervisor : 1; // 2 - uint64_t WriteThrough : 1; // 3 - uint64_t CacheDisable : 1; // 4 - uint64_t Accessed : 1; // 5 - uint64_t Available0 : 1; // 6 - uint64_t PageSize : 1; // 7 - uint64_t Available1 : 4; // 8-11 - uint64_t Address : 40; // 12-51 - uint64_t Available2 : 11; // 52-62 - uint64_t ExecuteDisable : 1; // 63 - }; - - struct - { - uint64_t Present : 1; // 0 - uint64_t ReadWrite : 1; // 1 - uint64_t UserSupervisor : 1; // 2 - uint64_t WriteThrough : 1; // 3 - uint64_t CacheDisable : 1; // 4 - uint64_t Accessed : 1; // 5 - uint64_t Dirty : 1; // 6 - uint64_t PageSize : 1; // 7 - uint64_t Global : 1; // 8 - uint64_t Available0 : 3; // 9-11 - uint64_t PageAttributeTable : 1; // 12 - uint64_t Reserved0 : 8; // 13-20 - uint64_t Address : 31; // 21-51 - uint64_t Available1 : 7; // 52-58 - uint64_t ProtectionKey : 4; // 59-62 - uint64_t ExecuteDisable : 1; // 63 - } TwoMB; - - uint64_t raw; - - /** @brief Set PageTableEntryPtr address */ - void SetAddress(uintptr_t _Address) - { - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); - } - - /** @brief Get PageTableEntryPtr address */ - uintptr_t GetAddress() - { - return (this->raw & 0x000FFFFFFFFFF000) >> 12; - } - }; - - struct __packed PageDirectoryEntryPtr - { - PageDirectoryEntry Entries[511]; - }; - - union __packed PageDirectoryPointerTableEntry - { - struct - { - uint64_t Present : 1; // 0 - uint64_t ReadWrite : 1; // 1 - uint64_t UserSupervisor : 1; // 2 - uint64_t WriteThrough : 1; // 3 - uint64_t CacheDisable : 1; // 4 - uint64_t Accessed : 1; // 5 - uint64_t Available0 : 1; // 6 - uint64_t PageSize : 1; // 7 - uint64_t Available1 : 4; // 8-11 - uint64_t Address : 40; // 12-51 - uint64_t Available2 : 11; // 52-62 - uint64_t ExecuteDisable : 1; // 63 - }; - - struct - { - uint64_t Present : 1; // 0 - uint64_t ReadWrite : 1; // 1 - uint64_t UserSupervisor : 1; // 2 - uint64_t WriteThrough : 1; // 3 - uint64_t CacheDisable : 1; // 4 - uint64_t Accessed : 1; // 5 - uint64_t Dirty : 1; // 6 - uint64_t PageSize : 1; // 7 - uint64_t Global : 1; // 8 - uint64_t Available0 : 3; // 9-11 - uint64_t PageAttributeTable : 1; // 12 - uint64_t Reserved0 : 17; // 13-29 - uint64_t Address : 22; // 30-51 - uint64_t Available1 : 7; // 52-58 - uint64_t ProtectionKey : 4; // 59-62 - uint64_t ExecuteDisable : 1; // 63 - } OneGB; - - uint64_t raw; - - /** @brief Set PageDirectoryEntryPtr address */ - void SetAddress(uintptr_t _Address) - { - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); - } - - /** @brief Get PageDirectoryEntryPtr address */ - uintptr_t GetAddress() - { - return (this->raw & 0x000FFFFFFFFFF000) >> 12; - } - }; - - struct __packed PageDirectoryPointerTableEntryPtr - { - PageDirectoryPointerTableEntry Entries[511]; - }; - - union __packed PageMapLevel4 - { - struct - { - uint64_t Present : 1; // 0 - uint64_t ReadWrite : 1; // 1 - uint64_t UserSupervisor : 1; // 2 - uint64_t WriteThrough : 1; // 3 - uint64_t CacheDisable : 1; // 4 - uint64_t Accessed : 1; // 5 - uint64_t Available0 : 1; // 6 - uint64_t Reserved0 : 1; // 7 - uint64_t Available1 : 4; // 8-11 - uint64_t Address : 40; // 12-51 - uint64_t Available2 : 11; // 52-62 - uint64_t ExecuteDisable : 1; // 63 - }; - uint64_t raw; - - /** @brief Set PageDirectoryPointerTableEntryPtr address */ - void SetAddress(uintptr_t _Address) - { - _Address &= 0x000000FFFFFFFFFF; - this->raw &= 0xFFF0000000000FFF; - this->raw |= (_Address << 12); - } - - /** @brief Get PageDirectoryPointerTableEntryPtr address */ - uintptr_t GetAddress() - { - return (this->raw & 0x000FFFFFFFFFF000) >> 12; - } - }; - - struct PageTable - { - PageMapLevel4 Entries[511]; - - /** - * @brief Update CR3 with this PageTable - */ - void Update() - { - asmv("mov %0, %%cr3" ::"r"(this)); - } - } __aligned(0x1000); - - class Physical - { - private: - uint64_t PageBitmapIndex = 0; - Bitmap PageBitmap; - - public: - uint64_t TotalMemory = 0; - uint64_t FreeMemory = 0; - uint64_t ReservedMemory = 0; - uint64_t UsedMemory = 0; - void LockPage(void *Address); - void LockPages(void *Address, size_t PageCount); - void ReservePage(void *Address); - void ReservePages(void *Address, size_t PageCount); - void UnreservePage(void *Address); - void UnreservePages(void *Address, size_t PageCount); - void *RequestPage(); - void *RequestPages(size_t Count); - void FreePage(void *Address); - void FreePages(void *Address, size_t Count); - void Init(BootInfo *Info); - Physical(); - ~Physical(); - }; - - class Virtual - { - private: - PageTable *Table = nullptr; - - public: - enum MapType - { - NoMapType, - FourKB, - TwoMB, - OneGB - }; - - class PageMapIndexer - { - public: - uintptr_t PMLIndex = 0; - uintptr_t PDPTEIndex = 0; - uintptr_t PDEIndex = 0; - uintptr_t PTEIndex = 0; - 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; - } - }; - - bool Check(void *VirtualAddress, PTFlag Flag = PTFlag::P, MapType Type = MapType::FourKB); - void *GetPhysical(void *VirtualAddress); - void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flag = PTFlag::P, MapType Type = MapType::FourKB); - - __always_inline inline void Map(void *VirtualAddress, void *PhysicalAddress, size_t Length, uint64_t Flags, MapType Type = MapType::FourKB) - { - int PageSize = PAGE_SIZE_4K; - - if (Type == MapType::TwoMB) - PageSize = PAGE_SIZE_2M; - else if (Type == MapType::OneGB) - PageSize = PAGE_SIZE_1G; - - for (uintptr_t i = 0; i < Length; i += PageSize) - this->Map((void *)((uintptr_t)VirtualAddress + i), (void *)((uintptr_t)PhysicalAddress + i), Flags, Type); - } - - __always_inline inline MapType OptimizedMap(void *VirtualAddress, void *PhysicalAddress, size_t Length, uint64_t Flags, bool Fit = false, bool FailOnModulo = false) - { - if (unlikely(Fit)) - { - while (Length >= PAGE_SIZE_1G) - { - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::OneGB); - VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_1G); - PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_1G); - Length -= PAGE_SIZE_1G; - } - - while (Length >= PAGE_SIZE_2M) - { - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::TwoMB); - VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_2M); - PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_2M); - Length -= PAGE_SIZE_2M; - } - - while (Length >= PAGE_SIZE_4K) - { - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::FourKB); - VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_4K); - PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_4K); - Length -= PAGE_SIZE_4K; - } - - return Virtual::MapType::FourKB; - } - - Virtual::MapType Type = Virtual::MapType::FourKB; - - if (Length >= PAGE_SIZE_1G) - { - Type = Virtual::MapType::OneGB; - if (Length % PAGE_SIZE_1G != 0) - { - warn("Length is not a multiple of 1GB."); - if (FailOnModulo) - return Virtual::MapType::NoMapType; - } - } - else if (Length >= PAGE_SIZE_2M) - { - Type = Virtual::MapType::TwoMB; - if (Length % PAGE_SIZE_2M != 0) - { - warn("Length is not a multiple of 2MB."); - if (FailOnModulo) - return Virtual::MapType::NoMapType; - } - } - - this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Type); - return Type; - } - - void Unmap(void *VirtualAddress, MapType Type = MapType::FourKB); - - __always_inline inline void Unmap(void *VirtualAddress, size_t Length, MapType Type = MapType::FourKB) - { - int PageSize = PAGE_SIZE_4K; - - if (Type == MapType::TwoMB) - PageSize = PAGE_SIZE_2M; - else if (Type == MapType::OneGB) - PageSize = PAGE_SIZE_1G; - - for (uintptr_t i = 0; i < Length; i += PageSize) - this->Unmap((void *)((uintptr_t)VirtualAddress + i), Type); - } - - __always_inline inline void Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type = MapType::FourKB) - { - this->Unmap(VirtualAddress, Type); - this->Map(VirtualAddress, PhysicalAddress, Flags, Type); - } - - Virtual(PageTable *Table = nullptr); - ~Virtual(); - }; -} - -extern Memory32::Physical KernelAllocator32; -extern Memory32::PageTable *KernelPageTable32; - -extern Memory64::Physical KernelAllocator64; -extern Memory64::PageTable *KernelPageTable64; - -void *memcpy(void *dest, const void *src, size_t n); -void *memset(void *s, int c, size_t n); -void InitializeMemoryManagement(BootInfo *Info, bool is32); diff --git a/FennixLoader/include/multiboot.h b/FennixLoader/include/multiboot.h deleted file mode 100644 index 683ae4b..0000000 --- a/FennixLoader/include/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 */ \ No newline at end of file diff --git a/FennixLoader/include/multiboot2.h b/FennixLoader/include/multiboot2.h deleted file mode 100644 index bcc4d25..0000000 --- a/FennixLoader/include/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/FennixLoader/include/printf.h b/FennixLoader/include/printf.h deleted file mode 100644 index 52866c6..0000000 --- a/FennixLoader/include/printf.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @author (c) Eyal Rozenberg - * 2021-2022, Haifa, Palestine/Israel - * @author (c) Marco Paland (info@paland.com) - * 2014-2019, PALANDesign Hannover, Germany - * - * @note Others have made smaller contributions to this file: see the - * contributors page at https://github.com/eyalroz/printf/graphs/contributors - * or ask one of the authors. - * - * @brief Small stand-alone implementation of the printf family of functions - * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with - * a very limited resources. - * - * @note the implementations are thread-safe; re-entrant; use no functions from - * the standard library; and do not dynamically allocate any memory. - * - * @license The MIT License (MIT) - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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 PRINTF_H_ -#define PRINTF_H_ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifdef __GNUC__ -#define ATTR_PRINTF(one_based_format_index, first_arg) \ - __attribute__((format(__printf__, (one_based_format_index), (first_arg)))) -#define ATTR_VPRINTF(one_based_format_index) ATTR_PRINTF((one_based_format_index), 0) -#else -#define ATTR_PRINTF((one_based_format_index), (first_arg)) -#define ATTR_VPRINTF(one_based_format_index) -#endif - -#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES -#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES 0 -#endif - -#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES -#define printf printf -#define sprintf sprintf -#define vsprintf vsprintf -#define snprintf_ snprintf -#define vsnprintf vsnprintf -#define vprintf vprintf -#endif - -// If you want to include this implementation file directly rather than -// link against, this will let you control the functions' visibility, -// e.g. make them static so as not to clash with other objects also -// using them. -#ifndef PRINTF_VISIBILITY -#define PRINTF_VISIBILITY -#endif - - /** - * Prints/send a single character to some opaque output entity - * - * @note This function is not implemented by the library, only declared; you must provide an - * implementation if you wish to use the @ref printf / @ref vprintf function (and possibly - * for linking against the library, if your toolchain does not support discarding unused functions) - * - * @note The output could be as simple as a wrapper for the `write()` system call on a Unix-like - * system, or even libc's @ref putchar , for replicating actual functionality of libc's @ref printf - * function; but on an embedded system it may involve interaction with a special output device, - * like a UART, etc. - * - * @note in libc's @ref putchar, the parameter type is an int; this was intended to support the - * representation of either a proper character or EOF in a variable - but this is really not - * meaningful to pass into @ref putchar and is discouraged today. See further discussion in: - * @link https://stackoverflow.com/q/17452847/1593077 - * - * @param c the single character to print - */ - // PRINTF_VISIBILITY - // void putchar(char c); - - /** - * An implementation of the C standard's printf/vprintf - * - * @note you must implement a @ref putchar_ function for using this function - it invokes @ref putchar_ - * rather than directly performing any I/O (which insulates it from any dependence on the operating system - * and external libraries). - * - * @param format A string specifying the format of the output, with %-marked specifiers of how to interpret - * additional arguments. - * @param arg Additional arguments to the function, one for each %-specifier in @p format string - * @return The number of characters written into @p s, not counting the terminating null character - */ - ///@{ - PRINTF_VISIBILITY - int printf(const char *format, ...) ATTR_PRINTF(1, 2); - PRINTF_VISIBILITY - int vprintf(const char *format, va_list arg) ATTR_VPRINTF(1); - ///@} - - /** - * An implementation of the C standard's sprintf/vsprintf - * - * @note For security considerations (the potential for exceeding the buffer bounds), please consider using - * the size-constrained variant, @ref snprintf / @ref vsnprintf , instead. - * - * @param s An array in which to store the formatted string. It must be large enough to fit the formatted - * output! - * @param format A string specifying the format of the output, with %-marked specifiers of how to interpret - * additional arguments. - * @param arg Additional arguments to the function, one for each specifier in @p format - * @return The number of characters written into @p s, not counting the terminating null character - */ - ///@{ - PRINTF_VISIBILITY - int sprintf(char *s, const char *format, ...) ATTR_PRINTF(2, 3); - PRINTF_VISIBILITY - int vsprintf(char *s, const char *format, va_list arg) ATTR_VPRINTF(2); - ///@} - - /** - * An implementation of the C standard's snprintf/vsnprintf - * - * @param s An array in which to store the formatted string. It must be large enough to fit either the - * entire formatted output, or at least @p n characters. Alternatively, it can be NULL, in which case - * nothing will be printed, and only the number of characters which _could_ have been printed is - * tallied and returned. - * @param n The maximum number of characters to write to the array, including a terminating null character - * @param format A string specifying the format of the output, with %-marked specifiers of how to interpret - * additional arguments. - * @param arg Additional arguments to the function, one for each specifier in @p format - * @return The number of characters that COULD have been written into @p s, not counting the terminating - * null character. A value equal or larger than @p n indicates truncation. Only when the returned value - * is non-negative and less than @p n, the null-terminated string has been fully and successfully printed. - */ - ///@{ - PRINTF_VISIBILITY - int snprintf(char *s, size_t count, const char *format, ...) ATTR_PRINTF(3, 4); - PRINTF_VISIBILITY - int vsnprintf(char *s, size_t count, const char *format, va_list arg) ATTR_VPRINTF(3); - ///@} - - /** - * printf/vprintf with user-specified output function - * - * An alternative to @ref printf, in which the output function is specified dynamically - * (rather than @ref putchar_ being used) - * - * @param out An output function which takes one character and a type-erased additional parameters - * @param extra_arg The type-erased argument to pass to the output function @p out with each call - * @param format A string specifying the format of the output, with %-marked specifiers of how to interpret - * additional arguments. - * @param arg Additional arguments to the function, one for each specifier in @p format - * @return The number of characters for which the output f unction was invoked, not counting the terminating null character - * - */ - PRINTF_VISIBILITY - int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...) ATTR_PRINTF(3, 4); - PRINTF_VISIBILITY - int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg) ATTR_VPRINTF(3); - -#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES -#undef printf -#undef sprintf -#undef vsprintf -#undef snprintf_ -#undef vsnprintf -#undef vprintf -#endif - -#ifdef __cplusplus -} -#endif - -#endif // PRINTF_H_ \ No newline at end of file diff --git a/FennixLoader/include/types.h b/FennixLoader/include/types.h deleted file mode 100644 index b5df5ee..0000000 --- a/FennixLoader/include/types.h +++ /dev/null @@ -1,343 +0,0 @@ -#ifndef __FENNIX_KERNEL_TYPES_H__ -#define __FENNIX_KERNEL_TYPES_H__ - -#ifdef __cplusplus -#define EXTERNC extern "C" -#define START_EXTERNC \ - EXTERNC \ - { -#define END_EXTERNC \ - } -#else // __cplusplus -#define EXTERNC -#define START_EXTERNC -#define END_EXTERNC -#endif // __cplusplus - -#ifdef __cplusplus -#define NULL 0 -#else // __cplusplus -#define NULL ((void *)0) -#define bool _Bool -#endif // __cplusplus - -#define asm __asm__ -#define asmv __asm__ volatile - -#define true 1 -#define false 0 - -#define inf_loop while (1) -#define ilp inf_loop; /* Used for debugging */ - -#ifdef __cplusplus -#define foreach for -#define in : - -#define r_cst(t, v) reinterpret_cast(v) -#define c_cst(t, v) const_cast(v) -#define s_cst(t, v) static_cast(v) -#define d_cst(t, v) dynamic_cast(v) -#endif // __cplusplus - -#define UNUSED(x) (void)(x) -#define CONCAT(x, y) x##y - -#ifndef __cplusplus /* This conflicts with std */ -#define toupper(c) ((c)-0x20 * (((c) >= 'a') && ((c) <= 'z'))) -#define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z'))) -#endif - -#ifndef __va_list__ -typedef __builtin_va_list va_list; -#endif - -#define va_start(v, l) __builtin_va_start(v, l) -#define va_end(v) __builtin_va_end(v) -#define va_arg(v, l) __builtin_va_arg(v, l) - -#define ALIGN_UP(x, align) ((__typeof__(x))(((uintptr_t)(x) + ((align)-1)) & (~((align)-1)))) -#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1)))) - -#define offsetof(type, member) __builtin_offsetof(type, member) - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -#define VPOKE(type, address) (*((volatile type *)(address))) -#define POKE(type, address) (*((type *)(address))) - -#ifndef __cplusplus - -#ifdef __STDC__ -#ifdef __STDC_VERSION__ -#if (__STDC_VERSION__ >= 201710L) -#define C_LANGUAGE_STANDARD 2018 -#elif (__STDC_VERSION__ >= 201112L) -#define C_LANGUAGE_STANDARD 2011 -#elif (__STDC_VERSION__ >= 199901L) -#define C_LANGUAGE_STANDARD 1999 -#elif (__STDC_VERSION__ >= 199409L) -#define C_LANGUAGE_STANDARD 1995 -#endif -#else -#define C_LANGUAGE_STANDARD 1990 -#endif -#else -#define C_LANGUAGE_STANDARD 1972 -#endif - -#else - -#ifdef __STDC__ -#ifdef __cplusplus -#if (__cplusplus >= 202100L) -#define CPP_LANGUAGE_STANDARD 2023 -#elif (__cplusplus >= 202002L) -#define CPP_LANGUAGE_STANDARD 2020 -#elif (__cplusplus >= 201703L) -#define CPP_LANGUAGE_STANDARD 2017 -#elif (__cplusplus >= 201402L) -#define CPP_LANGUAGE_STANDARD 2014 -#elif (__cplusplus >= 201103L) -#define CPP_LANGUAGE_STANDARD 2011 -#elif (__cplusplus >= 199711L) -#define CPP_LANGUAGE_STANDARD 1998 -#endif -#else -#define CPP_LANGUAGE_STANDARD __cplusplus -#endif -#else -#define CPP_LANGUAGE_STANDARD __cplusplus -#endif - -#endif // __cplusplus - -#ifndef __SIG_ATOMIC_TYPE__ -#define __SIG_ATOMIC_TYPE__ int -#endif - -typedef __INT8_TYPE__ int8_t; -typedef __INT16_TYPE__ int16_t; -typedef __INT32_TYPE__ int32_t; -typedef __INT64_TYPE__ int64_t; - -typedef __UINT8_TYPE__ uint8_t; -typedef __UINT16_TYPE__ uint16_t; -typedef __UINT32_TYPE__ uint32_t; -typedef __UINT64_TYPE__ uint64_t; - -typedef __INT_LEAST8_TYPE__ int_least8_t; -typedef __INT_LEAST16_TYPE__ int_least16_t; -typedef __INT_LEAST32_TYPE__ int_least32_t; -typedef __INT_LEAST64_TYPE__ int_least64_t; - -typedef __UINT_LEAST8_TYPE__ uint_least8_t; -typedef __UINT_LEAST16_TYPE__ uint_least16_t; -typedef __UINT_LEAST32_TYPE__ uint_least32_t; -typedef __UINT_LEAST64_TYPE__ uint_least64_t; - -typedef __INT_FAST8_TYPE__ int_fast8_t; -typedef __INT_FAST16_TYPE__ int_fast16_t; -typedef __INT_FAST32_TYPE__ int_fast32_t; -typedef __INT_FAST64_TYPE__ int_fast64_t; - -typedef __UINT_FAST8_TYPE__ uint_fast8_t; -typedef __UINT_FAST16_TYPE__ uint_fast16_t; -typedef __UINT_FAST32_TYPE__ uint_fast32_t; -typedef __UINT_FAST64_TYPE__ uint_fast64_t; - -typedef __INTPTR_TYPE__ intptr_t; -typedef __UINTPTR_TYPE__ uintptr_t; - -typedef __INTMAX_TYPE__ intmax_t; -typedef __UINTMAX_TYPE__ uintmax_t; - -typedef __PTRDIFF_TYPE__ ptrdiff_t; -typedef __SIZE_TYPE__ size_t; -#ifndef __cplusplus -typedef __WCHAR_TYPE__ wchar_t; -#endif -typedef __WINT_TYPE__ wint_t; -typedef __SIG_ATOMIC_TYPE__ sig_atomic_t; -// TODO: ssize_t -typedef intptr_t ssize_t; - -#define INT8_MAX __INT8_MAX__ -#define INT8_MIN (-INT8_MAX - 1) -#define UINT8_MAX __UINT8_MAX__ -#define INT16_MAX __INT16_MAX__ -#define INT16_MIN (-INT16_MAX - 1) -#define UINT16_MAX __UINT16_MAX__ -#define INT32_MAX __INT32_MAX__ -#define INT32_MIN (-INT32_MAX - 1) -#define UINT32_MAX __UINT32_MAX__ -#define INT64_MAX __INT64_MAX__ -#define INT64_MIN (-INT64_MAX - 1) -#define UINT64_MAX __UINT64_MAX__ - -#define INT_LEAST8_MAX __INT_LEAST8_MAX__ -#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1) -#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ -#define INT_LEAST16_MAX __INT_LEAST16_MAX__ -#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1) -#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ -#define INT_LEAST32_MAX __INT_LEAST32_MAX__ -#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1) -#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ -#define INT_LEAST64_MAX __INT_LEAST64_MAX__ -#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1) -#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ - -#define INT_FAST8_MAX __INT_FAST8_MAX__ -#define INT_FAST8_MIN (-INT_FAST8_MAX - 1) -#define UINT_FAST8_MAX __UINT_FAST8_MAX__ -#define INT_FAST16_MAX __INT_FAST16_MAX__ -#define INT_FAST16_MIN (-INT_FAST16_MAX - 1) -#define UINT_FAST16_MAX __UINT_FAST16_MAX__ -#define INT_FAST32_MAX __INT_FAST32_MAX__ -#define INT_FAST32_MIN (-INT_FAST32_MAX - 1) -#define UINT_FAST32_MAX __UINT_FAST32_MAX__ -#define INT_FAST64_MAX __INT_FAST64_MAX__ -#define INT_FAST64_MIN (-INT_FAST64_MAX - 1) -#define UINT_FAST64_MAX __UINT_FAST64_MAX__ - -#define INTPTR_MAX __INTPTR_MAX__ -#define INTPTR_MIN (-INTPTR_MAX - 1) -#define UINTPTR_MAX __UINTPTR_MAX__ - -#define INTMAX_MAX __INTMAX_MAX__ -#define INTMAX_MIN (-INTMAX_MAX - 1) -#define UINTMAX_MAX __UINTMAX_MAX__ - -#define PTRDIFF_MAX __PTRDIFF_MAX__ -#define PTRDIFF_MIN (-PTRDIFF_MAX - 1) - -#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__ -#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__ - -#define SIZE_MAX __SIZE_MAX__ - -#define WCHAR_MAX __WCHAR_MAX__ -#define WCHAR_MIN __WCHAR_MIN__ - -#define WINT_MAX __WINT_MAX__ -#define WINT_MIN __WINT_MIN__ - -#define BREAK __asm__ __volatile__("int $0x3" \ - : \ - : \ - : "memory"); - -#ifdef __INT48_TYPE__ -typedef __INT48_TYPE__ int48_t; -typedef __UINT48_TYPE__ uint48_t; -typedef int48_t int_least48_t; -typedef uint48_t uint_least48_t; -typedef int48_t int_fast48_t; -typedef uint48_t uint_fast48_t; -#else // __INT48_TYPE__ -typedef __INT64_TYPE__ int48_t; -typedef __UINT64_TYPE__ uint48_t; -typedef int48_t int_least48_t; -typedef uint48_t uint_least48_t; -typedef int48_t int_fast48_t; -typedef uint48_t uint_fast48_t; -#endif // __INT48_TYPE__ - -#define b4(x) ((x & 0x0F) << 4 | (x & 0xF0) >> 4) -#define b8(x) ((x)&0xFF) -#define b16(x) __builtin_bswap16(x) -#define b32(x) __builtin_bswap32(x) -#define b48(x) (((((x)&0x0000000000ff) << 40) | \ - (((x)&0x00000000ff00) << 24) | \ - (((x)&0x000000ff0000) << 8) | \ - (((x)&0x0000ff000000) >> 8) | \ - (((x)&0x00ff00000000) >> 24) | \ - (((x)&0xff0000000000) >> 40))) -#define b64(x) __builtin_bswap64(x) - -/* https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gnat_ugn/Optimization-Levels.html */ - -/** @brief No optimization (the default); generates unoptimized code but has the fastest compilation time. */ -#define O0 __attribute__((optimize("O0"))) -/** @brief Moderate optimization; optimizes reasonably well but does not degrade compilation time significantly. */ -#define O1 __attribute__((optimize("O1"))) -/** @brief Full optimization; generates highly optimized code and has the slowest compilation time. */ -#define O2 __attribute__((optimize("O2"))) -/** @brief Full optimization as in -O2; also uses more aggressive automatic inlining of subprograms within a unit (Inlining of Subprograms) and attempts to vectorize loops. */ -#define O3 __attribute__((optimize("O3"))) -/** @brief Optimize space usage (code and data) of resulting program. */ -#define Os __attribute__((optimize("Os"))) -/** @brief Disregard strict standards compliance. -Ofast enables all -O3 optimizations. It also enables optimizations that are not valid for all standard-compliant programs. */ -#define Ofast __attribute__((optimize("Ofast"))) - -#define __unused __attribute__((unused)) -#define __packed __attribute__((packed)) -#define __naked __attribute__((naked)) -#define __aligned(x) __attribute__((aligned(x))) -#define __section(x) __attribute__((section(x))) -#define __noreturn __attribute__((noreturn)) -#define __weak __attribute__((weak)) -#define __alias(x) __attribute__((alias(x))) -#define __always_inline __attribute__((always_inline)) -#define __noinline __attribute__((noinline)) -#define __pure __attribute__((pure)) -#define __const __attribute__((const)) -#define __malloc __attribute__((malloc)) -#define __returns_twice __attribute__((returns_twice)) -#define __used __attribute__((used)) -#define __deprecated __attribute__((deprecated)) -#define __deprecated_msg(x) __attribute__((deprecated(x))) -#define __weakref(x) __attribute__((weakref(x))) -#define __weakrefalias(x) __attribute__((weakref(#x))) -#define __visibility(x) __attribute__((visibility(x))) -#define __constructor __attribute__((constructor)) -#define __destructor __attribute__((destructor)) -#define __cleanup(x) __attribute__((cleanup(x))) -#define __fallthrough __attribute__((fallthrough)) -#define __nonnull(x) __attribute__((nonnull x)) -#define __nonnull_all __attribute__((nonnull)) -#define __returns_nonnull __attribute__((returns_nonnull)) -#define __sentinel __attribute__((sentinel)) -#define __sentinel_all __attribute__((sentinel(0))) -#define __format(x, y, z) __attribute__((format(x, y, z))) -#define __format_arg(x) __attribute__((format_arg(x))) -#define __nonnull_params(x) __attribute__((nonnull x)) -#define __nonnull_all __attribute__((nonnull)) -#define __warn_unused_result __attribute__((warn_unused_result)) -#define __no_stack_protector __attribute__((no_stack_protector)) -#define __no_instrument_function __attribute__((no_instrument_function)) -#define __no_debug __attribute__((no_debug)) -#define __target(x) __attribute__((target(x))) -#define __min_vector_width(x) __attribute__((min_vector_width(x))) - -// sanitizer -#define __no_sanitize_address __attribute__((no_sanitize_address)) -#define __no_sanitize_undefined __attribute__((no_sanitize_undefined)) -#define __no_address_safety_analysis __attribute__((no_address_safety_analysis)) -#define __no_sanitize_thread __attribute__((no_sanitize_thread)) - -#define __synchronize __sync_synchronize() -#define __sync __synchronize - -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) - -#define SafeFunction __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_address_safety_analysis __no_sanitize_thread - -#define NIF __no_instrument_function - -#define int1 \ - __asm__ __volatile__("int $0x1" \ - : \ - : \ - : "memory") - -#define int3 \ - __asm__ __volatile__("int3" \ - : \ - : \ - : "memory") - -#endif // !__FENNIX_KERNEL_TYPES_H__ diff --git a/FennixLoader/include/uart.hpp b/FennixLoader/include/uart.hpp deleted file mode 100644 index 0b1cee3..0000000 --- a/FennixLoader/include/uart.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __FENNIX_KERNEL_UART_H__ -#define __FENNIX_KERNEL_UART_H__ - -#include - -namespace UniversalAsynchronousReceiverTransmitter -{ - enum SerialPorts - { - COMNULL = 0, - COM1 = 0x3F8, - COM2 = 0x2F8, - COM3 = 0x3E8, - COM4 = 0x2E8, - COM5 = 0x5F8, - COM6 = 0x4F8, - COM7 = 0x5E8, - COM8 = 0x4E8 - }; - - class UART - { - private: - SerialPorts Port; - - public: - UART(SerialPorts Port = COMNULL); - ~UART(); - void Write(uint8_t Char); - uint8_t Read(); - }; -} - -#endif // !__FENNIX_KERNEL_UART_H__ diff --git a/FennixLoader/linker.ld b/FennixLoader/linker.ld deleted file mode 100644 index 5cc8c02..0000000 --- a/FennixLoader/linker.ld +++ /dev/null @@ -1,54 +0,0 @@ -ENTRY(_start) - -SECTIONS -{ - . = 0x100000; - _kernel_start = .; - - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.multiboot2) - *(.text) - } - - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } - - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - .init_array : - { - PROVIDE_HIDDEN(__init_array_start = .); - KEEP(*(.init_array .ctors)) - KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - PROVIDE_HIDDEN (__init_array_end = .); - } - - .fini_array : - { - PROVIDE_HIDDEN(__fini_array_start = .); - KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP(*(.fini_array .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } - - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } - - /DISCARD/ : - { - *(.comment*) - *(.note*) - } - . += CONSTANT(MAXPAGESIZE); - _kernel_end = ALIGN(CONSTANT(MAXPAGESIZE)); -} diff --git a/FennixLoader/loadelf.hpp b/FennixLoader/loadelf.hpp deleted file mode 100644 index 8c35b0a..0000000 --- a/FennixLoader/loadelf.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -bool LoadElfInMemory(void *Address, size_t Length, bool Allow64); diff --git a/FennixLoader/printf.c b/FennixLoader/printf.c deleted file mode 100644 index 7032a34..0000000 --- a/FennixLoader/printf.c +++ /dev/null @@ -1,1592 +0,0 @@ -/** - * @author (c) Eyal Rozenberg - * 2021-2022, Haifa, Palestine/Israel - * @author (c) Marco Paland (info@paland.com) - * 2014-2019, PALANDesign Hannover, Germany - * - * @note Others have made smaller contributions to this file: see the - * contributors page at https://github.com/eyalroz/printf/graphs/contributors - * or ask one of the authors. The original code for exponential specifiers was - * contributed by Martijn Jasperse . - * - * @brief Small stand-alone implementation of the printf family of functions - * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with - * a very limited resources. - * - * @note the implementations are thread-safe; re-entrant; use no functions from - * the standard library; and do not dynamically allocate any memory. - * - * @license The MIT License (MIT) - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - */ - -#pragma GCC diagnostic ignored "-Wfloat-equal" - -// Define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H=1 ...) to include the -// printf_config.h header file -#if PRINTF_INCLUDE_CONFIG_H -#include "printf_config.h" -#endif - -#include - -#ifdef __cplusplus -#include -#include -#else -#include -#include -#endif // __cplusplus - -#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES -#define printf printf -#define sprintf sprintf -#define vsprintf vsprintf -#define snprintf_ snprintf -#define vsnprintf vsnprintf -#define vprintf vprintf -#endif - -// 'ntoa' conversion buffer size, this must be big enough to hold one converted -// numeric number including padded zeros (dynamically created on stack) -#ifndef PRINTF_INTEGER_BUFFER_SIZE -#define PRINTF_INTEGER_BUFFER_SIZE 32 -#endif - -// size of the fixed (on-stack) buffer for printing individual decimal numbers. -// this must be big enough to hold one converted floating-point value including -// padded zeros. -#ifndef PRINTF_DECIMAL_BUFFER_SIZE -#define PRINTF_DECIMAL_BUFFER_SIZE 32 -#endif - -// Support for the decimal notation floating point conversion specifiers (%f, %F) -#ifndef PRINTF_SUPPORT_DECIMAL_SPECIFIERS -#define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 1 -#endif - -// Support for the exponential notation floating point conversion specifiers (%e, %g, %E, %G) -#ifndef PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS -#define PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS 1 -#endif - -// Support for the length write-back specifier (%n) -#ifndef PRINTF_SUPPORT_WRITEBACK_SPECIFIER -#define PRINTF_SUPPORT_WRITEBACK_SPECIFIER 1 -#endif - -// Default precision for the floating point conversion specifiers (the C standard sets this at 6) -#ifndef PRINTF_DEFAULT_FLOAT_PRECISION -#define PRINTF_DEFAULT_FLOAT_PRECISION 6 -#endif - -// According to the C languages standard, printf() and related functions must be able to print any -// integral number in floating-point notation, regardless of length, when using the %f specifier - -// possibly hundreds of characters, potentially overflowing your buffers. In this implementation, -// all values beyond this threshold are switched to exponential notation. -#ifndef PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL -#define PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9 -#endif - -// Support for the long long integral types (with the ll, z and t length modifiers for specifiers -// %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: 'L' (long double) is not supported. -#ifndef PRINTF_SUPPORT_LONG_LONG -#define PRINTF_SUPPORT_LONG_LONG 1 -#endif - -// The number of terms in a Taylor series expansion of log_10(x) to -// use for approximation - including the power-zero term (i.e. the -// value at the point of expansion). -#ifndef PRINTF_LOG10_TAYLOR_TERMS -#define PRINTF_LOG10_TAYLOR_TERMS 4 -#endif - -#if PRINTF_LOG10_TAYLOR_TERMS <= 1 -#error "At least one non-constant Taylor expansion is necessary for the log10() calculation" -#endif - -// Be extra-safe, and don't assume format specifiers are completed correctly -// before the format string end. -#ifndef PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER -#define PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER 1 -#endif - -#define PRINTF_PREFER_DECIMAL false -#define PRINTF_PREFER_EXPONENTIAL true - -/////////////////////////////////////////////////////////////////////////////// - -// The following will convert the number-of-digits into an exponential-notation literal -#define PRINTF_CONCATENATE(s1, s2) s1##s2 -#define PRINTF_EXPAND_THEN_CONCATENATE(s1, s2) PRINTF_CONCATENATE(s1, s2) -#define PRINTF_FLOAT_NOTATION_THRESHOLD PRINTF_EXPAND_THEN_CONCATENATE(1e, PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL) - -// internal flag definitions -#define FLAGS_ZEROPAD (1U << 0U) -#define FLAGS_LEFT (1U << 1U) -#define FLAGS_PLUS (1U << 2U) -#define FLAGS_SPACE (1U << 3U) -#define FLAGS_HASH (1U << 4U) -#define FLAGS_UPPERCASE (1U << 5U) -#define FLAGS_CHAR (1U << 6U) -#define FLAGS_SHORT (1U << 7U) -#define FLAGS_INT (1U << 8U) -// Only used with PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS -#define FLAGS_LONG (1U << 9U) -#define FLAGS_LONG_LONG (1U << 10U) -#define FLAGS_PRECISION (1U << 11U) -#define FLAGS_ADAPT_EXP (1U << 12U) -#define FLAGS_POINTER (1U << 13U) -// Note: Similar, but not identical, effect as FLAGS_HASH -#define FLAGS_SIGNED (1U << 14U) -// Only used with PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS - -#ifdef PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS - -#define FLAGS_INT8 FLAGS_CHAR - -#if (SHRT_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_SHORT -#elif (INT_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_INT -#elif (LONG_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_LONG -#elif (LLONG_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_LONG_LONG -#else -#error "No basic integer type has a size of 16 bits exactly" -#endif - -#if (SHRT_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_SHORT -#elif (INT_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_INT -#elif (LONG_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_LONG -#elif (LLONG_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_LONG_LONG -#else -#error "No basic integer type has a size of 32 bits exactly" -#endif - -#if (SHRT_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_SHORT -#elif (INT_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_INT -#elif (LONG_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_LONG -#elif (LLONG_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_LONG_LONG -#else -#error "No basic integer type has a size of 64 bits exactly" -#endif - -#endif // PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS - -typedef unsigned int printf_flags_t; - -#define BASE_BINARY 2 -#define BASE_OCTAL 8 -#define BASE_DECIMAL 10 -#define BASE_HEX 16 - -typedef uint8_t numeric_base_t; - -#if PRINTF_SUPPORT_LONG_LONG -typedef unsigned long long printf_unsigned_value_t; -typedef long long printf_signed_value_t; -#else -typedef unsigned long printf_unsigned_value_t; -typedef long printf_signed_value_t; -#endif - -// The printf()-family functions return an `int`; it is therefore -// unnecessary/inappropriate to use size_t - often larger than int -// in practice - for non-negative related values, such as widths, -// precisions, offsets into buffers used for printing and the sizes -// of these buffers. instead, we use: -typedef unsigned int printf_size_t; -#define PRINTF_MAX_POSSIBLE_BUFFER_SIZE INT_MAX -// If we were to nitpick, this would actually be INT_MAX + 1, -// since INT_MAX is the maximum return value, which excludes the -// trailing '\0'. - -#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) -#include -#if FLT_RADIX != 2 -#error "Non-binary-radix floating-point types are unsupported." -#endif - -#if DBL_MANT_DIG == 24 - -#define DOUBLE_SIZE_IN_BITS 32 -typedef uint32_t double_uint_t; -#define DOUBLE_EXPONENT_MASK 0xFFU -#define DOUBLE_BASE_EXPONENT 127 -#define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -38 -#define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 1e-38 - -#elif DBL_MANT_DIG == 53 - -#define DOUBLE_SIZE_IN_BITS 64 -typedef uint64_t double_uint_t; -#define DOUBLE_EXPONENT_MASK 0x7FFU -#define DOUBLE_BASE_EXPONENT 1023 -#define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -308 -#define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 1e-308 - -#else -#error "Unsupported double type configuration" -#endif -#define DOUBLE_STORED_MANTISSA_BITS (DBL_MANT_DIG - 1) - -typedef union -{ - double_uint_t U; - double F; -} double_with_bit_access; - -// This is unnecessary in C99, since compound initializers can be used, -// but: -// 1. Some compilers are finicky about this; -// 2. Some people may want to convert this to C89; -// 3. If you try to use it as C++, only C++20 supports compound literals -static inline NIF double_with_bit_access get_bit_access(double x) -{ - double_with_bit_access dwba; - dwba.F = x; - return dwba; -} - -static inline NIF int get_sign_bit(double x) -{ - // The sign is stored in the highest bit - return (int)(get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1)); -} - -static inline int get_exp2(double_with_bit_access x) -{ - // The exponent in an IEEE-754 floating-point number occupies a contiguous - // sequence of bits (e.g. 52..62 for 64-bit doubles), but with a non-trivial representation: An - // unsigned offset from some negative value (with the extremal offset values reserved for - // special use). - return (int)((x.U >> DOUBLE_STORED_MANTISSA_BITS) & DOUBLE_EXPONENT_MASK) - DOUBLE_BASE_EXPONENT; -} -#define PRINTF_ABS(_x) ((_x) > 0 ? (_x) : -(_x)) - -#endif // (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) - -// Note in particular the behavior here on LONG_MIN or LLONG_MIN; it is valid -// and well-defined, but if you're not careful you can easily trigger undefined -// behavior with -LONG_MIN or -LLONG_MIN -#define ABS_FOR_PRINTING(_x) ((printf_unsigned_value_t)((_x) > 0 ? (_x) : -((printf_signed_value_t)_x))) - -// wrapper (used as buffer) for output function type -// -// One of the following must hold: -// 1. max_chars is 0 -// 2. buffer is non-null -// 3. function is non-null -// -// ... otherwise bad things will happen. -typedef struct -{ - void (*function)(char c, void *extra_arg); - void *extra_function_arg; - char *buffer; - printf_size_t pos; - printf_size_t max_chars; -} output_gadget_t; - -// Note: This function currently assumes it is not passed a '\0' c, -// or alternatively, that '\0' can be passed to the function in the output -// gadget. The former assumption holds within the printf library. It also -// assumes that the output gadget has been properly initialized. -static inline NIF void putchar_via_gadget(output_gadget_t *gadget, char c) -{ - printf_size_t write_pos = gadget->pos++; - // We're _always_ increasing pos, so as to count how may characters - // _would_ have been written if not for the max_chars limitation - if (write_pos >= gadget->max_chars) - { - return; - } - if (gadget->function != NULL) - { - // No check for c == '\0' . - gadget->function(c, gadget->extra_function_arg); - } - else - { - // it must be the case that gadget->buffer != NULL , due to the constraint - // on output_gadget_t ; and note we're relying on write_pos being non-negative. - gadget->buffer[write_pos] = c; - } -} - -// Possibly-write the string-terminating '\0' character -static inline NIF void append_termination_with_gadget(output_gadget_t *gadget) -{ - if (gadget->function != NULL || gadget->max_chars == 0) - { - return; - } - if (gadget->buffer == NULL) - { - return; - } - printf_size_t null_char_pos = gadget->pos < gadget->max_chars ? gadget->pos : gadget->max_chars - 1; - gadget->buffer[null_char_pos] = '\0'; -} - -extern void putchar(char c); - -// We can't use putchar_ as is, since our output gadget -// only takes pointers to functions with an extra argument -static inline NIF void putchar_wrapper(char c, void *unused) -{ - putchar(c); - UNUSED(unused); -} - -static inline NIF output_gadget_t discarding_gadget(void) -{ - output_gadget_t gadget; - gadget.function = NULL; - gadget.extra_function_arg = NULL; - gadget.buffer = NULL; - gadget.pos = 0; - gadget.max_chars = 0; - return gadget; -} - -static inline NIF output_gadget_t buffer_gadget(char *buffer, size_t buffer_size) -{ - printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ? PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t)buffer_size; - output_gadget_t result = discarding_gadget(); - if (buffer != NULL) - { - result.buffer = buffer; - result.max_chars = usable_buffer_size; - } - return result; -} - -static inline NIF output_gadget_t function_gadget(void (*function)(char, void *), void *extra_arg) -{ - output_gadget_t result = discarding_gadget(); - result.function = function; - result.extra_function_arg = extra_arg; - result.max_chars = PRINTF_MAX_POSSIBLE_BUFFER_SIZE; - return result; -} - -static inline NIF output_gadget_t extern_putchar_gadget(void) -{ - return function_gadget(putchar_wrapper, NULL); -} - -// internal secure strlen -// @return The length of the string (excluding the terminating 0) limited by 'maxsize' -// @note strlen uses size_t, but wes only use this function with printf_size_t -// variables - hence the signature. -static inline NIF printf_size_t strnlen_s_(const char *str, printf_size_t maxsize) -{ - const char *s; - for (s = str; *s && maxsize--; ++s) - ; - return (printf_size_t)(s - str); -} - -// internal test if char is a digit (0-9) -// @return true if char is a digit -static inline NIF bool is_digit_(char ch) -{ - return (ch >= '0') && (ch <= '9'); -} - -// internal ASCII string to printf_size_t conversion -static NIF printf_size_t atou_(const char **str) -{ - printf_size_t i = 0U; - while (is_digit_(**str)) - { - i = i * 10U + (printf_size_t)(*((*str)++) - '0'); - } - return i; -} - -// output the specified string in reverse, taking care of any zero-padding -static NIF void out_rev_(output_gadget_t *output, const char *buf, printf_size_t len, printf_size_t width, printf_flags_t flags) -{ - const printf_size_t start_pos = output->pos; - - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) - { - for (printf_size_t i = len; i < width; i++) - { - putchar_via_gadget(output, ' '); - } - } - - // reverse string - while (len) - { - putchar_via_gadget(output, buf[--len]); - } - - // append pad spaces up to given width - if (flags & FLAGS_LEFT) - { - while (output->pos - start_pos < width) - { - putchar_via_gadget(output, ' '); - } - } -} - -// Invoked by print_integer after the actual number has been printed, performing necessary -// work on the number's prefix (as the number is initially printed in reverse order) -static NIF void print_integer_finalization(output_gadget_t *output, char *buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) -{ - printf_size_t unpadded_len = len; - - // pad with leading zeros - { - if (!(flags & FLAGS_LEFT)) - { - if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) - { - width--; - } - while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_INTEGER_BUFFER_SIZE)) - { - buf[len++] = '0'; - } - } - - while ((len < precision) && (len < PRINTF_INTEGER_BUFFER_SIZE)) - { - buf[len++] = '0'; - } - - if (base == BASE_OCTAL && (len > unpadded_len)) - { - // Since we've written some zeros, we've satisfied the alternative format leading space requirement - flags &= ~FLAGS_HASH; - } - } - - // handle hash - if (flags & (FLAGS_HASH | FLAGS_POINTER)) - { - if (!(flags & FLAGS_PRECISION) && len && ((len == precision) || (len == width))) - { - // Let's take back some padding digits to fit in what will eventually - // be the format-specific prefix - if (unpadded_len < len) - { - len--; // This should suffice for BASE_OCTAL - } - if (len && (base == BASE_HEX || base == BASE_BINARY) && (unpadded_len < len)) - { - len--; // ... and an extra one for 0x or 0b - } - } - if ((base == BASE_HEX) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_INTEGER_BUFFER_SIZE)) - { - buf[len++] = 'x'; - } - else if ((base == BASE_HEX) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_INTEGER_BUFFER_SIZE)) - { - buf[len++] = 'X'; - } - else if ((base == BASE_BINARY) && (len < PRINTF_INTEGER_BUFFER_SIZE)) - { - buf[len++] = 'b'; - } - if (len < PRINTF_INTEGER_BUFFER_SIZE) - { - buf[len++] = '0'; - } - } - - if (len < PRINTF_INTEGER_BUFFER_SIZE) - { - if (negative) - { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) - { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) - { - buf[len++] = ' '; - } - } - - out_rev_(output, buf, len, width, flags); -} - -// An internal itoa-like function -static NIF void print_integer(output_gadget_t *output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) -{ - char buf[PRINTF_INTEGER_BUFFER_SIZE]; - printf_size_t len = 0U; - - if (!value) - { - if (!(flags & FLAGS_PRECISION)) - { - buf[len++] = '0'; - flags &= ~FLAGS_HASH; - // We drop this flag this since either the alternative and regular modes of the specifier - // don't differ on 0 values, or (in the case of octal) we've already provided the special - // handling for this mode. - } - else if (base == BASE_HEX) - { - flags &= ~FLAGS_HASH; - // We drop this flag this since either the alternative and regular modes of the specifier - // don't differ on 0 values - } - } - else - { - do - { - const char digit = (char)(value % base); - buf[len++] = (char)(digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10); - value /= base; - } while (value && (len < PRINTF_INTEGER_BUFFER_SIZE)); - } - - print_integer_finalization(output, buf, len, negative, base, precision, width, flags); -} - -#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) - -// Stores a fixed-precision representation of a double relative -// to a fixed precision (which cannot be determined by examining this structure) -struct double_components -{ - int_fast64_t integral; - int_fast64_t fractional; - // ... truncation of the actual fractional part of the double value, scaled - // by the precision value - bool is_negative; -}; - -#define NUM_DECIMAL_DIGITS_IN_INT64_T 18 -#define PRINTF_MAX_PRECOMPUTED_POWER_OF_10 NUM_DECIMAL_DIGITS_IN_INT64_T -static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { - 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, - 1e09, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17}; - -#define PRINTF_MAX_SUPPORTED_PRECISION NUM_DECIMAL_DIGITS_IN_INT64_T - 1 - -// Break up a double number - which is known to be a finite non-negative number - -// into its base-10 parts: integral - before the decimal point, and fractional - after it. -// Taken the precision into account, but does not change it even internally. -static struct NIF double_components get_components(double number, printf_size_t precision) -{ - struct double_components number_; - number_.is_negative = get_sign_bit(number); - double abs_number = (number_.is_negative) ? -number : number; - number_.integral = (int_fast64_t)abs_number; - double remainder = (abs_number - (double)number_.integral) * powers_of_10[precision]; - number_.fractional = (int_fast64_t)remainder; - - remainder -= (double)number_.fractional; - - if (remainder > 0.5) - { - ++number_.fractional; - // handle rollover, e.g. case 0.99 with precision 1 is 1.0 - if ((double)number_.fractional >= powers_of_10[precision]) - { - number_.fractional = 0; - ++number_.integral; - } - } - else if ((remainder == 0.5) && ((number_.fractional == 0U) || (number_.fractional & 1U))) - { - // if halfway, round up if odd OR if last digit is 0 - ++number_.fractional; - } - - if (precision == 0U) - { - remainder = abs_number - (double)number_.integral; - if ((!(remainder < 0.5) || (remainder > 0.5)) && (number_.integral & 1)) - { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++number_.integral; - } - } - return number_; -} - -#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS -struct scaling_factor -{ - double raw_factor; - bool multiply; // if true, need to multiply by raw_factor; otherwise need to divide by it -}; - -static double apply_scaling(double num, struct scaling_factor normalization) -{ - return normalization.multiply ? num * normalization.raw_factor : num / normalization.raw_factor; -} - -static double unapply_scaling(double normalized, struct scaling_factor normalization) -{ -#ifdef __GNUC__ -// accounting for a static analysis bug in GCC 6.x and earlier -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - return normalization.multiply ? normalized / normalization.raw_factor : normalized * normalization.raw_factor; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif -} - -static struct scaling_factor update_normalization(struct scaling_factor sf, double extra_multiplicative_factor) -{ - struct scaling_factor result; - if (sf.multiply) - { - result.multiply = true; - result.raw_factor = sf.raw_factor * extra_multiplicative_factor; - } - else - { - int factor_exp2 = get_exp2(get_bit_access(sf.raw_factor)); - int extra_factor_exp2 = get_exp2(get_bit_access(extra_multiplicative_factor)); - - // Divide the larger-exponent raw raw_factor by the smaller - if (PRINTF_ABS(factor_exp2) > PRINTF_ABS(extra_factor_exp2)) - { - result.multiply = false; - result.raw_factor = sf.raw_factor / extra_multiplicative_factor; - } - else - { - result.multiply = true; - result.raw_factor = extra_multiplicative_factor / sf.raw_factor; - } - } - return result; -} - -static struct double_components get_normalized_components(bool negative, printf_size_t precision, double non_normalized, struct scaling_factor normalization, int floored_exp10) -{ - struct double_components components; - components.is_negative = negative; - double scaled = apply_scaling(non_normalized, normalization); - - bool close_to_representation_extremum = ((-floored_exp10 + (int)precision) >= DBL_MAX_10_EXP - 1); - if (close_to_representation_extremum) - { - // We can't have a normalization factor which also accounts for the precision, i.e. moves - // some decimal digits into the mantissa, since it's unrepresentable, or nearly unrepresentable. - // So, we'll give up early on getting extra precision... - return get_components(negative ? -scaled : scaled, precision); - } - components.integral = (int_fast64_t)scaled; - double remainder = non_normalized - unapply_scaling((double)components.integral, normalization); - double prec_power_of_10 = powers_of_10[precision]; - struct scaling_factor account_for_precision = update_normalization(normalization, prec_power_of_10); - double scaled_remainder = apply_scaling(remainder, account_for_precision); - double rounding_threshold = 0.5; - - components.fractional = (int_fast64_t)scaled_remainder; // when precision == 0, the assigned value should be 0 - scaled_remainder -= (double)components.fractional; // when precision == 0, this will not change scaled_remainder - - components.fractional += (scaled_remainder >= rounding_threshold); - if (scaled_remainder == rounding_threshold) - { - // banker's rounding: Round towards the even number (making the mean error 0) - components.fractional &= ~((int_fast64_t)0x1); - } - // handle rollover, e.g. the case of 0.99 with precision 1 becoming (0,100), - // and must then be corrected into (1, 0). - // Note: for precision = 0, this will "translate" the rounding effect from - // the fractional part to the integral part where it should actually be - // felt (as prec_power_of_10 is 1) - if ((double)components.fractional >= prec_power_of_10) - { - components.fractional = 0; - ++components.integral; - } - return components; -} -#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS - -static NIF void print_broken_up_decimal( - struct double_components number_, output_gadget_t *output, printf_size_t precision, - printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) -{ - if (precision != 0U) - { - // do fractional part, as an unsigned number - - printf_size_t count = precision; - - // %g/%G mandates we skip the trailing 0 digits... - if ((flags & FLAGS_ADAPT_EXP) && !(flags & FLAGS_HASH) && (number_.fractional > 0)) - { - while (true) - { - int_fast64_t digit = number_.fractional % 10U; - if (digit != 0) - { - break; - } - --count; - number_.fractional /= 10U; - } - // ... and even the decimal point if there are no - // non-zero fractional part digits (see below) - } - - if (number_.fractional > 0 || !(flags & FLAGS_ADAPT_EXP) || (flags & FLAGS_HASH)) - { - while (len < PRINTF_DECIMAL_BUFFER_SIZE) - { - --count; - buf[len++] = (char)('0' + number_.fractional % 10U); - if (!(number_.fractional /= 10U)) - { - break; - } - } - // add extra 0s - while ((len < PRINTF_DECIMAL_BUFFER_SIZE) && (count > 0U)) - { - buf[len++] = '0'; - --count; - } - if (len < PRINTF_DECIMAL_BUFFER_SIZE) - { - buf[len++] = '.'; - } - } - } - else - { - if ((flags & FLAGS_HASH) && (len < PRINTF_DECIMAL_BUFFER_SIZE)) - { - buf[len++] = '.'; - } - } - - // Write the integer part of the number (it comes after the fractional - // since the character order is reversed) - while (len < PRINTF_DECIMAL_BUFFER_SIZE) - { - buf[len++] = (char)('0' + (number_.integral % 10)); - if (!(number_.integral /= 10)) - { - break; - } - } - - // pad leading zeros - if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) - { - if (width && (number_.is_negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) - { - width--; - } - while ((len < width) && (len < PRINTF_DECIMAL_BUFFER_SIZE)) - { - buf[len++] = '0'; - } - } - - if (len < PRINTF_DECIMAL_BUFFER_SIZE) - { - if (number_.is_negative) - { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) - { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) - { - buf[len++] = ' '; - } - } - - out_rev_(output, buf, len, width, flags); -} - -// internal ftoa for fixed decimal floating point -static NIF void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) -{ - struct double_components value_ = get_components(number, precision); - print_broken_up_decimal(value_, output, precision, width, flags, buf, len); -} - -#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS - -// A floor function - but one which only works for numbers whose -// floor value is representable by an int. -static int bastardized_floor(double x) -{ - if (x >= 0) - { - return (int)x; - } - int n = (int)x; - return (((double)n) == x) ? n : n - 1; -} - -// Computes the base-10 logarithm of the input number - which must be an actual -// positive number (not infinity or NaN, nor a sub-normal) -static double log10_of_positive(double positive_number) -{ - // The implementation follows David Gay (https://www.ampl.com/netlib/fp/dtoa.c). - // - // Since log_10 ( M * 2^x ) = log_10(M) + x , we can separate the components of - // our input number, and need only solve log_10(M) for M between 1 and 2 (as - // the base-2 mantissa is always 1-point-something). In that limited range, a - // Taylor series expansion of log10(x) should serve us well enough; and we'll - // take the mid-point, 1.5, as the point of expansion. - - double_with_bit_access dwba = get_bit_access(positive_number); - // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) - int exp2 = get_exp2(dwba); - // drop the exponent, so dwba.F comes into the range [1,2) - dwba.U = (dwba.U & (((double_uint_t)(1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) | - ((double_uint_t)DOUBLE_BASE_EXPONENT << DOUBLE_STORED_MANTISSA_BITS); - double z = (dwba.F - 1.5); - return ( - // Taylor expansion around 1.5: - 0.1760912590556812420 // Expansion term 0: ln(1.5) / ln(10) - + z * 0.2895296546021678851 // Expansion term 1: (M - 1.5) * 2/3 / ln(10) -#if PRINTF_LOG10_TAYLOR_TERMS > 2 - - z * z * 0.0965098848673892950 // Expansion term 2: (M - 1.5)^2 * 2/9 / ln(10) -#if PRINTF_LOG10_TAYLOR_TERMS > 3 - + z * z * z * 0.0428932821632841311 // Expansion term 2: (M - 1.5)^3 * 8/81 / ln(10) -#endif -#endif - // exact log_2 of the exponent x, with logarithm base change - + exp2 * 0.30102999566398119521 // = exp2 * log_10(2) = exp2 * ln(2)/ln(10) - ); -} - -static double pow10_of_int(int floored_exp10) -{ - // A crude hack for avoiding undesired behavior with barely-normal or slightly-subnormal values. - if (floored_exp10 == DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10) - { - return DOUBLE_MAX_SUBNORMAL_POWER_OF_10; - } - // Compute 10^(floored_exp10) but (try to) make sure that doesn't overflow - double_with_bit_access dwba; - int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5); - const double z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453; - const double z2 = z * z; - dwba.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) << DOUBLE_STORED_MANTISSA_BITS; - // compute exp(z) using continued fractions, - // see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex - dwba.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); - return dwba.F; -} - -static NIF void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) -{ - const bool negative = get_sign_bit(number); - // This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it - double abs_number = negative ? -number : number; - - int floored_exp10; - bool abs_exp10_covered_by_powers_table; - struct scaling_factor normalization; - - // Determine the decimal exponent - if (abs_number == 0.0) - { - // TODO: This is a special-case for 0.0 (and -0.0); but proper handling is required for denormals more generally. - floored_exp10 = 0; // ... and no need to set a normalization factor or check the powers table - } - else - { - double exp10 = log10_of_positive(abs_number); - floored_exp10 = bastardized_floor(exp10); - double p10 = pow10_of_int(floored_exp10); - // correct for rounding errors - if (abs_number < p10) - { - floored_exp10--; - p10 /= 10; - } - abs_exp10_covered_by_powers_table = PRINTF_ABS(floored_exp10) < PRINTF_MAX_PRECOMPUTED_POWER_OF_10; - normalization.raw_factor = abs_exp10_covered_by_powers_table ? powers_of_10[PRINTF_ABS(floored_exp10)] : p10; - } - - // We now begin accounting for the widths of the two parts of our printed field: - // the decimal part after decimal exponent extraction, and the base-10 exponent part. - // For both of these, the value of 0 has a special meaning, but not the same one: - // a 0 exponent-part width means "don't print the exponent"; a 0 decimal-part width - // means "use as many characters as necessary". - - bool fall_back_to_decimal_only_mode = false; - if (flags & FLAGS_ADAPT_EXP) - { - int required_significant_digits = (precision == 0) ? 1 : (int)precision; - // Should we want to fall-back to "%f" mode, and only print the decimal part? - fall_back_to_decimal_only_mode = (floored_exp10 >= -4 && floored_exp10 < required_significant_digits); - // Now, let's adjust the precision - // This also decided how we adjust the precision value - as in "%g" mode, - // "precision" is the number of _significant digits_, and this is when we "translate" - // the precision value to an actual number of decimal digits. - int precision_ = fall_back_to_decimal_only_mode ? (int)precision - 1 - floored_exp10 : (int)precision - 1; // the presence of the exponent ensures only one significant digit comes before the decimal point - precision = (precision_ > 0 ? (unsigned)precision_ : 0U); - flags |= FLAGS_PRECISION; // make sure print_broken_up_decimal respects our choice above - } - - normalization.multiply = (floored_exp10 < 0 && abs_exp10_covered_by_powers_table); - bool should_skip_normalization = (fall_back_to_decimal_only_mode || floored_exp10 == 0); - struct double_components decimal_part_components = - should_skip_normalization ? get_components(negative ? -abs_number : abs_number, precision) : get_normalized_components(negative, precision, abs_number, normalization, floored_exp10); - - // Account for roll-over, e.g. rounding from 9.99 to 100.0 - which effects - // the exponent and may require additional tweaking of the parts - if (fall_back_to_decimal_only_mode) - { - if ((flags & FLAGS_ADAPT_EXP) && floored_exp10 >= -1 && decimal_part_components.integral == powers_of_10[floored_exp10 + 1]) - { - floored_exp10++; // Not strictly necessary, since floored_exp10 is no longer really used - precision--; - // ... and it should already be the case that decimal_part_components.fractional == 0 - } - // TODO: What about rollover strictly within the fractional part? - } - else - { - if (decimal_part_components.integral >= 10) - { - floored_exp10++; - decimal_part_components.integral = 1; - decimal_part_components.fractional = 0; - } - } - - // the floored_exp10 format is "E%+03d" and largest possible floored_exp10 value for a 64-bit double - // is "307" (for 2^1023), so we set aside 4-5 characters overall - printf_size_t exp10_part_width = fall_back_to_decimal_only_mode ? 0U : (PRINTF_ABS(floored_exp10) < 100) ? 4U - : 5U; - - printf_size_t decimal_part_width = - ((flags & FLAGS_LEFT) && exp10_part_width) ? - // We're padding on the right, so the width constraint is the exponent part's - // problem, not the decimal part's, so we'll use as many characters as we need: - 0U - : - // We're padding on the left; so the width constraint is the decimal part's - // problem. Well, can both the decimal part and the exponent part fit within our overall width? - ((width > exp10_part_width) ? - // Yes, so we limit our decimal part's width. - // (Note this is trivially valid even if we've fallen back to "%f" mode) - width - exp10_part_width - : - // No; we just give up on any restriction on the decimal part and use as many - // characters as we need - 0U); - - const printf_size_t printed_exponential_start_pos = output->pos; - print_broken_up_decimal(decimal_part_components, output, precision, decimal_part_width, flags, buf, len); - - if (!fall_back_to_decimal_only_mode) - { - putchar_via_gadget(output, (flags & FLAGS_UPPERCASE) ? 'E' : 'e'); - print_integer(output, - ABS_FOR_PRINTING(floored_exp10), - floored_exp10 < 0, 10, 0, exp10_part_width - 1, - FLAGS_ZEROPAD | FLAGS_PLUS); - if (flags & FLAGS_LEFT) - { - // We need to right-pad with spaces to meet the width requirement - while (output->pos - printed_exponential_start_pos < width) - { - putchar_via_gadget(output, ' '); - } - } - } -} -#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS - -static NIF void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential) -{ - char buf[PRINTF_DECIMAL_BUFFER_SIZE]; - printf_size_t len = 0U; - - // test for special values - if (value != value) - { - out_rev_(output, "nan", 3, width, flags); - return; - } - if (value < -DBL_MAX) - { - out_rev_(output, "fni-", 4, width, flags); - return; - } - if (value > DBL_MAX) - { - out_rev_(output, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); - return; - } - - if (!prefer_exponential && - ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) - { - // The required behavior of standard printf is to print _every_ integral-part digit -- which could mean - // printing hundreds of characters, overflowing any fixed internal buffer and necessitating a more complicated - // implementation. -#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS - print_exponential_number(output, value, precision, width, flags, buf, len); -#endif - return; - } - - // set default precision, if not set explicitly - if (!(flags & FLAGS_PRECISION)) - { - precision = PRINTF_DEFAULT_FLOAT_PRECISION; - } - - // limit precision so that our integer holding the fractional part does not overflow - while ((len < PRINTF_DECIMAL_BUFFER_SIZE) && (precision > PRINTF_MAX_SUPPORTED_PRECISION)) - { - buf[len++] = '0'; // This respects the precision in terms of result length only - precision--; - } - -#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS - if (prefer_exponential) - print_exponential_number(output, value, precision, width, flags, buf, len); - else -#endif - print_decimal_number(output, value, precision, width, flags, buf, len); -} - -#endif // (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) - -// Advances the format pointer past the flags, and returns the parsed flags -// due to the characters passed -static NIF printf_flags_t parse_flags(const char **format) -{ - printf_flags_t flags = 0U; - do - { - switch (**format) - { - case '0': - flags |= FLAGS_ZEROPAD; - (*format)++; - break; - case '-': - flags |= FLAGS_LEFT; - (*format)++; - break; - case '+': - flags |= FLAGS_PLUS; - (*format)++; - break; - case ' ': - flags |= FLAGS_SPACE; - (*format)++; - break; - case '#': - flags |= FLAGS_HASH; - (*format)++; - break; - default: - return flags; - } - } while (true); -} - -static inline NIF void format_string_loop(output_gadget_t *output, const char *format, va_list args) -{ -#if PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER -#define ADVANCE_IN_FORMAT_STRING(cptr_) \ - do \ - { \ - (cptr_)++; \ - if (!*(cptr_)) \ - return; \ - } while (0) -#else -#define ADVANCE_IN_FORMAT_STRING(cptr_) (cptr_)++ -#endif - - while (*format) - { - if (*format != '%') - { - // A regular content character - putchar_via_gadget(output, *format); - format++; - continue; - } - // We're parsing a format specifier: %[flags][width][.precision][length] - ADVANCE_IN_FORMAT_STRING(format); - - printf_flags_t flags = parse_flags(&format); - - // evaluate width field - printf_size_t width = 0U; - if (is_digit_(*format)) - { - width = (printf_size_t)atou_(&format); - } - else if (*format == '*') - { - const int w = va_arg(args, int); - if (w < 0) - { - flags |= FLAGS_LEFT; // reverse padding - width = (printf_size_t)-w; - } - else - { - width = (printf_size_t)w; - } - ADVANCE_IN_FORMAT_STRING(format); - } - - // evaluate precision field - printf_size_t precision = 0U; - if (*format == '.') - { - flags |= FLAGS_PRECISION; - ADVANCE_IN_FORMAT_STRING(format); - if (is_digit_(*format)) - { - precision = (printf_size_t)atou_(&format); - } - else if (*format == '*') - { - const int precision_ = va_arg(args, int); - precision = precision_ > 0 ? (printf_size_t)precision_ : 0U; - ADVANCE_IN_FORMAT_STRING(format); - } - } - - // evaluate length field - switch (*format) - { -#ifdef PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS - case 'I': - { - ADVANCE_IN_FORMAT_STRING(format); - // Greedily parse for size in bits: 8, 16, 32 or 64 - switch (*format) - { - case '8': - flags |= FLAGS_INT8; - ADVANCE_IN_FORMAT_STRING(format); - break; - case '1': - ADVANCE_IN_FORMAT_STRING(format); - if (*format == '6') - { - format++; - flags |= FLAGS_INT16; - } - break; - case '3': - ADVANCE_IN_FORMAT_STRING(format); - if (*format == '2') - { - ADVANCE_IN_FORMAT_STRING(format); - flags |= FLAGS_INT32; - } - break; - case '6': - ADVANCE_IN_FORMAT_STRING(format); - if (*format == '4') - { - ADVANCE_IN_FORMAT_STRING(format); - flags |= FLAGS_INT64; - } - break; - default: - break; - } - break; - } -#endif - case 'l': - flags |= FLAGS_LONG; - ADVANCE_IN_FORMAT_STRING(format); - if (*format == 'l') - { - flags |= FLAGS_LONG_LONG; - ADVANCE_IN_FORMAT_STRING(format); - } - break; - case 'h': - flags |= FLAGS_SHORT; - ADVANCE_IN_FORMAT_STRING(format); - if (*format == 'h') - { - flags |= FLAGS_CHAR; - ADVANCE_IN_FORMAT_STRING(format); - } - break; - case 't': - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - ADVANCE_IN_FORMAT_STRING(format); - break; - case 'j': - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - ADVANCE_IN_FORMAT_STRING(format); - break; - case 'z': - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - ADVANCE_IN_FORMAT_STRING(format); - break; - default: - break; - } - - // evaluate specifier - switch (*format) - { - case 'd': - case 'i': - case 'u': - case 'x': - case 'X': - case 'o': - case 'b': - { - - if (*format == 'd' || *format == 'i') - { - flags |= FLAGS_SIGNED; - } - - numeric_base_t base; - if (*format == 'x' || *format == 'X') - { - base = BASE_HEX; - } - else if (*format == 'o') - { - base = BASE_OCTAL; - } - else if (*format == 'b') - { - base = BASE_BINARY; - } - else - { - base = BASE_DECIMAL; - flags &= ~FLAGS_HASH; // decimal integers have no alternative presentation - } - - if (*format == 'X') - { - flags |= FLAGS_UPPERCASE; - } - - format++; - // ignore '0' flag when precision is given - if (flags & FLAGS_PRECISION) - { - flags &= ~FLAGS_ZEROPAD; - } - - if (flags & FLAGS_SIGNED) - { - // A signed specifier: d, i or possibly I + bit size if enabled - - if (flags & FLAGS_LONG_LONG) - { -#if PRINTF_SUPPORT_LONG_LONG - const long long value = va_arg(args, long long); - print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags); -#endif - } - else if (flags & FLAGS_LONG) - { - const long value = va_arg(args, long); - print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags); - } - else - { - // We never try to interpret the argument as something potentially-smaller than int, - // due to integer promotion rules: Even if the user passed a short int, short unsigned - // etc. - these will come in after promotion, as int's (or unsigned for the case of - // short unsigned when it has the same size as int) - const int value = - (flags & FLAGS_CHAR) ? (signed char)va_arg(args, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(args, int) - : va_arg(args, int); - print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags); - } - } - else - { - // An unsigned specifier: u, x, X, o, b - - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); - - if (flags & FLAGS_LONG_LONG) - { -#if PRINTF_SUPPORT_LONG_LONG - print_integer(output, (printf_unsigned_value_t)va_arg(args, unsigned long long), false, base, precision, width, flags); -#endif - } - else if (flags & FLAGS_LONG) - { - print_integer(output, (printf_unsigned_value_t)va_arg(args, unsigned long), false, base, precision, width, flags); - } - else - { - const unsigned int value = - (flags & FLAGS_CHAR) ? (unsigned char)va_arg(args, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(args, unsigned int) - : va_arg(args, unsigned int); - print_integer(output, (printf_unsigned_value_t)value, false, base, precision, width, flags); - } - } - break; - } -#if PRINTF_SUPPORT_DECIMAL_SPECIFIERS - case 'f': - case 'F': - if (*format == 'F') - flags |= FLAGS_UPPERCASE; - print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_DECIMAL); - format++; - break; -#endif -#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS - case 'e': - case 'E': - case 'g': - case 'G': - if ((*format == 'g') || (*format == 'G')) - flags |= FLAGS_ADAPT_EXP; - if ((*format == 'E') || (*format == 'G')) - flags |= FLAGS_UPPERCASE; - print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_EXPONENTIAL); - format++; - break; -#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS - case 'c': - { - printf_size_t l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) - { - while (l++ < width) - { - putchar_via_gadget(output, ' '); - } - } - // char output - putchar_via_gadget(output, (char)va_arg(args, int)); - // post padding - if (flags & FLAGS_LEFT) - { - while (l++ < width) - { - putchar_via_gadget(output, ' '); - } - } - format++; - break; - } - - case 's': - { - const char *p = va_arg(args, char *); - if (p == NULL) - { - out_rev_(output, ")llun(", 6, width, flags); - } - else - { - printf_size_t l = strnlen_s_(p, precision ? precision : PRINTF_MAX_POSSIBLE_BUFFER_SIZE); - // pre padding - if (flags & FLAGS_PRECISION) - { - l = (l < precision ? l : precision); - } - if (!(flags & FLAGS_LEFT)) - { - while (l++ < width) - { - putchar_via_gadget(output, ' '); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision)) - { - putchar_via_gadget(output, *(p++)); - --precision; - } - // post padding - if (flags & FLAGS_LEFT) - { - while (l++ < width) - { - putchar_via_gadget(output, ' '); - } - } - } - format++; - break; - } - - case 'p': - { - width = sizeof(void *) * 2U + 2; // 2 hex chars per byte + the "0x" prefix - flags |= FLAGS_ZEROPAD | FLAGS_POINTER; - uintptr_t value = (uintptr_t)va_arg(args, void *); - (value == (uintptr_t)NULL) ? out_rev_(output, ")lin(", 5, width, flags) : print_integer(output, (printf_unsigned_value_t)value, false, BASE_HEX, precision, width, flags); - format++; - break; - } - - case '%': - putchar_via_gadget(output, '%'); - format++; - break; - - // Many people prefer to disable support for %n, as it lets the caller - // engineer a write to an arbitrary location, of a value the caller - // effectively controls - which could be a security concern in some cases. -#if PRINTF_SUPPORT_WRITEBACK_SPECIFIER - case 'n': - { - if (flags & FLAGS_CHAR) - *(va_arg(args, char *)) = (char)output->pos; - else if (flags & FLAGS_SHORT) - *(va_arg(args, short *)) = (short)output->pos; - else if (flags & FLAGS_LONG) - *(va_arg(args, long *)) = (long)output->pos; -#if PRINTF_SUPPORT_LONG_LONG - else if (flags & FLAGS_LONG_LONG) - *(va_arg(args, long long *)) = (long long int)output->pos; -#endif // PRINTF_SUPPORT_LONG_LONG - else - *(va_arg(args, int *)) = (int)output->pos; - format++; - break; - } -#endif // PRINTF_SUPPORT_WRITEBACK_SPECIFIER - - default: - putchar_via_gadget(output, *format); - format++; - break; - } - } -} - -// internal vsnprintf - used for implementing _all library functions -static NIF int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args) -{ - // Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is - // possible to call this function with a non-zero pos value for some "remedial printing". - format_string_loop(output, format, args); - - // termination - append_termination_with_gadget(output); - - // return written chars without terminating \0 - return (int)output->pos; -} - -/////////////////////////////////////////////////////////////////////////////// - -NIF int vprintf(const char *format, va_list arg) -{ - output_gadget_t gadget = extern_putchar_gadget(); - return vsnprintf_impl(&gadget, format, arg); -} - -NIF int vsnprintf(char *s, size_t n, const char *format, va_list arg) -{ - output_gadget_t gadget = buffer_gadget(s, n); - return vsnprintf_impl(&gadget, format, arg); -} - -NIF int vsprintf(char *s, const char *format, va_list arg) -{ - return vsnprintf(s, PRINTF_MAX_POSSIBLE_BUFFER_SIZE, format, arg); -} - -NIF int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg) -{ - output_gadget_t gadget = function_gadget(out, extra_arg); - return vsnprintf_impl(&gadget, format, arg); -} - -NIF int printf(const char *format, ...) -{ - va_list args; - va_start(args, format); - const int ret = vprintf(format, args); - va_end(args); - return ret; -} - -NIF int sprintf(char *s, const char *format, ...) -{ - va_list args; - va_start(args, format); - const int ret = vsprintf(s, format, args); - va_end(args); - return ret; -} - -NIF int snprintf(char *s, size_t n, const char *format, ...) -{ - va_list args; - va_start(args, format); - const int ret = vsnprintf(s, n, format, args); - va_end(args); - return ret; -} - -NIF int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, ...) -{ - va_list args; - va_start(args, format); - const int ret = vfctprintf(out, extra_arg, format, args); - va_end(args); - return ret; -} diff --git a/FennixLoader/ubsan.h b/FennixLoader/ubsan.h deleted file mode 100644 index 9f0fc7c..0000000 --- a/FennixLoader/ubsan.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef __FENNIX_KERNEL_UBSAN_H__ -#define __FENNIX_KERNEL_UBSAN_H__ - -#include - -struct source_location -{ - const char *file; - uint32_t line; - uint32_t column; -}; - -struct type_descriptor -{ - uint16_t kind; - uint16_t info; - char name[]; -}; - -struct type_mismatch_v1_data -{ - struct source_location location; - struct type_descriptor *type; - uint8_t alignment; - uint8_t type_check_kind; -}; - -struct out_of_bounds_info -{ - struct source_location location; - struct type_descriptor left_type; - struct type_descriptor right_type; -}; - -struct overflow_data -{ - struct source_location location; - struct type_descriptor *type; -}; - -struct negative_vla_data -{ - struct source_location location; - struct type_descriptor *type; -}; - -struct invalid_value_data -{ - struct source_location location; - struct type_descriptor *type; -}; - -struct nonnull_return_data -{ - struct source_location location; -}; - -struct nonnull_arg_data -{ - struct source_location location; -}; - -struct unreachable_data -{ - struct source_location location; -}; - -struct invalid_builtin_data -{ - struct source_location location; - uint8_t kind; -}; - -struct array_out_of_bounds_data -{ - struct source_location location; - struct type_descriptor *array_type; - struct type_descriptor *index_type; -}; - -struct shift_out_of_bounds_data -{ - struct source_location location; - struct type_descriptor *left_type; - struct type_descriptor *right_type; -}; - -struct dynamic_type_cache_miss_data -{ - struct source_location location; - struct type_descriptor *type; -}; - -#endif // !__FENNIX_KERNEL_UBSAN_H__ diff --git a/Makefile b/Makefile index 0352b35..23d8924 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,6 @@ prepare: make -C BIOS prepare make -C UEFI prepare -loader: - make -C FennixLoader build - build: make -C BIOS build make -C UEFI build @@ -14,5 +11,4 @@ build: clean: make -C BIOS clean make -C UEFI clean - make -C FennixLoader clean - rm -f loader.bin efi-loader.bin FLDR.elf + rm -f loader.bin efi-loader.bin