mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-28 23:44:31 +00:00
Stability fixes (i hope); attempt to implement argc, argv, envp, auxv; Syscalls
This commit is contained in:
parent
40b1da9dd1
commit
77081b4e1e
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
using namespace CPU::x32;
|
||||
|
||||
extern "C" uint32_t SystemCallsHandler(SyscallsRegs *regs);
|
||||
extern "C" uint32_t SystemCallsHandler(SyscallsFrame *regs);
|
||||
|
||||
void InitializeSystemCalls()
|
||||
{
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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
65
Core/Crash/SFrame.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
Core/Crash/UserHandler.cpp
Normal file
17
Core/Crash/UserHandler.cpp
Normal 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
44
Core/Crash/chfcts.hpp
Normal 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__
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace Video
|
||||
{
|
||||
char Display::Print(char Char, int Index, bool WriteToUART)
|
||||
{
|
||||
SmartLock(PrintLock);
|
||||
// SmartLock(PrintLock);
|
||||
|
||||
if (this->ColorIteration)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -19,7 +19,8 @@
|
||||
"assert.h": "c",
|
||||
"cwalk.h": "c",
|
||||
"md5.h": "c",
|
||||
"stdint.h": "c"
|
||||
"stdint.h": "c",
|
||||
"debug.h": "c"
|
||||
}
|
||||
}
|
||||
}
|
13
KConfig.cpp
13
KConfig.cpp
@ -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.");
|
||||
|
45
KThread.cpp
45
KThread.cpp
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
2409
SystemCalls/Linux.cpp
Normal file
File diff suppressed because it is too large
Load Diff
46
SystemCalls/Native.cpp
Normal file
46
SystemCalls/Native.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
141
Tasking/Task.cpp
141
Tasking/Task.cpp
@ -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
72
include/abi.h
Normal 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__
|
@ -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) \
|
||||
|
@ -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)"
|
||||
// :
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ struct KernelConfig
|
||||
bool SchedulerType;
|
||||
char DriverDirectory[256];
|
||||
char InitPath[256];
|
||||
bool InterruptsOnCrash;
|
||||
int Cores;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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__
|
||||
|
1
kernel.h
1
kernel.h
@ -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
12
syscalls.h
Normal 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__
|
Loading…
x
Reference in New Issue
Block a user