Stability fixes (i hope); attempt to implement argc, argv, envp, auxv; Syscalls

This commit is contained in:
Alex 2022-11-10 07:09:32 +02:00
parent 40b1da9dd1
commit 77081b4e1e
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
35 changed files with 3116 additions and 211 deletions

View File

@ -7,7 +7,7 @@ extern "C" __attribute__((naked, used, no_stack_protector)) void SystemCallHandl
}
extern "C" uint64_t SystemCallsHandler(SyscallsRegs *regs);
extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs);
void InitializeSystemCalls()
{

View File

@ -8,7 +8,7 @@
using namespace CPU::x64;
// "Core/SystemCalls.cpp"
extern "C" uint64_t SystemCallsHandler(SyscallsRegs *regs);
extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs);
extern "C" void SystemCallHandlerStub();

View File

@ -30,7 +30,9 @@ namespace APIC
uint32_t APIC::Read(uint32_t Register)
{
if (Register != APIC_ICRLO && Register != APIC_ICRHI)
if (Register != APIC_ICRLO &&
Register != APIC_ICRHI &&
Register != APIC_ID)
debug("APIC::Read(%#lx) [x2=%d]", Register, x2APICSupported ? 1 : 0);
if (x2APICSupported)
{

View File

@ -2,15 +2,12 @@
#include <interrupts.hpp>
#include <memory.hpp>
#include <assert.h>
#include <cpu.hpp>
#include "../../../kernel.h"
#if defined(__amd64__)
#include "../Architecture/amd64/acpi.hpp"
#include "../Architecture/amd64/cpu/apic.hpp"
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
#include "../acpi.hpp"
#include "apic.hpp"
extern "C" uint64_t _trampoline_start, _trampoline_end;
@ -31,7 +28,24 @@ volatile bool CPUEnabled = false;
static __attribute__((aligned(PAGE_SIZE))) CPUData CPUs[MAX_CPU] = {0};
CPUData *GetCPU(long id) { return &CPUs[id]; }
CPUData *GetCurrentCPU() { return (CPUData *)CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE); }
CPUData *GetCurrentCPU()
{
CPUData *data = (CPUData *)CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE);
if (data == nullptr && Interrupts::apic[0])
data = &CPUs[((APIC::APIC *)Interrupts::apic[0])->Read(APIC::APIC_ID) >> 24];
if (data == nullptr)
return nullptr; // The caller should handle this.
if (!data->IsActive)
{
error("CPU %d is not active!", data->ID);
return &CPUs[0];
}
assert(data->Checksum == CPU_DATA_CHECKSUM); // This should never happen.
return data;
}
extern "C" void StartCPU()
{

View File

@ -6,7 +6,7 @@
using namespace CPU::x32;
extern "C" uint32_t SystemCallsHandler(SyscallsRegs *regs);
extern "C" uint32_t SystemCallsHandler(SyscallsFrame *regs);
void InitializeSystemCalls()
{

View File

@ -2,6 +2,7 @@
#include <interrupts.hpp>
#include <memory.hpp>
#include <assert.h>
#include <cpu.hpp>
#include "../../../kernel.h"
@ -16,18 +17,12 @@ CPUData *GetCPU(uint64_t id) { return &CPUs[id]; }
CPUData *GetCurrentCPU()
{
uint64_t ret = 0;
if (!CPUs[ret].IsActive)
if (!(&CPUs[ret])->IsActive)
{
error("CPU %d is not active!", ret);
return &CPUs[0];
}
if (CPUs[ret].Checksum != CPU_DATA_CHECKSUM)
{
error("CPU %d data is corrupted!", ret);
return &CPUs[0];
}
assert((&CPUs[ret])->Checksum == CPU_DATA_CHECKSUM);
return &CPUs[ret];
}

View File

@ -1,4 +1,5 @@
#include "crashhandler.hpp"
#include "../crashhandler.hpp"
#include "chfcts.hpp"
#include <display.hpp>
#include <printf.h>
@ -7,87 +8,15 @@
#include <cpu.hpp>
#if defined(__amd64__)
#include "../Architecture/amd64/cpu/gdt.hpp"
#include "../../Architecture/amd64/cpu/gdt.hpp"
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
#include "../kernel.h"
#if defined(__amd64__)
void DivideByZeroExceptionHandler(CPU::x64::TrapFrame *Frame);
void DebugExceptionHandler(CPU::x64::TrapFrame *Frame);
void NonMaskableInterruptExceptionHandler(CPU::x64::TrapFrame *Frame);
void BreakpointExceptionHandler(CPU::x64::TrapFrame *Frame);
void OverflowExceptionHandler(CPU::x64::TrapFrame *Frame);
void BoundRangeExceptionHandler(CPU::x64::TrapFrame *Frame);
void InvalidOpcodeExceptionHandler(CPU::x64::TrapFrame *Frame);
void DeviceNotAvailableExceptionHandler(CPU::x64::TrapFrame *Frame);
void DoubleFaultExceptionHandler(CPU::x64::TrapFrame *Frame);
void CoprocessorSegmentOverrunExceptionHandler(CPU::x64::TrapFrame *Frame);
void InvalidTSSExceptionHandler(CPU::x64::TrapFrame *Frame);
void SegmentNotPresentExceptionHandler(CPU::x64::TrapFrame *Frame);
void StackFaultExceptionHandler(CPU::x64::TrapFrame *Frame);
void GeneralProtectionExceptionHandler(CPU::x64::TrapFrame *Frame);
void PageFaultExceptionHandler(CPU::x64::TrapFrame *Frame);
void x87FloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame);
void AlignmentCheckExceptionHandler(CPU::x64::TrapFrame *Frame);
void MachineCheckExceptionHandler(CPU::x64::TrapFrame *Frame);
void SIMDFloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame);
void VirtualizationExceptionHandler(CPU::x64::TrapFrame *Frame);
void SecurityExceptionHandler(CPU::x64::TrapFrame *Frame);
void UnknownExceptionHandler(CPU::x64::TrapFrame *Frame);
void UserModeExceptionHandler(CPU::x64::TrapFrame *Frame);
#endif
#include "../../kernel.h"
namespace CrashHandler
{
struct StackFrame
{
struct StackFrame *rbp;
uint64_t rip;
};
__attribute__((no_stack_protector)) void TraceFrames(CPU::x64::TrapFrame *Frame, int Count)
{
struct StackFrame *frames = (struct StackFrame *)Frame->rbp; // (struct StackFrame *)__builtin_frame_address(0);
debug("Stack tracing...");
EHPrint("\e7981FC\nStack Trace:\n");
if (!frames || !frames->rip || !frames->rbp)
{
EHPrint("\e2565CC%p", (void *)Frame->rip);
EHPrint("\e7925CC-");
EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip));
EHPrint("\e7981FC <- Exception");
EHPrint("\eFF0000\n< No stack trace available. >\n");
}
else
{
EHPrint("\e2565CC%p", (void *)Frame->rip);
EHPrint("\e7925CC-");
if (Frame->rip >= 0xFFFFFFFF80000000 && Frame->rip <= (uint64_t)&_kernel_end)
EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip));
else
EHPrint("Outside Kernel");
EHPrint("\e7981FC <- Exception");
for (int frame = 0; frame < Count; ++frame)
{
if (!frames->rip)
break;
EHPrint("\n\e2565CC%p", (void *)frames->rip);
EHPrint("\e7925CC-");
if (frames->rip >= 0xFFFFFFFF80000000 && frames->rip <= (uint64_t)&_kernel_end)
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress(frames->rip));
else
EHPrint("\eFF4CA9Outside Kernel");
if (!Memory::Virtual().Check(frames->rbp))
return;
frames = frames->rbp;
}
}
}
__attribute__((no_stack_protector)) void printfWrapper(char c, void *unused)
{
Display->Print(c, 255, true);
@ -104,26 +33,44 @@ namespace CrashHandler
__attribute__((no_stack_protector)) void Handle(void *Data)
{
CPU::Interrupts(CPU::Disable);
#if defined(__amd64__)
CPU::x64::TrapFrame *Frame = (CPU::x64::TrapFrame *)Data;
CHArchTrapFrame *Frame = (CHArchTrapFrame *)Data;
error("Exception: %#llx", Frame->InterruptNumber);
if (Frame->cs != GDT_USER_CODE && Frame->cs != GDT_USER_DATA)
{
debug("Exception in kernel mode");
CPU::Interrupts(CPU::Disable);
Display->CreateBuffer(0, 0, 255);
}
else
{
debug("Exception in user mode");
if (!GetCurrentCPU()->CurrentThread->Security.IsCritical)
CPUData *data = GetCurrentCPU();
if (!data)
{
UserModeExceptionHandler(Frame);
return;
EHPrint("\eFF0000Cannot get CPU data! This results in a kernel crash!");
error("Cannot get CPU data! This results in a kernel crash!");
error("This should never happen!");
}
else
EHPrint("\eFF0000Init process crashed!");
{
debug("CPU %ld data is valid", data->ID);
if (data->CurrentThread)
{
debug("Current thread is valid %#lx", data->CurrentThread);
if (!data->CurrentThread->Security.IsCritical)
{
debug("Current thread is not critical");
UserModeExceptionHandler(Frame);
return;
}
else
{
EHPrint("\eFF0000Init process crashed!");
}
}
}
}
debug("Reading control registers...");
@ -267,8 +214,39 @@ namespace CrashHandler
}
}
EHPrint("\e7981FCTechnical Informations on CPU %lld:\n", GetCurrentCPU()->ID);
EHPrint("FS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx\n",
CPUData *cpudata = GetCurrentCPU();
if (cpudata == nullptr)
{
EHPrint("\eFFA500Invalid CPU data!\n");
for (long i = 0; i < MAX_CPU; i++)
{
cpudata = GetCPU(i);
if (cpudata != nullptr)
break;
if (i == MAX_CPU - 1)
{
EHPrint("\eFF0000No CPU data found!\n");
cpudata = nullptr;
}
}
debug("CPU ptr %#lx", cpudata);
}
if (cpudata != nullptr)
EHPrint("\e7981FCTechnical Informations on CPU %lld:\n", cpudata->ID);
if (TaskManager && cpudata != nullptr)
{
EHPrint("\e7981FCCurrent Process: %s(%ld)\n",
cpudata->CurrentProcess->Name,
cpudata->CurrentProcess->ID);
EHPrint("\e7981FCCurrent Thread: %s(%ld)\n",
cpudata->CurrentThread->Name,
cpudata->CurrentThread->ID);
}
EHPrint("\e7981FCFS=%#llx GS=%#llx SS=%#llx CS=%#llx DS=%#llx\n",
CPU::x64::rdmsr(CPU::x64::MSR_FS_BASE), CPU::x64::rdmsr(CPU::x64::MSR_GS_BASE),
Frame->ss, Frame->cs, Frame->ds);
EHPrint("R8=%#llx R9=%#llx R10=%#llx R11=%#llx\n", Frame->r8, Frame->r9, Frame->r10, Frame->r11);
@ -358,7 +336,7 @@ namespace CrashHandler
}
#if defined(__amd64__) || defined(__i386__)
static const char *PagefaultDescriptions[] = {
static const char *PagefaultDescriptions[8] = {
"Supervisory process tried to read a non-present page entry\n",
"Supervisory process tried to read a page and caused a protection fault\n",
"Supervisory process tried to write to a non-present page entry\n",
@ -370,70 +348,41 @@ static const char *PagefaultDescriptions[] = {
#endif
#if defined(__amd64__)
#define staticbuffer(name) char name[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
__attribute__((no_stack_protector)) void DivideByZeroExceptionHandler(CPU::x64::TrapFrame *Frame)
__attribute__((no_stack_protector)) void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame)
{
fixme("Divide by zero exception\n");
}
__attribute__((no_stack_protector)) void DebugExceptionHandler(CPU::x64::TrapFrame *Frame)
__attribute__((no_stack_protector)) void DebugExceptionHandler(CHArchTrapFrame *Frame)
{
CrashHandler::EHPrint("\eDD2920System crashed!\n");
CrashHandler::EHPrint("Kernel triggered debug exception.\n");
}
__attribute__((no_stack_protector)) void NonMaskableInterruptExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("NMI exception"); }
__attribute__((no_stack_protector)) void BreakpointExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Breakpoint exception"); }
__attribute__((no_stack_protector)) void OverflowExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Overflow exception"); }
__attribute__((no_stack_protector)) void BoundRangeExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Bound range exception"); }
__attribute__((no_stack_protector)) void InvalidOpcodeExceptionHandler(CPU::x64::TrapFrame *Frame)
__attribute__((no_stack_protector)) void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame) { fixme("NMI exception"); }
__attribute__((no_stack_protector)) void BreakpointExceptionHandler(CHArchTrapFrame *Frame) { fixme("Breakpoint exception"); }
__attribute__((no_stack_protector)) void OverflowExceptionHandler(CHArchTrapFrame *Frame) { fixme("Overflow exception"); }
__attribute__((no_stack_protector)) void BoundRangeExceptionHandler(CHArchTrapFrame *Frame) { fixme("Bound range exception"); }
__attribute__((no_stack_protector)) void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame)
{
CrashHandler::EHPrint("\eDD2920System crashed!\n");
CrashHandler::EHPrint("Kernel tried to execute an invalid opcode.\n");
}
__attribute__((no_stack_protector)) void DeviceNotAvailableExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Device not available exception"); }
__attribute__((no_stack_protector)) void DoubleFaultExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Double fault exception"); }
__attribute__((no_stack_protector)) void CoprocessorSegmentOverrunExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
__attribute__((no_stack_protector)) void InvalidTSSExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Invalid TSS exception"); }
__attribute__((no_stack_protector)) void SegmentNotPresentExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Segment not present exception"); }
__attribute__((no_stack_protector)) void StackFaultExceptionHandler(CPU::x64::TrapFrame *Frame)
__attribute__((no_stack_protector)) void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame) { fixme("Device not available exception"); }
__attribute__((no_stack_protector)) void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame) { fixme("Double fault exception"); }
__attribute__((no_stack_protector)) void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame) { fixme("Coprocessor segment overrun exception"); }
__attribute__((no_stack_protector)) void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame) { fixme("Invalid TSS exception"); }
__attribute__((no_stack_protector)) void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame) { fixme("Segment not present exception"); }
__attribute__((no_stack_protector)) void StackFaultExceptionHandler(CHArchTrapFrame *Frame)
{
staticbuffer(descbuf);
staticbuffer(desc_ext);
staticbuffer(desc_table);
staticbuffer(desc_idx);
staticbuffer(desc_tmp);
CPU::x64::SelectorErrorCode SelCode = {.raw = Frame->ErrorCode};
switch (SelCode.Table)
{
case 0b00:
memcpy(desc_tmp, "GDT", 3);
break;
case 0b01:
memcpy(desc_tmp, "IDT", 3);
break;
case 0b10:
memcpy(desc_tmp, "LDT", 3);
break;
case 0b11:
memcpy(desc_tmp, "IDT", 3);
break;
default:
memcpy(desc_tmp, "Unknown", 7);
break;
}
debug("external:%d table:%d idx:%#x", SelCode.External, SelCode.Table, SelCode.Idx);
sprintf_(descbuf, "Stack segment fault at address %#lx", Frame->rip);
CrashHandler::EHPrint(descbuf);
sprintf_(desc_ext, "External: %d", SelCode.External);
CrashHandler::EHPrint(desc_ext);
sprintf_(desc_table, "Table: %d (%s)", SelCode.Table, desc_tmp);
CrashHandler::EHPrint(desc_table);
sprintf_(desc_idx, "%s Index: %#x", desc_tmp, SelCode.Idx);
CrashHandler::EHPrint(desc_idx);
CrashHandler::EHPrint("\eDD2920System crashed!\n");
CrashHandler::EHPrint("More info about the exception:\n");
CrashHandler::EHPrint("Stack segment fault at address %#lx\n", Frame->rip);
CrashHandler::EHPrint("External: %d\n", SelCode.External);
CrashHandler::EHPrint("Table: %d\n", SelCode.Table);
CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx);
CrashHandler::EHPrint("Error code: %#lx\n", Frame->ErrorCode);
}
__attribute__((no_stack_protector)) void GeneralProtectionExceptionHandler(CPU::x64::TrapFrame *Frame)
__attribute__((no_stack_protector)) void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame)
{
// staticbuffer(descbuf);
// staticbuffer(desc_ext);
@ -466,7 +415,7 @@ __attribute__((no_stack_protector)) void GeneralProtectionExceptionHandler(CPU::
CrashHandler::EHPrint("Table: %d\n", SelCode.Table);
CrashHandler::EHPrint("Index: %#x\n", SelCode.Idx);
}
__attribute__((no_stack_protector)) void PageFaultExceptionHandler(CPU::x64::TrapFrame *Frame)
__attribute__((no_stack_protector)) void PageFaultExceptionHandler(CHArchTrapFrame *Frame)
{
CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode};
CrashHandler::EHPrint("\eDD2920System crashed!\n\eFFFFFF");
@ -484,15 +433,15 @@ __attribute__((no_stack_protector)) void PageFaultExceptionHandler(CPU::x64::Tra
else
CrashHandler::EHPrint(PagefaultDescriptions[Frame->ErrorCode & 0b111]);
}
__attribute__((no_stack_protector)) void x87FloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("x87 floating point exception"); }
__attribute__((no_stack_protector)) void AlignmentCheckExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Alignment check exception"); }
__attribute__((no_stack_protector)) void MachineCheckExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Machine check exception"); }
__attribute__((no_stack_protector)) void SIMDFloatingPointExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("SIMD floating point exception"); }
__attribute__((no_stack_protector)) void VirtualizationExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Virtualization exception"); }
__attribute__((no_stack_protector)) void SecurityExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Security exception"); }
__attribute__((no_stack_protector)) void UnknownExceptionHandler(CPU::x64::TrapFrame *Frame) { fixme("Unknown exception"); }
__attribute__((no_stack_protector)) void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("x87 floating point exception"); }
__attribute__((no_stack_protector)) void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Alignment check exception"); }
__attribute__((no_stack_protector)) void MachineCheckExceptionHandler(CHArchTrapFrame *Frame) { fixme("Machine check exception"); }
__attribute__((no_stack_protector)) void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame) { fixme("SIMD floating point exception"); }
__attribute__((no_stack_protector)) void VirtualizationExceptionHandler(CHArchTrapFrame *Frame) { fixme("Virtualization exception"); }
__attribute__((no_stack_protector)) void SecurityExceptionHandler(CHArchTrapFrame *Frame) { fixme("Security exception"); }
__attribute__((no_stack_protector)) void UnknownExceptionHandler(CHArchTrapFrame *Frame) { fixme("Unknown exception"); }
__attribute__((no_stack_protector)) void UserModeExceptionHandler(CPU::x64::TrapFrame *Frame)
__attribute__((no_stack_protector)) void UserModeExceptionHandler(CHArchTrapFrame *Frame)
{
CriticalSection cs;
debug("Interrupts? %s.", cs.IsInterruptsEnabled() ? "Yes" : "No");
@ -660,5 +609,9 @@ __attribute__((no_stack_protector)) void UserModeExceptionHandler(CPU::x64::Trap
break;
}
}
error("End of report.");
CPU::Interrupts(CPU::Enable);
debug("Interrupts enabled back.");
return;
}
#endif

