summaryrefslogtreecommitdiffhomepage
path: root/src/kernel/KernelKit
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-11-23 21:06:27 -0500
committerGitHub <noreply@github.com>2025-11-23 21:06:27 -0500
commit23040fad647634c08697451fc22ee2ca999629c8 (patch)
tree72888f88c7728c82f3f6df1f4f70591de15eab36 /src/kernel/KernelKit
parente5cc7351f0577b54c528fb827a7c7e6306c3e843 (diff)
parent83d870e58457a1d335a1d9b9966a6a1887cc297b (diff)
Merge pull request #81 from nekernel-org/dev
feat! breaking changes on kernel sources.
Diffstat (limited to 'src/kernel/KernelKit')
-rw-r--r--src/kernel/KernelKit/BinaryMutex.h39
-rw-r--r--src/kernel/KernelKit/CodeMgr.h49
-rw-r--r--src/kernel/KernelKit/CoreProcessScheduler.h273
-rw-r--r--src/kernel/KernelKit/DebugOutput.h207
-rw-r--r--src/kernel/KernelKit/Defines.h19
-rw-r--r--src/kernel/KernelKit/DeviceMgr.h129
-rw-r--r--src/kernel/KernelKit/DriveMgr.h175
-rw-r--r--src/kernel/KernelKit/FileMgr.h445
-rw-r--r--src/kernel/KernelKit/HardwareThreadScheduler.h135
-rw-r--r--src/kernel/KernelKit/HeapMgr.h58
-rw-r--r--src/kernel/KernelKit/HeapMgr.inl35
-rw-r--r--src/kernel/KernelKit/IDylibObject.h45
-rw-r--r--src/kernel/KernelKit/IFS.h25
-rw-r--r--src/kernel/KernelKit/ILoader.h32
-rw-r--r--src/kernel/KernelKit/IPEFDylibObject.h86
-rw-r--r--src/kernel/KernelKit/KPC.h78
-rw-r--r--src/kernel/KernelKit/KernelTaskScheduler.h47
-rw-r--r--src/kernel/KernelKit/LockDelegate.h58
-rw-r--r--src/kernel/KernelKit/MSDOS.h51
-rw-r--r--src/kernel/KernelKit/PCI/DMA.h75
-rw-r--r--src/kernel/KernelKit/PCI/DMA.inl17
-rw-r--r--src/kernel/KernelKit/PCI/Database.h51
-rw-r--r--src/kernel/KernelKit/PCI/Device.h73
-rw-r--r--src/kernel/KernelKit/PCI/Express.h12
-rw-r--r--src/kernel/KernelKit/PCI/IO.h63
-rw-r--r--src/kernel/KernelKit/PCI/IOArray+AMD64.inl49
-rw-r--r--src/kernel/KernelKit/PCI/Iterator.h41
-rw-r--r--src/kernel/KernelKit/PCI/PCI.h54
-rw-r--r--src/kernel/KernelKit/PE.h130
-rw-r--r--src/kernel/KernelKit/PE32CodeMgr.h91
-rw-r--r--src/kernel/KernelKit/PEF.h117
-rw-r--r--src/kernel/KernelKit/PEFCodeMgr.h75
-rw-r--r--src/kernel/KernelKit/ProcessScheduler.h18
-rw-r--r--src/kernel/KernelKit/Semaphore.h110
-rw-r--r--src/kernel/KernelKit/ThreadLocalStorage.h68
-rw-r--r--src/kernel/KernelKit/ThreadLocalStorage.inl89
-rw-r--r--src/kernel/KernelKit/Timer.h75
-rw-r--r--src/kernel/KernelKit/TraceSrv.h22
-rw-r--r--src/kernel/KernelKit/UserMgr.h95
-rw-r--r--src/kernel/KernelKit/UserProcessScheduler.h243
-rw-r--r--src/kernel/KernelKit/UserProcessScheduler.inl64
-rw-r--r--src/kernel/KernelKit/XCOFF.h51
-rw-r--r--src/kernel/KernelKit/ZXD.h53
43 files changed, 3722 insertions, 0 deletions
diff --git a/src/kernel/KernelKit/BinaryMutex.h b/src/kernel/KernelKit/BinaryMutex.h
new file mode 100644
index 00000000..5431ab72
--- /dev/null
+++ b/src/kernel/KernelKit/BinaryMutex.h
@@ -0,0 +1,39 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+class USER_PROCESS;
+
+/// @brief Access control class, which locks a task until one is done.
+class BinaryMutex final {
+ public:
+ explicit BinaryMutex() = default;
+ ~BinaryMutex() = default;
+
+ public:
+ bool IsLocked() const;
+ bool Unlock() noexcept;
+
+ public:
+ BOOL WaitForProcess(const UInt32& sec) noexcept;
+
+ public:
+ bool Lock(USER_PROCESS* process);
+ bool LockAndWait(USER_PROCESS* process, TimerInterface* timer);
+
+ public:
+ NE_COPY_DEFAULT(BinaryMutex)
+
+ private:
+ USER_PROCESS* fLockingProcess{nullptr};
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/CodeMgr.h b/src/kernel/KernelKit/CodeMgr.h
new file mode 100644
index 00000000..e537b26d
--- /dev/null
+++ b/src/kernel/KernelKit/CodeMgr.h
@@ -0,0 +1,49 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: CodeMgr.h
+ Purpose: Code Mgr.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+ 3/8/24: Add UPP struct.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/CoreProcessScheduler.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <KernelKit/PE32CodeMgr.h>
+#include <KernelKit/PEFCodeMgr.h>
+
+/// @file CodeMgr.h
+/// @brief Code Manager header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+namespace Kernel {
+/// @brief Main process entrypoint.
+typedef void (*rtl_main_kind)(void);
+
+/// @brief C++ Constructor entrypoint.
+typedef void (*rtl_cxx_ctor_kind)(void);
+
+/// @brief C++ Destructor entrypoint.
+typedef void (*rtl_cxx_dtor_kind)(void);
+
+/// @brief Executes a new process from a function. Kernel 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.
+BOOL rtl_create_kernel_task(HAL::StackFramePtr main, const KID kid) 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/src/kernel/KernelKit/CoreProcessScheduler.h b/src/kernel/KernelKit/CoreProcessScheduler.h
new file mode 100644
index 00000000..54a0614a
--- /dev/null
+++ b/src/kernel/KernelKit/CoreProcessScheduler.h
@@ -0,0 +1,273 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+
+/// @file CoreProcessScheduler.h
+/// @brief Core Process Scheduler header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#define kSchedMinMicroTime (AffinityKind::kStandard)
+#define kSchedInvalidPID (-1)
+#define kSchedProcessLimitPerTeam (32U)
+#define kSchedTeamCount (256U)
+
+#define kSchedMaxMemoryLimit (gib_cast(128)) /* max physical memory limit */
+#define kSchedMaxStackSz (kib_cast(8)) /* maximum stack size */
+
+#define kSchedNameLen (128U)
+
+EXTERN_C void sched_idle_task(void);
+
+namespace Kernel {
+class USER_PROCESS;
+class KERNEL_TASK;
+class KernelTaskScheduler;
+class UserProcessScheduler;
+class UserProcessTeam;
+
+template <typename T>
+struct PROCESS_HEAP_TREE;
+
+template <typename T>
+struct PROCESS_SPECIAL_TREE;
+
+template <typename T>
+struct PROCESS_FILE_TREE;
+
+enum {
+ kInvalidTreeKind = 0U,
+ kRedTreeKind = 100U,
+ kBlackTreeKind = 101U,
+ kTreeKindCount = 3U,
+};
+
+template <typename T>
+struct PROCESS_HEAP_TREE {
+ static constexpr auto kHeap = true;
+ static constexpr auto kFile = false;
+ static constexpr auto kSpecial = false;
+
+ T Entry{nullptr};
+ SizeT EntrySize{0UL};
+ SizeT EntryPad{0UL};
+
+ UInt32 Color{kBlackTreeKind};
+
+ struct PROCESS_HEAP_TREE<T>* Parent {
+ nullptr
+ };
+ struct PROCESS_HEAP_TREE<T>* Child {
+ nullptr
+ };
+
+ struct PROCESS_HEAP_TREE<T>* Prev {
+ nullptr
+ };
+ struct PROCESS_HEAP_TREE<T>* Next {
+ nullptr
+ };
+};
+
+template <typename T>
+struct PROCESS_FILE_TREE {
+ static constexpr auto kHeap = false;
+ static constexpr auto kFile = true;
+ static constexpr auto kSpecial = false;
+
+ T Entry{nullptr};
+ SizeT EntrySize{0UL};
+ SizeT EntryPad{0UL};
+
+ UInt32 Color{kBlackTreeKind};
+
+ struct PROCESS_FILE_TREE<T>* Parent {
+ nullptr
+ };
+
+ struct PROCESS_FILE_TREE<T>* Child {
+ nullptr
+ };
+
+ struct PROCESS_FILE_TREE<T>* Prev {
+ nullptr
+ };
+
+ struct PROCESS_FILE_TREE<T>* Next {
+ nullptr
+ };
+};
+
+using ProcessCtx = UInt32;
+
+template <typename T>
+struct PROCESS_SPECIAL_TREE {
+ static constexpr auto kHeap = false;
+ static constexpr auto kFile = false;
+ static constexpr auto kSpecial = true;
+
+ T Entry{nullptr};
+ SizeT EntrySize{0UL};
+ SizeT EntryPad{0UL};
+
+ /// @brief a context is where the resource comes from.
+ ProcessCtx EntryContext{0UL}; // could be a socket, printer, device...
+
+ UInt32 Color{kBlackTreeKind};
+
+ struct PROCESS_SPECIAL_TREE<T>* Parent {
+ nullptr
+ };
+
+ struct PROCESS_SPECIAL_TREE<T>* Child {
+ nullptr
+ };
+
+ struct PROCESS_SPECIAL_TREE<T>* Prev {
+ nullptr
+ };
+
+ struct PROCESS_SPECIAL_TREE<T>* Next {
+ nullptr
+ };
+};
+
+/***********************************************************************************/
+/// @brief Subsystem enum type.
+/***********************************************************************************/
+
+enum class ProcessSubsystem : Int32 {
+ kProcessSubsystemSecurity = 100,
+ kProcessSubsystemUser,
+ kProcessSubsystemService,
+ kProcessSubsystemDriver,
+ kProcessSubsystemKernel,
+ kProcessSubsystemCount = kProcessSubsystemKernel - kProcessSubsystemSecurity + 1,
+ kProcessSubsystemInvalid = 0xFFFFFFF,
+};
+
+/***********************************************************************************/
+//! @brief Local Process status enum.
+/***********************************************************************************/
+enum class ProcessStatusKind : Int32 {
+ kInvalid = 0,
+ kStarting = 100,
+ kRunning,
+ kKilled,
+ kFrozen,
+ kFinished,
+ kCount = kFinished - kStarting + 1,
+};
+
+/***********************************************************************************/
+//! @brief Affinity is the amount of nano-seconds this process is going to run.
+/***********************************************************************************/
+enum class AffinityKind : Int32 {
+ kInvalid = 0,
+ kRealTime = 100,
+ kVeryHigh = 150,
+ kHigh = 200,
+ kStandard = 1000,
+ kLowUsage = 1500,
+ kVeryLowUsage = 2000,
+};
+
+/***********************************************************************************/
+//! Operators for AffinityKind
+/***********************************************************************************/
+
+inline bool operator<(AffinityKind lhs, AffinityKind rhs) {
+ Int32 lhs_int = static_cast<Int32>(lhs);
+ Int32 rhs_int = static_cast<Int32>(rhs);
+
+ return lhs_int < rhs_int;
+}
+
+inline bool operator>(AffinityKind lhs, AffinityKind rhs) {
+ Int32 lhs_int = static_cast<Int32>(lhs);
+ Int32 rhs_int = static_cast<Int32>(rhs);
+
+ return lhs_int > rhs_int;
+}
+
+inline bool operator<=(AffinityKind lhs, AffinityKind rhs) {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int32>(rhs);
+
+ return lhs_int <= rhs_int;
+}
+
+inline bool operator>=(AffinityKind lhs, AffinityKind rhs) {
+ Int32 lhs_int = static_cast<Int32>(lhs);
+ Int32 rhs_int = static_cast<Int32>(rhs);
+
+ return lhs_int >= rhs_int;
+}
+
+using PTime = UInt64;
+using ProcessTime = PTime;
+
+/***********************************************************************************/
+//! @brief Local Process Identifier type.
+/***********************************************************************************/
+using ProcessID = Int64;
+
+/***********************************************************************************/
+/// @note For User manager, tells where we run the code.
+/***********************************************************************************/
+enum class ProcessLevelRing : Int32 {
+ kRingStdUser = 1,
+ kRingSuperUser = 2,
+ kRingGuestUser = 5,
+ kRingCount = 3,
+};
+
+/***********************************************************************************/
+/// @brief Helper type to describe a code image.
+/***********************************************************************************/
+using ImagePtr = VoidPtr;
+
+/***********************************************************************************/
+/// @brief Helper class to contain a process's image and blob.
+/***********************************************************************************/
+struct ProcessImage final {
+ explicit ProcessImage() = default;
+
+ private:
+ friend USER_PROCESS;
+ friend KERNEL_TASK;
+
+ friend UserProcessScheduler;
+ friend KernelTaskScheduler;
+
+ ImagePtr fCode{};
+ ImagePtr fBlob{};
+
+ public:
+ Bool HasCode() const { return this->fCode != nullptr; }
+
+ Bool HasImage() const { return this->fBlob != nullptr; }
+
+ ErrorOr<ImagePtr> LeakImage() {
+ if (this->fCode) {
+ return ErrorOr<ImagePtr>{this->fCode};
+ }
+
+ return ErrorOr<ImagePtr>{kErrorInvalidData};
+ }
+
+ ErrorOr<ImagePtr> LeakBlob() {
+ if (this->fBlob) {
+ return ErrorOr<ImagePtr>{this->fBlob};
+ }
+
+ return ErrorOr<ImagePtr>{kErrorInvalidData};
+ }
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/DebugOutput.h b/src/kernel/KernelKit/DebugOutput.h
new file mode 100644
index 00000000..3f9b5125
--- /dev/null
+++ b/src/kernel/KernelKit/DebugOutput.h
@@ -0,0 +1,207 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DeviceMgr.h>
+#include <NeKit/OwnPtr.h>
+#include <NeKit/Stream.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+class TerminalDevice;
+class DTraceDevice;
+class NeTraceDevice;
+class Utf8TerminalDevice;
+
+inline TerminalDevice end_line();
+inline TerminalDevice number(const Long& x);
+inline TerminalDevice hex_number(const Long& x);
+
+// @brief Emulates a VT100 terminal.
+class TerminalDevice final NE_DEVICE<const Char*> {
+ public:
+ TerminalDevice(void (*print)(DeviceInterface*, const Char*),
+ void (*gets)(DeviceInterface*, const Char*))
+ : DeviceInterface<const Char*>(print, gets) {}
+
+ ~TerminalDevice() override;
+
+ /// @brief returns device name (terminal name)
+ /// @return string type (const Char*)
+ const Char* Name() const override { return ("TerminalDevice"); }
+
+ NE_COPY_DEFAULT(TerminalDevice)
+
+ STATIC TerminalDevice The() noexcept;
+};
+
+class Utf8TerminalDevice final NE_DEVICE<const Utf8Char*> {
+ public:
+ Utf8TerminalDevice(void (*print)(DeviceInterface*, const Utf8Char*),
+ void (*gets)(DeviceInterface*, const Utf8Char*))
+ : DeviceInterface<const Utf8Char*>(print, gets) {}
+
+ ~Utf8TerminalDevice() override;
+
+ /// @brief returns device name (terminal name)
+ /// @return string type (const Char*)
+ const Char* Name() const override { return ("Utf8TerminalDevice"); }
+
+ NE_COPY_DEFAULT(Utf8TerminalDevice)
+
+ STATIC Utf8TerminalDevice The() noexcept;
+};
+
+inline TerminalDevice end_line() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\r");
+ return self;
+}
+
+inline Utf8TerminalDevice utf_end_line() {
+ Utf8TerminalDevice self = Utf8TerminalDevice::The();
+
+ self.operator<<(u8"\r");
+ return self;
+}
+
+inline TerminalDevice carriage_return() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\r");
+ return self;
+}
+
+inline TerminalDevice tabulate() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\t");
+ return self;
+}
+
+/// @brief emulate a terminal bell, like the VT100 does.
+inline TerminalDevice bell() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\a");
+ return self;
+}
+
+namespace Detail {
+ inline TerminalDevice _write_number(const Long& x, TerminalDevice& term) {
+ UInt64 y = (x > 0 ? x : -x) / 10;
+ UInt64 h = (x > 0 ? x : -x) % 10;
+
+ if (y) _write_number(y, term);
+
+ /* fail if the number is not base-10 */
+ if (h > 10) {
+ _write_number('?', term);
+ return term;
+ }
+
+ if (y == ~0UL) y = -y;
+
+ const Char kNumbers[11] = "0123456789";
+
+ Char buf[2];
+ buf[0] = kNumbers[h];
+ buf[1] = 0;
+
+ term.operator<<(buf);
+ return term;
+ }
+
+ inline TerminalDevice _write_number_hex(const Long& x, TerminalDevice& term) {
+ UInt64 y = (x > 0 ? x : -x) / 16;
+ UInt64 h = (x > 0 ? x : -x) % 16;
+
+ if (y) _write_number_hex(y, term);
+
+ /* fail if the hex number is not base-16 */
+ if (h > 16) {
+ _write_number_hex('?', term);
+ return term;
+ }
+
+ if (y == ~0UL) y = -y;
+
+ const Char kNumbers[17] = "0123456789ABCDEF";
+
+ Char buf[2];
+ buf[0] = kNumbers[h];
+ buf[1] = 0;
+
+ term.operator<<(buf);
+ return term;
+ }
+} // namespace Detail
+
+inline TerminalDevice hex_number(const Long& x) {
+ TerminalDevice self = TerminalDevice::The();
+
+ self << "0x";
+ Detail::_write_number_hex(x, self);
+
+ return self;
+}
+
+inline TerminalDevice number(const Long& x) {
+ TerminalDevice self = TerminalDevice::The();
+
+ Detail::_write_number(x, self);
+
+ return self;
+}
+
+inline TerminalDevice get_console_in(Char* buf) {
+ TerminalDevice self = TerminalDevice::The();
+
+ self >> buf;
+
+ return self;
+}
+
+inline constexpr auto kDebugPort = 51820;
+inline constexpr auto kDebugMagic = "VMK1.0.0;";
+inline constexpr auto kDebugVersion = 0x0100;
+
+inline constexpr SizeT kDebugCmdLen = 256U;
+
+typedef Char rt_debug_cmd[kDebugCmdLen];
+
+inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) {
+ src = number(num);
+ return src;
+}
+} // namespace Kernel
+
+#ifdef kout
+#undef kout
+#endif // ifdef kout
+
+#define kout TerminalDevice::The()
+
+#ifdef kendl
+#undef kendl
+#endif // ifdef kendl
+
+#define kendl end_line()
+
+#ifdef kout8
+#undef kout8
+#endif // ifdef kout8
+
+#define kout8 Utf8TerminalDevice::The()
+
+#ifdef kendl8
+#undef kendl8
+#endif // ifdef kendl8
+
+#define kendl8 utf_end_line()
diff --git a/src/kernel/KernelKit/Defines.h b/src/kernel/KernelKit/Defines.h
new file mode 100644
index 00000000..e88441d2
--- /dev/null
+++ b/src/kernel/KernelKit/Defines.h
@@ -0,0 +1,19 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define KERNELKIT_VERSION "0.0.1-kernelkit"
+#define KERNELKIT_VERSION_BCD 0x0001
+
+namespace Kernel {
+class UserProcessScheduler;
+class IDylibObject;
+class USER_PROCESS;
+class KERNEL_TASK;
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/DeviceMgr.h b/src/kernel/KernelKit/DeviceMgr.h
new file mode 100644
index 00000000..1dbad161
--- /dev/null
+++ b/src/kernel/KernelKit/DeviceMgr.h
@@ -0,0 +1,129 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/* ========================================
+
+ Revision History:
+
+ 31/01/24: Add kDeviceCnt (amlel)
+ 15/11/24: Add NE_DEVICE macro, to inherit from device object.
+
+ ======================================== */
+
+#pragma once
+
+/* @note Device Mgr. */
+/* @file KernelKit/DeviceMgr.h */
+/* @brief Device abstraction and I/O buffer. */
+
+#include <NeKit/ErrorOr.h>
+#include <NeKit/Ref.h>
+
+#define kDeviceMgrRootDirPath "/devices/"
+
+#define NE_DEVICE : public ::Kernel::DeviceInterface
+
+// Last Rev: Wed, May 27, 2025 6:22 PM
+
+namespace Kernel {
+template <typename T>
+class DeviceInterface;
+
+template <typename T>
+class IOBuf;
+
+/***********************************************************************************/
+/// @brief Device contract interface, represents an HW device.
+/***********************************************************************************/
+template <typename T>
+class DeviceInterface {
+ public:
+ DeviceInterface() = default;
+
+ explicit DeviceInterface(void (*Out)(DeviceInterface<T>*, T), void (*In)(DeviceInterface<T>*, T))
+ : fOut(Out), fIn(In) {}
+
+ virtual ~DeviceInterface() = default;
+
+ public:
+ DeviceInterface& operator=(const DeviceInterface<T>&) = default;
+ DeviceInterface(const DeviceInterface<T>&) = default;
+
+ public:
+ virtual DeviceInterface<T>& operator<<(T Data) {
+ fOut(this, Data);
+ return *this;
+ }
+
+ virtual DeviceInterface<T>& operator>>(T Data) {
+ fIn(this, Data);
+ return *this;
+ }
+
+ virtual const char* Name() const { return "/devices/null"; }
+
+ operator bool() { return fOut && fIn; }
+
+ Bool operator!() { return !fOut || !fIn; }
+
+ protected:
+ Void (*fOut)(DeviceInterface<T>*, T Data) = {nullptr};
+ Void (*fIn)(DeviceInterface<T>*, T Data) = {nullptr};
+};
+
+///
+/// @brief Input Output abstract class.
+/// Used mainly to communicate between OS to hardware.
+///
+template <typename T>
+class IOBuf final {
+ public:
+ explicit IOBuf(T dma_addr) : fData(dma_addr) {
+ // At least pass something valid when instancating this struct.
+ MUST_PASS(fData);
+ }
+
+ IOBuf& operator=(const IOBuf<T>&) = default;
+ IOBuf(const IOBuf<T>&) = default;
+
+ ~IOBuf() = default;
+
+ public:
+ template <typename R>
+ R operator->() const {
+ return fData;
+ }
+
+ template <typename R>
+ R& operator[](Size index) const {
+ return fData[index];
+ }
+
+ private:
+ T fData;
+};
+
+///! @brief Device enum types.
+enum {
+ kDeviceTypeInvalid = 0,
+ kDeviceTypeIDE = 100,
+ kDeviceTypeEthernet,
+ kDeviceTypeWiFi,
+ kDeviceTypeFW,
+ kDeviceTypeBT,
+ kDeviceTypeRS232,
+ kDeviceTypeSCSI,
+ kDeviceTypeAHCI,
+ kDeviceTypeMBCI,
+ kDeviceTypeATA,
+ kDeviceTypeUSB,
+ kDeviceTypeAPM, // Adv. Pwr. Mgmt.
+ kDeviceTypePCI,
+ kDeviceTypeVGA,
+ kDeviceTypeGPU,
+ kDeviceTypeCount,
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/DriveMgr.h b/src/kernel/KernelKit/DriveMgr.h
new file mode 100644
index 00000000..daf93b89
--- /dev/null
+++ b/src/kernel/KernelKit/DriveMgr.h
@@ -0,0 +1,175 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_DRIVE_MANAGER_H
+#define INC_DRIVE_MANAGER_H
+
+/// @file DriveMgr.h
+/// @brief Drive Manager.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <NeKit/Ref.h>
+
+#define kDriveMaxCount (4U)
+#define kDriveSectorSz (512U)
+#define kDriveInvalidID (-1)
+#define kDriveNameLen (32)
+
+#define drv_sector_cnt(SIZE, SECTOR_SZ) (((SIZE) + (SECTOR_SZ)) / (SECTOR_SZ))
+
+#define kDriveHiddenPrefix '~'
+
+namespace Kernel {
+enum {
+ kInvalidDrive = -1,
+
+ /// Storage types, combine with flags.
+ kBlockDevice = 0xAD,
+ kMassStorageDrive = 0xDA,
+ kFloppyDrive = 0xCD,
+ kOpticalDrive = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray
+ kTapeDrive = 0xD7,
+
+ /// Storage flags, combine with types.
+ kReadOnlyDrive = 0x10, // Read only drive
+ kEPMDrive = 0x11, // Explicit Partition Map.
+ kVEPMDrive = 0x12, // ESP w/ EPM partition.
+ kMBRDrive = 0x13, // PC classic partition scheme
+ kGPTDrive = 0x14, // PC new partition scheme
+ kUnformattedDrive = 0x15,
+ kStorageCount = 9,
+};
+
+/// @brief Media drive trait type.
+struct DriveTrait final {
+ Char fName[kDriveNameLen] = "/media/null"; // /System, /boot, //./Devices/USB...
+ UInt32 fKind{}; // fMassStorage, fFloppy, fOpticalDrive.
+ UInt32 fFlags{}; // fReadOnly, fEPMDrive...
+
+ /// @brief Packet drive (StorageKit compilant.)
+ struct DrivePacket final {
+ VoidPtr fPacketContent{nullptr}; //! packet body.
+ Char fPacketMime[kDriveNameLen] = "*/*"; //! identify what we're sending.
+ SizeT fPacketSize{0UL}; //! packet size
+ UInt32 fPacketCRC32{0UL}; //! sanity crc, in case if good is set to false
+ Boolean fPacketGood{YES};
+ Lba fPacketLba{0UL};
+ Boolean fPacketReadOnly{NO};
+ } fPacket;
+
+ Lba fLbaStart{0}, fLbaEnd{0};
+ SizeT fSectorSz{kDriveSectorSz};
+
+ Void (*fInput)(DrivePacket& packet){nullptr};
+ Void (*fOutput)(DrivePacket& packet){nullptr};
+ Void (*fVerify)(DrivePacket& packet){nullptr};
+ Void (*fInit)(DrivePacket& packet){nullptr};
+ const Char* (*fProtocol)(Void){nullptr};
+};
+
+namespace Probe {
+ Void io_detect_drive(DriveTrait& trait);
+}
+
+///! drive as a device.
+typedef DriveTrait* DriveTraitPtr;
+
+/**
+ * @brief Mounted drives interface.
+ * @note This class has all of it's drive set to nullptr, allocate them using
+ * GetAddressOf(index).
+ */
+class IMountpoint final {
+ public:
+ explicit IMountpoint() = default;
+ ~IMountpoint() = default;
+
+ NE_COPY_DEFAULT(IMountpoint)
+
+ public:
+ DriveTrait& A() { return mA; }
+
+ DriveTrait& B() { return mB; }
+
+ DriveTrait& C() { return mC; }
+
+ DriveTrait& D() { return mD; }
+
+ enum {
+ kDriveIndexA = 0,
+ kDriveIndexB,
+ kDriveIndexC,
+ kDriveIndexD,
+ kDriveIndexInvalid,
+ };
+
+ DriveTraitPtr GetAddressOf(const Int32& index) {
+ err_local_get() = kErrorSuccess;
+
+ switch (index) {
+ case kDriveIndexA:
+ return &mA;
+ case kDriveIndexB:
+ return &mB;
+ case kDriveIndexC:
+ return &mC;
+ case kDriveIndexD:
+ return &mD;
+ default: {
+ err_local_get() = kErrorNoSuchDisk;
+ kout << "No such disc letter.\n";
+
+ break;
+ }
+ }
+
+ return nullptr;
+ }
+
+ private:
+ DriveTrait mA, mB, mC, mD;
+};
+
+/// @brief Unimplemented drive.
+/// @param pckt the packet to read.
+/// @return
+Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) noexcept;
+
+/// @brief Gets the drive kind (ATA, SCSI, AHCI...)
+/// @param void none.
+/// @return the drive kind (ATA, Flash, NVM)
+const Char* io_drv_kind(Void);
+
+/// @brief Makes a new drive.
+/// @return the new drive as a trait.
+DriveTrait io_construct_blank_drive(Void) noexcept;
+
+/// @brief Fetches the main drive.
+/// @param trait the new drive as a trait.
+Void io_construct_main_drive(DriveTrait& trait) noexcept;
+
+/// @brief Fetches the main drive.
+/// @return the new drive as a trait.
+/// @deprecated use io_construct_main_drive(DriveTrait& trait) instead.
+DriveTrait io_construct_main_drive(Void) noexcept;
+
+namespace Detect {
+ Void io_detect_drive(DriveTrait& trait);
+}
+
+Void io_drv_input(DriveTrait::DrivePacket pckt);
+
+Void io_drv_output(DriveTrait::DrivePacket pckt);
+} // namespace Kernel
+
+#endif /* ifndef INC_DRIVE_MANAGER_H */
diff --git a/src/kernel/KernelKit/FileMgr.h b/src/kernel/KernelKit/FileMgr.h
new file mode 100644
index 00000000..93d5f580
--- /dev/null
+++ b/src/kernel/KernelKit/FileMgr.h
@@ -0,0 +1,445 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss , licensed under the Apache 2.0 license.
+
+ File: FileMgr.h
+ Purpose: Kernel file manager.
+ Author: Amlal El Mahrouss (amlal@nekernel.org)
+
+======================================== */
+
+/* ========================================
+
+ Revision History:
+
+ 31/01/24: Update documentation (amlel)
+ 05/07/24: NeFS support, and fork support, updated constants and specs
+ as well.
+ 18/01/25: Patches to FileStream class.
+
+ ======================================== */
+
+#ifndef INC_FILEMGR_H
+#define INC_FILEMGR_H
+
+/// @file FileMgr.h
+/// @brief File Manager System.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+//! Include filesystems that NeKernel supports.
+#include <FSKit/Ext2+IFS.h>
+#include <FSKit/NeFS.h>
+#include <FSKit/OpenHeFS.h>
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/Ref.h>
+#include <NeKit/Stream.h>
+#include <hint/CompilerHint.h>
+
+/// @brief Filesystem manager, abstraction over mounted filesystem.
+/// Works like an VFS (Virtual File System) or IFS subsystem on NT/OS 2.
+
+#define kRestrictR "r"
+#define kRestrictRB "rb"
+#define kRestrictW "w"
+#define kRestrictWR "rw"
+#define kRestrictWRB "rwb"
+
+#define kRestrictMax (5U)
+
+#define rtl_node_cast(PTR) reinterpret_cast<Kernel::NodePtr>(PTR)
+
+#define kFileMimeGeneric "ne-application-kind/all"
+
+/** @brief invalid position. (n-pos) */
+#define kFileMgrNPos (~0UL)
+
+namespace Kernel {
+enum {
+ kFileIOInvalid = 0,
+ kFileWriteAll = 100,
+ kFileReadAll = 101,
+ kFileReadChunk = 102,
+ kFileWriteChunk = 103,
+ // File flags (HFS+, NeFS specific)
+ kFileFlagRsrc = 104,
+ kFileFlagData = 105,
+ kFileIOCnt = (kFileFlagData - kFileWriteAll) + 1,
+};
+
+using NodePtr = VoidPtr;
+
+/**
+@brief Filesystem Mgr Interface class
+@brief Used to provide common I/O for a specific filesystem.
+*/
+class IFilesystemMgr {
+ public:
+ explicit IFilesystemMgr() = default;
+ virtual ~IFilesystemMgr() = default;
+
+ public:
+ NE_COPY_DEFAULT(IFilesystemMgr)
+
+ public:
+ /// @brief Mounts a new filesystem into an active state.
+ /// @param interface the filesystem interface
+ /// @return
+ static bool Mount(IFilesystemMgr* interface);
+
+ /// @brief Unmounts the active filesystem
+ /// @return
+ static IFilesystemMgr* Unmount();
+
+ /// @brief Getter, gets the active filesystem.
+ /// @return
+ static IFilesystemMgr* GetMounted();
+
+ public:
+ virtual NodePtr Create(_Input const Char* path) = 0;
+ virtual NodePtr CreateAlias(_Input const Char* path) = 0;
+ virtual NodePtr CreateDirectory(_Input const Char* path) = 0;
+ virtual NodePtr CreateSwapFile(const Char* path) = 0;
+
+ public:
+ virtual bool Remove(_Input const Char* path) = 0;
+
+ public:
+ virtual NodePtr Open(_Input const Char* path, _Input const Char* r) = 0;
+
+ public:
+ virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) = 0;
+
+ virtual Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data,
+ _Input Int32 flags, _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) = 0;
+
+ public:
+ virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0;
+
+ public:
+ virtual SizeT Tell(_Input NodePtr node) = 0;
+ virtual bool Rewind(_Input NodePtr node) = 0;
+};
+
+#ifdef __FSKIT_INCLUDES_NEFS__
+/**
+ * @brief Based of IFilesystemMgr, takes care of managing NeFS
+ * disks.
+ */
+class NeFileSystemMgr final : public IFilesystemMgr {
+ public:
+ explicit NeFileSystemMgr();
+ ~NeFileSystemMgr() override;
+
+ public:
+ NE_COPY_DEFAULT(NeFileSystemMgr)
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+ NodePtr CreateSwapFile(const Char* path) override;
+
+ public:
+ bool Remove(_Input const Char* path) override;
+ NodePtr Open(_Input const Char* path, _Input const Char* r) override;
+ Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT sz) override;
+ VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override;
+ bool Seek(_Input NodePtr node, _Input SizeT off) override;
+ SizeT Tell(_Input NodePtr node) override;
+ bool Rewind(_Input NodePtr node) override;
+
+ Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ /// @brief Get NeFS parser class.
+ /// @return The filesystem parser class.
+ NeFileSystemParser* GetParser() noexcept;
+
+ private:
+ NeFileSystemParser* mParser{nullptr};
+};
+
+#endif // ifdef __FSKIT_INCLUDES_NEFS__
+
+#ifdef __FSKIT_INCLUDES_EXT2__
+/**
+ * @brief Based of IFilesystemMgr, takes care of managing NeFS
+ * disks.
+ */
+class Ext2FileSystemMgr final : public IFilesystemMgr {
+ public:
+ explicit Ext2FileSystemMgr();
+ ~Ext2FileSystemMgr() override;
+
+ public:
+ NE_COPY_DEFAULT(Ext2FileSystemMgr)
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+ NodePtr CreateSwapFile(const Char* path) override;
+
+ public:
+ bool Remove(_Input const Char* path) override;
+ NodePtr Open(_Input const Char* path, _Input const Char* r) override;
+ Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT sz) override;
+ VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override;
+ bool Seek(_Input NodePtr node, _Input SizeT off) override;
+ SizeT Tell(_Input NodePtr node) override;
+ bool Rewind(_Input NodePtr node) override;
+
+ Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ /// @brief Get NeFS parser class.
+ /// @return The filesystem parser class.
+ Ext2FileSystemParser* GetParser() noexcept;
+
+ private:
+ Ext2FileSystemParser* mParser{nullptr};
+};
+
+#endif // ifdef __FSKIT_INCLUDES_EXT2__
+
+#ifdef __FSKIT_INCLUDES_OPENHEFS__
+/**
+ * @brief Based of IFilesystemMgr, takes care of managing NeFS
+ * disks.
+ */
+class HeFileSystemMgr final : public IFilesystemMgr {
+ public:
+ explicit HeFileSystemMgr();
+ ~HeFileSystemMgr() override;
+
+ public:
+ NE_COPY_DEFAULT(HeFileSystemMgr)
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+ NodePtr CreateSwapFile(const Char* path) override;
+
+ public:
+ bool Remove(_Input const Char* path) override;
+ NodePtr Open(_Input const Char* path, _Input const Char* r) override;
+ Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT sz) override;
+ VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override;
+ bool Seek(_Input NodePtr node, _Input SizeT off) override;
+ SizeT Tell(_Input NodePtr node) override;
+ bool Rewind(_Input NodePtr node) override;
+
+ Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ /// @brief Get NeFS parser class.
+ /// @return The filesystem parser class.
+ HeFileSystemParser* GetParser() noexcept;
+
+ private:
+ HeFileSystemParser* mParser{nullptr};
+};
+
+#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__
+
+/**
+ * FileStream class.
+ * @tparam Encoding file encoding (char, wchar_t...)
+ * @tparam FSClass Filesystem contract who takes care of it.
+ */
+template <typename Encoding = Char, typename FSClass = IFilesystemMgr>
+class FileStream final {
+ public:
+ explicit FileStream(const Encoding* path, const Encoding* restrict_type);
+ ~FileStream();
+
+ public:
+ FileStream& operator=(const FileStream&);
+ FileStream(const FileStream&);
+
+ public:
+ ErrorOr<Int64> Write(SizeT offset, const VoidPtr data, SizeT len) noexcept {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictWrite &&
+ this->fFileRestrict != kFileMgrRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr) return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ man->Write(offset, fFile, data, len);
+ return ErrorOr<Int64>(kErrorSuccess);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ ErrorOr<Int64> Write(const Char* name, const VoidPtr data, SizeT len) noexcept {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictWrite &&
+ this->fFileRestrict != kFileMgrRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr) return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ man->Write(name, fFile, data, 0, len);
+ return ErrorOr<Int64>(kErrorSuccess);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ VoidPtr Read(const Char* name, SizeT sz) noexcept {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictRead &&
+ this->fFileRestrict != kFileMgrRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ VoidPtr ret = man->Read(name, fFile, kFileReadAll, sz);
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ VoidPtr Read(SizeT offset, SizeT sz) {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictRead &&
+ this->fFileRestrict != kFileMgrRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ man->Seek(fFile, offset);
+ auto ret = man->Read(fFile, kFileReadChunk, sz);
+
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ public:
+ /// @brief Leak node pointer.
+ /// @return The node pointer.
+ NodePtr Leak() { return fFile; }
+
+ /// @brief Leak MIME.
+ /// @return The MIME.
+ Char* MIME() noexcept { return const_cast<Char*>(fMime); }
+
+ enum {
+ kFileMgrRestrictRead = 100,
+ kFileMgrRestrictReadBinary,
+ kFileMgrRestrictWrite,
+ kFileMgrRestrictWriteBinary,
+ kFileMgrRestrictReadWrite,
+ kFileMgrRestrictReadWriteBinary,
+ };
+
+ private:
+ NodePtr fFile{nullptr};
+ Int32 fFileRestrict{kFileMgrRestrictReadBinary};
+ const Char* fMime{kFileMimeGeneric};
+};
+
+using FileStreamASCII = FileStream<Char>;
+using FileStreamUTF8 = FileStream<Utf8Char>;
+using FileStreamUTF16 = FileStream<WideChar>;
+
+typedef UInt64 CursorType;
+
+inline STATIC const auto kRestrictStrLen = 8U;
+
+/// @brief restrict information about the file descriptor.
+struct FILEMGR_RESTRICT final {
+ Char fRestrict[kRestrictStrLen];
+ Int32 fMappedTo;
+};
+
+/// @brief constructor
+template <typename Encoding, typename Class>
+inline FileStream<Encoding, Class>::FileStream(const Encoding* path, const Encoding* restrict_type)
+ : fFile(Class::GetMounted()->Open(path, restrict_type)) {
+ SizeT kRestrictCount = kRestrictMax;
+ const FILEMGR_RESTRICT kRestrictList[] = {{
+ .fRestrict = kRestrictR,
+ .fMappedTo = kFileMgrRestrictRead,
+ },
+ {
+ .fRestrict = kRestrictRB,
+ .fMappedTo = kFileMgrRestrictReadBinary,
+ },
+ {
+ .fRestrict = kRestrictWRB,
+ .fMappedTo = kFileMgrRestrictReadWriteBinary,
+ },
+ {
+ .fRestrict = kRestrictW,
+ .fMappedTo = kFileMgrRestrictWrite,
+ },
+ {
+ .fRestrict = kRestrictWR,
+ .fMappedTo = kFileMgrRestrictReadWrite,
+ }};
+
+ for (SizeT index = 0; index < kRestrictCount; ++index) {
+ if (rt_string_cmp(restrict_type, kRestrictList[index].fRestrict,
+ rt_string_len(kRestrictList[index].fRestrict)) == 0) {
+ fFileRestrict = kRestrictList[index].fMappedTo;
+ break;
+ }
+ }
+
+ kout << "FileMgr: Open file at: " << path << ".\r";
+}
+
+/// @brief destructor of the file stream.
+template <typename Encoding, typename Class>
+inline FileStream<Encoding, Class>::~FileStream() {
+ mm_free_ptr(fFile);
+ fFile = nullptr;
+}
+} // namespace Kernel
+
+#endif // ifndef INC_FILEMGR_H
diff --git a/src/kernel/KernelKit/HardwareThreadScheduler.h b/src/kernel/KernelKit/HardwareThreadScheduler.h
new file mode 100644
index 00000000..36a870ba
--- /dev/null
+++ b/src/kernel/KernelKit/HardwareThreadScheduler.h
@@ -0,0 +1,135 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __INC_MP_MANAGER_H__
+#define __INC_MP_MANAGER_H__
+
+#include <ArchKit/ArchKit.h>
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Ref.h>
+
+/// @note Last Rev Sun 28 Jul CET 2024
+/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM
+
+#define kMaxAPInsideSched (4U)
+
+namespace Kernel {
+class HardwareThread;
+class HardwareThreadScheduler;
+
+using ThreadID = UInt32;
+
+enum ThreadKind {
+ kAPInvalid = 0,
+ kAPSystemReserved = 100, // System reserved thread, well user can't use it
+ kAPStandard, // user thread, cannot be used by Kernel
+ kAPRealTime, // fallback thread, cannot be used by user if not clear or
+ // used by Kernel.
+ kAPBoot, // The core we booted from, the mama.
+ kAPCount,
+};
+
+typedef enum ThreadKind ThreadKind;
+typedef ThreadID ThreadID;
+
+/***********************************************************************************/
+///
+/// \name HardwareThread
+/// \brief Abstraction over the CPU's core, used to run processes or threads.
+///
+/***********************************************************************************/
+
+class HardwareThread final {
+ public:
+ explicit HardwareThread();
+ ~HardwareThread();
+
+ public:
+ NE_COPY_DEFAULT(HardwareThread)
+
+ public:
+ operator bool();
+
+ public:
+ void Wake(const BOOL wakeup = false) noexcept;
+ void Busy(const BOOL busy = false) noexcept;
+
+ public:
+ BOOL Switch(HAL::StackFramePtr frame);
+ BOOL IsWakeup() noexcept;
+
+ public:
+ HAL::StackFramePtr StackFrame() noexcept;
+ ThreadKind& Kind() noexcept;
+ BOOL IsBusy() noexcept;
+ ThreadID& ID() noexcept;
+
+ private:
+ HAL::StackFramePtr fStack{nullptr};
+ ThreadKind fKind{ThreadKind::kAPStandard};
+ ThreadID fID{0};
+ Bool fWakeup{NO};
+ Bool fBusy{NO};
+ UInt64 fPTime{0};
+
+ private:
+ friend class HardwareThreadScheduler;
+ friend class UserProcessHelper;
+};
+
+///
+/// \name HardwareThreadScheduler
+/// \brief Class to manage the thread scheduling.
+///
+
+class HardwareThreadScheduler final : public ISchedulable {
+ private:
+ friend class UserProcessHelper;
+
+ public:
+ explicit HardwareThreadScheduler();
+ ~HardwareThreadScheduler();
+ NE_COPY_DEFAULT(HardwareThreadScheduler)
+
+ public:
+ HAL::StackFramePtr Leak() noexcept;
+
+ public:
+ Ref<HardwareThread*> operator[](SizeT idx);
+ bool operator!() noexcept;
+ operator bool() noexcept;
+
+ Bool IsUser() override { return Yes; }
+
+ Bool IsKernel() override { return No; }
+
+ Bool HasMP() override { return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; }
+
+ public:
+ /// @brief Shared instance of the MP Mgr.
+ /// @return the reference to the mp manager class.
+ STATIC HardwareThreadScheduler& The();
+
+ public:
+ /// @brief Returns the amount of threads present in the system.
+ /// @returns SizeT the amount of cores present.
+ SizeT Capacity() noexcept;
+
+ private:
+ Array<HardwareThread, kMaxAPInsideSched> fThreadList;
+ ThreadID fCurrentThreadIdx{0};
+};
+
+/// @brief wakes up thread.
+/// wakes up thread from hang.
+Void mp_wakeup_thread(HAL::StackFramePtr stack);
+
+/// @brief makes thread sleep.
+/// hooks and hangs thread to prevent code from executing.
+Void mp_hang_thread(HAL::StackFramePtr stack);
+} // namespace Kernel
+
+#endif // !__INC_MP_MANAGER_H__
diff --git a/src/kernel/KernelKit/HeapMgr.h b/src/kernel/KernelKit/HeapMgr.h
new file mode 100644
index 00000000..58bac7a5
--- /dev/null
+++ b/src/kernel/KernelKit/HeapMgr.h
@@ -0,0 +1,58 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_KERNEL_HEAP_H
+#define INC_KERNEL_HEAP_H
+
+/// @date 30/01/24
+/// @file: HeapMgr.h
+/// @brief: Memory allocation support for the NeKernel.
+
+#include <KernelKit/KPC.h>
+#include <NeKit/KernelPanic.h>
+#include <hint/CompilerHint.h>
+
+namespace Kernel {
+/// @brief Declare pointer as free.
+/// @param heap_ptr the pointer.
+/// @return a status code regarding the deallocation.
+Int32 mm_free_ptr(VoidPtr heap_ptr);
+
+/// @brief Check if pointer is a valid Kernel pointer.
+/// @param heap_ptr the pointer
+/// @return if it exists it returns true.
+Boolean mm_is_valid_ptr(VoidPtr heap_ptr);
+
+/// @brief Allocate chunk of memory.
+/// @param sz Size of pointer
+/// @param wr Read Write bit.
+/// @param user User enable bit.
+/// @return The newly allocated pointer, or nullptr.
+VoidPtr mm_alloc_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount = 0);
+
+/// @brief Protect the heap with a CRC value.
+/// @param heap_ptr pointer.
+/// @return if it valid: point has crc now., otherwise fail.
+Boolean mm_protect_ptr(VoidPtr heap_ptr);
+
+/// @brief Makes a Kernel page.
+/// @param heap_ptr the page pointer.
+/// @return status code
+Int32 mm_make_page(VoidPtr heap_ptr);
+
+/// @brief Overwrites and set the flags of a heap header.
+/// @param heap_ptr the pointer to update.
+/// @param flags the flags to set.
+Int32 mm_set_ptr_flags(VoidPtr heap_ptr, UInt64 flags);
+
+/// @brief Gets the flags of a heap header.
+/// @param heap_ptr the pointer to get.
+UInt64 mm_get_ptr_flags(VoidPtr heap_ptr);
+} // namespace Kernel
+
+#include <KernelKit/HeapMgr.inl>
+
+#endif // !INC_KERNEL_HEAP_H
diff --git a/src/kernel/KernelKit/HeapMgr.inl b/src/kernel/KernelKit/HeapMgr.inl
new file mode 100644
index 00000000..3231d33c
--- /dev/null
+++ b/src/kernel/KernelKit/HeapMgr.inl
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#ifndef INC_KERNEL_HEAP_H
+#include <KernelKit/HeapMgr.h>
+#endif // !INC_KERNEL_HEAP_H
+
+namespace Kernel {
+/// @brief Allocate C++ class.
+/// @param cls The class to allocate.
+/// @param args The args to pass.
+template <typename T, typename... Args>
+inline BOOL mm_new_class(_Input _Output T** cls, _Input Args&&... args) {
+ if (*cls) {
+ err_global_get() = Kernel::kErrorInvalidData;
+ return NO;
+ }
+
+ *cls = new T(move(args)...);
+ return *cls;
+}
+
+/// @brief Delete and nullify C++ class.
+/// @param cls The class to delete.
+template <typename T>
+inline Void mm_delete_class(_Input _Output T** cls) {
+ delete *cls;
+ *cls = nullptr;
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/IDylibObject.h b/src/kernel/KernelKit/IDylibObject.h
new file mode 100644
index 00000000..ef6b96db
--- /dev/null
+++ b/src/kernel/KernelKit/IDylibObject.h
@@ -0,0 +1,45 @@
+/*
+ * ========================================================
+ *
+ * Kernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+
+#define NE_DYLIB_OBJECT : public IDylibObject
+
+namespace Kernel {
+class IDylibObject;
+
+/// @brief Dylib class object. A handle to a shared library.
+class IDylibObject {
+ public:
+ explicit IDylibObject() = default;
+ virtual ~IDylibObject() = default;
+
+ struct DylibTraits final {
+ VoidPtr ImageObject{nullptr};
+ VoidPtr ImageEntrypointOffset{nullptr};
+
+ VoidPtr Image() const { return ImageObject; }
+ Bool IsValid() const { return ImageObject && ImageEntrypointOffset; }
+ };
+
+ NE_COPY_DEFAULT(IDylibObject)
+
+ virtual DylibTraits** GetAddressOf() = 0;
+ virtual DylibTraits* Get() = 0;
+
+ virtual Void Mount(DylibTraits* to_mount) = 0;
+ virtual Void Unmount() = 0;
+};
+
+/// @brief Pure implementation, missing method/function handler.
+EXTERN_C void __ne_pure_call(void);
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/IFS.h b/src/kernel/KernelKit/IFS.h
new file mode 100644
index 00000000..7118a935
--- /dev/null
+++ b/src/kernel/KernelKit/IFS.h
@@ -0,0 +1,25 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DriveMgr.h>
+
+namespace Kernel {
+/// @brief Read from IFS disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_read(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex);
+
+/// @brief Write to IFS disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_write(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex);
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/ILoader.h b/src/kernel/KernelKit/ILoader.h
new file mode 100644
index 00000000..28dd1ed9
--- /dev/null
+++ b/src/kernel/KernelKit/ILoader.h
@@ -0,0 +1,32 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+#include <hint/CompilerHint.h>
+
+namespace Kernel {
+/// @brief This interface is used to make loader contracts (MSCOFF, PEF).
+/// @author @Amlal-El-Mahrouss
+class ILoader {
+ public:
+ explicit ILoader() = default;
+ virtual ~ILoader() = default;
+
+ NE_COPY_DEFAULT(ILoader)
+
+ public:
+ virtual _Output ErrorOr<VoidPtr> GetBlob() = 0;
+ virtual _Output const Char* AsString() = 0;
+ virtual _Output const Char* MIME() = 0;
+ virtual _Output const Char* Path() = 0;
+ virtual _Output ErrorOr<VoidPtr> FindStart() = 0;
+ virtual _Output ErrorOr<VoidPtr> FindSymbol(_Input const Char* name, _Input Int32 kind) = 0;
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/IPEFDylibObject.h b/src/kernel/KernelKit/IPEFDylibObject.h
new file mode 100644
index 00000000..17ef02d5
--- /dev/null
+++ b/src/kernel/KernelKit/IPEFDylibObject.h
@@ -0,0 +1,86 @@
+/*
+ * ========================================================
+ *
+ * Kernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#ifndef __KERNELKIT_PEF_SHARED_OBJECT_H__
+#define __KERNELKIT_PEF_SHARED_OBJECT_H__
+
+#include <KernelKit/IDylibObject.h>
+#include <KernelKit/PEF.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+/**
+ * @brief Shared Library class
+ * Load library from this class
+ */
+class IPEFDylibObject final NE_DYLIB_OBJECT {
+ public:
+ explicit IPEFDylibObject() = default;
+ ~IPEFDylibObject() = default;
+
+ public:
+ NE_COPY_DEFAULT(IPEFDylibObject)
+
+ private:
+ DylibTraits* fMounted{nullptr};
+
+ public:
+ DylibTraits** GetAddressOf() { return &fMounted; }
+
+ DylibTraits* Get() { return fMounted; }
+
+ public:
+ void Mount(DylibTraits* to_mount) noexcept {
+ if (!to_mount || !to_mount->ImageObject) return;
+
+ fMounted = to_mount;
+
+ if (fLoader && to_mount) {
+ delete fLoader;
+ fLoader = nullptr;
+ }
+
+ if (!fLoader) {
+ fLoader = new PEFLoader(fMounted->ImageObject);
+ }
+ }
+
+ void Unmount() noexcept {
+ if (fMounted) fMounted = nullptr;
+ };
+
+ template <typename SymbolType>
+ SymbolType Load(const Char* symbol_name, const SizeT& len, const UInt32& kind) {
+ if (symbol_name == nullptr || *symbol_name == 0) return nullptr;
+ if (len > kPathLen || len < 1) return nullptr;
+
+ auto ret = reinterpret_cast<SymbolType>(fLoader->FindSymbol(symbol_name, kind).Leak().Leak());
+
+ if (!ret) {
+ if (kind == kPefCode) return (VoidPtr) &__ne_pure_call;
+
+ return nullptr;
+ }
+
+ return ret;
+ }
+
+ private:
+ PEFLoader* fLoader{nullptr};
+};
+
+typedef IPEFDylibObject* IDylibRef;
+
+EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& header);
+EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& header, IDylibRef lib, Bool* successful);
+} // namespace Kernel
+
+#endif /* ifndef __KERNELKIT_PEF_SHARED_OBJECT_H__ */
diff --git a/src/kernel/KernelKit/KPC.h b/src/kernel/KernelKit/KPC.h
new file mode 100644
index 00000000..dbdc2a93
--- /dev/null
+++ b/src/kernel/KernelKit/KPC.h
@@ -0,0 +1,78 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+/// @file KPC.h
+/// @brief Kernel Procedure Code.
+
+#define err_local_ok() \
+ (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode() == \
+ Kernel::kErrorSuccess)
+#define err_local_fail() \
+ (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode() != \
+ Kernel::kErrorSuccess)
+#define err_local_get() \
+ (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode())
+
+#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess)
+#define err_global_fail() (Kernel::kErrorLocalNumber != Kernel::kErrorSuccess)
+#define err_global_get() (Kernel::kErrorLocalNumber)
+
+namespace Kernel {
+typedef Int32 KPCError;
+
+inline KPCError kErrorLocalNumber = 0UL;
+
+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 kErrorDiskIsTooTiny = 65;
+inline constexpr KPCError kErrorDmaExhausted = 66;
+inline constexpr KPCError kErrorOutOfBitMapMemory = 67;
+inline constexpr KPCError kErrorTimeout = 68;
+inline constexpr KPCError kErrorAccessDenied = 69;
+inline constexpr KPCError kErrorUnavailable = 70;
+/// Generic errors.
+inline constexpr KPCError kErrorUnimplemented = -1;
+
+/// @brief Does a system wide bug check.
+/// @param void no params are needed.
+/// @return if error-free: false, otherwise true.
+Boolean err_bug_check_raise(Void) noexcept;
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/KernelTaskScheduler.h b/src/kernel/KernelKit/KernelTaskScheduler.h
new file mode 100644
index 00000000..9bfce1d6
--- /dev/null
+++ b/src/kernel/KernelKit/KernelTaskScheduler.h
@@ -0,0 +1,47 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/// @file KernelTaskScheduler.h
+/// @brief Kernel Task Scheduler header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/CoreProcessScheduler.h>
+#include <KernelKit/LockDelegate.h>
+
+namespace Kernel {
+class KernelTaskHelper;
+
+typedef ProcessID KID;
+
+/// @brief Equivalent of USER_PROCESS, but for kernel tasks.
+/// @author Amlal
+class KERNEL_TASK final {
+ public:
+ Char Name[kSchedNameLen] = {"KERNEL_TASK"};
+ ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemKernel};
+ HAL::StackFramePtr StackFrame{nullptr};
+ UInt8* StackReserve{nullptr};
+ SizeT StackSize{kSchedMaxStackSz};
+ ProcessImage Image{};
+ /// @brief a KID is a Kernel ID, it is used to find a task running within
+ /// the kernel.
+ KID Kid{0};
+};
+
+/// @brief Equivalent of UserProcessHelper, but for kernel tasks.
+/// @author Amlal
+class KernelTaskHelper final {
+ public:
+ STATIC Bool Add(HAL::StackFramePtr frame_ptr, ProcessID new_kid);
+ STATIC Bool Remove(const KID kid);
+ STATIC Bool CanBeScheduled(const KERNEL_TASK& process);
+ STATIC ErrorOr<KID> TheCurrentKID();
+ STATIC SizeT StartScheduling();
+};
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/LockDelegate.h b/src/kernel/KernelKit/LockDelegate.h
new file mode 100644
index 00000000..8ff67f19
--- /dev/null
+++ b/src/kernel/KernelKit/LockDelegate.h
@@ -0,0 +1,58 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Atom.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+enum {
+ kLockInvalid = 0,
+ kLockDone = 200,
+ kLockTimedOut = 300,
+ kLockCount = 3,
+};
+
+/// @brief Lock condition pointer.
+typedef Boolean* LockPtr;
+
+/// @brief Locking delegate class, hangs until limit.
+/// @tparam N the amount of cycles to wait.
+template <SizeT N>
+class LockDelegate final {
+ public:
+ LockDelegate() = delete;
+
+ public:
+ explicit LockDelegate(LockPtr expr) {
+ auto spin = 0U;
+
+ while (spin < N) {
+ if (*expr) {
+ fLockStatus | kLockDone;
+ break;
+ }
+
+ ++spin;
+ }
+
+ if (spin > N) fLockStatus | kLockTimedOut;
+ }
+
+ ~LockDelegate() = default;
+
+ LockDelegate& operator=(const LockDelegate&) = delete;
+ LockDelegate(const LockDelegate&) = delete;
+
+ bool Done() { return fLockStatus[kLockDone] == kLockDone; }
+
+ bool HasTimedOut() { return fLockStatus[kLockTimedOut] != kLockTimedOut; }
+
+ private:
+ Atom<UInt> fLockStatus;
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/MSDOS.h b/src/kernel/KernelKit/MSDOS.h
new file mode 100644
index 00000000..8c58b65b
--- /dev/null
+++ b/src/kernel/KernelKit/MSDOS.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: MSDOS.h
+ Purpose: MS-DOS header for Kernel.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+======================================== */
+
+#ifndef __MSDOS_EXEC__
+#define __MSDOS_EXEC__
+
+#include <KernelKit/PE.h>
+#include <NeKit/Defines.h>
+
+// Last Rev
+// Sat Feb 24 CET 2024
+
+#define kMagMz0 'M'
+#define kMagMz1 'Z'
+
+typedef Kernel::UInt32 DosWord;
+typedef Kernel::Long DosLong;
+
+typedef struct _DosHeader {
+ Kernel::UInt8 eMagic[2];
+ DosWord eMagLen;
+ DosWord ePagesCount;
+ DosWord eCrlc;
+ DosWord eCParHdr;
+ DosWord eMinAlloc;
+ DosWord eMaxAlloc;
+ DosWord eStackSeg;
+ DosWord eStackPtr;
+ DosWord eChksum;
+ DosWord eIp;
+ DosWord eCs;
+ DosWord eLfarlc;
+ DosWord eOvno;
+ DosWord eRes[4];
+ DosWord eOemid;
+ DosWord eOeminfo;
+ DosWord eRes2[10];
+ DosLong eLfanew;
+} DosHeader, *DosHeaderPtr;
+
+#endif /* ifndef __MSDOS_EXEC__ */
diff --git a/src/kernel/KernelKit/PCI/DMA.h b/src/kernel/KernelKit/PCI/DMA.h
new file mode 100644
index 00000000..80103dab
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/DMA.h
@@ -0,0 +1,75 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/PCI/Device.h>
+#include <NeKit/Array.h>
+#include <NeKit/OwnPtr.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+enum class DmaKind {
+ PCI = 10, // Bus mastering is required to be turned on. Basiaclly a request
+ // control system. 64-Bit access depends on the PAE bit and the device
+ // (if Double Address Cycle is available)
+ ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM.
+ Count = 2,
+ Invalid = 0,
+};
+
+class DMAWrapper final {
+ public:
+ explicit DMAWrapper() = delete;
+
+ public:
+ explicit DMAWrapper(nullPtr) = delete;
+ explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) : fAddress(Ptr), fKind(Kind) {}
+
+ public:
+ DMAWrapper& operator=(voidPtr Ptr);
+
+ public:
+ DMAWrapper& operator=(const DMAWrapper&) = default;
+ DMAWrapper(const DMAWrapper&) = default;
+
+ public:
+ ~DMAWrapper() = default;
+
+ template <class T>
+ T* operator->();
+
+ template <class T>
+ T* Get(UIntPtr off = 0);
+
+ public:
+ operator bool();
+ bool operator!();
+
+ public:
+ bool Write(UIntPtr& bit, const UInt32& offset);
+ UIntPtr Read(const UInt32& offset);
+ Boolean Check(UIntPtr offset) const;
+
+ public:
+ UIntPtr operator[](UIntPtr& offset);
+
+ private:
+ voidPtr fAddress{nullptr};
+ DmaKind fKind{DmaKind::Invalid};
+
+ private:
+ friend class DMAFactory;
+};
+
+class DMAFactory final {
+ public:
+ static OwnPtr<IOBuf<Char*>> Construct(OwnPtr<DMAWrapper>& dma);
+};
+} // namespace Kernel
+
+#include <KernelKit/PCI/DMA.inl>
diff --git a/src/kernel/KernelKit/PCI/DMA.inl b/src/kernel/KernelKit/PCI/DMA.inl
new file mode 100644
index 00000000..d81a632e
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/DMA.inl
@@ -0,0 +1,17 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+namespace Kernel {
+template <class T>
+T* DMAWrapper::operator->() {
+ return this->fAddress;
+}
+
+template <class T>
+T* DMAWrapper::Get(UIntPtr offset) {
+ return reinterpret_cast<T*>((UIntPtr) this->fAddress + offset);
+}
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/PCI/Database.h b/src/kernel/KernelKit/PCI/Database.h
new file mode 100644
index 00000000..463fde38
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Database.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+#pragma once
+
+#include <KernelKit/PCI/Device.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+namespace Types {
+ // https://wiki.osdev.org/PCI
+ enum class PciDeviceKind : UChar {
+ MassStorageController = 0x1,
+ NetworkController = 0x2,
+ DisplayController = 0x3,
+ MultimediaController = 0x4,
+ MemoryController = 0x5,
+ Bridge = 0x6,
+ CommunicationController = 0x7,
+ GenericSystemPeripheral = 0x8,
+ InputDeviceController = 0x9,
+ DockingStation = 0xa,
+ Processor = 0xb,
+ SerialBusController = 0xc,
+ WirelessController = 0xd,
+ IntelligentController = 0xe,
+ SatelliteCommunicationsController = 0xf,
+ CoProcessor = 0x40,
+ Unassgined = 0xf,
+ Invalid = Unassgined,
+ };
+} // namespace Types
+} // namespace Kernel
+
+inline BOOL operator!=(const Kernel::Types::PciDeviceKind& lhs, Kernel::UChar rhs) {
+ return rhs != (Kernel::UChar) lhs;
+}
+
+inline BOOL operator==(const Kernel::Types::PciDeviceKind& lhs, Kernel::UChar rhs) {
+ return rhs == (Kernel::UChar) lhs;
+}
+
+inline BOOL operator!=(Kernel::UChar lhs, const Kernel::Types::PciDeviceKind& rhs) {
+ return lhs != (Kernel::UChar) rhs;
+}
+
+inline BOOL operator==(Kernel::UChar lhs, const Kernel::Types::PciDeviceKind& rhs) {
+ return lhs == (Kernel::UChar) rhs;
+} \ No newline at end of file
diff --git a/src/kernel/KernelKit/PCI/Device.h b/src/kernel/KernelKit/PCI/Device.h
new file mode 100644
index 00000000..f2111e40
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Device.h
@@ -0,0 +1,73 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel::PCI {
+enum class PciConfigKind : UShort {
+ ConfigAddress = 0xCF8,
+ ConfigData = 0xCFC,
+ CommandReg = 0x0004,
+ Invalid = 0xFFFF,
+};
+
+/// @brief Device interface class
+class Device final {
+ public:
+ Device() = default;
+
+ public:
+ Device(UShort bus, UShort device, UShort function, UInt32 bar);
+
+ Device& operator=(const Device&) = default;
+ Device(const Device&) = default;
+
+ ~Device();
+
+ public:
+ UInt Read(UInt bar, Size szData);
+ void Write(UInt bar, UIntPtr data, Size szData);
+
+ public:
+ operator bool();
+
+ public:
+ template <typename T>
+ UInt Read(UInt bar) {
+ static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported");
+ return Read(bar, sizeof(T));
+ }
+
+ template <typename T>
+ void Write(UInt bar, UIntPtr data) {
+ static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported");
+ Write(bar, data, sizeof(T));
+ }
+
+ public:
+ UShort DeviceId();
+ UShort VendorId();
+ UShort InterfaceId();
+ UChar Class();
+ UChar Subclass();
+ UChar ProgIf();
+ UChar HeaderType();
+ UIntPtr Bar(UInt32 bar_in);
+
+ public:
+ void EnableMmio();
+ void BecomeBusMaster(); // for PCI-DMA, PC-DMA does not need that.
+
+ UShort Vendor();
+
+ private:
+ UShort fBus;
+ UShort fDevice;
+ UShort fFunction;
+ UInt32 fBar;
+};
+} // namespace Kernel::PCI
diff --git a/src/kernel/KernelKit/PCI/Express.h b/src/kernel/KernelKit/PCI/Express.h
new file mode 100644
index 00000000..484739ec
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Express.h
@@ -0,0 +1,12 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/PCI/PCI.h>
+#include <NeKit/Defines.h>
+
+#define PCI_EXPRESS_BUS_COUNT (4096)
diff --git a/src/kernel/KernelKit/PCI/IO.h b/src/kernel/KernelKit/PCI/IO.h
new file mode 100644
index 00000000..2ab72269
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/IO.h
@@ -0,0 +1,63 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <ArchKit/ArchKit.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+template <SizeT Sz>
+class IOArray final {
+ public:
+ IOArray() = delete;
+
+ IOArray(nullPtr) = delete;
+
+ explicit IOArray(Array<UShort, Sz>& ports) : fPorts(ports) {}
+
+ ~IOArray() {}
+
+ IOArray& operator=(const IOArray&) = default;
+
+ IOArray(const IOArray&) = default;
+
+ operator bool() { return !fPorts.Empty(); }
+
+ public:
+ template <typename T>
+ T In(SizeT index);
+
+ template <typename T>
+ void Out(SizeT index, T value);
+
+ private:
+ Array<UShort, Sz> fPorts;
+};
+
+inline constexpr UInt16 kMaxPorts = 16;
+
+using IOArray16 = IOArray<kMaxPorts>;
+
+template <SizeT Sz>
+inline Array<UShort, Sz> make_ports(UShort base) {
+ Array<UShort, Sz> ports;
+
+ for (UShort i = 0; i < Sz; ++i) {
+ ports[i] = base + i;
+ }
+
+ return ports;
+}
+} // namespace Kernel
+
+#ifdef __NE_AMD64__
+#include <KernelKit/PCI/IOArray+AMD64.inl>
+#else
+#error Please provide platform specific code for the I/O
+#endif // ifdef __NE_AMD64__
diff --git a/src/kernel/KernelKit/PCI/IOArray+AMD64.inl b/src/kernel/KernelKit/PCI/IOArray+AMD64.inl
new file mode 100644
index 00000000..2b9125e0
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/IOArray+AMD64.inl
@@ -0,0 +1,49 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: IO-Impl-AMD64.h
+ Purpose: I/O for AMD64.
+
+ Revision History:
+
+ 30/01/24: Add file. (amlel)
+ 02/02/24: Update I/O routines. (amlel)
+
+======================================== */
+
+namespace Kernel {
+template <SizeT Sz>
+template <typename T>
+T IOArray<Sz>::In(SizeT index) {
+ switch (sizeof(T)) {
+#ifdef __NE_AMD64__
+ case 4:
+ return HAL::rt_in32(fPorts[index].Leak());
+ case 2:
+ return HAL::rt_in16(fPorts[index].Leak());
+ case 1:
+ return HAL::rt_in8(fPorts[index].Leak());
+#endif
+ default:
+ return 0xFFFF;
+ }
+}
+
+template <SizeT Sz>
+template <typename T>
+void IOArray<Sz>::Out(SizeT index, T value) {
+ switch (sizeof(T)) {
+#ifdef __NE_AMD64__
+ case 4:
+ HAL::rt_out32(fPorts[index].Leak(), value);
+ case 2:
+ HAL::rt_out16(fPorts[index].Leak(), value);
+ case 1:
+ HAL::rt_out8(fPorts[index].Leak(), value);
+#endif
+ default:
+ break;
+ }
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/PCI/Iterator.h b/src/kernel/KernelKit/PCI/Iterator.h
new file mode 100644
index 00000000..5926049b
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Iterator.h
@@ -0,0 +1,41 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __PCI_ITERATOR_H__
+#define __PCI_ITERATOR_H__
+
+#include <KernelKit/PCI/Database.h>
+#include <KernelKit/PCI/Device.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+
+#define NE_BUS_COUNT (256)
+#define NE_DEVICE_COUNT (33)
+#define NE_FUNCTION_COUNT (8)
+
+namespace Kernel::PCI {
+class Iterator final {
+ public:
+ Iterator() = delete;
+
+ public:
+ explicit Iterator(const Types::PciDeviceKind deviceType, UInt32 bar);
+
+ Iterator& operator=(const Iterator&) = default;
+ Iterator(const Iterator&) = default;
+
+ ~Iterator();
+
+ public:
+ Ref<PCI::Device> operator[](const Size& sz);
+
+ private:
+ Array<PCI::Device, NE_BUS_COUNT> fDevices;
+};
+} // namespace Kernel::PCI
+
+#endif // __PCI_ITERATOR_H__
diff --git a/src/kernel/KernelKit/PCI/PCI.h b/src/kernel/KernelKit/PCI/PCI.h
new file mode 100644
index 00000000..f76270da
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/PCI.h
@@ -0,0 +1,54 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define kPCIConfigAddressPort (0xCF8)
+#define kPCIConfigDataPort (0xCFC)
+
+#define kPCIDeviceCount (32)
+#define kPCIFuncCount (8)
+#define kPCIBusCount (256U)
+
+namespace Kernel::PCI {
+// model
+struct DeviceHeader {
+ UInt16 VendorId;
+ UInt16 DeviceId;
+ UInt8 Command;
+ UInt8 Status;
+ UInt8 RevisionId;
+ UInt8 ProgIf;
+ UInt8 SubClass;
+ UInt8 Class;
+ UInt8 CacheLineSz;
+ UInt8 LatencyTimer;
+ UInt8 HeaderType;
+ UInt8 Bist;
+ UInt8 Bus;
+ UInt8 Device;
+ UInt8 Function;
+};
+
+namespace Detail {
+ class BAR {
+ public:
+ UIntPtr BAR;
+ SizeT Size;
+ };
+} // namespace Detail
+
+class BAR {
+ public:
+ Detail::BAR BAR1;
+ Detail::BAR BAR2;
+ Detail::BAR BAR3;
+ Detail::BAR BAR4;
+ Detail::BAR BAR5;
+};
+} // namespace Kernel::PCI
diff --git a/src/kernel/KernelKit/PE.h b/src/kernel/KernelKit/PE.h
new file mode 100644
index 00000000..b4b4576e
--- /dev/null
+++ b/src/kernel/KernelKit/PE.h
@@ -0,0 +1,130 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: PE.h
+ Purpose: Portable Executable for Kernel.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+======================================== */
+
+#ifndef __KERNELKIT_INC_PE_H__
+#define __KERNELKIT_INC_PE_H__
+
+#include <NeKit/Defines.h>
+
+#define kPeSignature (0x00004550)
+
+#define kPeMagic32 (0x010b)
+#define kPeMagic64 (0x020b)
+
+#define kPeMachineAMD64 (0x8664)
+#define kPeMachineARM64 (0xaa64)
+
+typedef struct LDR_EXEC_HEADER final {
+ Kernel::UInt32 Signature;
+ Kernel::UInt16 Machine;
+ Kernel::UInt16 NumberOfSections;
+ Kernel::UInt32 TimeDateStamp;
+ Kernel::UInt32 PointerToSymbolTable;
+ Kernel::UInt32 NumberOfSymbols;
+ Kernel::UInt16 SizeOfOptionalHeader;
+ Kernel::UInt16 Characteristics;
+} LDR_EXEC_HEADER, *LDR_EXEC_HEADER_PTR;
+
+typedef struct LDR_OPTIONAL_HEADER final {
+ Kernel::UInt16 Magic; // 0x010b - PE32, 0x020b - PE32+ (64 bit)
+ Kernel::UInt8 MajorLinkerVersion;
+ Kernel::UInt8 MinorLinkerVersion;
+ Kernel::UInt32 SizeOfCode;
+ Kernel::UInt32 SizeOfInitializedData;
+ Kernel::UInt32 SizeOfUninitializedData;
+ Kernel::UInt32 AddressOfEntryPoint;
+ Kernel::UInt32 BaseOfCode;
+ Kernel::UInt64 ImageBase;
+ Kernel::UInt32 SectionAlignment;
+ Kernel::UInt32 FileAlignment;
+ Kernel::UInt16 MajorOperatingSystemVersion;
+ Kernel::UInt16 MinorOperatingSystemVersion;
+ Kernel::UInt16 MajorImageVersion;
+ Kernel::UInt16 MinorImageVersion;
+ Kernel::UInt16 MajorSubsystemVersion;
+ Kernel::UInt16 MinorSubsystemVersion;
+ Kernel::UInt32 Win32VersionValue;
+ Kernel::UInt32 SizeOfImage;
+ Kernel::UInt32 SizeOfHeaders;
+ Kernel::UInt32 CheckSum;
+ Kernel::UInt16 Subsystem;
+ Kernel::UInt16 DllCharacteristics;
+ Kernel::UInt32 SizeOfStackReserve;
+ Kernel::UInt32 SizeOfStackCommit;
+ Kernel::UInt32 SizeOfHeapReserve;
+ Kernel::UInt32 SizeOfHeapCommit;
+ Kernel::UInt32 LoaderFlags;
+ Kernel::UInt32 NumberOfRvaAndSizes;
+} LDR_OPTIONAL_HEADER, *LDR_OPTIONAL_HEADER_PTR;
+
+typedef struct LDR_SECTION_HEADER final {
+ Kernel::Char Name[8];
+ Kernel::UInt32 VirtualSize;
+ Kernel::UInt32 VirtualAddress;
+ Kernel::UInt32 SizeOfRawData;
+ Kernel::UInt32 PointerToRawData;
+ Kernel::UInt32 PointerToRelocations;
+ Kernel::UInt32 PointerToLineNumbers;
+ Kernel::UInt16 NumberOfRelocations;
+ Kernel::UInt16 NumberOfLinenumbers;
+ Kernel::UInt32 Characteristics;
+} LDR_SECTION_HEADER, *LDR_SECTION_HEADER_PTR;
+
+enum kExecDataDirParams {
+ kExecExport,
+ kExecImport,
+ kExecInvalid,
+ kExecCount,
+};
+
+typedef struct LDR_EXPORT_DIRECTORY {
+ Kernel::UInt32 Characteristics;
+ Kernel::UInt32 TimeDateStamp;
+ Kernel::UInt16 MajorVersion;
+ Kernel::UInt16 MinorVersion;
+ Kernel::UInt32 Name;
+ Kernel::UInt32 Base;
+ Kernel::UInt32 NumberOfFunctions;
+ Kernel::UInt32 NumberOfNames;
+ Kernel::UInt32 AddressOfFunctions; // export table rva
+ Kernel::UInt32 AddressOfNames;
+ Kernel::UInt32 AddressOfNameOrdinal; // ordinal table rva
+} LDR_EXPORT_DIRECTORY, *LDR_EXPORT_DIRECTORY_PTR;
+
+typedef struct LDR_IMPORT_DIRECTORY {
+ union {
+ Kernel::UInt32 Characteristics;
+ Kernel::UInt32 OriginalFirstThunk;
+ };
+ Kernel::UInt32 TimeDateStamp;
+ Kernel::UInt32 ForwarderChain;
+ Kernel::UInt32 NameRva;
+ Kernel::UInt32 ThunkTableRva;
+} LDR_IMPORT_DIRECTORY, *LDR_IMPORT_DIRECTORY_PTR;
+
+typedef struct LDR_DATA_DIRECTORY {
+ Kernel::UInt32 VirtualAddress;
+ Kernel::UInt32 Size;
+} LDR_DATA_DIRECTORY, *LDR_DATA_DIRECTORY_PTR;
+
+typedef struct LDR_IMAGE_HEADER {
+ LDR_EXEC_HEADER Header;
+ LDR_OPTIONAL_HEADER OptHdr;
+} LDR_IMAGE_HEADER, *LDR_IMAGE_HEADER_PTR;
+
+enum {
+ kUserSection = 0x00000020,
+ kPEResourceId = 0xFFaadd00,
+};
+
+#endif /* ifndef __KERNELKIT_INC_PE_H__ */
diff --git a/src/kernel/KernelKit/PE32CodeMgr.h b/src/kernel/KernelKit/PE32CodeMgr.h
new file mode 100644
index 00000000..52bc22b4
--- /dev/null
+++ b/src/kernel/KernelKit/PE32CodeMgr.h
@@ -0,0 +1,91 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: PE32CodeMgr.h
+ Purpose: PE32+ Code Mgr and Dylib mgr.
+
+ Revision History:
+
+ 12/02/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+////////////////////////////////////////////////////
+
+// LAST REV: Mon Feb 12 13:52:01 CET 2024
+
+////////////////////////////////////////////////////
+
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/ILoader.h>
+#include <KernelKit/PE.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KString.h>
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/ProcessScheduler.h>
+#endif
+
+#define kPeStackSizeSymbol "__NESizeOfReserveStack"
+#define kPeHeapSizeSymbol "__NESizeOfReserveHeap"
+#define kPeNameSymbol "__NEProgramName"
+
+#define kPeApplicationMime "application/vnd-portable-executable"
+
+#define kPeImageStart "__ImageStart"
+
+namespace Kernel {
+///
+/// \name PE32Loader
+/// \brief PE32+ loader class.
+///
+class PE32Loader : public ILoader {
+ private:
+ explicit PE32Loader() = delete;
+
+ public:
+ explicit PE32Loader(const VoidPtr blob);
+ explicit PE32Loader(const Char* path);
+ ~PE32Loader() override;
+
+ public:
+ NE_COPY_DEFAULT(PE32Loader)
+
+ public:
+ const Char* Path() override;
+ const Char* AsString() override;
+ const Char* MIME() override;
+
+ public:
+ ErrorOr<VoidPtr> FindStart() override;
+ ErrorOr<VoidPtr> FindSectionByName(const Char* name);
+ ErrorOr<VoidPtr> FindSymbol(const Char* name, Int32 kind) override;
+ ErrorOr<VoidPtr> GetBlob() override;
+
+ public:
+ bool IsLoaded() noexcept;
+
+ private:
+#ifdef __FSKIT_INCLUDES_NEFS__
+ OwnPtr<FileStream<Char, NeFileSystemMgr>> fFile;
+#elif defined(__FSKIT_INCLUDES_OPENHEFS__)
+ OwnPtr<FileStream<Char, HeFileSystemMgr>> fFile;
+#else
+ OwnPtr<FileStream<Char>> fFile;
+#endif // __FSKIT_INCLUDES_NEFS__
+
+ Ref<KString> fPath;
+ VoidPtr fCachedBlob;
+ BOOL fBad;
+};
+
+enum { kPEPlatformInvalid, kPEPlatformAMD64 = 100, kPEPlatformARM64 };
+enum { kPETypeInvalid, kPETypeText = 100, kPETypeData, kPETypeBSS };
+
+typedef LDR_SECTION_HEADER PE_SECTION_INFO;
+
+ProcessID rtl_create_user_process(PE32Loader& exec, const Int32& process_kind) noexcept;
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/PEF.h b/src/kernel/KernelKit/PEF.h
new file mode 100644
index 00000000..94284c98
--- /dev/null
+++ b/src/kernel/KernelKit/PEF.h
@@ -0,0 +1,117 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: PEF.h
+ Purpose: Preferred Executable Format for Kernel.
+
+ Revision History:
+
+ ?/?/23: Added file (amlel)
+
+======================================== */
+
+#ifndef __KERNELKIT_PEF_H__
+#define __KERNELKIT_PEF_H__
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/ILoader.h>
+#include <NeKit/Defines.h>
+
+#define kPefMagic "Open"
+#define kPefMagicFat "nepO"
+
+#define kPefMagicLen (5)
+
+#define kPefVersion (0x0500)
+#define kPefNameLen (256U)
+
+/* not mandatory, only for non fork based filesystems. */
+#define kPefExt ".exec"
+#define kPefDylibExt ".dylib"
+#define kPefLibExt ".lib"
+#define kPefObjectExt ".obj"
+#define kPefDebugExt ".dbg"
+#define kPefDriverExt ".sys"
+
+// Kernel System Binary Interface.
+#define kPefAbi (0x5046)
+
+#define kPefBaseOrigin (0x40000000)
+
+#define kPefStart "__ImageStart"
+#define kPefMainSymbol "_NeMain"
+
+#define kPefForkKind kPefMagic
+#define kPefForkKindFAT kPefMagicFat
+
+namespace Kernel {
+enum {
+ kPefArchIntel86S,
+ kPefArchAMD64,
+ kPefArchRISCV,
+ kPefArch64x0, /* 64x0. ISA */
+ kPefArch32x0, /* 32x0. ISA */
+ kPefArchPowerPC,
+ kPefArchARM64,
+ kPefArchCount = (kPefArchARM64 - kPefArchIntel86S) + 1,
+ kPefArchInvalid = 0xFF,
+};
+
+enum {
+ kPefSubArchGeneric = 0,
+ kPefSubArchAMD = 200,
+ kPefSubArchIntel,
+ kPefSubArchARM,
+ kPefSubArchIBM,
+};
+
+enum {
+ kPefKindInvalid = 0,
+ kPefKindExec = 1, /* .exec */
+ kPefKindDylib = 2, /* .dylib */
+ kPefKindObject = 4, /* .obj */
+ kPefKindDebug = 5, /* .dbg */
+ kPefKindDriver = 6,
+ kPefKindCount,
+};
+
+typedef struct PEFContainer final {
+ Char Magic[kPefMagicLen];
+ UInt32 Linker;
+ UInt32 Version;
+ UInt32 Kind;
+ UInt32 Abi;
+ UInt32 Cpu;
+ UInt32 SubCpu; /* Cpu specific information */
+ UIntPtr Start;
+ SizeT HdrSz; /* Size of header */
+ SizeT Count; /* container header count */
+ UInt32 Checksum;
+} PACKED PEFContainer;
+
+/* First PEFCommandHeader starts after PEFContainer */
+
+typedef struct PEFCommandHeader final {
+ Char Name[kPefNameLen]; /* container name */
+ UInt32 Cpu; /* container cpu */
+ UInt32 SubCpu; /* container sub-cpu */
+ UInt32 Flags; /* container flags */
+ UInt16 Kind; /* container kind */
+ UIntPtr Offset; /* content offset */
+ SizeT OffsetSize; /* offset size (physical size inside the file) */
+ UIntPtr VMAddress; /* Virtual Address */
+ SizeT VMSize; /* Virtual Size */
+} PACKED PEFCommandHeader;
+
+enum {
+ kPefInvalid = 0x0,
+ kPefCode = 0xC,
+ kPefData = 0xD,
+ kPefZero = 0xE,
+ kPefLinkerID = 0x1,
+ kPefCount = 4,
+};
+} // namespace Kernel
+
+#endif /* ifndef __KERNELKIT_PEF_H__ */
diff --git a/src/kernel/KernelKit/PEFCodeMgr.h b/src/kernel/KernelKit/PEFCodeMgr.h
new file mode 100644
index 00000000..41b135e0
--- /dev/null
+++ b/src/kernel/KernelKit/PEFCodeMgr.h
@@ -0,0 +1,75 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef _INC_CODE_MANAGER_PEF_H_
+#define _INC_CODE_MANAGER_PEF_H_
+
+/// @file PEFCodeMgr.h
+/// @brief PEF Code Manager header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/PEF.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KString.h>
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/ProcessScheduler.h>
+#endif
+
+#define kPefApplicationMime "application/vnd-nekernel-executable"
+
+namespace Kernel {
+///
+/// \name PEFLoader
+/// \brief PEF loader class.
+///
+class PEFLoader : public ILoader {
+ private:
+ explicit PEFLoader() = delete;
+
+ public:
+ explicit PEFLoader(const VoidPtr blob);
+ explicit PEFLoader(const Char* path);
+ ~PEFLoader() override;
+
+ public:
+ NE_COPY_DEFAULT(PEFLoader)
+
+ public:
+ const Char* Path() override;
+ const Char* AsString() override;
+ const Char* MIME() override;
+
+ public:
+ ErrorOr<VoidPtr> FindStart() override;
+ ErrorOr<VoidPtr> FindSymbol(const Char* name, Int32 kind) override;
+ ErrorOr<VoidPtr> GetBlob() override;
+
+ public:
+ bool IsLoaded() noexcept;
+
+ private:
+#ifdef __FSKIT_INCLUDES_NEFS__
+ OwnPtr<FileStream<Char, NeFileSystemMgr>> fFile;
+#elif defined(__FSKIT_INCLUDES_OPENHEFS__)
+ OwnPtr<FileStream<Char, HeFileSystemMgr>> fFile;
+#else
+ OwnPtr<FileStream<Char>> fFile;
+#endif // __FSKIT_INCLUDES_NEFS__
+
+ Ref<KString> fPath;
+ VoidPtr fCachedBlob;
+ BOOL fFatBinary{};
+ BOOL fBad{};
+};
+
+namespace Utils {
+ ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& procKind) noexcept;
+} // namespace Utils
+} // namespace Kernel
+
+#endif // ifndef _INC_CODE_MANAGER_PEF_H_
diff --git a/src/kernel/KernelKit/ProcessScheduler.h b/src/kernel/KernelKit/ProcessScheduler.h
new file mode 100644
index 00000000..7414e4fe
--- /dev/null
+++ b/src/kernel/KernelKit/ProcessScheduler.h
@@ -0,0 +1,18 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/KernelTaskScheduler.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+#ifdef __NEOSKRNL__
+namespace Kernel {
+inline UserProcessTeam kLowUserTeam;
+inline UserProcessTeam kHighUserTeam;
+inline UserProcessTeam kMidUserTeam;
+} // namespace Kernel
+#endif \ No newline at end of file
diff --git a/src/kernel/KernelKit/Semaphore.h b/src/kernel/KernelKit/Semaphore.h
new file mode 100644
index 00000000..831774a5
--- /dev/null
+++ b/src/kernel/KernelKit/Semaphore.h
@@ -0,0 +1,110 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/// @author Amlal El Mahrouss
+/// @file Semaphore.h
+/// @brief Semaphore structure and functions for synchronization in the kernel.
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/Defines.h>
+
+#define kSemaphoreOwnerIndex (0U)
+#define kSemaphoreCountIndex (1U)
+
+#define kSemaphoreCount (2U)
+
+#define kSemaphoreIncrementOwner(sem) (sem[kSemaphoreOwnerIndex]++)
+#define kSemaphoreDecrementOwner(sem) (sem[kSemaphoreOwnerIndex]--)
+
+namespace Kernel {
+/// @brief Semaphore structure used for synchronization.
+typedef UInt64 SemaphoreArr[kSemaphoreCount];
+
+/// @brief Checks if the semaphore is valid.
+inline BOOL rtl_sem_is_valid(const SemaphoreArr& sem, UInt64 owner = 0) {
+ return sem[kSemaphoreOwnerIndex] == owner && sem[kSemaphoreCountIndex] > 0;
+}
+
+/// @brief Releases the semaphore, resetting its owner and count.
+/// @param sem
+/// @return
+inline BOOL rtl_sem_release(SemaphoreArr& sem) {
+ sem[kSemaphoreOwnerIndex] = 0;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Initializes the semaphore with an owner and a count of zero.
+/// @param sem the semaphore array to use.
+/// @param owner the owner to set, could be anything identifitable.
+/// @return
+inline BOOL rtl_sem_acquire(SemaphoreArr& sem, UInt64 owner) {
+ if (!owner) {
+ err_global_get() = kErrorInvalidData;
+ return FALSE; // Invalid owner
+ }
+
+ sem[kSemaphoreOwnerIndex] = owner;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Waits for the semaphore to be available, blocking until it is.
+/// @param sem
+/// @param timeout
+/// @param condition condition pointer.
+/// @return
+inline BOOL rtl_sem_wait(SemaphoreArr& sem, UInt64 owner, UInt64 timeout,
+ BOOL* condition = nullptr) {
+ if (!rtl_sem_is_valid(sem, owner)) {
+ return FALSE;
+ }
+
+ if (timeout <= 0) {
+ err_global_get() = kErrorTimeout;
+
+ return FALSE;
+ }
+
+ if (!condition || *condition) {
+ if (sem[kSemaphoreCountIndex] == 0) {
+ err_global_get() = kErrorUnavailable;
+ return FALSE;
+ }
+
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+
+ HardwareTimer timer(timeout);
+ BOOL ret = timer.Wait();
+
+ if (ret) {
+ if (!condition || *condition) {
+ if (sem[kSemaphoreCountIndex] == 0) {
+ err_global_get() = kErrorUnavailable;
+ return FALSE;
+ }
+
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+ }
+
+ err_global_get() = kErrorTimeout;
+
+ return FALSE; // Failed to acquire semaphore
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/ThreadLocalStorage.h b/src/kernel/KernelKit/ThreadLocalStorage.h
new file mode 100644
index 00000000..205d6df9
--- /dev/null
+++ b/src/kernel/KernelKit/ThreadLocalStorage.h
@@ -0,0 +1,68 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef KERNELKIT_TLS_H
+#define KERNELKIT_TLS_H
+
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+
+///! @brief Thread Local Storage for NeKernel.
+
+#define kCookieMag0Idx (0U)
+#define kCookieMag1Idx (1U)
+#define kCookieMag2Idx (2U)
+
+#define kCookieMag0 'N'
+#define kCookieMag1 'K'
+#define kCookieMag2 'O'
+
+#define kCookieMagLen (3U)
+
+struct THREAD_INFORMATION_BLOCK;
+
+/// @brief Thread Information Block.
+/// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64)
+struct PACKED THREAD_INFORMATION_BLOCK final {
+ Kernel::Char Cookie[kCookieMagLen]{0}; //! Thread Magic Number.
+ Kernel::VoidPtr UserData{nullptr}; //! Thread Information Record (User defined canary structure)
+};
+
+///! @brief Cookie Sanity check.
+Kernel::Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* the_tib);
+
+///! @brief new ptr syscall.
+template <typename T>
+T* tls_new_ptr(void) noexcept;
+
+///! @brief delete ptr syscall.
+template <typename T>
+Kernel::Boolean tls_delete_ptr(T* ptr) noexcept;
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept;
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept;
+
+template <typename T, typename... Args>
+T* tls_new_class(Args&&... args);
+
+/// @brief TLS install TIB and PIB. (syscall)
+EXTERN_C Kernel::Void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB);
+
+/// @brief TLS check (syscall)
+EXTERN_C Kernel::Bool tls_check_syscall_impl(Kernel::VoidPtr TIB) noexcept;
+
+#include <KernelKit/ThreadLocalStorage.inl>
+
+// last rev 7/7/24
+
+#endif /* ifndef KERNELKIT_TLS_H */
diff --git a/src/kernel/KernelKit/ThreadLocalStorage.inl b/src/kernel/KernelKit/ThreadLocalStorage.inl
new file mode 100644
index 00000000..66a3d282
--- /dev/null
+++ b/src/kernel/KernelKit/ThreadLocalStorage.inl
@@ -0,0 +1,89 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+//! @file ThreadLocalStorage.inl
+//! @brief Allocate resources from the process's heap storage.
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/ProcessScheduler.h>
+#endif
+
+template <typename T>
+inline T* tls_new_ptr(void) noexcept {
+ using namespace Kernel;
+
+ auto ref_process = UserProcessScheduler::The().TheCurrentProcess();
+ MUST_PASS(ref_process);
+
+ auto pointer = ref_process.Leak().New(sizeof(T));
+
+ if (pointer.Error()) return nullptr;
+
+ return reinterpret_cast<T*>(pointer.Leak().Leak());
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(T* obj) noexcept {
+ using namespace Kernel;
+
+ if (!obj) return No;
+
+ auto ref_process = UserProcessScheduler::The().TheCurrentProcess();
+ MUST_PASS(ref_process);
+
+ ErrorOr<T*> obj_wrapped{obj};
+
+ return ref_process.Leak().Delete(obj_wrapped);
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept {
+ return tls_delete_ptr(obj.Leak());
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept {
+ return tls_delete_ptr(obj->Leak());
+}
+
+/// @brief Allocate a C++ class, and then call the constructor of it.
+/// @tparam T class type.
+/// @tparam ...Args varg class type.
+/// @param args arguments list.
+/// @return Class instance.
+template <typename T, typename... Args>
+T* tls_new_class(Args&&... args) {
+ using namespace Kernel;
+
+ T* obj = tls_new_ptr<T>();
+
+ if (obj) {
+ *obj = T(forward(args)...);
+ return obj;
+ }
+
+ return nullptr;
+}
+
+/// @brief Delete a C++ class (call constructor first.)
+/// @tparam T
+/// @param obj
+/// @return
+template <typename T>
+inline Kernel::Bool tls_delete_class(T* obj) {
+ using namespace Kernel;
+
+ if (!obj) return No;
+
+ obj->~T();
+ return tls_delete_ptr(obj);
+}
diff --git a/src/kernel/KernelKit/Timer.h b/src/kernel/KernelKit/Timer.h
new file mode 100644
index 00000000..46db5671
--- /dev/null
+++ b/src/kernel/KernelKit/Timer.h
@@ -0,0 +1,75 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/KPC.h>
+
+namespace Kernel {
+class SoftwareTimer;
+class TimerInterface;
+
+inline constexpr Int16 kTimeUnit = 1000;
+
+class TimerInterface {
+ public:
+ /// @brief Default constructor
+ explicit TimerInterface() = default;
+ virtual ~TimerInterface() = default;
+
+ public:
+ NE_COPY_DEFAULT(TimerInterface)
+
+ public:
+ virtual BOOL Wait() noexcept;
+};
+
+class SoftwareTimer final : public TimerInterface {
+ public:
+ explicit SoftwareTimer(Int64 seconds);
+ ~SoftwareTimer() override;
+
+ public:
+ NE_COPY_DEFAULT(SoftwareTimer)
+
+ public:
+ BOOL Wait() noexcept override;
+
+ private:
+ UIntPtr* fDigitalTimer{nullptr};
+ Int64 fWaitFor{0};
+};
+
+class HardwareTimer final : public TimerInterface {
+ public:
+ explicit HardwareTimer(UInt64 seconds);
+ ~HardwareTimer() override;
+
+ public:
+ NE_COPY_DEFAULT(HardwareTimer)
+
+ public:
+ BOOL Wait() noexcept override;
+
+ private:
+ volatile UInt8* fDigitalTimer{nullptr};
+ Int64 fWaitFor{0};
+};
+
+inline UInt64 rtl_microseconds(UInt64 time) {
+ if (time < 1) return 0;
+
+ // TODO: nanoseconds maybe?
+ return time / kTimeUnit;
+}
+
+inline UInt64 rtl_milliseconds(UInt64 time) {
+ if (time < 1) return 0;
+
+ return time;
+}
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/TraceSrv.h b/src/kernel/KernelKit/TraceSrv.h
new file mode 100644
index 00000000..df188ea2
--- /dev/null
+++ b/src/kernel/KernelKit/TraceSrv.h
@@ -0,0 +1,22 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ NeKernel is licensed under the Apache License 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+
+namespace Kernel {
+namespace Detail {
+ inline constexpr auto kDebugCmdLen = 256U;
+ inline constexpr auto kDebugPort = 51820;
+ inline constexpr auto kDebugMagic = "NE1.0.0;";
+ inline constexpr auto kDebugVersion = 0x0100;
+ inline constexpr auto kDebugDelim = ';';
+ inline constexpr auto kDebugEnd = '\r';
+ typedef UInt64 dk_socket_type;
+} // namespace Detail
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/UserMgr.h b/src/kernel/KernelKit/UserMgr.h
new file mode 100644
index 00000000..3ce6254d
--- /dev/null
+++ b/src/kernel/KernelKit/UserMgr.h
@@ -0,0 +1,95 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_USER_H
+#define INC_USER_H
+
+/* ========================================
+
+ Revision History:
+
+ 04/03/25: Set users directory as /libSystem/ instead of /usr/
+
+ ======================================== */
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+
+///! We got the MGMT, STD (%s format) and GUEST users,
+///! all are used to make authorized operations.
+#define kMgmtUser "NEKERNEL/MGMT/%s"
+#define kGuestUser "NEKERNEL/GUEST/%s"
+#define kStdUser "NEKERNEL/STD/%s"
+
+#define kUsersDir "/users/"
+
+#define kMaxUserNameLen (256U)
+#define kMaxUserTokenLen (256U)
+
+namespace Kernel {
+class User;
+
+enum class UserRingKind : Int32 {
+ kRingInvalid = 0,
+ kRingStdUser = 444,
+ kRingSuperUser = 666,
+ kRingGuestUser = 777,
+ kRingCount = 3,
+};
+
+typedef Char* UserPublicKey;
+typedef Char UserPublicKeyType;
+
+/// @brief System User class.
+class User final {
+ public:
+ User() = delete;
+
+ User(const Int32& sel, const Char* username);
+ User(const UserRingKind& kind, const Char* username);
+
+ ~User();
+
+ public:
+ NE_COPY_DEFAULT(User)
+
+ public:
+ bool operator==(const User& lhs);
+ bool operator!=(const User& lhs);
+
+ public:
+ /// @brief Get software ring
+ const UserRingKind& Ring() noexcept;
+
+ /// @brief Get user name
+ Char* Name() noexcept;
+
+ /// @brief Is he a standard user?
+ Bool IsStdUser() noexcept;
+
+ /// @brief Is she a super user?
+ Bool IsSuperUser() noexcept;
+
+ /// @brief Saves a password from the public key.
+ Bool Save(const UserPublicKey password) noexcept;
+
+ /// @brief Checks if a password matches the **password**.
+ /// @param password the password to check.
+ Bool Login(const UserPublicKey password) noexcept;
+
+ private:
+ UserRingKind mUserRing{UserRingKind::kRingStdUser};
+ Char mUserName[kMaxUserNameLen] = {0};
+ UInt64 mUserFNV{0UL};
+};
+
+inline User* kCurrentUser = nullptr;
+inline User* kRootUser = nullptr;
+} // namespace Kernel
+
+#endif /* ifndef INC_USER_H */
diff --git a/src/kernel/KernelKit/UserProcessScheduler.h b/src/kernel/KernelKit/UserProcessScheduler.h
new file mode 100644
index 00000000..b2ab7dc2
--- /dev/null
+++ b/src/kernel/KernelKit/UserProcessScheduler.h
@@ -0,0 +1,243 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#define INC_PROCESS_SCHEDULER_H
+
+/// @file UserProcessScheduler.h
+/// @brief User Process Scheduler header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/CoreProcessScheduler.h>
+#include <KernelKit/LockDelegate.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/MutableArray.h>
+
+////////////////////////////////////////////////////
+// Last revision date is: Fri Mar 28 2025 //
+////////////////////////////////////////////////////
+
+namespace Kernel {
+//! @brief Forward declarations.
+
+class IDylibObject;
+class UserProcessScheduler;
+class UserProcessHelper;
+
+/***********************************************************************************/
+/// @name USER_PROCESS
+/// @brief USER_PROCESS class, holds information about the running process/thread.
+/***********************************************************************************/
+class USER_PROCESS final {
+ public:
+ explicit USER_PROCESS();
+ ~USER_PROCESS();
+
+ public:
+ NE_COPY_DEFAULT(USER_PROCESS)
+
+ public:
+ Char Name[kSchedNameLen] = {"USER_PROCESS"};
+ ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemUser};
+ User* Owner{nullptr};
+ HAL::StackFramePtr StackFrame{nullptr};
+ AffinityKind Affinity{AffinityKind::kStandard};
+ ProcessStatusKind Status{ProcessStatusKind::kKilled};
+ UInt8 StackReserve[kSchedMaxStackSz];
+ ProcessImage Image{};
+ SizeT StackSize{kSchedMaxStackSz};
+ IDylibObject* DylibDelegate{nullptr};
+ SizeT MemoryCursor{0UL};
+ SizeT MemoryLimit{kSchedMaxMemoryLimit};
+ SizeT UsedMemory{0UL};
+
+ struct USER_PROCESS_SIGNAL final {
+ UIntPtr SignalArg{0};
+ ProcessStatusKind Status{ProcessStatusKind::kKilled};
+ UIntPtr SignalID{0};
+ };
+
+ USER_PROCESS_SIGNAL Signal;
+ PROCESS_FILE_TREE<VoidPtr>* FileTree{nullptr};
+ PROCESS_HEAP_TREE<VoidPtr>* HeapTree{nullptr};
+ UserProcessTeam* ParentTeam;
+
+ VoidPtr VMRegister{0UL};
+
+ enum {
+ kInvalidExecutableKind,
+ kExecutableKind,
+ kExecutableDylibKind,
+ kExecutableKindCount,
+ };
+
+ ProcessTime PTime{0}; //! @brief Process allocated tine.
+ ProcessTime RTime{0}; //! @brief Process run time.
+ ProcessTime UTime{0}; //! #brief Process used time.
+
+ ProcessID ProcessId{kSchedInvalidPID};
+ Int32 Kind{kExecutableKind};
+
+ public:
+ /***********************************************************************************/
+ //! @brief boolean operator, check status.
+ /***********************************************************************************/
+ explicit operator bool();
+
+ /***********************************************************************************/
+ ///! @brief Crashes the app, exits with code ~0.
+ /***********************************************************************************/
+ Void Crash();
+
+ /***********************************************************************************/
+ ///! @brief Spawns a dynamic library handle if dylib.
+ /***********************************************************************************/
+ Bool InitDylib();
+
+ /***********************************************************************************/
+ ///! @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<VoidPtr> New(SizeT sz, SizeT pad_amount = 0);
+
+ /***********************************************************************************/
+ ///! @brief TLS free.
+ ///! @param ptr the pointer to free.
+ ///! @param sz the size of it.
+ /***********************************************************************************/
+ template <typename T>
+ Boolean Delete(ErrorOr<T*> ptr);
+
+ /***********************************************************************************/
+ ///! @brief Wakes up thread.
+ /***********************************************************************************/
+ Void Wake(Bool wakeup = false);
+
+ public:
+ /***********************************************************************************/
+ //! @brief Gets the local exit code.
+ /***********************************************************************************/
+ KPCError& 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.
+ /***********************************************************************************/
+ KPCError& GetLocalCode() noexcept;
+
+ const User* GetOwner() noexcept;
+ const ProcessStatusKind& GetStatus() noexcept;
+ const AffinityKind& GetAffinity() noexcept;
+
+ private:
+ KPCError LastExitCode{0};
+ KPCError LocalCode{0};
+
+ friend UserProcessScheduler;
+ friend UserProcessHelper;
+};
+
+typedef Array<USER_PROCESS, kSchedProcessLimitPerTeam> USER_PROCESS_ARRAY;
+typedef Ref<USER_PROCESS> USER_PROCESS_REF;
+
+/// \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<USER_PROCESS, kSchedProcessLimitPerTeam>& AsArray();
+ Ref<USER_PROCESS>& AsRef();
+ ProcessID& Id() noexcept;
+
+ public:
+ USER_PROCESS_ARRAY mProcessList;
+ USER_PROCESS_REF mCurrentProcess;
+ ProcessID mTeamId{0};
+ ProcessID mProcessCur{0};
+};
+
+/***********************************************************************************/
+/// @brief USER_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_DELETE(UserProcessScheduler)
+ NE_MOVE_DELETE(UserProcessScheduler)
+
+ public:
+ explicit operator bool();
+ bool operator!();
+
+ public:
+ UserProcessTeam& TheCurrentTeam();
+ BOOL SwitchTeam(UserProcessTeam& team);
+
+ public:
+ ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image);
+ Void Remove(ProcessID process_id);
+
+ Bool IsUser() override;
+ Bool IsKernel() override;
+ Bool HasMP() override;
+
+ public:
+ USER_PROCESS_REF& TheCurrentProcess();
+ SizeT Run() noexcept;
+
+ public:
+ STATIC UserProcessScheduler& The();
+
+ private:
+ UserProcessTeam mTeam{};
+};
+
+/***********************************************************************************/
+/**
+ * \brief USER_PROCESS helper class, which contains needed utilities for the scheduler.
+ */
+/***********************************************************************************/
+
+class UserProcessHelper final {
+ public:
+ STATIC Bool Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid);
+ STATIC Bool CanBeScheduled(const USER_PROCESS& process);
+ STATIC ErrorOr<ProcessID> TheCurrentPID();
+ STATIC SizeT StartScheduling();
+};
+} // namespace Kernel
+
+#include <KernelKit/ThreadLocalStorage.h>
+#include <KernelKit/UserProcessScheduler.inl>
+
+////////////////////////////////////////////////////
+// END
+////////////////////////////////////////////////////
+
+#endif /* ifndef INC_PROCESS_SCHEDULER_H */
diff --git a/src/kernel/KernelKit/UserProcessScheduler.inl b/src/kernel/KernelKit/UserProcessScheduler.inl
new file mode 100644
index 00000000..3d3659d6
--- /dev/null
+++ b/src/kernel/KernelKit/UserProcessScheduler.inl
@@ -0,0 +1,64 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ FILE: UserProcessScheduler.inl
+ PURPOSE: Low level/Ring-3 process scheduler.
+
+======================================== */
+
+/// @brief USER_PROCESS inline definitions.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+/// @date Tue Apr 22 22:01:07 CEST 2025
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/UserProcessScheduler.h>
+#endif // INC_PROCESS_SCHEDULER_H
+
+namespace Kernel {
+/***********************************************************************************/
+/** @brief Free pointer/file from usage. */
+/***********************************************************************************/
+
+template <typename T>
+BOOL USER_PROCESS::Delete(ErrorOr<T*> ptr) {
+ if (!ptr) return No;
+
+ if (!this->HeapTree) {
+ kout << "USER_PROCESS's heap is empty.\r";
+ return No;
+ }
+
+ PROCESS_HEAP_TREE<VoidPtr>* entry = this->HeapTree;
+
+ while (entry != nullptr) {
+ if (entry->Entry == ptr.Leak().Leak()) {
+ this->UsedMemory -= entry->EntrySize;
+
+#ifdef __NE_AMD64__
+ auto pd = hal_read_cr3();
+
+ hal_write_cr3(this->VMRegister);
+
+ auto ret = mm_free_ptr(entry->Entry);
+
+ hal_write_cr3(pd);
+
+ return ret == kErrorSuccess;
+#else
+ Bool ret = mm_free_ptr(ptr.Leak().Leak());
+
+ return ret == kErrorSuccess;
+#endif
+ }
+
+ entry = entry->Next;
+ }
+
+ kout << "USER_PROCESS: Trying to free a pointer which doesn't exist.\r";
+
+ this->Crash();
+
+ return No;
+}
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/XCOFF.h b/src/kernel/KernelKit/XCOFF.h
new file mode 100644
index 00000000..cbee6100
--- /dev/null
+++ b/src/kernel/KernelKit/XCOFF.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: XCOFF.h
+ Purpose: XCOFF for Kernel.
+
+ Revision History:
+
+ 04/07/24: Added file (amlel)
+
+======================================== */
+
+#ifndef INC_XOCFF_H
+#define INC_XOCFF_H
+
+#include <NeKit/Defines.h>
+
+#define kXCOFF64Magic (0x01F7)
+#define kXCOFF64ForkNameLen (256U)
+
+#define kXCOFFRelFlg (0x0001)
+#define kXCOFFExecutable (0x0002)
+#define kXCOFFLnno (0x0004)
+#define kXCOFFLSyms (0x0008)
+
+struct XCOFF_FILE_HEADER;
+struct XCOFF_FORK_HEADER;
+
+/// @brief XCoff file header, meant for POWER apps.
+typedef struct XCOFF_FILE_HEADER {
+ Kernel::UInt16 fMagic;
+ Kernel::UInt16 fTarget;
+ Kernel::UInt16 fNumSecs;
+ Kernel::UInt32 fTimeDat;
+ Kernel::UIntPtr fSymPtr;
+ Kernel::UInt32 fNumSyms;
+ Kernel::UInt16 fOptHdr; // ?: Number of bytes in optional header
+} XCOFF_FILE_HEADER, XCOFF_FILE_HEADER32, XCOFF_FILE_HEADER64;
+
+/// @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[kXCOFF64ForkNameLen];
+ Kernel::Char fDynamicLoaderFork[kXCOFF64ForkNameLen];
+ Kernel::Char fCodeSignFork[kXCOFF64ForkNameLen];
+} XCOFF_FORK_HEADER;
+
+#endif // ifndef INC_XOCFF_H
diff --git a/src/kernel/KernelKit/ZXD.h b/src/kernel/KernelKit/ZXD.h
new file mode 100644
index 00000000..a4b07bfa
--- /dev/null
+++ b/src/kernel/KernelKit/ZXD.h
@@ -0,0 +1,53 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define kZXDMagicNumber (0x2010AF)
+#define kZXDVersion (0x0001)
+
+namespace Kernel {
+struct ZXD_EXEC_HEADER;
+struct ZXD_STUB_HEADER;
+
+enum ZXD_FLAGS {
+ kZXDFlagsInvalid,
+ kZXDFlagsDriver,
+ kZXDFlagsCount,
+};
+
+/// @brief ZXD executable header
+/// @details This header is used to identify ZXD executable files.
+struct PACKED ZXD_EXEC_HEADER final {
+ UInt32 fMagic;
+ UInt32 fVersion;
+ UInt32 fFlags;
+ UInt32 fHdrSize;
+ UInt32 fCRC32;
+ UInt32 fAssigneeSignature;
+ UInt32 fIssuerSingature;
+ UIntPtr fExecOffset;
+ SizeT fExecSize;
+ UIntPtr fStubOffset;
+ SizeT fStubSize;
+ SizeT fStubAlign;
+ SizeT fStubCount;
+};
+
+/// @brief ZXD stub header
+/// @details This header is used to identify ZXD stub files. It contains the size of the stub, the
+/// offset of the stub, and the CRC32 checksum of the stub.
+struct PACKED ZXD_STUB_HEADER final {
+ UInt32 fStubSize;
+ UInt32 fStubOffset;
+ UInt32 fStubCRC32;
+};
+
+using ZXD_EXEC_HEADER_PTR = ZXD_EXEC_HEADER*;
+using ZXD_STUB_HEADER_PTR = ZXD_STUB_HEADER*;
+} // namespace Kernel