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); . += CONSTANT(MAXPAGESIZE);
.bss : .bss :
{ {
*(COMMON) *(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 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 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__ #endif // !__FENNIX_KERNEL_GDT_H__

View File

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

View File

@ -124,7 +124,13 @@ SafeFunction void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
uintptr_t CheckPageFaultAddress = 0; uintptr_t CheckPageFaultAddress = 0;
CheckPageFaultAddress = CPU::x64::readcr2().PFLA; CheckPageFaultAddress = CPU::x64::readcr2().PFLA;
if (CheckPageFaultAddress == 0) if (CheckPageFaultAddress == 0)
#ifdef __amd64__
CheckPageFaultAddress = Frame->rip; 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)); Memory::Virtual vma = Memory::Virtual(((Memory::PageTable4 *)CPU::x64::readcr3().raw));
bool PageAvailable = vma.Check((void *)CheckPageFaultAddress); bool PageAvailable = vma.Check((void *)CheckPageFaultAddress);

View File

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

View File

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

View File

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

View File

@ -772,7 +772,7 @@ namespace PCI
} }
#endif #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 Offset = Function << 12;
uintptr_t FunctionAddress = DeviceAddress + Offset; uintptr_t FunctionAddress = DeviceAddress + Offset;
@ -788,7 +788,7 @@ namespace PCI
#endif #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 Offset = Device << 15;
uintptr_t DeviceAddress = BusAddress + Offset; uintptr_t DeviceAddress = BusAddress + Offset;
@ -802,7 +802,7 @@ namespace PCI
EnumerateFunction(DeviceAddress, Function); 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 Offset = Bus << 20;
uintptr_t BusAddress = BaseAddress + Offset; uintptr_t BusAddress = BaseAddress + Offset;

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ class Bitmap
public: public:
size_t Size; size_t Size;
uint8_t *Buffer; uint8_t *Buffer;
bool operator[](uintptr_t index); bool operator[](uint64_t index);
bool Set(uintptr_t index, bool value); bool Set(uint64_t index, bool value);
bool Get(uintptr_t index); 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; size_t Size = this->framebuffer.Pitch * Height;
if (!this->Buffers[Index]) if (!this->Buffers[Index])
{ {
if (this->Buffers[Index]->Checksum != 0xDEAD5C9EE7) if (this->Buffers[Index]->Checksum != 0xDEAD)
{ {
ScreenBuffer *buffer = new ScreenBuffer; ScreenBuffer *buffer = new ScreenBuffer;
buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size)); buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
@ -122,7 +122,7 @@ namespace Video
buffer->CursorY = 0; buffer->CursorY = 0;
this->Buffers[Index] = buffer; this->Buffers[Index] = buffer;
memset(this->Buffers[Index]->Buffer, 0, Size); memset(this->Buffers[Index]->Buffer, 0, Size);
this->Buffers[Index]->Checksum = 0xDEAD5C9EE7; this->Buffers[Index]->Checksum = 0xDEAD;
} }
else else
warn("Buffer %d already exists, skipping creation", Index); warn("Buffer %d already exists, skipping creation", Index);

View File

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