65
Core/Crash/SFrame.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "../crashhandler.hpp"
#include "chfcts.hpp"
#include <display.hpp>
#include <printf.h>
#include <debug.h>
#include <smp.hpp>
#include <cpu.hpp>
#if defined(__amd64__)
#include "../../Architecture/amd64/cpu/gdt.hpp"
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
#include "../../kernel.h"
namespace CrashHandler
{
struct StackFrame
{
struct StackFrame *rbp;
uint64_t rip;
};
__attribute__((no_stack_protector)) void TraceFrames(CHArchTrapFrame *Frame, int Count)
{
struct StackFrame *frames = (struct StackFrame *)Frame->rbp; // (struct StackFrame *)__builtin_frame_address(0);
debug("Stack tracing...");
EHPrint("\e7981FC\nStack Trace:\n");
if (!frames || !frames->rip || !frames->rbp)
{
EHPrint("\e2565CC%p", (void *)Frame->rip);
EHPrint("\e7925CC-");
EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip));
EHPrint("\e7981FC <- Exception");
EHPrint("\eFF0000\n< No stack trace available. >\n");
}
else
{
EHPrint("\e2565CC%p", (void *)Frame->rip);
EHPrint("\e7925CC-");
if (Frame->rip >= 0xFFFFFFFF80000000 && Frame->rip <= (uint64_t)&_kernel_end)
EHPrint("\eAA25CC%s", KernelSymbolTable->GetSymbolFromAddress(Frame->rip));
else
EHPrint("Outside Kernel");
EHPrint("\e7981FC <- Exception");
for (int frame = 0; frame < Count; ++frame)
{
if (!frames->rip)
break;
EHPrint("\n\e2565CC%p", (void *)frames->rip);
EHPrint("\e7925CC-");
if (frames->rip >= 0xFFFFFFFF80000000 && frames->rip <= (uint64_t)&_kernel_end)
EHPrint("\e25CCC9%s", KernelSymbolTable->GetSymbolFromAddress(frames->rip));
else
EHPrint("\eFF4CA9Outside Kernel");
if (!Memory::Virtual().Check(frames->rbp))
return;
frames = frames->rbp;
}
}
}
}

