mirror of
https://github.com/Fennix-Project/Lynx.git
synced 2025-05-25 22:14:44 +00:00
Revert changes
This commit is contained in:
parent
4e8599969b
commit
64553b5f84
139
.vscode/c_cpp_properties.json
vendored
139
.vscode/c_cpp_properties.json
vendored
@ -199,145 +199,6 @@
|
|||||||
"-fstack-check",
|
"-fstack-check",
|
||||||
"-fsanitize=undefined",
|
"-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
|
// VSCode flags
|
||||||
"-ffreestanding",
|
"-ffreestanding",
|
||||||
"-nostdinc",
|
"-nostdinc",
|
||||||
|
40
.vscode/launch.json
vendored
40
.vscode/launch.json
vendored
@ -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."
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -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; }
|
|
@ -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
|
|
@ -1,115 +0,0 @@
|
|||||||
#include <debug.h>
|
|
||||||
#include <printf.h>
|
|
||||||
|
|
||||||
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');
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -1,142 +0,0 @@
|
|||||||
#include "loadelf.hpp"
|
|
||||||
|
|
||||||
#include <memory.hpp>
|
|
||||||
#include <debug.h>
|
|
||||||
#include <elf.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,371 +0,0 @@
|
|||||||
#include <multiboot2.h>
|
|
||||||
#include <memory.hpp>
|
|
||||||
#include <binfo.h>
|
|
||||||
#include <debug.h>
|
|
||||||
#include <uart.hpp>
|
|
||||||
|
|
||||||
#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");
|
|
||||||
}
|
|
@ -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:
|
|
@ -1,5 +0,0 @@
|
|||||||
section .multiboot
|
|
||||||
align 4
|
|
||||||
dd 0x1BADB002
|
|
||||||
dd 1 << 0 | 1 << 1
|
|
||||||
dd -(0x1BADB002 + (1 << 0 | 1 << 1))
|
|
@ -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)
|
|
@ -1,28 +0,0 @@
|
|||||||
#include <bitmap.hpp>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
#include <memory.hpp>
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,583 +0,0 @@
|
|||||||
#include <memory.hpp>
|
|
||||||
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() {}
|
|
||||||
}
|
|
@ -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
|
|
@ -1,316 +0,0 @@
|
|||||||
#include <memory.hpp>
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
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() {}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#include <memory.hpp>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,513 +0,0 @@
|
|||||||
#include "ubsan.h"
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
#include <uart.hpp>
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,277 +0,0 @@
|
|||||||
#include <types.h>
|
|
||||||
|
|
||||||
#include <memory.hpp>
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
@ -1,166 +0,0 @@
|
|||||||
/* https://wiki.osdev.org/Bare_Bones */
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
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.
|
|
||||||
}
|
|
@ -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__
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
@ -1,89 +0,0 @@
|
|||||||
#ifndef __FENNIX_KERNEL_DEBUGGER_H__
|
|
||||||
#define __FENNIX_KERNEL_DEBUGGER_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
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__
|
|
@ -1,476 +0,0 @@
|
|||||||
#ifndef __FENNIX_KERNEL_ELF_H__
|
|
||||||
#define __FENNIX_KERNEL_ELF_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
// 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__
|
|
@ -1,618 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <bitmap.hpp>
|
|
||||||
#include <binfo.h>
|
|
||||||
#include <debug.h>
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
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);
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -1,194 +0,0 @@
|
|||||||
/**
|
|
||||||
* @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
|
|
||||||
* 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 <types.h>
|
|
||||||
|
|
||||||
#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_
|
|
@ -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<t>(v)
|
|
||||||
#define c_cst(t, v) const_cast<t>(v)
|
|
||||||
#define s_cst(t, v) static_cast<t>(v)
|
|
||||||
#define d_cst(t, v) dynamic_cast<t>(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__
|
|
@ -1,34 +0,0 @@
|
|||||||
#ifndef __FENNIX_KERNEL_UART_H__
|
|
||||||
#define __FENNIX_KERNEL_UART_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
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__
|
|
@ -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));
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
bool LoadElfInMemory(void *Address, size_t Length, bool Allow64);
|
|
File diff suppressed because it is too large
Load Diff
@ -1,94 +0,0 @@
|
|||||||
#ifndef __FENNIX_KERNEL_UBSAN_H__
|
|
||||||
#define __FENNIX_KERNEL_UBSAN_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
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__
|
|
6
Makefile
6
Makefile
@ -2,9 +2,6 @@ prepare:
|
|||||||
make -C BIOS prepare
|
make -C BIOS prepare
|
||||||
make -C UEFI prepare
|
make -C UEFI prepare
|
||||||
|
|
||||||
loader:
|
|
||||||
make -C FennixLoader build
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
make -C BIOS build
|
make -C BIOS build
|
||||||
make -C UEFI build
|
make -C UEFI build
|
||||||
@ -14,5 +11,4 @@ build:
|
|||||||
clean:
|
clean:
|
||||||
make -C BIOS clean
|
make -C BIOS clean
|
||||||
make -C UEFI clean
|
make -C UEFI clean
|
||||||
make -C FennixLoader clean
|
rm -f loader.bin efi-loader.bin
|
||||||
rm -f loader.bin efi-loader.bin FLDR.elf
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user