From c4870d08fa4bfb2613bf22a0b7cf306b388f58a4 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sat, 29 Mar 2025 05:03:14 +0100 Subject: ddk: refactor: reorganize kit into a standard kernel kit. sched: refactor: refactor scheduler file names, for future additions. xcoff: refactor: document and improve XCOFF for NeFS (regarding Ne's FW) codemgr: refactor: make a difference between kernel and user processes. refactor: document project overall. Signed-off-by: Amlal El Mahrouss --- dev/kernel/KernelKit/CodeMgr.h | 8 +- dev/kernel/KernelKit/DriveMgr.h | 2 +- dev/kernel/KernelKit/IDylibObject.h | 2 +- dev/kernel/KernelKit/IPEFDylibObject.h | 2 +- dev/kernel/KernelKit/KPC.h | 72 ++--- dev/kernel/KernelKit/PECodeMgr.h | 2 +- dev/kernel/KernelKit/PEFCodeMgr.h | 6 +- dev/kernel/KernelKit/ProcessScheduler.h | 379 ++++++++++++++++++++++++++ dev/kernel/KernelKit/ProcessScheduler.inl | 62 +++++ dev/kernel/KernelKit/ThreadLocalStorage.inl | 2 +- dev/kernel/KernelKit/UserProcessScheduler.h | 379 -------------------------- dev/kernel/KernelKit/UserProcessScheduler.inl | 62 ----- dev/kernel/KernelKit/XCOFF.h | 28 +- 13 files changed, 507 insertions(+), 499 deletions(-) create mode 100644 dev/kernel/KernelKit/ProcessScheduler.h create mode 100644 dev/kernel/KernelKit/ProcessScheduler.inl delete mode 100644 dev/kernel/KernelKit/UserProcessScheduler.h delete mode 100644 dev/kernel/KernelKit/UserProcessScheduler.inl (limited to 'dev/kernel/KernelKit') diff --git a/dev/kernel/KernelKit/CodeMgr.h b/dev/kernel/KernelKit/CodeMgr.h index 15ec420e..c781263e 100644 --- a/dev/kernel/KernelKit/CodeMgr.h +++ b/dev/kernel/KernelKit/CodeMgr.h @@ -33,5 +33,11 @@ namespace Kernel /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. /// @param main the start of the process. /// @return The team's process id. - ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept; + ProcessID rtl_create_kernel_process(rtl_main_kind main, const Char* process_name) noexcept; + + /// @brief Executes a new process from a function. User code only. + /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. + /// @param main the start of the process. + /// @return The team's process id. + ProcessID rtl_create_user_process(rtl_main_kind main, const Char* process_name) noexcept; } // namespace Kernel diff --git a/dev/kernel/KernelKit/DriveMgr.h b/dev/kernel/KernelKit/DriveMgr.h index 9d461703..a8c3dec5 100644 --- a/dev/kernel/KernelKit/DriveMgr.h +++ b/dev/kernel/KernelKit/DriveMgr.h @@ -7,7 +7,7 @@ #ifndef INC_DRIVE_MANAGER_H #define INC_DRIVE_MANAGER_H -#include +#include #include #include #include diff --git a/dev/kernel/KernelKit/IDylibObject.h b/dev/kernel/KernelKit/IDylibObject.h index f02fb9d3..faecede0 100644 --- a/dev/kernel/KernelKit/IDylibObject.h +++ b/dev/kernel/KernelKit/IDylibObject.h @@ -16,7 +16,7 @@ namespace Kernel { - /// @brief DLL class object. A handle to a shared library. + /// @brief Dylib class object. A handle to a shared library. class IDylibObject { public: diff --git a/dev/kernel/KernelKit/IPEFDylibObject.h b/dev/kernel/KernelKit/IPEFDylibObject.h index 22360e50..8c4ec22a 100644 --- a/dev/kernel/KernelKit/IPEFDylibObject.h +++ b/dev/kernel/KernelKit/IPEFDylibObject.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include namespace Kernel diff --git a/dev/kernel/KernelKit/KPC.h b/dev/kernel/KernelKit/KPC.h index c6724282..3e52be64 100644 --- a/dev/kernel/KernelKit/KPC.h +++ b/dev/kernel/KernelKit/KPC.h @@ -21,44 +21,44 @@ namespace Kernel { - typedef Int32 HError; + typedef Int32 KPCError; - inline HError kErrorLocalNumber = 0UL; + inline KPCError kErrorLocalNumber = 0UL; - inline constexpr HError kErrorSuccess = 0; - inline constexpr HError kErrorExecutable = 33; - inline constexpr HError kErrorExecutableLib = 34; - inline constexpr HError kErrorFileNotFound = 35; - inline constexpr HError kErrorDirectoryNotFound = 36; - inline constexpr HError kErrorDiskReadOnly = 37; - inline constexpr HError kErrorDiskIsFull = 38; - inline constexpr HError kErrorProcessFault = 39; - inline constexpr HError kErrorSocketHangUp = 40; - inline constexpr HError kErrorThreadLocalStorage = 41; - inline constexpr HError kErrorMath = 42; - inline constexpr HError kErrorNoNetwork = 43; - inline constexpr HError kErrorHeapOutOfMemory = 44; - inline constexpr HError kErrorNoSuchDisk = 45; - inline constexpr HError kErrorFileExists = 46; - inline constexpr HError kErrorFormatFailed = 47; - inline constexpr HError kErrorNetworkTimeout = 48; - inline constexpr HError kErrorInternal = 49; - inline constexpr HError kErrorForkAlreadyExists = 50; - inline constexpr HError kErrorOutOfTeamSlot = 51; - inline constexpr HError kErrorHeapNotPresent = 52; - inline constexpr HError kErrorNoEntrypoint = 53; - inline constexpr HError kErrorDiskIsCorrupted = 54; - inline constexpr HError kErrorDisk = 55; - inline constexpr HError kErrorInvalidData = 56; - inline constexpr HError kErrorAsync = 57; - inline constexpr HError kErrorNonBlocking = 58; - inline constexpr HError kErrorIPC = 59; - inline constexpr HError kErrorSign = 60; - inline constexpr HError kErrorInvalidCreds = 61; - inline constexpr HError kErrorCDTrayBroken = 62; - inline constexpr HError kErrorUnrecoverableDisk = 63; - inline constexpr HError kErrorFileLocked = 64; - inline constexpr HError kErrorUnimplemented = -1; + inline constexpr KPCError kErrorSuccess = 0; + inline constexpr KPCError kErrorExecutable = 33; + inline constexpr KPCError kErrorExecutableLib = 34; + inline constexpr KPCError kErrorFileNotFound = 35; + inline constexpr KPCError kErrorDirectoryNotFound = 36; + inline constexpr KPCError kErrorDiskReadOnly = 37; + inline constexpr KPCError kErrorDiskIsFull = 38; + inline constexpr KPCError kErrorProcessFault = 39; + inline constexpr KPCError kErrorSocketHangUp = 40; + inline constexpr KPCError kErrorThreadLocalStorage = 41; + inline constexpr KPCError kErrorMath = 42; + inline constexpr KPCError kErrorNoNetwork = 43; + inline constexpr KPCError kErrorHeapOutOfMemory = 44; + inline constexpr KPCError kErrorNoSuchDisk = 45; + inline constexpr KPCError kErrorFileExists = 46; + inline constexpr KPCError kErrorFormatFailed = 47; + inline constexpr KPCError kErrorNetworkTimeout = 48; + inline constexpr KPCError kErrorInternal = 49; + inline constexpr KPCError kErrorForkAlreadyExists = 50; + inline constexpr KPCError kErrorOutOfTeamSlot = 51; + inline constexpr KPCError kErrorHeapNotPresent = 52; + inline constexpr KPCError kErrorNoEntrypoint = 53; + inline constexpr KPCError kErrorDiskIsCorrupted = 54; + inline constexpr KPCError kErrorDisk = 55; + inline constexpr KPCError kErrorInvalidData = 56; + inline constexpr KPCError kErrorAsync = 57; + inline constexpr KPCError kErrorNonBlocking = 58; + inline constexpr KPCError kErrorIPC = 59; + inline constexpr KPCError kErrorSign = 60; + inline constexpr KPCError kErrorInvalidCreds = 61; + inline constexpr KPCError kErrorCDTrayBroken = 62; + inline constexpr KPCError kErrorUnrecoverableDisk = 63; + inline constexpr KPCError kErrorFileLocked = 64; + inline constexpr KPCError kErrorUnimplemented = -1; /// @brief Does a system wide bug check. /// @param void no params are needed. diff --git a/dev/kernel/KernelKit/PECodeMgr.h b/dev/kernel/KernelKit/PECodeMgr.h index 1e445b9f..cf7f625d 100644 --- a/dev/kernel/KernelKit/PECodeMgr.h +++ b/dev/kernel/KernelKit/PECodeMgr.h @@ -3,7 +3,7 @@ Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. File: PECodeMgr.h - Purpose: PE32+ Code Mgr and DLL mgr. + Purpose: PE32+ Code Mgr and Dylib mgr. Revision History: diff --git a/dev/kernel/KernelKit/PEFCodeMgr.h b/dev/kernel/KernelKit/PEFCodeMgr.h index aa82f84d..3d96c6c0 100644 --- a/dev/kernel/KernelKit/PEFCodeMgr.h +++ b/dev/kernel/KernelKit/PEFCodeMgr.h @@ -13,10 +13,10 @@ #include #ifndef INC_PROCESS_SCHEDULER_H -#include +#include #endif -#define kPefApplicationMime "application/vnd-zka-executable" +#define kPefApplicationMime "application/vnd-amlal-executable" namespace Kernel { @@ -65,7 +65,7 @@ namespace Kernel namespace Utils { - ProcessID rtl_create_process(PEFLoader& exec, const Int32& procKind) noexcept; + ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& procKind) noexcept; } // namespace Utils } // namespace Kernel diff --git a/dev/kernel/KernelKit/ProcessScheduler.h b/dev/kernel/KernelKit/ProcessScheduler.h new file mode 100644 index 00000000..5e88d1ec --- /dev/null +++ b/dev/kernel/KernelKit/ProcessScheduler.h @@ -0,0 +1,379 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#ifndef INC_PROCESS_SCHEDULER_H +#define INC_PROCESS_SCHEDULER_H + +#include +#include +#include +#include + +#define kSchedMinMicroTime (AffinityKind::kStandard) +#define kSchedInvalidPID ((PID)~0) +#define kSchedProcessLimitPerTeam (32U) + +#define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ +#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ + +#define kSchedNameLen (128U) + +//////////////////////////////////////////////////// +// Last revision date is: Fri Mar 28 2025 // +//////////////////////////////////////////////////// + +namespace Kernel +{ + //! @note Forward class declaration. + + class IDylibObject; + class UserProcess; + class UserProcessTeam; + class UserProcessScheduler; + class UserProcessHelper; + + typedef UInt64 PTime; + + /***********************************************************************************/ + //! @brief Local Process identifier. + /***********************************************************************************/ + typedef Int64 ProcessID; + + /***********************************************************************************/ + //! @brief Local Process status enum. + /***********************************************************************************/ + enum class ProcessStatusKind : Int32 + { + kInvalid, + kStarting, + kRunning, + kKilled, + kFrozen, + kFinished, + kCount, + }; + + /***********************************************************************************/ + //! @brief Affinity is the amount of nano-seconds this process is going to run. + /***********************************************************************************/ + enum class AffinityKind : Int32 + { + kRealTime = 500, + kVeryHigh = 250, + kHigh = 200, + kStandard = 1000, + kLowUsage = 1500, + kVeryLowUsage = 2000, + }; + + /***********************************************************************************/ + //! Operators for AffinityKind + /***********************************************************************************/ + + inline bool operator<(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int < rhs_int; + } + + inline bool operator>(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int > rhs_int; + } + + inline bool operator<=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int <= rhs_int; + } + + inline bool operator>=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int >= rhs_int; + } + + /***********************************************************************************/ + /// @brief Subsystem enum type. + /***********************************************************************************/ + + enum class ProcessSubsystem : Int32 + { + kProcessSubsystemSecurity = 100, + kProcessSubsystemApplication, + kProcessSubsystemService, + kProcessSubsystemDriver, + kProcessSubsystemInvalid = 256U, + kProcessSubsystemCount = 4, + }; + + using ProcessTime = UInt64; + using PID = UInt64; + + /***********************************************************************************/ + /// @note For User manager, tells where we run the code. + /***********************************************************************************/ + enum class ProcessLevelRing : Int32 + { + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 5, + }; + + /***********************************************************************************/ + /// @brief Helper type to describe a code image. + /***********************************************************************************/ + using ImagePtr = VoidPtr; + + struct UserProcessImage final + { + explicit UserProcessImage() = default; + + ImagePtr fCode; + ImagePtr fBlob; + + Bool HasCode() + { + return this->fCode != nullptr; + } + + Bool HasImage() + { + return this->fBlob != nullptr; + } + }; + + /***********************************************************************************/ + /// @name UserProcess + /// @brief User process class, holds information about the running process/thread. + /***********************************************************************************/ + class UserProcess final + { + public: + explicit UserProcess(); + ~UserProcess(); + + public: + NE_COPY_DEFAULT(UserProcess); + + public: + Char Name[kSchedNameLen] = {"Process"}; + ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid}; + User* Owner{nullptr}; + HAL::StackFramePtr StackFrame{nullptr}; + AffinityKind Affinity{AffinityKind::kStandard}; + ProcessStatusKind Status{ProcessStatusKind::kFinished}; + UInt8* StackReserve{nullptr}; + UserProcessImage Image{}; + SizeT StackSize{kSchedMaxStackSz}; + IDylibObject* DylibDelegate{nullptr}; + SizeT MemoryCursor{0UL}; + SizeT MemoryLimit{kSchedMaxMemoryLimit}; + SizeT UsedMemory{0UL}; + + struct ProcessMemoryHeapList final + { + VoidPtr MemoryEntry{nullptr}; + SizeT MemoryEntrySize{0UL}; + SizeT MemoryEntryPad{0UL}; + + struct ProcessMemoryHeapList* MemoryPrev{nullptr}; + struct ProcessMemoryHeapList* MemoryNext{nullptr}; + }; + + struct UserProcessSignal final + { + UIntPtr SignalArg; + ProcessStatusKind PreviousStatus; + UIntPtr SignalID; + }; + + UserProcessSignal ProcessSignal; + ProcessMemoryHeapList* ProcessMemoryHeap{nullptr}; + UserProcessTeam* ProcessParentTeam; + + VoidPtr VMRegister{0UL}; + + enum + { + kInvalidExecutableKind, + kExectuableKind, + kExectuableDylibKind, + kExectuableKindCount, + }; + + ProcessTime PTime{0}; //! @brief Process allocated tine. + + PID ProcessId{kSchedInvalidPID}; + Int32 Kind{kExectuableKind}; + + public: + /***********************************************************************************/ + //! @brief boolean operator, check status. + /***********************************************************************************/ + operator bool(); + + /***********************************************************************************/ + ///! @brief Crashes the app, exits with code ~0. + /***********************************************************************************/ + Void Crash(); + + /***********************************************************************************/ + ///! @brief Exits the app. + /***********************************************************************************/ + Void Exit(const Int32& exit_code = 0); + + /***********************************************************************************/ + ///! @brief TLS allocate. + ///! @param sz size of data structure. + ///! @param pad_amount amount to add after pointer. + ///! @return A wrapped pointer, or error code. + /***********************************************************************************/ + ErrorOr New(const SizeT& sz, const SizeT& pad_amount = 0); + + /***********************************************************************************/ + ///! @brief TLS free. + ///! @param ptr the pointer to free. + ///! @param sz the size of it. + /***********************************************************************************/ + template + Boolean Delete(ErrorOr ptr, const SizeT& sz); + + /***********************************************************************************/ + ///! @brief Wakes up thread. + /***********************************************************************************/ + Void Wake(const Bool wakeup = false); + + public: + /***********************************************************************************/ + //! @brief Gets the local exit code. + /***********************************************************************************/ + const UInt32& GetExitCode() noexcept; + + /***********************************************************************************/ + ///! @brief Get the process's name + ///! @example 'C Runtime Library' + /***********************************************************************************/ + const Char* GetName() noexcept; + + /***********************************************************************************/ + //! @brief return local error code of process. + //! @return Int32 local error code. + /***********************************************************************************/ + Int32& GetLocalCode() noexcept; + + const User* GetOwner() noexcept; + const ProcessStatusKind& GetStatus() noexcept; + const AffinityKind& GetAffinity() noexcept; + + private: + UInt32 fLastExitCode{0}; + Int32 fLocalCode{0}; + + friend UserProcessScheduler; + friend UserProcessHelper; + }; + + /// \brief Processs Team (contains multiple processes inside it.) + /// Equivalent to a process batch + class UserProcessTeam final + { + public: + explicit UserProcessTeam(); + ~UserProcessTeam() = default; + + NE_COPY_DEFAULT(UserProcessTeam); + + Array& AsArray(); + Ref& AsRef(); + ProcessID& Id() noexcept; + + public: + Array mProcessList; + Ref mCurrentProcess; + ProcessID mTeamId{0}; + ProcessID mProcessCount{0}; + }; + + typedef Array UserThreadArray; + + using UserProcessRef = UserProcess&; + + /***********************************************************************************/ + /// @brief Process scheduler class. + /// The main class which you call to schedule user processes. + /***********************************************************************************/ + class UserProcessScheduler final : public ISchedulable + { + friend class UserProcessHelper; + + public: + explicit UserProcessScheduler() = default; + ~UserProcessScheduler() override = default; + + NE_COPY_DEFAULT(UserProcessScheduler) + + operator bool(); + bool operator!(); + + public: + UserProcessTeam& CurrentTeam(); + + public: + ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image); + const Bool Remove(ProcessID process_id); + + const Bool IsUser() override; + const Bool IsKernel() override; + const Bool HasMP() override; + + public: + Ref& CurrentProcess(); + const SizeT Run() noexcept; + + public: + STATIC UserProcessScheduler& The(); + + private: + UserProcessTeam mTeam{}; + }; + + /***********************************************************************************/ + /** + * \brief UserProcess helper class, which contains needed utilities for the scheduler. + */ + /***********************************************************************************/ + + class UserProcessHelper final + { + public: + STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, const PID& new_pid); + STATIC Bool CanBeScheduled(const UserProcess& process); + STATIC ErrorOr TheCurrentPID(); + STATIC SizeT StartScheduling(); + }; + + const UInt32& sched_get_exit_code(void) noexcept; +} // namespace Kernel + +#include +#include + +//////////////////////////////////////////////////// +// END +//////////////////////////////////////////////////// + +#endif /* ifndef INC_PROCESS_SCHEDULER_H */ diff --git a/dev/kernel/KernelKit/ProcessScheduler.inl b/dev/kernel/KernelKit/ProcessScheduler.inl new file mode 100644 index 00000000..b624e623 --- /dev/null +++ b/dev/kernel/KernelKit/ProcessScheduler.inl @@ -0,0 +1,62 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + + FILE: ProcessScheduler.inl + PURPOSE: Low level/Ring-3 Process scheduler. + +------------------------------------------- */ + +namespace Kernel +{ + /***********************************************************************************/ + /** @brief Free pointer from usage. */ + /***********************************************************************************/ + + template + Boolean UserProcess::Delete(ErrorOr ptr, const SizeT& sz) + { + if (!ptr) + return No; + + if (!this->ProcessMemoryHeap) + { + kout << "Process's heap is empty.\r"; + return No; + } + + ProcessMemoryHeapList* entry = this->ProcessMemoryHeap; + + while (entry != nullptr) + { + if (entry->MemoryEntry == ptr.Leak().Leak()) + { + this->UsedMemory -= entry->MemoryEntrySize; + +#ifdef __NE_AMD64__ + auto pd = hal_read_cr3(); + + hal_write_cr3(this->VMRegister); + + auto ret = mm_delete_heap(entry->MemoryEntry); + + hal_write_cr3(pd); + + return ret == kErrorSuccess; +#else + Bool ret = mm_delete_heap(ptr.Leak().Leak()); + + return ret == kErrorSuccess; +#endif + } + + entry = entry->MemoryNext; + } + + kout << "Invalid Pointer: Trying to free a pointer which doesn't exist.\r"; + + this->Crash(); + + return No; + } +} // namespace Kernel diff --git a/dev/kernel/KernelKit/ThreadLocalStorage.inl b/dev/kernel/KernelKit/ThreadLocalStorage.inl index 0517dada..f9f9da12 100644 --- a/dev/kernel/KernelKit/ThreadLocalStorage.inl +++ b/dev/kernel/KernelKit/ThreadLocalStorage.inl @@ -8,7 +8,7 @@ //! @brief Allocate resources from the process's heap storage. #ifndef INC_PROCESS_SCHEDULER_H -#include +#include #endif template diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h deleted file mode 100644 index b9c1676b..00000000 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ /dev/null @@ -1,379 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. - -------------------------------------------- */ - -#ifndef INC_PROCESS_SCHEDULER_H -#define INC_PROCESS_SCHEDULER_H - -#include -#include -#include -#include - -#define kSchedMinMicroTime (AffinityKind::kStandard) -#define kSchedInvalidPID ((PID)~0) -#define kSchedProcessLimitPerTeam (32U) - -#define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ -#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ - -#define kSchedNameLen (128U) - -//////////////////////////////////////////////////// -// Last revision date is: Fri Mar 28 2025 // -//////////////////////////////////////////////////// - -namespace Kernel -{ - //! @note Forward class declaration. - - class IDylibObject; - class UserProcess; - class UserProcessTeam; - class UserProcessScheduler; - class UserProcessHelper; - - typedef UInt64 PTime; - - /***********************************************************************************/ - //! @brief Local Process identifier. - /***********************************************************************************/ - typedef Int64 ProcessID; - - /***********************************************************************************/ - //! @brief Local Process status enum. - /***********************************************************************************/ - enum class ProcessStatusKind : Int32 - { - kInvalid, - kStarting, - kRunning, - kKilled, - kFrozen, - kFinished, - kCount, - }; - - /***********************************************************************************/ - //! @brief Affinity is the amount of nano-seconds this process is going to run. - /***********************************************************************************/ - enum class AffinityKind : Int32 - { - kRealTime = 500, - kVeryHigh = 250, - kHigh = 200, - kStandard = 1000, - kLowUsage = 1500, - kVeryLowUsage = 2000, - }; - - /***********************************************************************************/ - //! Operators for AffinityKind - /***********************************************************************************/ - - inline bool operator<(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int < rhs_int; - } - - inline bool operator>(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int > rhs_int; - } - - inline bool operator<=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int <= rhs_int; - } - - inline bool operator>=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int >= rhs_int; - } - - /***********************************************************************************/ - /// @brief Subsystem enum type. - /***********************************************************************************/ - - enum class ProcessSubsystem : Int32 - { - kProcessSubsystemSecurity = 100, - kProcessSubsystemApplication, - kProcessSubsystemService, - kProcessSubsystemDriver, - kProcessSubsystemInvalid = 256U, - kProcessSubsystemCount = 4, - }; - - using ProcessTime = UInt64; - using PID = UInt64; - - /***********************************************************************************/ - /// @note For User manager, tells where we run the code. - /***********************************************************************************/ - enum class ProcessLevelRing : Int32 - { - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 5, - }; - - /***********************************************************************************/ - /// @brief Helper type to describe a code image. - /***********************************************************************************/ - using ImagePtr = VoidPtr; - - struct UserProcessImage final - { - explicit UserProcessImage() = default; - - ImagePtr fCode; - ImagePtr fBlob; - - Bool HasCode() - { - return this->fCode != nullptr; - } - - Bool HasImage() - { - return this->fBlob != nullptr; - } - }; - - /***********************************************************************************/ - /// @name UserProcess - /// @brief User process class, holds information about the running process/thread. - /***********************************************************************************/ - class UserProcess final - { - public: - explicit UserProcess(); - ~UserProcess(); - - public: - NE_COPY_DEFAULT(UserProcess); - - public: - Char Name[kSchedNameLen] = {"Process"}; - ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid}; - User* Owner{nullptr}; - HAL::StackFramePtr StackFrame{nullptr}; - AffinityKind Affinity{AffinityKind::kStandard}; - ProcessStatusKind Status{ProcessStatusKind::kFinished}; - UInt8* StackReserve{nullptr}; - UserProcessImage Image{}; - SizeT StackSize{kSchedMaxStackSz}; - IDylibObject* DylibDelegate{nullptr}; - SizeT MemoryCursor{0UL}; - SizeT MemoryLimit{kSchedMaxMemoryLimit}; - SizeT UsedMemory{0UL}; - - struct ProcessMemoryHeapList final - { - VoidPtr MemoryEntry{nullptr}; - SizeT MemoryEntrySize{0UL}; - SizeT MemoryEntryPad{0UL}; - - struct ProcessMemoryHeapList* MemoryPrev{nullptr}; - struct ProcessMemoryHeapList* MemoryNext{nullptr}; - }; - - struct UserProcessSignal final - { - UIntPtr SignalArg; - ProcessStatusKind PreviousStatus; - UIntPtr SignalID; - }; - - UserProcessSignal ProcessSignal; - ProcessMemoryHeapList* ProcessMemoryHeap{nullptr}; - UserProcessTeam* ProcessParentTeam; - - VoidPtr VMRegister{0UL}; - - enum - { - kInvalidExecutableKind, - kExectuableKind, - kExectuableDylibKind, - kExectuableKindCount, - }; - - ProcessTime PTime{0}; //! @brief Process allocated tine. - - PID ProcessId{kSchedInvalidPID}; - Int32 Kind{kExectuableKind}; - - public: - /***********************************************************************************/ - //! @brief boolean operator, check status. - /***********************************************************************************/ - operator bool(); - - /***********************************************************************************/ - ///! @brief Crashes the app, exits with code ~0. - /***********************************************************************************/ - Void Crash(); - - /***********************************************************************************/ - ///! @brief Exits the app. - /***********************************************************************************/ - Void Exit(const Int32& exit_code = 0); - - /***********************************************************************************/ - ///! @brief TLS allocate. - ///! @param sz size of data structure. - ///! @param pad_amount amount to add after pointer. - ///! @return A wrapped pointer, or error code. - /***********************************************************************************/ - ErrorOr New(const SizeT& sz, const SizeT& pad_amount = 0); - - /***********************************************************************************/ - ///! @brief TLS free. - ///! @param ptr the pointer to free. - ///! @param sz the size of it. - /***********************************************************************************/ - template - Boolean Delete(ErrorOr ptr, const SizeT& sz); - - /***********************************************************************************/ - ///! @brief Wakes up thread. - /***********************************************************************************/ - Void Wake(const Bool wakeup = false); - - public: - /***********************************************************************************/ - //! @brief Gets the local exit code. - /***********************************************************************************/ - const UInt32& GetExitCode() noexcept; - - /***********************************************************************************/ - ///! @brief Get the process's name - ///! @example 'C Runtime Library' - /***********************************************************************************/ - const Char* GetName() noexcept; - - /***********************************************************************************/ - //! @brief return local error code of process. - //! @return Int32 local error code. - /***********************************************************************************/ - Int32& GetLocalCode() noexcept; - - const User* GetOwner() noexcept; - const ProcessStatusKind& GetStatus() noexcept; - const AffinityKind& GetAffinity() noexcept; - - private: - UInt32 fLastExitCode{0}; - Int32 fLocalCode{0}; - - friend UserProcessScheduler; - friend UserProcessHelper; - }; - - /// \brief Processs Team (contains multiple processes inside it.) - /// Equivalent to a process batch - class UserProcessTeam final - { - public: - explicit UserProcessTeam(); - ~UserProcessTeam() = default; - - NE_COPY_DEFAULT(UserProcessTeam); - - Array& AsArray(); - Ref& AsRef(); - ProcessID& Id() noexcept; - - public: - Array mProcessList; - Ref mCurrentProcess; - ProcessID mTeamId{0}; - ProcessID mProcessCount{0}; - }; - - typedef Array UserThreadArray; - - using UserProcessRef = UserProcess&; - - /***********************************************************************************/ - /// @brief Process scheduler class. - /// The main class which you call to schedule user processes. - /***********************************************************************************/ - class UserProcessScheduler final : public ISchedulable - { - friend class UserProcessHelper; - - public: - explicit UserProcessScheduler() = default; - ~UserProcessScheduler() override = default; - - NE_COPY_DEFAULT(UserProcessScheduler) - - operator bool(); - bool operator!(); - - public: - UserProcessTeam& CurrentTeam(); - - public: - ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image); - const Bool Remove(ProcessID process_id); - - const Bool IsUser() override; - const Bool IsKernel() override; - const Bool HasMP() override; - - public: - Ref& CurrentProcess(); - const SizeT Run() noexcept; - - public: - STATIC UserProcessScheduler& The(); - - private: - UserProcessTeam mTeam{}; - }; - - /***********************************************************************************/ - /** - * \brief UserProcess helper class, which contains needed utilities for the scheduler. - */ - /***********************************************************************************/ - - class UserProcessHelper final - { - public: - STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, const PID& new_pid); - STATIC Bool CanBeScheduled(const UserProcess& process); - STATIC ErrorOr TheCurrentPID(); - STATIC SizeT StartScheduling(); - }; - - const UInt32& sched_get_exit_code(void) noexcept; -} // namespace Kernel - -#include -#include - -//////////////////////////////////////////////////// -// END -//////////////////////////////////////////////////// - -#endif /* ifndef INC_PROCESS_SCHEDULER_H */ diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl deleted file mode 100644 index 4b3d5820..00000000 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ /dev/null @@ -1,62 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. - - FILE: UserProcessScheduler.inl - PURPOSE: Low level/Ring-3 Process scheduler. - -------------------------------------------- */ - -namespace Kernel -{ - /***********************************************************************************/ - /** @brief Free pointer from usage. */ - /***********************************************************************************/ - - template - Boolean UserProcess::Delete(ErrorOr ptr, const SizeT& sz) - { - if (!ptr) - return No; - - if (!this->ProcessMemoryHeap) - { - kout << "Process Memory is empty.\r"; - return No; - } - - ProcessMemoryHeapList* entry = this->ProcessMemoryHeap; - - while (entry != nullptr) - { - if (entry->MemoryEntry == ptr.Leak().Leak()) - { - this->UsedMemory -= entry->MemoryEntrySize; - -#ifdef __NE_AMD64__ - auto pd = hal_read_cr3(); - - hal_write_cr3(this->VMRegister); - - auto ret = mm_delete_heap(entry->MemoryEntry); - - hal_write_cr3(pd); - - return ret == kErrorSuccess; -#else - Bool ret = mm_delete_heap(ptr.Leak().Leak()); - - return ret == kErrorSuccess; -#endif - } - - entry = entry->MemoryNext; - } - - kout << "Invalid Pointer: Trying to free a pointer which doesn't exist.\r"; - - this->Crash(); - - return No; - } -} // namespace Kernel diff --git a/dev/kernel/KernelKit/XCOFF.h b/dev/kernel/KernelKit/XCOFF.h index d38c2e02..eb536c01 100644 --- a/dev/kernel/KernelKit/XCOFF.h +++ b/dev/kernel/KernelKit/XCOFF.h @@ -16,18 +16,19 @@ #include -#define kXCOFF64Magic (0x01F7) +#define kXCOFF64Magic (0x01F7) +#define kXCOFF64ForkNameLen (256U) #define kXCOFFRelFlg (0x0001) #define kXCOFFExecutable (0x0002) #define kXCOFFLnno (0x0004) #define kXCOFFLSyms (0x0008) -struct XCoffFileHeader; -struct XCoffForkHeader; +struct XCOFF_FILE_HEADER; +struct XCOFF_FORK_HEADER; /// @brief XCoff file header, meant for POWER apps. -typedef struct XCoffFileHeader +typedef struct XCOFF_FILE_HEADER { Kernel::UInt16 fMagic; Kernel::UInt16 fTarget; @@ -36,16 +37,17 @@ typedef struct XCoffFileHeader Kernel::UIntPtr fSymPtr; Kernel::UInt32 fNumSyms; Kernel::UInt16 fOptHdr; // ?: Number of bytes in optional header -} XCoffFileHeader64; +} XCOFF_FILE_HEADER, XCOFF_FILE_HEADER32, XCOFF_FILE_HEADER64; -#define kForkNameLen (256U) - -/// @brief This the executable manifest fork. -typedef struct XCoffForkHeader +/// @brief This the executable's manifest fork, designed for NeFS. +/// @param fPropertiesXMLFork The XML fork of the executable. +/// @param fDynamicLoaderFork The DYLD fork metadata. +/// @param fCodeSignFork Executable's certificate contained in a fork. +typedef struct XCOFF_FORK_HEADER { - Kernel::Char fPropertiesXMLFork[kForkNameLen]; - Kernel::Char fDynamicLoaderFork[kForkNameLen]; - Kernel::Char fCodeSignFork[kForkNameLen]; -} XCoffForkHeader; + Kernel::Char fPropertiesXMLFork[kXCOFF64ForkNameLen]; + Kernel::Char fDynamicLoaderFork[kXCOFF64ForkNameLen]; + Kernel::Char fCodeSignFork[kXCOFF64ForkNameLen]; +} XCOFF_FORK_HEADER; #endif // ifndef INC_XOCFF_H -- cgit v1.2.3