View File

@ -0,0 +1,17 @@
#include "../crashhandler.hpp"
#include "chfcts.hpp"
#include <display.hpp>
#include <printf.h>
#include <debug.h>
#include <smp.hpp>
#include <cpu.hpp>
#if defined(__amd64__)
#include "../../Architecture/amd64/cpu/gdt.hpp"
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
#include "../../kernel.h"

44
Core/Crash/chfcts.hpp Normal file
View File

@ -0,0 +1,44 @@
#ifndef __FENNIX_KERNEL_CRASH_HANDLERS_FUNCTIONS_H__
#define __FENNIX_KERNEL_CRASH_HANDLERS_FUNCTIONS_H__
#include <types.h>
#include <cpu.hpp>
#if defined(__amd64__)
typedef struct CPU::x64::TrapFrame CHArchTrapFrame;
#elif defined(__i386__)
typedef struct CPU::x86::TrapFrame CHArchTrapFrame;
#elif defined(__aarch64__)
typedef struct CPU::aarch64::TrapFrame CHArchTrapFrame;
#endif
namespace CrashHandler
{
void TraceFrames(CHArchTrapFrame *Frame, int Count);
}
void DivideByZeroExceptionHandler(CHArchTrapFrame *Frame);
void DebugExceptionHandler(CHArchTrapFrame *Frame);
void NonMaskableInterruptExceptionHandler(CHArchTrapFrame *Frame);
void BreakpointExceptionHandler(CHArchTrapFrame *Frame);
void OverflowExceptionHandler(CHArchTrapFrame *Frame);
void BoundRangeExceptionHandler(CHArchTrapFrame *Frame);
void InvalidOpcodeExceptionHandler(CHArchTrapFrame *Frame);
void DeviceNotAvailableExceptionHandler(CHArchTrapFrame *Frame);
void DoubleFaultExceptionHandler(CHArchTrapFrame *Frame);
void CoprocessorSegmentOverrunExceptionHandler(CHArchTrapFrame *Frame);
void InvalidTSSExceptionHandler(CHArchTrapFrame *Frame);
void SegmentNotPresentExceptionHandler(CHArchTrapFrame *Frame);
void StackFaultExceptionHandler(CHArchTrapFrame *Frame);
void GeneralProtectionExceptionHandler(CHArchTrapFrame *Frame);
void PageFaultExceptionHandler(CHArchTrapFrame *Frame);
void x87FloatingPointExceptionHandler(CHArchTrapFrame *Frame);
void AlignmentCheckExceptionHandler(CHArchTrapFrame *Frame);
void MachineCheckExceptionHandler(CHArchTrapFrame *Frame);
void SIMDFloatingPointExceptionHandler(CHArchTrapFrame *Frame);
void VirtualizationExceptionHandler(CHArchTrapFrame *Frame);
void SecurityExceptionHandler(CHArchTrapFrame *Frame);
void UnknownExceptionHandler(CHArchTrapFrame *Frame);
void UserModeExceptionHandler(CHArchTrapFrame *Frame);
#endif // !__FENNIX_KERNEL_CRASH_HANDLERS_FUNCTIONS_H__

