Compiles on x86 but everything is broken

This commit is contained in:
Alex 2022-12-21 02:11:49 +02:00
parent a677f3c159
commit 985d614be2
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
16 changed files with 1834 additions and 29 deletions

View File

@ -46,7 +46,6 @@ SECTIONS
}
. += CONSTANT(MAXPAGESIZE);
.bss :
{
*(COMMON)

View File

@ -0,0 +1,99 @@
#include "gdt.hpp"
#include <memory.hpp>
#include <smp.hpp>
#include <cpu.hpp>
#include <debug.h>
namespace GlobalDescriptorTable
{
static GlobalDescriptorTableEntries GDTEntriesTemplate = {
// null
{.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {.Raw = 0x0},
.Flags = {.Raw = 0x0},
.BaseHigh = 0x0},
// kernel code
{.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {.A = 0,
.RW = 1,
.DC = 0,
.E = 1,
.S = 1,
.DPL = 0,
.P = 1},
.Flags = {.Unknown = 0x0, .L = 1},
.BaseHigh = 0x0},
// kernel data
{.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {.A = 0,
.RW = 1,
.DC = 0,
.E = 0,
.S = 1,
.DPL = 0,
.P = 1},
.Flags = {.Raw = 0x0},
.BaseHigh = 0x0},
// user data
{.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {.A = 0,
.RW = 1,
.DC = 0,
.E = 0,
.S = 1,
.DPL = 3,
.P = 1},
.Flags = {.Raw = 0x0},
.BaseHigh = 0x0},
// user code
{.Length = 0x0,
.BaseLow = 0x0,
.BaseMiddle = 0x0,
.Access = {.A = 0,
.RW = 1,
.DC = 0,
.E = 1,
.S = 1,
.DPL = 3,
.P = 1},
.Flags = {.Unknown = 0x0, .L = 1},
.BaseHigh = 0x0},
// tss
{}};
GlobalDescriptorTableEntries GDTEntries[MAX_CPU];
GlobalDescriptorTableDescriptor gdt[MAX_CPU];
TaskStateSegment tss[MAX_CPU] = {
0,
{0, 0, 0},
0,
{0, 0, 0, 0, 0, 0, 0},
0,
0,
};
void *CPUStackPointer[MAX_CPU];
SafeFunction void Init(int Core)
{
}
SafeFunction void SetKernelStack(void *Stack)
{
}
}

View File

@ -5,7 +5,141 @@
namespace GlobalDescriptorTable
{
/** @brief The GDT Access Table
* @details For more information, see https://wiki.osdev.org/Global_Descriptor_Table
*/
union GlobalDescriptorTableAccess
{
struct
{
/** @brief Access bit.
* @note The CPU sets this bit to 1 when the segment is accessed.
*/
uint8_t A : 1;
/** @brief Readable bit for code segments, writable bit for data segments.
* @details For code segments, this bit must be 1 for the segment to be readable.
* @details For data segments, this bit must be 1 for the segment to be writable.
*/
uint8_t RW : 1;
/** @brief Direction bit for data segments, conforming bit for code segments.
* @details For data segments, this bit must be 1 for the segment to grow up (higher addresses).
* @details For code segments, this bit must be 1 for code in the segment to be able to be executed from an equal or lower privilege level.
*/
uint8_t DC : 1;
/** @brief Executable bit.
* @details This bit must be 1 for code-segment descriptors.
* @details This bit must be 0 for data-segment and system descriptors.
*/
uint8_t E : 1;
/** @brief Descriptor type.
* @details This bit must be 0 for system descriptors.
* @details This bit must be 1 for code or data segment descriptor.
*/
uint8_t S : 1;
/** @brief Descriptor privilege level.
* @details This field determines the privilege level of the segment.
* @details 0 = kernel mode, 3 = user mode.
*/
uint8_t DPL : 2;
/** @brief Present bit.
* @details This bit must be 1 for all valid descriptors.
*/
uint8_t P : 1;
} __attribute__((packed));
uint8_t Raw;
};
union GlobalDescriptorTableFlags
{
// TODO: Add more flags.
struct
{
/** @brief Unknown. */
uint8_t Unknown : 5;
/** @brief Long mode.
* @details If the long mode bit is clear, the segment is in 32-bit protected mode.
* @details If the long mode bit is set, the segment is in 64-bit long mode.
*/
uint8_t L : 1;
} __attribute__((packed));
uint8_t Raw;
};
typedef struct _TaskStateSegmentEntry
{
/* LOW */
uint16_t Length;
uint16_t BaseLow;
uint8_t BaseMiddle;
GlobalDescriptorTableAccess Flags;
uint8_t Granularity;
uint8_t BaseHigh;
/* HIGH */
uint32_t BaseUpper;
uint32_t Reserved;
} __attribute__((packed)) TaskStateSegmentEntry;
typedef struct _TaskStateSegment
{
uint32_t Reserved0 __attribute__((aligned(16)));
uint64_t StackPointer[3];
uint64_t Reserved1;
uint64_t InterruptStackTable[7];
uint16_t Reserved2;
uint16_t IOMapBaseAddressOffset;
} __attribute__((packed)) TaskStateSegment;
typedef struct _GlobalDescriptorTableEntry
{
/** @brief Length */
uint16_t Length;
/** @brief Low Base */
uint16_t BaseLow;
/** @brief Middle Base */
uint8_t BaseMiddle;
/** @brief Access */
GlobalDescriptorTableAccess Access;
/** @brief Flags */
GlobalDescriptorTableFlags Flags;
/** @brief High Base */
uint8_t BaseHigh;
} __attribute__((packed)) GlobalDescriptorTableEntry;
typedef struct _GlobalDescriptorTableEntries
{
GlobalDescriptorTableEntry Null;
GlobalDescriptorTableEntry Code;
GlobalDescriptorTableEntry Data;
GlobalDescriptorTableEntry UserData;
GlobalDescriptorTableEntry UserCode;
TaskStateSegmentEntry TaskStateSegment;
} __attribute__((packed)) GlobalDescriptorTableEntries;
typedef struct _GlobalDescriptorTableDescriptor
{
/** @brief GDT entries length */
uint16_t Length;
/** @brief GDT entries address */
GlobalDescriptorTableEntries *Entries;
} __attribute__((packed)) GlobalDescriptorTableDescriptor;
extern void *CPUStackPointer[];
extern TaskStateSegment tss[];
void Init(int Core);
void SetKernelStack(void *Stack);
}
#define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code)
#define GDT_KERNEL_DATA offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Data)
#define GDT_USER_CODE (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserCode) | 3)
#define GDT_USER_DATA (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, UserData) | 3)
#define GDT_TSS (offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, TaskStateSegment) | 3)
#endif // !__FENNIX_KERNEL_GDT_H__

View File

@ -27,6 +27,23 @@ SECTIONS
}
_kernel_rodata_end = .;
.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 = .);
}
. += CONSTANT(MAXPAGESIZE);
.bss ALIGN (4096) : AT(ADDR(.bss) - 0xC0000000)
{
*(COMMON)

View File

@ -124,7 +124,13 @@ SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
uintptr_t CheckPageFaultAddress = 0;
CheckPageFaultAddress = CPU::x64::readcr2().PFLA;
if (CheckPageFaultAddress == 0)
#ifdef __amd64__
CheckPageFaultAddress = Frame->rip;
#elif defined(__i386__)
CheckPageFaultAddress = Frame->eip;
#elif defined(__aarch64__)
CheckPageFaultAddress = 0;
#endif
Memory::Virtual vma = Memory::Virtual(((Memory::PageTable4 *)CPU::x64::readcr3().raw));
bool PageAvailable = vma.Check((void *)CheckPageFaultAddress);

View File

@ -14,6 +14,7 @@
#if defined(__amd64__)
#include "../../Architecture/amd64/cpu/gdt.hpp"
#elif defined(__i386__)
#include "../../Architecture/i686/cpu/gdt.hpp"
#elif defined(__aarch64__)
#endif

View File

@ -40,7 +40,12 @@ namespace CrashHandler
#elif defined(__aarch64__)
#endif
{
#if defined(__amd64__)
EHPrint("Invalid rbp pointer: %p\n", Frame->rbp);
#elif defined(__i386__)
EHPrint("Invalid ebp pointer: %p\n", Frame->ebp);
#elif defined(__aarch64__)
#endif
return;
}

View File

@ -61,9 +61,9 @@ namespace CrashHandler
uintptr_t LastRIP = 0;
for (int i = 0; i < 128; i++)
{
if (data.Thread->RIPHistory[i] == 0)
if (data.Thread->IPHistory[i] == 0)
break;
if (data.Thread->RIPHistory[i] == LastRIP)
if (data.Thread->IPHistory[i] == LastRIP)
{
SameItr++;
if (SameItr > 3)
@ -71,11 +71,11 @@ namespace CrashHandler
}
else
SameItr = 0;
LastRIP = data.Thread->RIPHistory[i];
LastRIP = data.Thread->IPHistory[i];
if (!sh)
EHPrint("\n\e2565CC%p", data.Thread->RIPHistory[i]);
EHPrint("\n\e2565CC%p", data.Thread->IPHistory[i]);
else
EHPrint("\n\e2565CC%p\e7925CC-\e25CCC9%s", data.Thread->RIPHistory[i], sh->GetSymbolFromAddress(data.Thread->RIPHistory[i]));
EHPrint("\n\e2565CC%p\e7925CC-\e25CCC9%s", data.Thread->IPHistory[i], sh->GetSymbolFromAddress(data.Thread->IPHistory[i]));
}
EHPrint("\n\e7925CCNote: \e2565CCSame RIPs are not shown more than 3 times.\n");
}

