Update kernel

This commit is contained in:
Alex
2023-08-06 04:53:14 +03:00
parent 3b65386399
commit 2c51e4432f
181 changed files with 21873 additions and 21475 deletions

View File

@ -32,14 +32,15 @@
namespace Tasking
{
/** @brief Instruction Pointer */
using VirtualFileSystem::FileDescriptorTable;
using VirtualFileSystem::Node;
/** Instruction Pointer */
typedef __UINTPTR_TYPE__ IP;
/** @brief Process ID */
/** Process ID */
typedef int PID;
/** @brief Thread ID */
/** Thread ID */
typedef int TID;
/* @brief Token */
typedef __UINTPTR_TYPE__ Token;
enum TaskArchitecture
{
@ -47,7 +48,10 @@ namespace Tasking
x32,
x64,
ARM32,
ARM64
ARM64,
_ArchitectureMin = UnknownArchitecture,
_ArchitectureMax = ARM64
};
enum TaskCompatibility
@ -55,26 +59,35 @@ namespace Tasking
UnknownPlatform,
Native,
Linux,
Windows
Windows,
_CompatibilityMin = UnknownPlatform,
_CompatibilityMax = Windows
};
enum TaskTrustLevel
enum TaskExecutionMode
{
UnknownElevation,
UnknownExecutionMode,
Kernel,
System,
User
User,
_ExecuteModeMin = UnknownExecutionMode,
_ExecuteModeMax = User
};
enum TaskStatus
enum TaskStatus : int
{
UnknownStatus,
Ready,
Running,
Sleeping,
Waiting,
Stopped,
Terminated
Blocked,
Zombie,
Terminated,
_StatusMin = UnknownStatus,
_StatusMax = Terminated
};
enum TaskPriority
@ -84,60 +97,81 @@ namespace Tasking
Low = 2,
Normal = 5,
High = 8,
Critical = 10
Critical = 10,
_PriorityMin = UnknownPriority,
_PriorityMax = Critical
};
enum KillErrorCodes : int
{
KILL_SCHEDULER_DESTRUCTION = -0xFFFF,
KILL_CXXABI_EXCEPTION = -0xECE97,
KILL_BY_OTHER_PROCESS = -0x7A55,
KILL_SYSCALL = -0xCA11,
KILL_CRASH = -0xDEAD,
KILL_OOM = -0x1008,
KILL_ERROR = -0x1,
KILL_SUCCESS = 0,
};
struct TaskSecurity
{
TaskTrustLevel TrustLevel;
Token UniqueToken;
bool IsCritical;
bool IsDebugEnabled;
bool IsKernelDebugEnabled;
};
struct TaskInfo
{
size_t OldUserTime = 0;
size_t OldKernelTime = 0;
uint64_t OldUserTime = 0;
uint64_t OldKernelTime = 0;
size_t SleepUntil = 0;
size_t KernelTime = 0, UserTime = 0, SpawnTime = 0, LastUpdateTime = 0;
uint64_t Year, Month, Day, Hour, Minute, Second;
bool Affinity[256]; // MAX_CPU
TaskPriority Priority;
TaskArchitecture Architecture;
TaskCompatibility Compatibility;
uint64_t SleepUntil = 0;
uint64_t KernelTime = 0, UserTime = 0, SpawnTime = 0, LastUpdateTime = 0;
uint64_t Year = 0, Month = 0, Day = 0, Hour = 0, Minute = 0, Second = 0;
bool Affinity[256] = {true}; // MAX_CPU
TaskPriority Priority = TaskPriority::Normal;
TaskArchitecture Architecture = TaskArchitecture::UnknownArchitecture;
TaskCompatibility Compatibility = TaskCompatibility::UnknownPlatform;
};
struct TCB
/**
* TCB struct for gs register
*/
struct gsTCB
{
/** @brief Used by syscall handler */
uintptr_t SyscallStack; /* gs+0x0 */
/**
* Used by syscall handler
*
* gs+0x0
*/
uintptr_t SyscallStack = __UINTPTR_MAX__;
/** @brief Used by syscall handler */
uintptr_t TempStack; /* gs+0x8 */
/**
* Used by syscall handler
*
* gs+0x8
*/
uintptr_t TempStack = __UINTPTR_MAX__;
TID ID;
char Name[256];
struct PCB *Parent;
IP EntryPoint;
int ExitCode;
/**
* The current thread class
*/
class TCB *t;
};
class TCB
{
private:
class Task *ctx = nullptr;
public:
TID ID = -1;
const char * Name = nullptr;
class PCB *Parent = nullptr;
IP EntryPoint = 0;
std::atomic_int ExitCode;
std::atomic<TaskStatus> Status = TaskStatus::UnknownStatus;
Memory::StackGuard *Stack;
Memory::MemMgr *Memory;
TaskStatus Status;
int ErrorNumber;
#if defined(a64)
CPU::x64::TrapFrame Registers;
CPU::x64::TrapFrame Registers{};
uintptr_t ShadowGSBase, GSBase, FSBase;
#elif defined(a32)
CPU::x32::TrapFrame Registers; // TODO
@ -146,52 +180,25 @@ namespace Tasking
uintptr_t Registers; // TODO
#endif
uintptr_t IPHistory[128];
TaskSecurity Security;
TaskInfo Info;
struct
{
TaskExecutionMode ExecutionMode = UnknownExecutionMode;
bool IsCritical = false;
bool IsDebugEnabled = false;
bool IsKernelDebugEnabled = false;
} Security{};
TaskInfo Info{};
CPU::x64::FXState *FPU;
void Rename(const char *name)
{
CriticalSection cs;
if (strlen(name) > 256 || strlen(name) == 0)
{
debug("Invalid thread name");
return;
}
void Rename(const char *name);
void SetPriority(TaskPriority priority);
int GetExitCode() { return ExitCode.load(); }
void SetCritical(bool Critical);
void SetDebugMode(bool Enable);
void SetKernelDebugMode(bool Enable);
trace("Renaming thread %s to %s", Name, name);
strncpy(Name, name, 256);
}
void SetPriority(TaskPriority priority)
{
CriticalSection cs;
trace("Setting priority of thread %s to %d", Name, priority);
Info.Priority = priority;
}
int GetExitCode() { return ExitCode; }
void SetCritical(bool Critical)
{
CriticalSection cs;
trace("Setting criticality of thread %s to %s", Name, Critical ? "true" : "false");
Security.IsCritical = Critical;
}
void SetDebugMode(bool Enable)
{
CriticalSection cs;
trace("Setting debug mode of thread %s to %s", Name, Enable ? "true" : "false");
Security.IsDebugEnabled = Enable;
}
void SetKernelDebugMode(bool Enable)
{
CriticalSection cs;
trace("Setting kernel debug mode of thread %s to %s", Name, Enable ? "true" : "false");
Security.IsKernelDebugEnabled = Enable;
}
void Block() { Status.store(TaskStatus::Blocked); }
void Unblock() { Status.store(TaskStatus::Ready); }
void SYSV_ABI_Call(uintptr_t Arg1 = 0,
uintptr_t Arg2 = 0,
@ -199,92 +206,79 @@ namespace Tasking
uintptr_t Arg4 = 0,
uintptr_t Arg5 = 0,
uintptr_t Arg6 = 0,
void *Function = nullptr)
{
CriticalSection cs;
#if defined(a64)
this->Registers.rdi = Arg1;
this->Registers.rsi = Arg2;
this->Registers.rdx = Arg3;
this->Registers.rcx = Arg4;
this->Registers.r8 = Arg5;
this->Registers.r9 = Arg6;
if (Function != nullptr)
this->Registers.rip = (uint64_t)Function;
#else
#warning "SYSV ABI not implemented for this architecture"
#endif
}
void *Function = nullptr);
TCB(class Task *ctx,
PCB *Parent,
IP EntryPoint,
const char **argv = nullptr,
const char **envp = nullptr,
const std::vector<AuxiliaryVector> &auxv = std::vector<AuxiliaryVector>(),
TaskArchitecture Architecture = TaskArchitecture::x64,
TaskCompatibility Compatibility = TaskCompatibility::Native,
bool ThreadNotReady = false);
~TCB();
};
struct PCB
class PCB
{
PID ID;
char Name[256];
PCB *Parent;
int ExitCode;
TaskStatus Status;
TaskSecurity Security;
TaskInfo Info;
private:
class Task *ctx = nullptr;
bool OwnPageTable = false;
public:
PID ID = -1;
const char * Name = nullptr;
PCB *Parent = nullptr;
std::atomic_int ExitCode;
std::atomic<TaskStatus> Status = Zombie;
struct
{
TaskExecutionMode ExecutionMode = UnknownExecutionMode;
bool IsCritical = false;
bool IsDebugEnabled = false;
bool IsKernelDebugEnabled = false;
struct
{
uint16_t UserID = UINT16_MAX;
uint16_t GroupID = UINT16_MAX;
} Real, Effective;
} Security{};
TaskInfo Info{};
std::vector<TCB *> Threads;
std::vector<PCB *> Children;
InterProcessCommunication::IPC *IPC;
Memory::PageTable *PageTable;
SymbolResolver::Symbols *ELFSymbolTable;
VirtualFileSystem::Node *CurrentWorkingDirectory;
VirtualFileSystem::Node *ProcessDirectory;
VirtualFileSystem::Node *memDirectory;
void SetWorkingDirectory(VirtualFileSystem::Node *node)
{
CriticalSection cs;
trace("Setting working directory of process %s to %#lx (%s)", Name, node, node->Name);
CurrentWorkingDirectory = node;
}
};
/** @brief Token Trust Level */
enum TTL
{
UnknownTrustLevel = 0b0001,
Untrusted = 0b0010,
Trusted = 0b0100,
TrustedByKernel = 0b1000,
FullTrust = Trusted | TrustedByKernel,
AllFlags = 0b1111
};
class Security
{
private:
struct TokenData
{
Token token;
int TrustLevel;
uint64_t OwnerID;
bool Process;
};
std::vector<TokenData> Tokens;
Node *CurrentWorkingDirectory;
Node *ProcessDirectory;
Node *memDirectory;
Memory::MemMgr *Memory;
FileDescriptorTable *FileDescriptors;
public:
Token CreateToken();
bool TrustToken(Token token, TTL TrustLevel);
bool AddTrustLevel(Token token, TTL TrustLevel);
bool RemoveTrustLevel(Token token, TTL TrustLevel);
bool UntrustToken(Token token);
bool DestroyToken(Token token);
bool IsTokenTrusted(Token token, TTL TrustLevel);
bool IsTokenTrusted(Token token, int TrustLevel);
int GetTokenTrustLevel(Token token);
Security();
~Security();
void Rename(const char *name);
void SetWorkingDirectory(Node *node);
PCB(class Task *ctx,
PCB *Parent,
const char *Name,
TaskExecutionMode ExecutionMode,
void *Image = nullptr,
bool DoNotCreatePageTable = false,
uint16_t UserID = -1,
uint16_t GroupID = -1);
~PCB();
};
class Task : public Interrupts::Handler
{
private:
Security SecurityManager;
NewLock(SchedulerLock);
NewLock(TaskingLock);
PID NextPID = 0;
TID NextTID = 0;
@ -295,30 +289,76 @@ namespace Tasking
std::atomic_size_t SchedulerTicks = 0;
std::atomic_size_t LastTaskTicks = 0;
std::atomic_int LastCore = 0;
bool StopScheduler = false;
std::atomic_bool StopScheduler = false;
std::atomic_bool SchedulerUpdateTrapFrame = false;
bool InvalidPCB(PCB *pcb);
bool InvalidTCB(TCB *tcb);
/**
* @note This function is NOT thread safe
*/
void RemoveThread(TCB *tcb);
/**
* @note This function is NOT thread safe
*/
void RemoveProcess(PCB *pcb);
void UpdateUsage(TaskInfo *Info, TaskSecurity *Security, int Core);
void UpdateUsage(TaskInfo *Info,
TaskExecutionMode Mode,
int Core);
/**
* @note This function is NOT thread safe
*/
bool FindNewProcess(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
bool GetNextAvailableThread(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
bool GetNextAvailableProcess(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
bool SchedulerSearchProcessThread(void *CPUDataPointer);
/**
* @note This function is NOT thread safe
*/
void UpdateProcessStatus();
/**
* @note This function is NOT thread safe
*/
void WakeUpThreads();
#if defined(a64)
/**
* @note This function is NOT thread safe
*/
void Schedule(CPU::x64::TrapFrame *Frame);
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
#elif defined(a32)
/**
* @note This function is NOT thread safe
*/
void Schedule(void *Frame);
void OnInterruptReceived(CPU::x32::TrapFrame *Frame);
#elif defined(aa64)
/**
* @note This function is NOT thread safe
*/
void Schedule(CPU::aarch64::TrapFrame *Frame);
void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame);
#endif
@ -328,42 +368,62 @@ namespace Tasking
size_t GetLastTaskTicks() { return LastTaskTicks.load(); }
int GetLastCore() { return LastCore.load(); }
std::vector<PCB *> GetProcessList() { return ProcessList; }
Security *GetSecurityManager() { return &SecurityManager; }
void CleanupProcessesThread();
void Panic() { StopScheduler = true; }
bool IsPanic() { return StopScheduler; }
__always_inline inline void Schedule()
/**
* Yield the current thread and switch
* to another thread if available
*/
__always_inline inline void Yield()
{
/* This will trigger the IRQ16
instantly so we won't execute
the next instruction */
#if defined(a86)
asmv("int $0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
asmv("int $0x30");
#elif defined(aa64)
asmv("svc #0x30"); /* This will trigger the IRQ16 instantly so we won't execute the next instruction */
asmv("svc #0x30");
#endif
}
/**
* Update the current thread's trap frame
* without switching to another thread
*/
__always_inline inline void UpdateFrame()
{
SchedulerUpdateTrapFrame = true;
Yield();
}
void SignalShutdown();
void RevertProcessCreation(PCB *Process);
void RevertThreadCreation(TCB *Thread);
void KillThread(TCB *tcb, enum KillErrorCodes Code)
{
tcb->Status = TaskStatus::Terminated;
tcb->ExitCode = (int)Code;
debug("Killing thread %s(%d) with exit code %d",
tcb->Name, tcb->ID, Code);
}
void KillProcess(PCB *pcb, enum KillErrorCodes Code)
{
pcb->Status = TaskStatus::Terminated;
pcb->ExitCode = (int)Code;
debug("Killing process %s(%d) with exit code %d",
pcb->Name, pcb->ID, Code);
}
/**
* @brief Get the Current Process object
* Get the Current Process object
* @return PCB*
*/
PCB *GetCurrentProcess();
/**
* @brief Get the Current Thread object
* Get the Current Thread object
* @return TCB*
*/
TCB *GetCurrentThread();
@ -372,17 +432,17 @@ namespace Tasking
TCB *GetThreadByID(TID ID);
/** @brief Wait for process to terminate */
/** Wait for process to terminate */
void WaitForProcess(PCB *pcb);
/** @brief Wait for thread to terminate */
/** Wait for thread to terminate */
void WaitForThread(TCB *tcb);
void WaitForProcessStatus(PCB *pcb, TaskStatus Status);
void WaitForThreadStatus(TCB *tcb, TaskStatus Status);
/**
* @brief Sleep for a given amount of milliseconds
* Sleep for a given amount of milliseconds
*
* @param Milliseconds Amount of milliseconds to sleep
*/
@ -390,9 +450,11 @@ namespace Tasking
PCB *CreateProcess(PCB *Parent,
const char *Name,
TaskTrustLevel TrustLevel,
TaskExecutionMode TrustLevel,
void *Image = nullptr,
bool DoNotCreatePageTable = false);
bool DoNotCreatePageTable = false,
uint16_t UserID = UINT16_MAX,
uint16_t GroupID = UINT16_MAX);
TCB *CreateThread(PCB *Parent,
IP EntryPoint,
@ -405,11 +467,17 @@ namespace Tasking
Task(const IP EntryPoint);
~Task();
friend PCB;
friend TCB;
};
}
#define PEXIT(Code) TaskManager->GetCurrentProcess()->ExitCode = Code
#define TEXIT(Code) TaskManager->GetCurrentThread()->ExitCode = Code
#define thisProcess TaskManager->GetCurrentProcess()
#define thisThread TaskManager->GetCurrentThread()
#define PEXIT(Code) thisProcess->ExitCode = Code
#define TEXIT(Code) thisThread->ExitCode = Code
extern "C" void TaskingScheduler_OneShot(int TimeSlice);