View File

@ -52,7 +52,7 @@ namespace Interrupts
CoreData->Stack = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
if (CoreData->Checksum != CPU_DATA_CHECKSUM)
{
KPrint("CPU %d data it's corrupted!", Core);
KPrint("CPU %d checksum mismatch! %x != %x", Core, CoreData->Checksum, CPU_DATA_CHECKSUM);
CPU::Stop();
}
debug("Stack for core %d is %#lx (Address: %#lx)", Core, CoreData->Stack, CoreData->Stack - STACK_SIZE);

View File

@ -11,7 +11,7 @@ extern "C" void DeadLockHandler(LockClass *Lock)
{
CPUData *CoreData = GetCurrentCPU();
long CCore = 0xdead;
if (CoreData)
if (CoreData != nullptr)
CCore = CoreData->ID;
warn("Potential deadlock in lock '%s' held by '%s' (%ld) [%#lx-%ld] [%ld->%ld]",
Lock->GetLockData()->AttemptingToGet,
@ -35,7 +35,7 @@ int LockClass::Lock(const char *FunctionName)
LockData.CurrentHolder = FunctionName;
LockData.Count++;
CPUData *CoreData = GetCurrentCPU();
if (CoreData)
if (CoreData != nullptr)
LockData.Core = CoreData->ID;
CPU::MemBar::Barrier();

View File

@ -265,9 +265,11 @@ namespace Memory
trace("Reserving pages...");
this->ReservePages(0, MemorySize / PAGE_SIZE + 1);
trace("Unreserving usable pages...");
for (uint64_t i = 0; i < Info->Memory.Entries; i++)
if (Info->Memory.Entry[i].Type == Usable)
this->UnreservePages((void *)Info->Memory.Entry[i].BaseAddress, Info->Memory.Entry[i].Length / PAGE_SIZE + 1);
trace("Locking bitmap pages...");
this->ReservePages(0, 0x100); // Reserve between 0 and 0x100000.
this->LockPages(PageBitmap.Buffer, PageBitmap.Size / PAGE_SIZE + 1);
}

View File

@ -13,7 +13,7 @@ namespace Video
{
char Display::Print(char Char, int Index, bool WriteToUART)
{
SmartLock(PrintLock);
// SmartLock(PrintLock);
if (this->ColorIteration)
{

View File

@ -5,6 +5,7 @@
#include <msexec.h>
#include <cwalk.h>
#include <elf.h>
#include <abi.h>
#include "../kernel.h"
#include "../Fex.hpp"
@ -13,7 +14,7 @@ using namespace Tasking;
namespace Execute
{
SpawnData Spawn(char *Path, uint64_t Arg0, uint64_t Arg1)
SpawnData Spawn(char *Path, Vector<const char *> &argv, Vector<const char *> &envp)
{
SpawnData ret = {.Status = ExStatus::Unknown,
.Process = nullptr,
@ -42,9 +43,11 @@ namespace Execute
for (uint64_t i = 0; i < TO_PAGES(ExFile->Node->Length); i++)
pva.Map((void *)((uint64_t)BaseImage + (i * PAGE_SIZE)), (void *)((uint64_t)BaseImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US);
Vector<AuxiliaryVector> auxv; // TODO!
TCB *Thread = TaskManager->CreateThread(Process,
(IP)FexHdr->Pointer,
Arg0, Arg1,
argv, envp, auxv,
(IPOffset)BaseImage,
TaskArchitecture::x64,
TaskCompatibility::Native);
@ -130,9 +133,20 @@ namespace Execute
memcpy(dst, ((char *)BaseImage) + pheader->p_offset, pheader->p_filesz);
}
Vector<AuxiliaryVector> auxv;
auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}});
auxv.push_back({.archaux = {.a_type = AT_PHENT, .a_un = {.a_val = (uint64_t)ELFHeader->e_phentsize}}});
auxv.push_back({.archaux = {.a_type = AT_PHNUM, .a_un = {.a_val = (uint64_t)ELFHeader->e_phnum}}});
auxv.push_back({.archaux = {.a_type = AT_PAGESZ, .a_un = {.a_val = (uint64_t)PAGE_SIZE}}});
auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)Offset}}});
auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)ELFHeader->e_entry + (uint64_t)Offset}}});
auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t) "x86_64"}}});
auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)Path}}});
TCB *Thread = TaskManager->CreateThread(Process,
(IP)ELFHeader->e_entry,
Arg0, Arg1,
argv, envp, auxv,
(IPOffset)Offset,
Arch,
Comp);
@ -154,9 +168,13 @@ namespace Execute
ret.Status = ExStatus::InvalidFileEntryPoint;
goto Exit;
}
Vector<AuxiliaryVector> auxv;
fixme("auxv");
TCB *Thread = TaskManager->CreateThread(Process,
(IP)EP,
Arg0, Arg1,
argv, envp, auxv,
(IPOffset)BaseImage,
Arch,
Comp);