View File

@ -772,7 +772,7 @@ namespace PCI
}
#endif
void PCI::EnumerateFunction(uintptr_t DeviceAddress, uintptr_t Function)
void PCI::EnumerateFunction(uintptr_t DeviceAddress, uint64_t Function)
{
uintptr_t Offset = Function << 12;
uintptr_t FunctionAddress = DeviceAddress + Offset;
@ -788,7 +788,7 @@ namespace PCI
#endif
}
void PCI::EnumerateDevice(uintptr_t BusAddress, uintptr_t Device)
void PCI::EnumerateDevice(uintptr_t BusAddress, uint64_t Device)
{
uintptr_t Offset = Device << 15;
uintptr_t DeviceAddress = BusAddress + Offset;
@ -802,7 +802,7 @@ namespace PCI
EnumerateFunction(DeviceAddress, Function);
}
void PCI::EnumerateBus(uintptr_t BaseAddress, uintptr_t Bus)
void PCI::EnumerateBus(uintptr_t BaseAddress, uint64_t Bus)
{
uintptr_t Offset = Bus << 20;
uintptr_t BusAddress = BaseAddress + Offset;

View File

@ -12,7 +12,7 @@
namespace Time
{
void time::Sleep(uintptr_t Milliseconds)
void time::Sleep(uint64_t Milliseconds)
{
#if defined(__amd64__) || defined(__i386__)
uintptr_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000) / clk;

View File

@ -2391,7 +2391,7 @@ static void *LinuxSyscallsTable[] = {
[335] = (void *)pkey_mprotect_,
};
uint64_t HandleLinuxSyscalls(SyscallsFrame *Frame)
uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame)
{
#if defined(__amd64__)
if (Frame->rax > sizeof(LinuxSyscallsTable))

View File

@ -493,17 +493,17 @@ namespace Tasking
// FIXME: Untested
for (int i = 0; i < 128; i++)
{
if (CurrentCPU->CurrentThread->RIPHistory[i] == 0)
if (CurrentCPU->CurrentThread->IPHistory[i] == 0)
{
CurrentCPU->CurrentThread->RIPHistory[i] = Frame->rip;
CurrentCPU->CurrentThread->IPHistory[i] = Frame->rip;
break;
}
if (i == 127)
{
for (int j = 0; j < 127; j++)
CurrentCPU->CurrentThread->RIPHistory[j] = CurrentCPU->CurrentThread->RIPHistory[j + 1];
CurrentCPU->CurrentThread->RIPHistory[127] = Frame->rip;
CurrentCPU->CurrentThread->IPHistory[j] = CurrentCPU->CurrentThread->IPHistory[j + 1];
CurrentCPU->CurrentThread->IPHistory[127] = Frame->rip;
}
}
GlobalDescriptorTable::SetKernelStack((void *)((uintptr_t)CurrentCPU->CurrentThread->Stack->GetStackTop()));
@ -942,14 +942,25 @@ namespace Tasking
Thread->Info.Architecture = Architecture;
Thread->Info.Compatibility = Compatibility;
#ifdef DEBUG
#ifdef __amd64__
debug("Thread offset is %#lx (EntryPoint: %#lx) => RIP: %#lx", Thread->Offset, Thread->EntryPoint, Thread->Registers.rip);
if (Parent->Security.TrustLevel == TaskTrustLevel::User)
debug("Thread stack region is %#lx-%#lx (U) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.rsp);
else
debug("Thread stack region is %#lx-%#lx (K) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.rsp);
#elif defined(__i386__)
debug("Thread offset is %#lx (EntryPoint: %#lx) => RIP: %#lx", Thread->Offset, Thread->EntryPoint, Thread->Registers.eip);
if (Parent->Security.TrustLevel == TaskTrustLevel::User)
debug("Thread stack region is %#lx-%#lx (U) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.esp);
else
debug("Thread stack region is %#lx-%#lx (K) and rsp is %#lx", Thread->Stack->GetStackBottom(), Thread->Stack->GetStackTop(), Thread->Registers.esp);
#elif defined(__aarch64__)
#endif
debug("Created thread \"%s\"(%d) in process \"%s\"(%d)",
Thread->Name, Thread->ID,
Thread->Parent->Name, Thread->Parent->ID);
#endif
Parent->Threads.push_back(Thread);
return Thread;

View File

@ -6,7 +6,7 @@ class Bitmap
public:
size_t Size;
uint8_t *Buffer;
bool operator[](uintptr_t index);
bool Set(uintptr_t index, bool value);
bool Get(uintptr_t index);
bool operator[](uint64_t index);
bool Set(uint64_t index, bool value);
bool Get(uint64_t index);
};

File diff suppressed because it is too large Load Diff

View File

@ -110,7 +110,7 @@ namespace Video
size_t Size = this->framebuffer.Pitch * Height;
if (!this->Buffers[Index])
{
if (this->Buffers[Index]->Checksum != 0xDEAD5C9EE7)
if (this->Buffers[Index]->Checksum != 0xDEAD)
{
ScreenBuffer *buffer = new ScreenBuffer;
buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
@ -122,7 +122,7 @@ namespace Video
buffer->CursorY = 0;
this->Buffers[Index] = buffer;
memset(this->Buffers[Index]->Buffer, 0, Size);
this->Buffers[Index]->Checksum = 0xDEAD5C9EE7;
this->Buffers[Index]->Checksum = 0xDEAD;
}
else
warn("Buffer %d already exists, skipping creation", Index);

View File

@ -94,14 +94,13 @@ namespace Tasking
#if defined(__amd64__)
CPU::x64::TrapFrame Registers;
uint64_t GSBase, FSBase;
uint64_t RIPHistory[128];
#elif defined(__i386__)
uint32_t Registers; // TODO
CPU::x32::TrapFrame Registers; // TODO
uint64_t GSBase, FSBase;
uint32_t EIPHistory[128];
#elif defined(__aarch64__)
uint64_t Registers; // TODO
#endif
uintptr_t IPHistory[128];
TaskSecurity Security;
TaskInfo Info;
char FXRegion[512] __attribute__((aligned(16)));