View File

@ -19,7 +19,8 @@
"assert.h": "c",
"cwalk.h": "c",
"md5.h": "c",
"stdint.h": "c"
"stdint.h": "c",
"debug.h": "c"
}
}
}

View File

@ -49,6 +49,12 @@ static struct cag_option ConfigOptions[] = {
.value_name = "PATH",
.description = "Path to init program"},
{.identifier = 'o',
.access_letters = NULL,
.access_name = "ioc",
.value_name = "BOOL",
.description = "Enable Interrupts On Crash. If enabled, the navigation keys will be enabled on crash."},
{.identifier = 'h',
.access_letters = "h",
.access_name = "help",
@ -335,6 +341,13 @@ ParseSuccess:
KPrint("\eAAFFAAUsing %s as init program", value);
break;
}
case 'o':
{
value = cag_option_get_value(&context);
strcmp(value, "true") ? config.InterruptsOnCrash = false : config.InterruptsOnCrash = true;
KPrint("\eAAFFAAInterrupts on crash: %s", value);
break;
}
case 'h':
{
KPrint("\n---------------------------------------------------------------------------\nUsage: kernel.fsys [OPTION]...\nKernel configuration.");

View File

@ -47,49 +47,66 @@ void FetchDisks()
void KernelMainThread()
{
Vector<const char *> argv;
Vector<const char *> envp;
Vector<AuxiliaryVector> auxv;
Tasking::TCB *CurrentWorker = nullptr;
KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD);
KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus);
TaskManager->GetCurrentThread()->SetPriority(1);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem, argv, envp, auxv);
CurrentWorker->Rename("Disk");
CurrentWorker->SetPriority(100);
TaskManager->WaitForThread(CurrentWorker);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)LoadDrivers);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)LoadDrivers, argv, envp, auxv);
CurrentWorker->Rename("Drivers");
CurrentWorker->SetPriority(100);
TaskManager->WaitForThread(CurrentWorker);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks);
CurrentWorker = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)FetchDisks, argv, envp, auxv);
CurrentWorker->Rename("Fetch Disks");
CurrentWorker->SetPriority(100);
TaskManager->WaitForThread(CurrentWorker);
KPrint("Waiting for userspace process to start...");
KPrint("Setting up userspace...");
Vector<char *> argv;
int argc = 0;
envp.clear();
envp.push_back("PATH=/system:/system/bin");
envp.push_back("TERM=tty");
envp.push_back("HOME=/");
envp.push_back("USER=root");
envp.push_back("SHELL=/system/bin/sh");
envp.push_back("PWD=/");
envp.push_back("LANG=en_US.UTF-8");
envp.push_back("TZ=UTC");
/* ... */
argv.push_back((char *)"--start");
/* ... */
argv.push_back(nullptr);
argc = argv.size() - 1;
argv.clear();
argv.push_back("--init");
argv.push_back("--critical");
// TODO: Untested!
Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argc, (uint64_t)argv.data());
bool ien = CPU::Interrupts(CPU::Check);
CPU::Interrupts(CPU::Disable);
Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argv, envp);
if (ret.Status != Execute::ExStatus::OK)
{
KPrint("\eE85230Failed to start %s! Code: %d", Config.InitPath, ret.Status);
CPU::Halt(true);
if (ien)
CPU::Interrupts(CPU::Enable);
goto Exit;
}
ret.Thread->SetCritical(true);
if (ien)
CPU::Interrupts(CPU::Enable);
KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath);
TaskManager->WaitForThread(ret.Thread);
KPrint("\eE85230Userspace process exited with code %d", ret.Thread->GetExitCode());
error("Userspace process exited with code %d (%#x)", ret.Thread->GetExitCode(), ret.Thread->GetExitCode());
Exit:
KPrint("Well, that's it. I'm going to sleep now.");
CPU::Halt(true);
}

View File

@ -26,7 +26,7 @@ KernelConfig Config;
Time::Clock BootClock;
// For the Display class. Printing on first buffer as default.
extern "C" void putchar(char c) { Display->Print(c, 0); }
EXTERNC void putchar(char c) { Display->Print(c, 0); }
EXTERNC void KPrint(const char *Format, ...)
{

2409
SystemCalls/Linux.cpp Normal file

File diff suppressed because it is too large Load Diff

46
SystemCalls/Native.cpp Normal file
View File

@ -0,0 +1,46 @@
#include <syscalls.hpp>
#include <debug.h>
#include "../syscalls.h"
#include "../kernel.h"
static uint64_t sys_exit(SyscallsFrame *Frame, uint64_t code)
{
trace("Userspace thread %s(%lld) exited with code %#llx", TaskManager->GetCurrentThread()->Name, TaskManager->GetCurrentThread()->ID, code);
TaskManager->GetCurrentThread()->ExitCode = code;
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Terminated;
return 0;
}
static int sys_print(SyscallsFrame *Frame, char Char, int Index)
{
debug("%c", Char);
return Display->Print(Char, Index, true);
}
static void *NativeSyscallsTable[] = {
[_exit] = (void *)sys_exit,
[_print] = (void *)sys_print,
};
uint64_t HandleNativeSyscalls(SyscallsFrame *Frame)
{
debug("rax: %#llx, rbx: %#llx, rcx: %#llx, rdx: %#llx, rsi: %#llx, rdi: %#llx, rbp: %#llx, r8: %#llx, r9: %#llx, r10: %#llx, r11: %#llx, r12: %#llx, r13: %#llx, r14: %#llx, r15: %#llx", Frame->rax, Frame->rbx, Frame->rcx, Frame->rdx, Frame->rsi, Frame->rdi, Frame->rbp, Frame->r8, Frame->r9, Frame->r10, Frame->r11, Frame->r12, Frame->r13, Frame->r14, Frame->r15);
if (Frame->rax > sizeof(NativeSyscallsTable))
{
fixme("Syscall %lld not implemented", Frame->rax);
return -1;
}
uint64_t (*call)(uint64_t, ...) = reinterpret_cast<uint64_t (*)(uint64_t, ...)>(NativeSyscallsTable[Frame->rax]);
if (!call)
{
error("Syscall %#llx failed.", Frame->rax);
return -1;
}
debug("%#lx %#lx %#lx %#lx %#lx %#lx", Frame->rdi, Frame->rsi, Frame->rdx, Frame->rcx, Frame->r8, Frame->r9);
uint64_t ret = call((uint64_t)Frame, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9);
Frame->rax = ret;
return ret;
}

View File

@ -2,14 +2,33 @@
#include <debug.h>
extern "C" uint64_t SystemCallsHandler(SyscallsRegs *regs)
#include "../kernel.h"
extern "C" uint64_t SystemCallsHandler(SyscallsFrame *Frame)
{
#if defined(__amd64__)
fixme("System call %ld", regs->rax);
switch (TaskManager->GetCurrentThread()->Info.Compatibility)
{
case Tasking::TaskCompatibility::Native:
return HandleNativeSyscalls(Frame);
case Tasking::TaskCompatibility::Linux:
return HandleLinuxSyscalls(Frame);
case Tasking::TaskCompatibility::Windows:
{
error("Windows compatibility not implemented yet.");
break;
}
default:
{
error("Unknown compatibility mode! Killing thread...");
TaskManager->KillThread(TaskManager->GetCurrentThread(), -0xCA11);
break;
}
}
#elif defined(__i386__)
fixme("System call %lld", regs->eax);
#elif defined(__aarch64__)
fixme("System call");
#endif
return 0;
return -1;
}

View File

@ -54,7 +54,10 @@ namespace InterProcessCommunication
IPC::IPC()
{
trace("Starting IPC Service...");
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub);
Vector<const char *> argv;
Vector<const char *> envp;
Vector<AuxiliaryVector> auxv;
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)IPCServiceStub, argv, envp, auxv);
TaskManager->GetCurrentThread()->Rename("IPC Service");
}

View File

@ -2,6 +2,7 @@
#include <lock.hpp>
#include <printf.h>
#include <dumper.hpp>
#include <smp.hpp>
#include "../kernel.h"
@ -379,6 +380,50 @@ namespace Tasking
Success:
{
#ifdef DEBUG_SCHEDULER
static int sanity;
const char *Statuses[] = {
"FF0000", // Unknown
"AAFF00", // Ready
"00AA00", // Running
"FFAA00", // Sleeping
"FFAA00", // Waiting
"FF0088", // Stopped
"FF0000", // Terminated
};
const char *StatusesSign[] = {
"U", // Unknown
"R", // Ready
"r", // Running
"S", // Sleeping
"W", // Waiting
"s", // Stopped
"T", // Terminated
};
for (int i = 0; i < 200; i++)
for (int j = 0; j < 200; j++)
Display->SetPixel(i, j, 0x222222, 0);
uint32_t tmpX, tmpY;
Display->GetBufferCursor(0, &tmpX, &tmpY);
Display->SetBufferCursor(0, 0, 0);
foreach (auto var in ListProcess)
{
int statuu = var->Status;
printf_("\e%s-> \eAABBCC%s\eCCCCCC[%d] \e00AAAA%s\n",
Statuses[statuu], var->Name, statuu, StatusesSign[statuu]);
foreach (auto var2 in var->Threads)
{
int statui = var2->Status;
printf_(" \e%s-> \eAABBCC%s\eCCCCCC[%d] \e00AAAA%s\n\eAABBCC",
Statuses[statui], var2->Name, statui, StatusesSign[statui]);
}
}
printf_("%d", sanity++);
if (sanity > 1000)
sanity = 0;
Display->SetBufferCursor(0, tmpX, tmpY);
Display->SetBuffer(0);
#endif
schedbg("Process \"%s\"(%d) Thread \"%s\"(%d) is now running on CPU %d",
CurrentCPU->CurrentProcess->Name, CurrentCPU->CurrentProcess->ID,
CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID, CurrentCPU->ID);
@ -546,8 +591,9 @@ namespace Tasking
TCB *Task::CreateThread(PCB *Parent,
IP EntryPoint,
Arg Argument0,
Arg Argument1,
Vector<const char *> &argv,
Vector<const char *> &envp,
Vector<AuxiliaryVector> &auxv,
IPOffset Offset,
TaskArchitecture Architecture,
TaskCompatibility Compatibility)
@ -570,8 +616,6 @@ namespace Tasking
strcpy(Thread->Name, Parent->Name);
Thread->EntryPoint = EntryPoint;
Thread->Offset = Offset;
Thread->Argument0 = Argument0;
Thread->Argument1 = Argument1;
Thread->ExitCode = 0xdead;
Thread->Stack = (void *)((uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)));
Thread->Status = TaskStatus::Ready;
@ -579,8 +623,6 @@ namespace Tasking
#if defined(__amd64__)
memset(&Thread->Registers, 0, sizeof(CPU::x64::TrapFrame)); // Just in case
Thread->Registers.rip = (EntryPoint + Offset);
Thread->Registers.rdi = Argument0;
Thread->Registers.rsi = Argument1;
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
@ -622,6 +664,80 @@ namespace Tasking
Thread->Registers.rflags.IF = 1;
Thread->Registers.rflags.ID = 1;
Thread->Registers.rsp = ((uint64_t)Thread->Stack + STACK_SIZE);
// https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf#figure.3.9
// What is a "eightbyte"? unsigned long? 1 eightbyte = 8 bytes? 2 eightbyte each = 16 bytes?
uint64_t TmpStack = Thread->Registers.rsp;
uint64_t TmpStack2 = TmpStack;
uint64_t *TmpStackPtr = (uint64_t *)TmpStack;
// TODO: argc, argv, envp, auxv not tested and probably not working
foreach (auto var in envp)
{
TmpStack -= strlen(var) + 1;
strcpy((char *)TmpStack, var);
}
foreach (auto var in argv)
{
TmpStack -= strlen(var) + 1;
strcpy((char *)TmpStack, var);
}
/* align by 16 */
TmpStack = (uint64_t)((uint64_t)TmpStack - ((uint64_t)TmpStack & 0x0F));
/* TODO: more aligment here? */
/* auxv null */
TmpStack -= sizeof(uint64_t);
POKE(uint64_t, TmpStack) = (uint64_t)0;
/* This should be included too? */
TmpStack -= sizeof(uint64_t);
POKE(uint64_t, TmpStack) = (uint64_t)0;
/* auxv */
foreach (auto var in auxv)
{
if (var.archaux.a_type == AT_ENTRY)
Thread->Registers.rdi = var.archaux.a_un.a_val;
TmpStack -= sizeof(uint64_t) * 2;
POKE(uint64_t, TmpStack) = (uint64_t)var.archaux.a_type;
TmpStack -= sizeof(uint64_t) * 2;
POKE(uint64_t, TmpStack) = (uint64_t)var.archaux.a_un.a_val;
}
/* empty */
TmpStack -= sizeof(uint64_t);
POKE(uint64_t, TmpStack) = 0;
/* envp pointers */
for (uint64_t i = 0; i < envp.size(); i++)
{
/* Not sure if this works */
TmpStack2 -= strlen(envp[i]) + 1;
TmpStackPtr[i] = TmpStack2;
}
/* empty */
TmpStack -= sizeof(uint64_t);
POKE(uint64_t, TmpStack) = 0;
/* argv pointers */
for (uint64_t i = 0; i < argv.size(); i++)
{
/* Not sure if this works */
TmpStack2 -= strlen(argv[i]) + 1;
TmpStackPtr[i] = TmpStack2;
}
/* argc */
TmpStack -= sizeof(uint64_t);
POKE(uint64_t, TmpStack) = argv.size() - 1;
Thread->Registers.rsp -= (uint64_t)Thread->Stack + STACK_SIZE - TmpStack;
/* We need to leave the libc's crt to make a syscall when the Thread is exited or we are going to get GPF or PF exception. */
Memory::Virtual uva = Memory::Virtual(Parent->PageTable);
@ -635,6 +751,9 @@ namespace Tasking
}
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
#ifdef DEBUG_SCHEDULER
DumpData(Thread->Name, Thread->Stack, STACK_SIZE);
#endif
break;
}
@ -786,7 +905,10 @@ namespace Tasking
TaskArchitecture Arch = TaskArchitecture::ARM64;
#endif
PCB *kproc = CreateProcess(nullptr, "Kernel", TaskTrustLevel::Kernel);
TCB *kthrd = CreateThread(kproc, EntryPoint, 0, 0, 0, Arch);
Vector<const char *> argv;
Vector<const char *> envp;
Vector<AuxiliaryVector> auxv;
TCB *kthrd = CreateThread(kproc, EntryPoint, argv, envp, auxv, 0, Arch);
kthrd->Rename("Main Thread");
debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name);
TaskingLock.Lock(__FUNCTION__);
@ -810,7 +932,10 @@ namespace Tasking
IdleProcess = CreateProcess(nullptr, (char *)"Idle", TaskTrustLevel::Idle);
for (int i = 0; i < SMP::CPUCores; i++)
{
IdleThread = CreateThread(IdleProcess, reinterpret_cast<uint64_t>(IdleProcessLoop));
Vector<const char *> argv;
Vector<const char *> envp;
Vector<AuxiliaryVector> auxv;
IdleThread = CreateThread(IdleProcess, reinterpret_cast<uint64_t>(IdleProcessLoop), argv, envp, auxv);
char IdleName[16];
sprintf_(IdleName, "Idle Thread %d", i);
IdleThread->Rename(IdleName);

72
include/abi.h Normal file
View File

@ -0,0 +1,72 @@
#ifndef __FENNIX_KERNEL_ABI_H__
#define __FENNIX_KERNEL_ABI_H__
#include <types.h>
#define AT_NULL 0
#define AT_IGNORE 1
#define AT_EXECFD 2
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_BASE 7
#define AT_FLAGS 8
#define AT_ENTRY 9
#define AT_NOTELF 10
#define AT_UID 11
#define AT_EUID 12
#define AT_GID 13
#define AT_EGID 14
#define AT_PLATFORM 15
#define AT_HWCAP 16
#define AT_CLKTCK 17
#define AT_SECURE 23
#define AT_BASE_PLATFORM 24
#define AT_RANDOM 25
#define AT_HWCAP2 26
#define AT_EXECFN 31
#define AT_SYSINFO 32
#define AT_SYSINFO_EHDR 33
#define AT_L1I_CACHESHAPE 34
#define AT_L1D_CACHESHAPE 35
#define AT_L2_CACHESHAPE 36
#define AT_L3_CACHESHAPE 37
#define AT_L1I_CACHESIZE 40
#define AT_L1I_CACHEGEOMETRY 41
#define AT_L1D_CACHESIZE 42
#define AT_L1D_CACHEGEOMETRY 43
#define AT_L2_CACHESIZE 44
#define AT_L2_CACHEGEOMETRY 45
#define AT_L3_CACHESIZE 46
#define AT_L3_CACHEGEOMETRY 47
#define AT_MINSIGSTKSZ 51
typedef struct
{
uint32_t a_type;
union
{
uint32_t a_val;
} a_un;
} Elf32_auxv_t;
typedef struct
{
uint64_t a_type;
union
{
uint64_t a_val;
} a_un;
} Elf64_auxv_t;
typedef struct
{
#if defined(__amd64__)
Elf64_auxv_t archaux;
#elif defined(__i386__)
#elif defined(__aarch64__)
#endif
} AuxiliaryVector;
#endif // !__FENNIX_KERNEL_ABI_H__

View File

@ -3,12 +3,28 @@
#include <types.h>
#define assert(x) \
do \
{ \
if (!(x)) \
while (1) \
; \
#include <debug.h>
#define assert(x) \
do \
{ \
if (!(x)) \
{ \
void *CallerAddress = __builtin_extract_return_addr(__builtin_return_address(0)); \
error("Assertion failed! [%s] [%#lx => %s:%s:%d]", #x, CallerAddress, __FILE__, __FUNCTION__, __LINE__); \
while (1) \
; \
} \
} while (0)
#define assert_allow_continue(x) \
do \
{ \
if (!(x)) \
{ \
void *CallerAddress = __builtin_extract_return_addr(__builtin_return_address(0)); \
error("Assertion failed! [%s] [%#lx => %s:%s:%d]", #x, CallerAddress, __FILE__, __FUNCTION__, __LINE__); \
} \
} while (0)
#define static_assert(x) \

View File

@ -1585,6 +1585,9 @@ namespace CPU
__attribute__((no_stack_protector)) static inline void fxsave(char *FXSaveArea)
{
#if defined(__amd64__)
if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
return;
_amd64_fxsave(FXSaveArea);
// asmv("fxsaveq (%0)"
// :
@ -1596,6 +1599,9 @@ namespace CPU
__attribute__((no_stack_protector)) static inline void fxrstor(char *FXRstorArea)
{
#if defined(__amd64__)
if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)
return;
_amd64_fxrstor(FXRstorArea);
// asmv("fxrstorq (%0)"
// :

View File

@ -40,7 +40,7 @@ namespace Execute
};
BinaryType GetBinaryType(char *Path);
SpawnData Spawn(char *Path, uint64_t Arg0, uint64_t Arg1);
SpawnData Spawn(char *Path, Vector<const char *> &argv, Vector<const char *> &envp);
void *ELFLoadRel(Elf64_Ehdr *Header);
}

View File

@ -10,6 +10,7 @@ struct KernelConfig
bool SchedulerType;
char DriverDirectory[256];
char InitPath[256];
bool InterruptsOnCrash;
int Cores;
};

View File

@ -38,7 +38,7 @@ struct CPUData
/** @brief Current running thread */
Tasking::TCB *CurrentThread;
/** @brief Architecture-specific CPU data. */
/** @brief Architecture-specific data. */
CPUArchData *Data;
/** @brief Checksum. Used to verify the integrity of the data. Must be equal to CPU_DATA_CHECKSUM (0xC0FFEE). */
int Checksum;

View File

@ -3,7 +3,7 @@
#include <types.h>
typedef struct SyscallsRegs
typedef struct SyscallsFrame
{
#if defined(__amd64__)
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
@ -15,7 +15,10 @@ typedef struct SyscallsRegs
uint64_t InterruptNumber, ErrorCode, eip, cs, eflags, esp, ss;
#elif defined(__aarch64__)
#endif
} SyscallsRegs;
} SyscallsFrame;
uint64_t HandleNativeSyscalls(SyscallsFrame *Frame);
uint64_t HandleLinuxSyscalls(SyscallsFrame *Frame);
/**
* @brief Initialize syscalls for the current CPU. (Function is available on x32, x64 & aarch64)

View File

@ -9,11 +9,11 @@
#include <hashmap.hpp>
#include <ipc.hpp>
#include <debug.h>
#include <abi.h>
namespace Tasking
{
typedef unsigned long IP;
typedef unsigned long Arg;
typedef unsigned long IPOffset;
typedef unsigned long UPID;
typedef unsigned long UTID;
@ -84,8 +84,6 @@ namespace Tasking
struct PCB *Parent;
IP EntryPoint;
IPOffset Offset;
Arg Argument0;
Arg Argument1;
int ExitCode;
void *Stack;
TaskStatus Status;
@ -217,6 +215,17 @@ namespace Tasking
public:
void Schedule();
long GetUsage(int Core) { return 100 - IdleProcess->Info.Usage[Core]; }
void KillThread(TCB *tcb, int Code)
{
tcb->Status = TaskStatus::Terminated;
tcb->ExitCode = Code;
}
void KillProcess(PCB *pcb, int Code)
{
pcb->Status = TaskStatus::Terminated;
pcb->ExitCode = Code;
}
/**
* @brief Get the Current Process object
@ -242,8 +251,9 @@ namespace Tasking
TCB *CreateThread(PCB *Parent,
IP EntryPoint,
Arg Argument0 = 0,
Arg Argument1 = 0,
Vector<const char *> &argv,
Vector<const char *> &envp,
Vector<AuxiliaryVector> &auxv,
IPOffset Offset = 0,
TaskArchitecture Architecture = TaskArchitecture::x64,
TaskCompatibility Compatibility = TaskCompatibility::Native);

View File

@ -200,4 +200,45 @@ typedef __SIZE_TYPE__ size_t;
#define WINT_MAX __WINT_MAX__
#define WINT_MIN __WINT_MIN__
#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)
#define O0 __attribute__((optimize("O0")))
#define O1 __attribute__((optimize("O1")))
#define O2 __attribute__((optimize("O2")))
#define O3 __attribute__((optimize("O3")))
#define Os __attribute__((optimize("Os")))
#define Ofast __attribute__((optimize("Ofast")))
/** @brief dbg */
#define OPTMZ O0
#define __unused __attribute__((unused))
#define __packed __attribute__((packed))
#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)))
#endif // !__FENNIX_KERNEL_TYPES_H__

View File

@ -35,6 +35,7 @@ extern Disk::Manager *DiskManager;
#endif
EXTERNC void putchar(char c);
EXTERNC void KPrint(const char *format, ...);
EXTERNC void Entry(struct BootInfo *Info);

12
syscalls.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef __FENNIX_KERNEL_SYSCALLS_LIST_H__
#define __FENNIX_KERNEL_SYSCALLS_LIST_H__
#include <types.h>
enum NativeSyscalls
{
_exit = 0,
_print,
};
#endif // !__FENNIX_KERNEL_SYSCALLS_LIST_H__