summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'dev/Kernel/src')
-rw-r--r--dev/Kernel/src/ACPIFactoryInterface.cc96
-rw-r--r--dev/Kernel/src/Array.cc7
-rw-r--r--dev/Kernel/src/ArrayList.cc7
-rw-r--r--dev/Kernel/src/Atom.cc10
-rw-r--r--dev/Kernel/src/BitMapMgr.cc186
-rw-r--r--dev/Kernel/src/CodeMgr.cc28
-rw-r--r--dev/Kernel/src/Crc32.cc83
-rw-r--r--dev/Kernel/src/CxxAbi-AMD64.cc90
-rw-r--r--dev/Kernel/src/CxxAbi-ARM64.cc107
-rw-r--r--dev/Kernel/src/Defines.cc7
-rw-r--r--dev/Kernel/src/DeviceMgr.cc7
-rw-r--r--dev/Kernel/src/DriveMgr+IO.cc96
-rw-r--r--dev/Kernel/src/DriveMgr.cc230
-rw-r--r--dev/Kernel/src/ErrorOr.cc12
-rw-r--r--dev/Kernel/src/FS/HPFS.cc22
-rw-r--r--dev/Kernel/src/FileMgr.cc52
-rw-r--r--dev/Kernel/src/GUIDWizard.cc72
-rw-r--r--dev/Kernel/src/GUIDWrapper.cc11
-rw-r--r--dev/Kernel/src/HardwareThreadScheduler.cc219
-rw-r--r--dev/Kernel/src/Heap.cc301
-rw-r--r--dev/Kernel/src/IDylibObject.cc15
-rw-r--r--dev/Kernel/src/IPEFDylibObject.cc103
-rw-r--r--dev/Kernel/src/IndexableProperty.cc57
-rw-r--r--dev/Kernel/src/Json.cc10
-rw-r--r--dev/Kernel/src/KString.cc217
-rw-r--r--dev/Kernel/src/KernelMain.cc102
-rw-r--r--dev/Kernel/src/LPC.cc34
-rw-r--r--dev/Kernel/src/LockDelegate.cc12
-rw-r--r--dev/Kernel/src/MutableArray.cc7
-rw-r--r--dev/Kernel/src/Network/IPAddr.cc129
-rw-r--r--dev/Kernel/src/Network/IPCAddr.cc0
-rw-r--r--dev/Kernel/src/Network/IPCMsg.cc102
-rw-r--r--dev/Kernel/src/Network/NetworkDevice.cc35
-rw-r--r--dev/Kernel/src/New+Delete.cc50
-rw-r--r--dev/Kernel/src/OwnPtr.cc7
-rw-r--r--dev/Kernel/src/PEFCodeMgr.cc268
-rw-r--r--dev/Kernel/src/PRDT.cc24
-rw-r--r--dev/Kernel/src/PageMgr.cc110
-rw-r--r--dev/Kernel/src/Pmm.cc98
-rw-r--r--dev/Kernel/src/Property.cc45
-rw-r--r--dev/Kernel/src/Ref.cc7
-rw-r--r--dev/Kernel/src/Semaphore.cc69
-rw-r--r--dev/Kernel/src/SoftwareTimer.cc39
-rw-r--r--dev/Kernel/src/Storage/AHCIDeviceInterface.cc35
-rw-r--r--dev/Kernel/src/Storage/ATADeviceInterface.cc88
-rw-r--r--dev/Kernel/src/Storage/NVMEDeviceInterface.cc28
-rw-r--r--dev/Kernel/src/Storage/SCSIDeviceInterface.cc11
-rw-r--r--dev/Kernel/src/Stream.cc12
-rw-r--r--dev/Kernel/src/System/SwapDisk.cc47
-rw-r--r--dev/Kernel/src/ThreadLocalStorage.cc67
-rw-r--r--dev/Kernel/src/Timer.cc19
-rw-r--r--dev/Kernel/src/User.cc188
-rw-r--r--dev/Kernel/src/UserProcessScheduler.cc607
-rw-r--r--dev/Kernel/src/UserProcessTeam.cc58
-rw-r--r--dev/Kernel/src/Utils.cc219
-rw-r--r--dev/Kernel/src/Variant.cc33
56 files changed, 4595 insertions, 0 deletions
diff --git a/dev/Kernel/src/ACPIFactoryInterface.cc b/dev/Kernel/src/ACPIFactoryInterface.cc
new file mode 100644
index 00000000..cbfded4e
--- /dev/null
+++ b/dev/Kernel/src/ACPIFactoryInterface.cc
@@ -0,0 +1,96 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <NewKit/KString.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Heap.h>
+
+namespace Kernel
+{
+ /// @brief Finds a descriptor table inside ACPI XSDT.
+ ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature)
+ {
+ MUST_PASS(fRsdp);
+
+ if (!signature)
+ return ErrorOr<voidPtr>{-1};
+
+ if (*signature == 0)
+ return ErrorOr<voidPtr>{-1};
+
+ RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp);
+
+ if (rsp_ptr->Revision <= 1)
+ return ErrorOr<voidPtr>{-1};
+
+ RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress);
+
+ Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64);
+
+ /***
+ crucial to avoid underflows.
+ */
+ if (num < 1)
+ {
+ /// stop here, we should have entries...
+ ke_panic(RUNTIME_CHECK_ACPI);
+ return ErrorOr<voidPtr>{-1};
+ }
+
+ this->fEntries = num;
+
+ kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl;
+ kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl;
+ kcout << "ACPI: Signature: " << xsdt->Signature << endl;
+ kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl;
+
+ const short cAcpiSignatureLength = 4;
+
+ for (Size index = 0; index < this->fEntries; ++index)
+ {
+ SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]);
+
+ kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl;
+ kcout << "ACPI: Revision: " << number(sdt->Revision) << endl;
+
+ for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index)
+ {
+ if (sdt->Signature[signature_index] != signature[signature_index])
+ break;
+
+ if (signature_index == (cAcpiSignatureLength - 1))
+ {
+ kcout << "ACPI: SDT Signature: " << sdt->Signature << endl;
+ kcout << "ACPI: SDT OEM ID: " << sdt->OemId << endl;
+ return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index]));
+ }
+ }
+ }
+
+ return ErrorOr<voidPtr>{-1};
+ }
+
+ /***
+ @brief Checksum on SDT header.
+ @param checksum the header to checksum
+ @param len the length of it.
+ */
+ bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len)
+ {
+ if (len == 0)
+ return 1;
+
+ char chr = 0;
+
+ for (int index = 0; index < len; ++index)
+ {
+ chr += checksum[index];
+ }
+
+ return chr == 0;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Array.cc b/dev/Kernel/src/Array.cc
new file mode 100644
index 00000000..71f65c06
--- /dev/null
+++ b/dev/Kernel/src/Array.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Array.h>
diff --git a/dev/Kernel/src/ArrayList.cc b/dev/Kernel/src/ArrayList.cc
new file mode 100644
index 00000000..a43fd4e0
--- /dev/null
+++ b/dev/Kernel/src/ArrayList.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/ArrayList.h>
diff --git a/dev/Kernel/src/Atom.cc b/dev/Kernel/src/Atom.cc
new file mode 100644
index 00000000..92937411
--- /dev/null
+++ b/dev/Kernel/src/Atom.cc
@@ -0,0 +1,10 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Atom.h>
+
+// @file Atom.cpp
+// @brief Atomic primitives
diff --git a/dev/Kernel/src/BitMapMgr.cc b/dev/Kernel/src/BitMapMgr.cc
new file mode 100644
index 00000000..a098322c
--- /dev/null
+++ b/dev/Kernel/src/BitMapMgr.cc
@@ -0,0 +1,186 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+
+#ifdef __ZKA_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#elif defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Paging.h>
+#endif
+
+#include <NewKit/Defines.h>
+#include <NewKit/KernelPanic.h>
+
+#define kBitMapMagic (0x10210U)
+#define kBitMapPadSize (mib_cast(16))
+
+#define kBitMapMagIdx (0U)
+#define kBitMapSizeIdx (1U)
+#define kBitMapUsedIdx (2U)
+
+namespace Kernel
+{
+ namespace HAL
+ {
+ namespace Detail
+ {
+ /// \brief Proxy Interface to allocate a bitmap.
+ class IBitMapAllocator final
+ {
+ public:
+ explicit IBitMapAllocator() = default;
+ ~IBitMapAllocator() = default;
+
+ ZKA_COPY_DELETE(IBitMapAllocator);
+
+ auto IsBitMap(VoidPtr page_ptr) -> Bool
+ {
+ if (!page_ptr)
+ return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ if (!ptr_bit_set[kBitMapMagIdx] ||
+ ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
+ return No;
+
+ return Yes;
+ }
+
+ auto FreeBitMap(VoidPtr page_ptr) -> Bool
+ {
+ if (this->IsBitMap(page_ptr) == No)
+ return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[kBitMapUsedIdx] = No;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ return Yes;
+ }
+
+ UInt32 MakeMMFlags(Bool wr, Bool user)
+ {
+ UInt32 flags = kMMFlagsPresent;
+
+ if (wr)
+ flags |= kMMFlagsWr;
+
+ if (user)
+ flags |= kMMFlagsUser;
+
+ return flags;
+ }
+
+ /// @brief Iterate over availables pages for a free one.
+ /// @return The new address which was found.
+ auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr
+ {
+ if (!size)
+ return nullptr;
+
+ VoidPtr base = reinterpret_cast<VoidPtr>(((UIntPtr)base_ptr) + kPageSize);
+
+ while (YES)
+ {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
+
+ if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic &&
+ ptr_bit_set[kBitMapSizeIdx] <= size)
+ {
+ if (ptr_bit_set[kBitMapUsedIdx] == No)
+ {
+ ptr_bit_set[kBitMapSizeIdx] = size;
+ ptr_bit_set[kBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeMMFlags(wr, user);
+ mm_map_page(ptr_bit_set, flags);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+
+ kcout << "Missed potential BitMap as it is already used!\r\n";
+ }
+ else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
+ {
+ ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[kBitMapSizeIdx] = size;
+ ptr_bit_set[kBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeMMFlags(wr, user);
+ mm_map_page(ptr_bit_set, flags);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+
+ base = reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(base) + ((ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) ? (size) : ptr_bit_set[kBitMapSizeIdx]));
+ }
+
+ return nullptr;
+ }
+
+ /// @brief Print Bitmap status
+ auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void
+ {
+ if (!this->IsBitMap(ptr_bit_set))
+ {
+ kcout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl;
+ return;
+ }
+
+ kcout << "Magic Number: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << endl;
+ kcout << "Is Allocated: " << (ptr_bit_set[kBitMapUsedIdx] ? "Yes" : "No") << endl;
+ kcout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << endl;
+ kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Address Of BitMap Header: " << hex_number((UIntPtr)ptr_bit_set) << endl;
+ }
+ };
+ } // namespace Detail
+
+ auto mm_is_bitmap(VoidPtr ptr) -> Bool
+ {
+ Detail::IBitMapAllocator traits;
+ return traits.IsBitMap(ptr);
+ }
+
+ /// @brief Allocate a new page to be used by the OS.
+ /// @param wr read/write bit.
+ /// @param user user bit.
+ /// @return a new bitmap allocated pointer.
+ auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr
+ {
+ VoidPtr ptr_new = nullptr;
+ Detail::IBitMapAllocator traits;
+
+ ptr_new = traits.FindBitMap(kKernelBitMpStart, size, wr, user);
+
+ return (UIntPtr*)ptr_new;
+ }
+
+ /// @brief Free Bitmap, and mark it a absent in page terms.
+ auto mm_free_bitmap(VoidPtr page_ptr) -> Bool
+ {
+ if (!page_ptr)
+ return No;
+
+ Detail::IBitMapAllocator traits;
+ Bool ret = traits.FreeBitMap(page_ptr);
+
+ return ret;
+ }
+ } // namespace HAL
+} // namespace Kernel
diff --git a/dev/Kernel/src/CodeMgr.cc b/dev/Kernel/src/CodeMgr.cc
new file mode 100644
index 00000000..de35f846
--- /dev/null
+++ b/dev/Kernel/src/CodeMgr.cc
@@ -0,0 +1,28 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/CodeMgr.h>
+#include <NewKit/Utils.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @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 if the process was started or not.
+ /***********************************************************************************/
+
+ ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept
+ {
+ if (!process_name ||
+ *process_name == 0)
+ return kProcessInvalidID;
+
+ return UserProcessScheduler::The().Spawn(process_name, reinterpret_cast<VoidPtr>(main), nullptr);
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Crc32.cc b/dev/Kernel/src/Crc32.cc
new file mode 100644
index 00000000..fcc2bf3f
--- /dev/null
+++ b/dev/Kernel/src/Crc32.cc
@@ -0,0 +1,83 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Crc32.h>
+
+// @file CRC32.cpp
+// @brief Check sequence implementation.
+
+namespace Kernel
+{
+ /// @brief The CRC32 seed table.
+ UInt32 kCrcTbl[kCrcCnt] = {
+ 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL,
+ 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL,
+ 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L,
+ 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+ 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L,
+ 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL,
+ 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L,
+ 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+ 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
+ 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L,
+ 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L,
+ 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+ 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL,
+ 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L,
+ 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L,
+ 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+ 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL,
+ 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
+ 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L,
+ 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+ 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL,
+ 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L,
+ 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL,
+ 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+ 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL,
+ 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL,
+ 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
+ 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+ 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L,
+ 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL,
+ 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL,
+ 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+ 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L,
+ 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL,
+ 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L,
+ 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+ 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L,
+ 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL,
+ 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L,
+ 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+ 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L,
+ 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L,
+ 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L,
+ 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+ 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
+ 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L,
+ 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L,
+ 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+ 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL,
+ 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L,
+ 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L,
+ 0xAD7D5351L};
+
+ /// @brief Calculate CRC32 of p
+ /// @param p the data to compute.
+ /// @param len the length of the data.
+ /// @return the CRC32.
+ UInt ke_calculate_crc32(const Char* p, UInt len) noexcept
+ {
+ UInt crc = 0xffffffff;
+
+ while (len-- != 0)
+ crc = kCrcTbl[((UInt8)crc ^ *(p++))] ^ (crc >> 8);
+
+ // return (~crc); also works, does the same thing.
+ return (crc ^ 0xffffffff);
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/CxxAbi-AMD64.cc b/dev/Kernel/src/CxxAbi-AMD64.cc
new file mode 100644
index 00000000..9065ece5
--- /dev/null
+++ b/dev/Kernel/src/CxxAbi-AMD64.cc
@@ -0,0 +1,90 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifdef __ZKA_AMD64__
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/CxxAbi.h>
+#include <KernelKit/LPC.h>
+
+atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors];
+
+uarch_t __atexit_func_count;
+
+/// @brief dynamic shared object Handle.
+Kernel::UIntPtr __dso_handle;
+
+EXTERN_C Kernel::Void __cxa_pure_virtual(void* self)
+{
+ kcout << "object: " << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self));
+ kcout << ", has unimplemented virtual functions.\r";
+}
+
+EXTERN_C void ___chkstk_ms(void)
+{
+}
+
+EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso)
+{
+ if (__atexit_func_count >= kAtExitMacDestructors)
+ return 1;
+
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+ __atexit_funcs[__atexit_func_count].obj_ptr = arg;
+ __atexit_funcs[__atexit_func_count].dso_handle = dso;
+
+ __atexit_func_count++;
+
+ return 0;
+}
+
+EXTERN_C void __cxa_finalize(void* f)
+{
+ uarch_t i = __atexit_func_count;
+ if (!f)
+ {
+ while (i--)
+ {
+ if (__atexit_funcs[i].destructor_func)
+ {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ };
+ }
+
+ return;
+ }
+
+ while (i--)
+ {
+ if (__atexit_funcs[i].destructor_func)
+ {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+}
+
+namespace cxxabiv1
+{
+ EXTERN_C int __cxa_guard_acquire(__guard* g)
+ {
+ (void)g;
+ return 0;
+ }
+
+ EXTERN_C int __cxa_guard_release(__guard* g)
+ {
+ *(char*)g = 1;
+ return 0;
+ }
+
+ EXTERN_C void __cxa_guard_abort(__guard* g)
+ {
+ (void)g;
+ }
+} // namespace cxxabiv1
+
+#endif // ifdef __ZKA_AMD64__
diff --git a/dev/Kernel/src/CxxAbi-ARM64.cc b/dev/Kernel/src/CxxAbi-ARM64.cc
new file mode 100644
index 00000000..127e12c6
--- /dev/null
+++ b/dev/Kernel/src/CxxAbi-ARM64.cc
@@ -0,0 +1,107 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifdef __ZKA_ARM64__
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/CxxAbi.h>
+#include <KernelKit/LPC.h>
+
+atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors];
+
+uarch_t __atexit_func_count;
+
+/// @brief dynamic shared object Handle.
+Kernel::UIntPtr __dso_handle;
+
+EXTERN_C void __chkstk(void)
+{
+}
+
+EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso)
+{
+ if (__atexit_func_count >= kAtExitMacDestructors)
+ return 1;
+
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+ __atexit_funcs[__atexit_func_count].obj_ptr = arg;
+ __atexit_funcs[__atexit_func_count].dso_handle = dso;
+
+ __atexit_func_count++;
+
+ return 0;
+}
+
+EXTERN_C void __cxa_finalize(void* f)
+{
+ uarch_t i = __atexit_func_count;
+ if (!f)
+ {
+ while (i--)
+ {
+ if (__atexit_funcs[i].destructor_func)
+ {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ };
+ }
+
+ return;
+ }
+
+ while (i--)
+ {
+ if (__atexit_funcs[i].destructor_func)
+ {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+}
+
+namespace cxxabiv1
+{
+ EXTERN_C int __cxa_guard_acquire(__guard* g)
+ {
+ (void)g;
+ return 0;
+ }
+
+ EXTERN_C int __cxa_guard_release(__guard* g)
+ {
+ *(char*)g = 1;
+ return 0;
+ }
+
+ EXTERN_C void __cxa_guard_abort(__guard* g)
+ {
+ (void)g;
+ }
+} // namespace cxxabiv1
+
+EXTERN_C Kernel::Void _purecall(void* self)
+{
+ kcout << "object: " << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self));
+ kcout << ", has unimplemented virtual functions.\r";
+}
+
+EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj)
+{
+ ZKA_UNUSED(thread_obj);
+}
+
+EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void)
+{
+ ZKA_UNUSED(0);
+}
+
+EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj)
+{
+ ZKA_UNUSED(0);
+}
+
+EXTERN_C Kernel::Int _tls_index = 0UL;
+
+#endif // ifdef __ZKA_ARM64__
diff --git a/dev/Kernel/src/Defines.cc b/dev/Kernel/src/Defines.cc
new file mode 100644
index 00000000..2252d68d
--- /dev/null
+++ b/dev/Kernel/src/Defines.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Defines.h>
diff --git a/dev/Kernel/src/DeviceMgr.cc b/dev/Kernel/src/DeviceMgr.cc
new file mode 100644
index 00000000..88bed209
--- /dev/null
+++ b/dev/Kernel/src/DeviceMgr.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DeviceMgr.h>
diff --git a/dev/Kernel/src/DriveMgr+IO.cc b/dev/Kernel/src/DriveMgr+IO.cc
new file mode 100644
index 00000000..ee857ed4
--- /dev/null
+++ b/dev/Kernel/src/DriveMgr+IO.cc
@@ -0,0 +1,96 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/FileMgr.h>
+
+/*************************************************************
+ *
+ * File: DriveMgr+IO.cc
+ * Purpose: Filesystem to mountpoint interface.
+ * Date: 3/26/24
+ *
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ *************************************************************/
+
+/// Useful macros.
+
+#define rtl_nefs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS)
+#define rtl_nefs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS)
+
+namespace Kernel
+{
+ /// @brief Read from newfs disk.
+ /// @param Mnt mounted interface.
+ /// @param DrvTrait drive info
+ /// @param DrvIndex drive index.
+ /// @return
+ Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex)
+ {
+ if (!Mnt)
+ return 1;
+
+ DrvTrait.fPacket.fPacketGood = false;
+
+ switch (DrvIndex)
+ {
+ case MountpointInterface::kDriveIndexA: {
+ rtl_nefs_read(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexB: {
+ rtl_nefs_read(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexC: {
+ rtl_nefs_read(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexD: {
+ rtl_nefs_read(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
+
+ return DrvTrait.fPacket.fPacketGood;
+ }
+
+ /// @brief Write to newfs disk.
+ /// @param Mnt mounted interface.
+ /// @param DrvTrait drive info
+ /// @param DrvIndex drive index.
+ /// @return
+ Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex)
+ {
+ if (!Mnt)
+ return 1;
+
+ DrvTrait.fPacket.fPacketGood = false;
+
+ switch (DrvIndex)
+ {
+ case MountpointInterface::kDriveIndexA: {
+ rtl_nefs_write(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexB: {
+ rtl_nefs_write(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexC: {
+ rtl_nefs_write(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexD: {
+ rtl_nefs_write(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
+
+ return DrvTrait.fPacket.fPacketGood;
+ }
+} // namespace Kernel \ No newline at end of file
diff --git a/dev/Kernel/src/DriveMgr.cc b/dev/Kernel/src/DriveMgr.cc
new file mode 100644
index 00000000..9968e2e6
--- /dev/null
+++ b/dev/Kernel/src/DriveMgr.cc
@@ -0,0 +1,230 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/DriveMgr.h>
+#include <NewKit/Utils.h>
+#include <FirmwareKit/EPM.h>
+#include <Mod/ATA/ATA.h>
+#include <Mod/AHCI/AHCI.h>
+#include <Mod/NVME/NVME.h>
+
+/***********************************************************************************/
+/// @file DriveMgr.cc
+/// @brief Drive Manager of minoskrnl.
+/***********************************************************************************/
+
+namespace Kernel
+{
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ STATIC UInt16 kATAIO = 0U;
+ STATIC UInt8 kATAMaster = 0U;
+#endif
+
+ /// @brief reads from an ATA drive.
+ /// @param pckt Packet structure (fPacketContent must be non null)
+ /// @return
+ Void io_drv_input(DriveTrait::DrivePacket pckt)
+ {
+#ifdef __AHCI__
+ drv_std_read(pckt.fPacketLba, (Char*)pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize);
+#elif defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ drv_std_read(pckt.fPacketLba, kATAIO, kATAMaster, (Char*)pckt.fPacketContent, kATASectorSize, pckt.fPacketSize);
+#endif
+ }
+
+ /// @brief Writes to an ATA drive.
+ /// @param pckt the packet to write.
+ /// @return
+ Void io_drv_output(DriveTrait::DrivePacket pckt)
+ {
+ if (pckt.fPacketReadOnly)
+ return;
+
+ kcout << "Writing blob to disk...\r";
+
+#ifdef __AHCI__
+ drv_std_write(pckt.fPacketLba, (Char*)pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize);
+#elif defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ drv_std_write(pckt.fPacketLba, kATAIO, kATAMaster, (Char*)pckt.fPacketContent, kATASectorSize, pckt.fPacketSize);
+#endif
+ }
+
+ /// @brief Executes a disk check on the ATA drive.
+ /// @param pckt the packet to read.
+ /// @return
+ Void io_drv_init(DriveTrait::DrivePacket pckt)
+ {
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ kATAMaster = 0;
+ kATAIO = 0;
+#endif
+
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ kATAMaster = true;
+ kATAIO = ATA_PRIMARY_IO;
+
+ if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster))
+ {
+ pckt.fPacketGood = YES;
+ return;
+ }
+
+ kATAMaster = false;
+ kATAIO = ATA_SECONDARY_IO;
+
+ if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster))
+ {
+ return;
+ }
+
+ pckt.fPacketGood = YES;
+#elif defined(__AHCI__)
+ UInt16 pi = 0;
+
+ if (!drv_std_init(pi))
+ {
+ return;
+ }
+#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__)
+ }
+
+/// @brief Gets the drive kind (ATA, SCSI, AHCI...)
+/// @param no arguments.
+/// @return no arguments.
+#ifdef __ATA_PIO__
+ const Char* io_drv_kind(Void)
+ {
+ return "ATA-PIO";
+ }
+#endif
+#ifdef __ATA_DMA__
+ const Char* io_drv_kind(Void)
+ {
+ return "ATA-DMA";
+ }
+#endif
+#ifdef __AHCI__
+ const Char* io_drv_kind(Void)
+ {
+ return "AHCI";
+ }
+#endif
+#ifdef __ZKA_MINIMAL_OS__
+ const Char* io_drv_kind(Void)
+ {
+ return "Not Loaded";
+ }
+#endif
+
+ /// @brief Unimplemented drive function.
+ /// @param pckt the packet to read.
+ Void io_drv_unimplemented(DriveTrait::DrivePacket pckt) noexcept
+ {
+ ZKA_UNUSED(pckt);
+ }
+
+ /// @brief Makes a new drive.
+ /// @return the new blank drive.
+ DriveTrait io_construct_blank_drive() noexcept
+ {
+ DriveTrait trait;
+
+ constexpr auto kBlankDrive = "/media/blank/";
+
+ rt_copy_memory((VoidPtr)kBlankDrive, trait.fName, rt_string_len(kBlankDrive));
+ trait.fKind = kInvalidDisc;
+
+ trait.fInput = io_drv_unimplemented;
+ trait.fOutput = io_drv_unimplemented;
+ trait.fVerify = io_drv_unimplemented;
+ trait.fInit = io_drv_unimplemented;
+ trait.fDriveKind = io_drv_kind;
+
+ kcout << "Construct: " << trait.fName << "\r";
+
+ return trait;
+ }
+
+ namespace Detect
+ {
+ Void io_detect_drive(DriveTrait& trait)
+ {
+ EPM_PART_BLOCK block_struct;
+
+ trait.fPacket.fPacketLba = kEPMBootBlockLba;
+ trait.fPacket.fPacketSize = sizeof(EPM_PART_BLOCK);
+ trait.fPacket.fPacketContent = &block_struct;
+
+ rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime,
+ rt_string_len("fs/detect-packet"));
+
+ trait.fInit(trait.fPacket);
+
+ trait.fInput(trait.fPacket);
+
+ if (rt_string_cmp(((BOOT_BLOCK_STRUCT*)trait.fPacket.fPacketContent)->Magic, kEPMMagic, kEPMMagicLength) == 0)
+ {
+ trait.fPacket.fPacketReadOnly = NO;
+ trait.fKind = kMassStorageDisc | kEPMDrive;
+
+ kcout << "Formatted Disk is EPM (Mass Storage)\r";
+
+ trait.fSectorSz = block_struct.SectorSz;
+ trait.fLbaEnd = block_struct.LbaEnd;
+ trait.fLbaStart = block_struct.LbaStart;
+
+ if (trait.fSectorSz == 0 ||
+ trait.fLbaEnd == 0)
+ {
+ ke_panic(RUNTIME_CHECK_FAILED, "Invalid EPM partition!");
+ }
+ }
+ else
+ {
+ trait.fPacket.fPacketReadOnly = YES;
+ trait.fKind = kMassStorageDisc | kUnformattedDrive | kReadOnlyDrive;
+
+ kcout << "Scheme Found: " << block_struct.Name << endl;
+
+ if (block_struct.Name[0] == 0)
+ kcout << "Disk partition is empty (Read Only)\r";
+ }
+
+ rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime,
+ rt_string_len("*/*"));
+
+ trait.fPacket.fPacketLba = 0;
+ trait.fPacket.fPacketSize = 0UL;
+ trait.fPacket.fPacketContent = nullptr;
+ }
+ } // namespace Detect
+
+ /// @brief Fetches the main drive.
+ /// @return the new drive. (returns kEPMDrive if EPM formatted)
+ DriveTrait io_construct_main_drive() noexcept
+ {
+ DriveTrait trait;
+
+ constexpr auto kMainDrive = "/media/sda/";
+
+ rt_copy_memory((VoidPtr)kMainDrive, trait.fName, rt_string_len(kMainDrive));
+
+ MUST_PASS(trait.fName[0] != 0);
+
+ trait.fVerify = io_drv_unimplemented;
+ trait.fOutput = io_drv_output;
+ trait.fInput = io_drv_input;
+ trait.fInit = io_drv_init;
+ trait.fDriveKind = io_drv_kind;
+
+ kcout << "Detecting partition scheme of: " << trait.fName << ".\r";
+
+ Detect::io_detect_drive(trait);
+
+ return trait;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/ErrorOr.cc b/dev/Kernel/src/ErrorOr.cc
new file mode 100644
index 00000000..f365277f
--- /dev/null
+++ b/dev/Kernel/src/ErrorOr.cc
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/ErrorOr.h>
+
+/***********************************************************************************/
+/// @file ErrorOr.cc ///
+/// @brief ErrorOr container class. ///
+/***********************************************************************************/
diff --git a/dev/Kernel/src/FS/HPFS.cc b/dev/Kernel/src/FS/HPFS.cc
new file mode 100644
index 00000000..984ca243
--- /dev/null
+++ b/dev/Kernel/src/FS/HPFS.cc
@@ -0,0 +1,22 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifdef __FSKIT_INCLUDES_HPFS__
+
+#include <Mod/AHCI/AHCI.h>
+#include <Mod/ATA/ATA.h>
+#include <Mod/Flash/Flash.h>
+#include <FSKit/HPFS.h>
+#include <KernelKit/LPC.h>
+#include <NewKit/Crc32.h>
+#include <NewKit/KernelPanic.h>
+#include <NewKit/KString.h>
+#include <NewKit/Utils.h>
+#include <FirmwareKit/EPM.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/User.h>
+
+#endif // ifdef __FSKIT_INCLUDES_HPFS__
diff --git a/dev/Kernel/src/FileMgr.cc b/dev/Kernel/src/FileMgr.cc
new file mode 100644
index 00000000..0e05daa1
--- /dev/null
+++ b/dev/Kernel/src/FileMgr.cc
@@ -0,0 +1,52 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/FileMgr.h>
+#include <NewKit/Utils.h>
+
+/// @file FileMgr.cc
+//! @brief File System Manager API.
+
+namespace Kernel
+{
+ STATIC IFilesystemMgr* kMountedFilesystem = nullptr;
+
+ /// @brief FilesystemMgr getter.
+ /// @return The mounted filesystem.
+ _Output IFilesystemMgr* IFilesystemMgr::GetMounted()
+ {
+ return kMountedFilesystem;
+ }
+
+ /// @brief Unmount filesystem.
+ /// @return The unmounted filesystem.
+ _Output IFilesystemMgr* IFilesystemMgr::Unmount()
+ {
+ if (kMountedFilesystem)
+ {
+ auto mount = kMountedFilesystem;
+ kMountedFilesystem = nullptr;
+
+ return mount;
+ }
+
+ return nullptr;
+ }
+
+ /// @brief Mount filesystem.
+ /// @param mount_ptr The filesystem to mount.
+ /// @return if it succeeded true, otherwise false.
+ _Output Bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr)
+ {
+ if (mount_ptr != nullptr)
+ {
+ kMountedFilesystem = mount_ptr;
+ return Yes;
+ }
+
+ return No;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/GUIDWizard.cc b/dev/Kernel/src/GUIDWizard.cc
new file mode 100644
index 00000000..854a0db7
--- /dev/null
+++ b/dev/Kernel/src/GUIDWizard.cc
@@ -0,0 +1,72 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: GUIDWizard.cc
+ Purpose: GUID helper code
+
+ Revision History:
+
+------------------------------------------- */
+
+#include <CFKit/GUIDWizard.h>
+#include <NewKit/Ref.h>
+
+// begin of ascii 'readable' characters. (A, C, C, 1, 2)
+#define kUUIDAsciiBegin 47
+// @brief Size of UUID.
+#define kUUIDSize 37
+
+namespace CFKit::XRN::Version1
+{
+ auto cf_make_sequence(const ArrayList<UInt32>& uuidSeq) -> Ref<GUIDSequence*>
+ {
+ GUIDSequence* seq = new GUIDSequence();
+ MUST_PASS(seq);
+
+ Ref<GUIDSequence*> seq_ref{seq};
+
+ seq_ref.Leak()->fMs1 = uuidSeq[0];
+ seq_ref.Leak()->fMs2 = uuidSeq[1];
+ seq_ref.Leak()->fMs3 = uuidSeq[2];
+ seq_ref.Leak()->fMs4[0] = uuidSeq[3];
+ seq_ref.Leak()->fMs4[1] = uuidSeq[4];
+ seq_ref.Leak()->fMs4[2] = uuidSeq[5];
+ seq_ref.Leak()->fMs4[3] = uuidSeq[6];
+ seq_ref.Leak()->fMs4[4] = uuidSeq[7];
+ seq_ref.Leak()->fMs4[5] = uuidSeq[8];
+ seq_ref.Leak()->fMs4[6] = uuidSeq[9];
+ seq_ref.Leak()->fMs4[7] = uuidSeq[10];
+
+ return seq_ref;
+ }
+
+ // @brief Tries to make a guid out of a string.
+ // This function is not complete for now
+ auto cf_try_guid_to_string(Ref<GUIDSequence*>& seq) -> ErrorOr<Ref<KString>>
+ {
+ Char buf[kUUIDSize];
+
+ for (SizeT index = 0; index < 16; ++index)
+ {
+ buf[index] = seq.Leak()->u8[index] + kUUIDAsciiBegin;
+ }
+
+ for (SizeT index = 16; index < 24; ++index)
+ {
+ buf[index] = seq.Leak()->u16[index] + kUUIDAsciiBegin;
+ }
+
+ for (SizeT index = 24; index < 28; ++index)
+ {
+ buf[index] = seq.Leak()->u32[index] + kUUIDAsciiBegin;
+ }
+
+ auto view = StringBuilder::Construct(buf);
+
+ if (view)
+ return ErrorOr<Ref<KString>>{view.Leak()};
+
+ return ErrorOr<Ref<KString>>{-1};
+ }
+} // namespace CFKit::XRN::Version1
diff --git a/dev/Kernel/src/GUIDWrapper.cc b/dev/Kernel/src/GUIDWrapper.cc
new file mode 100644
index 00000000..eda9cf29
--- /dev/null
+++ b/dev/Kernel/src/GUIDWrapper.cc
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <CFKit/GUIDWrapper.h>
+
+namespace CFKit::XRN
+{
+}
diff --git a/dev/Kernel/src/HardwareThreadScheduler.cc b/dev/Kernel/src/HardwareThreadScheduler.cc
new file mode 100644
index 00000000..66500f73
--- /dev/null
+++ b/dev/Kernel/src/HardwareThreadScheduler.cc
@@ -0,0 +1,219 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <CFKit/Property.h>
+
+/***********************************************************************************/
+///! @file HardwareThreadScheduler.cc
+///! @brief This file handles multi processing in the Kernel.
+///! @brief Multi processing is needed for multi-tasking operations.
+/***********************************************************************************/
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @note Those symbols are needed in order to switch and validate the stack.
+ /***********************************************************************************/
+
+ EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame);
+ EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid);
+
+ STATIC HardwareThreadScheduler kHardwareThreadScheduler;
+
+ ///! A HardwareThread class takes care of it's owned hardware thread.
+ ///! It has a stack for it's core.
+
+ /***********************************************************************************/
+ ///! @brief C++ constructor.
+ /***********************************************************************************/
+ HardwareThread::HardwareThread() = default;
+
+ /***********************************************************************************/
+ ///! @brief C++ destructor.
+ /***********************************************************************************/
+ HardwareThread::~HardwareThread() = default;
+
+ /***********************************************************************************/
+ //! @brief returns the id of the thread.
+ /***********************************************************************************/
+ const ThreadID& HardwareThread::ID() noexcept
+ {
+ return fID;
+ }
+
+ /***********************************************************************************/
+ //! @brief returns the kind of thread we have.
+ /***********************************************************************************/
+ const ThreadKind& HardwareThread::Kind() noexcept
+ {
+ return fKind;
+ }
+
+ /***********************************************************************************/
+ //! @brief is the thread busy?
+ //! @return whether the thread is busy or not.
+ /***********************************************************************************/
+ Bool HardwareThread::IsBusy() noexcept
+ {
+ STATIC Int64 busy_timer = 0U;
+
+ if (fBusy && busy_timer > this->fPTime)
+ {
+ busy_timer = 0U;
+ fBusy = No;
+ }
+
+ ++busy_timer;
+
+ return fBusy;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get processor stack frame.
+ /***********************************************************************************/
+
+ HAL::StackFramePtr HardwareThread::StackFrame() noexcept
+ {
+ MUST_PASS(fStack);
+ return fStack;
+ }
+
+ Void HardwareThread::Busy(const Bool busy) noexcept
+ {
+ fBusy = busy;
+ }
+
+ HardwareThread::operator bool()
+ {
+ return this->fStack && !this->fBusy;
+ }
+
+ /***********************************************************************************/
+ /// @brief Wakeup the processor.
+ /***********************************************************************************/
+
+ Void HardwareThread::Wake(const bool wakeup) noexcept
+ {
+ fWakeup = wakeup;
+ }
+
+ /***********************************************************************************/
+ /// @brief Switch to hardware thread.
+ /// @param stack the new hardware thread.
+ /// @retval true stack was changed, code is running.
+ /// @retval false stack is invalid, previous code is running.
+ /***********************************************************************************/
+ Bool HardwareThread::Switch(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid)
+ {
+ this->fStack = frame;
+ this->fSourcePID = pid;
+
+ fStack->BP = reinterpret_cast<UIntPtr>(image_ptr);
+ fStack->SP = reinterpret_cast<UIntPtr>(stack_ptr);
+
+ Bool ret = mp_register_process(fStack, this->fSourcePID);
+
+ if (ret)
+ this->Busy(YES);
+
+ return ret;
+ }
+
+ /***********************************************************************************/
+ ///! @brief Tells if processor is waked up.
+ /***********************************************************************************/
+ bool HardwareThread::IsWakeup() noexcept
+ {
+ return fWakeup;
+ }
+
+ /***********************************************************************************/
+ ///! @brief Constructor and destructors.
+ ///! @brief Default constructor.
+ /***********************************************************************************/
+
+ HardwareThreadScheduler::HardwareThreadScheduler() = default;
+
+ /***********************************************************************************/
+ ///! @brief Default destructor.
+ /***********************************************************************************/
+ HardwareThreadScheduler::~HardwareThreadScheduler() = default;
+
+ /***********************************************************************************/
+ /// @brief Shared singleton function
+ /***********************************************************************************/
+ HardwareThreadScheduler& HardwareThreadScheduler::The()
+ {
+ return kHardwareThreadScheduler;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get Stack Frame of AP.
+ /***********************************************************************************/
+ HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept
+ {
+ return fThreadList[fCurrentThread].fStack;
+ }
+
+ /***********************************************************************************/
+ /**
+ * Get Hardware thread at index.
+ * @param idx the index
+ * @return the reference to the hardware thread.
+ */
+ /***********************************************************************************/
+ Ref<HardwareThread*> HardwareThreadScheduler::operator[](const SizeT& idx)
+ {
+ if (idx == 0)
+ {
+ if (fThreadList[idx].Kind() != kAPSystemReserved)
+ {
+ fThreadList[idx].fKind = kAPBoot;
+ }
+ }
+ else if (idx >= kMaxAPInsideSched)
+ {
+ static HardwareThread* fakeThread = nullptr;
+ return {fakeThread};
+ }
+
+ return &fThreadList[idx];
+ }
+
+ /***********************************************************************************/
+ /**
+ * Check if thread pool isn't empty.
+ * @return
+ */
+ /***********************************************************************************/
+ HardwareThreadScheduler::operator bool() noexcept
+ {
+ return !fThreadList.Empty();
+ }
+
+ /***********************************************************************************/
+ /**
+ * Reverse operator bool
+ * @return
+ */
+ /***********************************************************************************/
+ bool HardwareThreadScheduler::operator!() noexcept
+ {
+ return fThreadList.Empty();
+ }
+
+ /***********************************************************************************/
+ /// @brief Returns the amount of core present.
+ /// @return the number of APs.
+ /***********************************************************************************/
+ SizeT HardwareThreadScheduler::Capacity() noexcept
+ {
+ return fThreadList.Count();
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Heap.cc b/dev/Kernel/src/Heap.cc
new file mode 100644
index 00000000..7b2da96d
--- /dev/null
+++ b/dev/Kernel/src/Heap.cc
@@ -0,0 +1,301 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/LPC.h>
+#include <KernelKit/Heap.h>
+#include <NewKit/Crc32.h>
+#include <NewKit/PageMgr.h>
+#include <NewKit/Utils.h>
+#include <ArchKit/ArchKit.h>
+
+/* -------------------------------------------
+
+ Revision History:
+ 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field.
+ 20/10/24: Fix mm_new_ and mm_delete_ APIs inside Heap.h header. (amlal)
+
+ ------------------------------------------- */
+
+//! @file Heap.cc
+//! @brief This serves as the main memory manager.
+
+#define kKernelHeapMagic (0xD4D7D5)
+#define kKernelHeapAlignSz (__BIGGEST_ALIGNMENT__)
+#define kKernelHeapMaxSize (gib_cast(2))
+
+namespace Kernel
+{
+ /// @brief Contains data structures and algorithms for the heap.
+ namespace Detail
+ {
+ struct PACKED HEAP_INFORMATION_BLOCK;
+
+ /// @brief Kernel heap information block.
+ /// Located before the address bytes.
+ /// | HIB | CLASS/STRUCT/DATA TYPES... |
+ struct PACKED HEAP_INFORMATION_BLOCK final
+ {
+ ///! @brief 32-bit value which contains the magic number of the heap.
+ UInt64 fMagic;
+
+ ///! @brief Boolean value which tells if the heap is allocated.
+ Boolean fPresent : 1;
+
+ /// @brief Is this valued owned by the user?
+ Boolean fWriteRead : 1;
+
+ /// @brief Is this valued owned by the user?
+ Boolean fUser : 1;
+
+ /// @brief Is this a page pointer?
+ Boolean fPagePtr : 1;
+
+ /// @brief 32-bit CRC checksum.
+ UInt32 fCRC32;
+
+ /// @brief 64-bit Allocation flags.
+ UInt64 fFlags;
+
+ /// @brief 64-bit pointer size.
+ SizeT fHeapSize;
+
+ /// @brief 64-bit target offset pointer.
+ UIntPtr fHeapPtr;
+
+ /// @brief Padding bytes for header.
+ UInt8 fPadding[kKernelHeapAlignSz];
+ };
+
+ /// @brief Check for heap address validity.
+ /// @param heap_ptr The address_ptr to check.
+ /// @return Bool if the pointer is valid or not.
+ _Output auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool
+ {
+ if (!heap_ptr)
+ return false;
+
+ /// Add that check in case we're having an integer underflow. ///
+
+ auto base_heap = (IntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK);
+
+ if (base_heap < 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ typedef HEAP_INFORMATION_BLOCK* HEAP_INFORMATION_BLOCK_PTR;
+ } // namespace Detail
+
+ /// @brief Declare a new size for ptr_heap.
+ /// @param ptr_heap the pointer.
+ /// @return Newly allocated heap header.
+ _Output VoidPtr mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz)
+ {
+ if (Detail::mm_check_heap_address(ptr_heap) == No)
+ return nullptr;
+
+ if (!ptr_heap || new_sz < 1)
+ return nullptr;
+
+ kcout << "This function is not implemented by minOSKrnl, please use the BSD's realloc instead.\r";
+ ke_panic(RUNTIME_CHECK_PROCESS);
+
+ return nullptr;
+ }
+
+ /// @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.
+ _Output VoidPtr mm_new_heap(const SizeT sz, const bool wr, const bool user)
+ {
+ auto sz_fix = sz;
+
+ if (sz_fix == 0)
+ return nullptr;
+
+ // We can't allocate that big now.
+ MUST_PASS(sz < kKernelHeapMaxSize);
+
+ sz_fix += sizeof(Detail::HEAP_INFORMATION_BLOCK);
+
+ PageMgr heap_mgr;
+ auto wrapper = heap_mgr.Request(wr, user, No, sz_fix);
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ wrapper.VirtualAddress() + sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ heap_info_ptr->fHeapSize = sz_fix;
+ heap_info_ptr->fMagic = kKernelHeapMagic;
+ heap_info_ptr->fCRC32 = 0; // dont fill it for now.
+ heap_info_ptr->fHeapPtr = reinterpret_cast<UIntPtr>(heap_info_ptr) + sizeof(Detail::HEAP_INFORMATION_BLOCK);
+ heap_info_ptr->fPagePtr = No;
+ heap_info_ptr->fWriteRead = wr;
+ heap_info_ptr->fUser = user;
+ heap_info_ptr->fPresent = Yes;
+
+ rt_set_memory(heap_info_ptr->fPadding, 0, kKernelHeapAlignSz);
+
+ auto result = reinterpret_cast<VoidPtr>(heap_info_ptr->fHeapPtr);
+
+ kcout << "Created Heap address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << endl;
+
+ return result;
+ }
+
+ /// @brief Makes a page heap.
+ /// @param heap_ptr the pointer to make a page heap.
+ /// @return kErrorSuccess if successful, otherwise an error code.
+ _Output Int32 mm_make_page(VoidPtr heap_ptr)
+ {
+ if (Detail::mm_check_heap_address(heap_ptr) == No)
+ return kErrorHeapNotPresent;
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr)
+ return kErrorHeapNotPresent;
+
+ heap_info_ptr->fPagePtr = true;
+
+ kcout << "Created page address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << endl;
+
+ return kErrorSuccess;
+ }
+
+ /// @brief Overwrites and set the flags of a heap header.
+ /// @param heap_ptr the pointer to update.
+ /// @param flags the flags to set.
+ _Output Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags)
+ {
+ if (Detail::mm_check_heap_address(heap_ptr) == No)
+ return kErrorHeapNotPresent;
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr)
+ return kErrorHeapNotPresent;
+
+ heap_info_ptr->fFlags = flags;
+
+ return kErrorSuccess;
+ }
+
+ /// @brief Gets the flags of a heap header.
+ /// @param heap_ptr the pointer to get.
+ _Output UInt64 mm_get_flags(VoidPtr heap_ptr)
+ {
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr)
+ return kErrorHeapNotPresent;
+
+ return heap_info_ptr->fFlags;
+ }
+
+ /// @brief Declare pointer as free.
+ /// @param heap_ptr the pointer.
+ /// @return
+ _Output Int32 mm_delete_heap(VoidPtr heap_ptr)
+ {
+ if (Detail::mm_check_heap_address(heap_ptr) == No)
+ return kErrorHeapNotPresent;
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (heap_info_ptr && heap_info_ptr->fMagic == kKernelHeapMagic)
+ {
+ if (!heap_info_ptr->fPresent)
+ {
+ return kErrorHeapNotPresent;
+ }
+
+ heap_info_ptr->fHeapSize = 0UL;
+ heap_info_ptr->fPresent = No;
+ heap_info_ptr->fHeapPtr = 0;
+ heap_info_ptr->fCRC32 = 0;
+ heap_info_ptr->fWriteRead = No;
+ heap_info_ptr->fUser = No;
+ heap_info_ptr->fMagic = 0;
+
+ PTEWrapper pageWrapper(No, No, No, reinterpret_cast<UIntPtr>(heap_info_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+ Ref<PTEWrapper> pteAddress{pageWrapper};
+
+ PageMgr heap_mgr;
+ heap_mgr.Free(pteAddress);
+
+ kcout << "Freed Heap address successfully." << endl;
+
+ return kErrorSuccess;
+ }
+
+ return kErrorInternal;
+ }
+
+ /// @brief Check if pointer is a valid Kernel pointer.
+ /// @param heap_ptr the pointer
+ /// @return if it exists.
+ _Output Boolean mm_is_valid_heap(VoidPtr heap_ptr)
+ {
+ if (heap_ptr && HAL::mm_is_bitmap(heap_ptr))
+ {
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kKernelHeapMagic)
+ {
+ if (heap_info_ptr->fCRC32 !=
+ ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr,
+ heap_info_ptr->fHeapSize))
+ {
+ return No;
+ }
+
+ return Yes;
+ }
+ }
+
+ return No;
+ }
+
+ /// @brief Protect the heap with a CRC value.
+ /// @param heap_ptr HIB pointer.
+ /// @return if it valid: point has crc now., otherwise fail.
+ _Output Boolean mm_protect_heap(VoidPtr heap_ptr)
+ {
+ if (heap_ptr)
+ {
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (heap_info_ptr && heap_info_ptr->fPresent && kKernelHeapMagic == heap_info_ptr->fMagic)
+ {
+ heap_info_ptr->fCRC32 =
+ ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr, heap_info_ptr->fHeapSize);
+
+ return Yes;
+ }
+ }
+
+ return No;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/IDylibObject.cc b/dev/Kernel/src/IDylibObject.cc
new file mode 100644
index 00000000..2bd84a2c
--- /dev/null
+++ b/dev/Kernel/src/IDylibObject.cc
@@ -0,0 +1,15 @@
+/*
+ * ========================================================
+ *
+ * minoskrnl
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/IDylibObject.h>
+#include <KernelKit/DebugOutput.h>
+
+#include <KernelKit/UserProcessScheduler.h>
+
+using namespace Kernel;
diff --git a/dev/Kernel/src/IPEFDylibObject.cc b/dev/Kernel/src/IPEFDylibObject.cc
new file mode 100644
index 00000000..a28f2a94
--- /dev/null
+++ b/dev/Kernel/src/IPEFDylibObject.cc
@@ -0,0 +1,103 @@
+/*
+ * ========================================================
+ *
+ * minoskrnl
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/PEF.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/ThreadLocalStorage.h>
+#include <NewKit/Defines.h>
+
+/* -------------------------------------------
+
+ Revision History:
+
+ 01/02/24: Reworked dll ABI, expect a rtl_init_dylib and
+ rtl_fini_dylib (amlel) 15/02/24: Breaking changes, changed the name of the
+ routines. (amlel)
+
+ 07/28/24: Replace rt_library_free with rtl_fini_dylib
+
+ 10/8/24: FIX: Fix log comment.
+
+ ------------------------------------------- */
+
+using namespace Kernel;
+
+/***********************************************************************************/
+/// @file IPEFDylibObject.cc
+/// @brief PEF's Dylib runtime.
+/***********************************************************************************/
+
+/***********************************************************************************/
+/** @brief Library initializer. */
+/***********************************************************************************/
+
+EXTERN_C IDylibRef rtl_init_dylib(UserProcess& thread)
+{
+ IDylibRef dll_obj = tls_new_class<IPEFDylibObject>();
+
+ if (!dll_obj)
+ {
+ thread.Crash();
+ return nullptr;
+ }
+
+ dll_obj->Mount(new IPEFDylibObject::DLL_TRAITS());
+
+ if (!dll_obj->Get())
+ {
+ tls_delete_class(dll_obj);
+ thread.Crash();
+
+ return nullptr;
+ }
+
+ dll_obj->Get()->ImageObject =
+ thread.Image.fBlob;
+
+ if (!dll_obj->Get()->ImageObject)
+ {
+ tls_delete_class(dll_obj);
+ thread.Crash();
+
+ return nullptr;
+ }
+
+ dll_obj->Get()->ImageEntrypointOffset =
+ dll_obj->Load<VoidPtr>(kPefStart, rt_string_len(kPefStart, 0), kPefCode);
+
+ return dll_obj;
+}
+
+/***********************************************************************************/
+/** @brief Frees the dll_obj. */
+/** @note Please check if the dll_obj got freed! */
+/** @param dll_obj The dll_obj to free. */
+/** @param successful Reports if successful or not. */
+/***********************************************************************************/
+
+EXTERN_C Void rtl_fini_dylib(UserProcess& thread, IDylibRef dll_obj, Bool* successful)
+{
+ MUST_PASS(successful);
+
+ // sanity check (will also trigger a bug check if this fails)
+ if (dll_obj == nullptr)
+ {
+ *successful = false;
+ thread.Crash();
+ }
+
+ delete dll_obj->Get();
+ delete dll_obj;
+
+ dll_obj = nullptr;
+
+ *successful = true;
+}
diff --git a/dev/Kernel/src/IndexableProperty.cc b/dev/Kernel/src/IndexableProperty.cc
new file mode 100644
index 00000000..2d64e4d7
--- /dev/null
+++ b/dev/Kernel/src/IndexableProperty.cc
@@ -0,0 +1,57 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <CompilerKit/CompilerKit.h>
+#include <FSKit/IndexableProperty.h>
+#include <NewKit/MutableArray.h>
+#include <NewKit/Utils.h>
+
+/// @brief File indexer API for fast path access.
+/// BUGS: 0
+
+#define kMaxLenIndexer (256U)
+
+namespace Kernel
+{
+ namespace Indexer
+ {
+ IndexProperty& IndexableProperty::Leak() noexcept
+ {
+ return fIndex;
+ }
+
+ Void IndexableProperty::AddFlag(Int16 flag)
+ {
+ fFlags |= flag;
+ }
+
+ Void IndexableProperty::RemoveFlag(Int16 flag)
+ {
+ fFlags &= flag;
+ }
+
+ Int16 IndexableProperty::HasFlag(Int16 flag)
+ {
+ return fFlags & flag;
+ }
+
+ /// @brief Index a file into the indexer instance.
+ /// @param filename filesystem path to access.
+ /// @param filenameLen used bytes in path.
+ /// @param indexer the filesystem indexer.
+ /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)).
+ Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer)
+ {
+ if (!indexer.HasFlag(kIndexerClaimed))
+ {
+ indexer.AddFlag(kIndexerClaimed);
+ rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen);
+
+ kcout << "FSKit: Indexed new file: " << filename << endl;
+ }
+ }
+ } // namespace Indexer
+} // namespace Kernel
diff --git a/dev/Kernel/src/Json.cc b/dev/Kernel/src/Json.cc
new file mode 100644
index 00000000..9dff3959
--- /dev/null
+++ b/dev/Kernel/src/Json.cc
@@ -0,0 +1,10 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Json.h>
+
+/// @brief Undefined object, is null in length.
+RTL_INIT_OBJECT(Kernel::JSON::kNull, Kernel::JSON);
diff --git a/dev/Kernel/src/KString.cc b/dev/Kernel/src/KString.cc
new file mode 100644
index 00000000..64429c1e
--- /dev/null
+++ b/dev/Kernel/src/KString.cc
@@ -0,0 +1,217 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/KString.h>
+#include <NewKit/Utils.h>
+
+/// @file KString.cc
+/// @brief Kernel String manipulation file.
+
+namespace Kernel
+{
+ Char* KString::Data()
+ {
+ return fData;
+ }
+
+ const Char* KString::CData() const
+ {
+ return fData;
+ }
+
+ Size KString::Length() const
+ {
+ return fDataSz;
+ }
+
+ bool KString::operator==(const KString& rhs) const
+ {
+ if (rhs.Length() != this->Length())
+ return false;
+
+ for (Size index = 0; index < this->Length(); ++index)
+ {
+ if (rhs.fData[index] != fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool KString::operator==(const Char* rhs) const
+ {
+ if (rt_string_len(rhs) != this->Length())
+ return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index)
+ {
+ if (rhs[index] != fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool KString::operator!=(const KString& rhs) const
+ {
+ if (rhs.Length() != this->Length())
+ return false;
+
+ for (Size index = 0; index < rhs.Length(); ++index)
+ {
+ if (rhs.fData[index] == fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool KString::operator!=(const Char* rhs) const
+ {
+ if (rt_string_len(rhs) != this->Length())
+ return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index)
+ {
+ if (rhs[index] == fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ ErrorOr<KString> StringBuilder::Construct(const Char* data)
+ {
+ if (!data || *data == 0)
+ return {};
+
+ KString* view = new KString(rt_string_len(data));
+ (*view) += data;
+
+ return ErrorOr<KString>(*view);
+ }
+
+ const Char* StringBuilder::FromBool(const Char* fmt, bool i)
+ {
+ if (!fmt)
+ return ("?");
+
+ const Char* boolean_expr = i ? "YES" : "NO";
+ Char* ret = (Char*)rtl_alloca((sizeof(char) * i) ? 4 : 5 + rt_string_len(fmt));
+
+ if (!ret)
+ return ("?");
+
+ const auto fmt_len = rt_string_len(fmt);
+ const auto res_len = rt_string_len(boolean_expr);
+
+ for (Size idx = 0; idx < fmt_len; ++idx)
+ {
+ if (fmt[idx] == '%')
+ {
+ SizeT result_cnt = idx;
+
+ for (auto y_idx = idx; y_idx < res_len; ++y_idx)
+ {
+ ret[result_cnt] = boolean_expr[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+ }
+
+ bool StringBuilder::Equals(const Char* lhs, const Char* rhs)
+ {
+ if (rt_string_len(rhs) != rt_string_len(lhs))
+ return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index)
+ {
+ if (rhs[index] != lhs[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool StringBuilder::Equals(const WideChar* lhs, const WideChar* rhs)
+ {
+ for (Size index = 0; rhs[index] != 0; ++index)
+ {
+ if (rhs[index] != lhs[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ const Char* StringBuilder::Format(const Char* fmt, const Char* fmt2)
+ {
+ if (!fmt || !fmt2)
+ return ("?");
+
+ Char* ret =
+ (Char*)rtl_alloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt));
+
+ if (!ret)
+ return ("?");
+
+ for (Size idx = 0; idx < rt_string_len(fmt); ++idx)
+ {
+ if (fmt[idx] == '%')
+ {
+ Size result_cnt = idx;
+ for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx)
+ {
+ ret[result_cnt] = fmt2[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+ }
+
+ STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur)
+ {
+ SizeT sz_rhs = rt_string_len(rhs);
+ SizeT rhs_i = 0;
+
+ for (; rhs_i < sz_rhs; ++rhs_i)
+ {
+ lhs[rhs_i + cur] = rhs[rhs_i];
+ }
+ }
+
+ KString& KString::operator+=(const Char* rhs)
+ {
+ rt_string_append(this->fData, rhs, this->fCur);
+ this->fCur += rt_string_len(rhs);
+
+ return *this;
+ }
+
+ KString& KString::operator+=(const KString& rhs)
+ {
+ if (rt_string_len(rhs.fData) > this->Length())
+ return *this;
+
+ rt_string_append(this->fData, const_cast<Char*>(rhs.fData), this->fCur);
+ this->fCur += rt_string_len(const_cast<Char*>(rhs.fData));
+
+ return *this;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/KernelMain.cc b/dev/Kernel/src/KernelMain.cc
new file mode 100644
index 00000000..7875fa7c
--- /dev/null
+++ b/dev/Kernel/src/KernelMain.cc
@@ -0,0 +1,102 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss
+
+ File: Main.cxx
+ Purpose: Main entrypoint of kernel.
+
+------------------------------------------- */
+
+#include <KernelKit/PE.h>
+#include <ArchKit/ArchKit.h>
+#include <CompilerKit/Detail.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Heap.h>
+#include <KernelKit/PEF.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/Heap.h>
+#include <NewKit/Json.h>
+#include <NewKit/KString.h>
+#include <NewKit/Utils.h>
+#include <KernelKit/CodeMgr.h>
+#include <CFKit/Property.h>
+#include <KernelKit/Timer.h>
+
+#ifdef __ZKA_AUTO_FORMAT__
+namespace Kernel::Detail
+{
+ /// @brief Filesystem auto formatter, additional checks are also done by the class.
+ class NeFilesystemInstaller final
+ {
+ private:
+ Kernel::NeFileSystemParser* mNeFS{nullptr};
+ Kernel::NeFileSystemJournal mJournal;
+
+ public:
+ /// @brief wizard constructor.
+ explicit NeFilesystemInstaller()
+ {
+ mNeFS = new Kernel::NeFileSystemParser();
+
+ if (mNeFS)
+ {
+ const SizeT kFolderCount = 13;
+ const Char* kFolderStr[kFolderCount] = {
+ "/", "/boot/", "/sys/", "/media/", "/etc/",
+ "/usr/", "/lib/", "/mnt/", "/sbin/", "/n/", "/dev/", "/run/", "/root/"};
+
+ for (Kernel::SizeT dir_index = 0UL; dir_index < kFolderCount; ++dir_index)
+ {
+ auto catalog_folder = mNeFS->GetCatalog(kFolderStr[dir_index]);
+
+ if (catalog_folder)
+ {
+ delete catalog_folder;
+ catalog_folder = nullptr;
+
+ continue;
+ }
+
+ catalog_folder = mNeFS->CreateCatalog(kFolderStr[dir_index], 0,
+ kNeFSCatalogKindDir);
+
+ if (!catalog_folder)
+ continue;
+
+ delete catalog_folder;
+ catalog_folder = nullptr;
+ }
+
+ if (!mJournal.GetJournal(mNeFS))
+ mJournal.CreateJournal(mNeFS);
+
+ mJournal.CommitJournal(mNeFS, "<LOG_XML><FS>NeFS</FS></LOG_XML>", "NeFS Format System");
+ mJournal.ReleaseJournal();
+ }
+ }
+
+ ~NeFilesystemInstaller()
+ {
+ if (mNeFS)
+ delete mNeFS;
+
+ mNeFS = nullptr;
+ }
+
+ ZKA_COPY_DEFAULT(NeFilesystemInstaller);
+ };
+} // namespace Kernel::Detail
+#endif // ifdef __ZKA_AUTO_FORMAT__
+
+/// @brief Kernel entrypoint.
+/// @param Void
+/// @return Void
+EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len)
+{
+#ifdef __ZKA_AUTO_FORMAT__
+ Kernel::NeFS::fs_init_nefs();
+ Kernel::Detail::NeFilesystemInstaller installer{};
+#endif // __ZKA_AUTO_FORMAT__
+}
diff --git a/dev/Kernel/src/LPC.cc b/dev/Kernel/src/LPC.cc
new file mode 100644
index 00000000..6d614672
--- /dev/null
+++ b/dev/Kernel/src/LPC.cc
@@ -0,0 +1,34 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/LPC.h>
+#include <NewKit/KernelPanic.h>
+
+namespace Kernel
+{
+ STATIC Bool kRaiseOnBugCheck = false;
+
+ /// @brief Does a system wide bug check.
+ /// @param void no params.
+ /// @return if error-free: false, otherwise true.
+ Boolean err_bug_check(void) noexcept
+ {
+ if (kRaiseOnBugCheck)
+ {
+ ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR);
+ }
+
+ return No;
+ }
+
+ /// @brief Tells if we should raise a bug check not.
+ /// @param void
+ /// @return void
+ Void err_bug_check_raise(Void) noexcept
+ {
+ kRaiseOnBugCheck = true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/LockDelegate.cc b/dev/Kernel/src/LockDelegate.cc
new file mode 100644
index 00000000..8f9a4b1a
--- /dev/null
+++ b/dev/Kernel/src/LockDelegate.cc
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/LockDelegate.h>
+
+namespace Kernel
+{
+ /// @note Leave it empty for now.
+} // namespace Kernel
diff --git a/dev/Kernel/src/MutableArray.cc b/dev/Kernel/src/MutableArray.cc
new file mode 100644
index 00000000..aa3c76a2
--- /dev/null
+++ b/dev/Kernel/src/MutableArray.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/MutableArray.h>
diff --git a/dev/Kernel/src/Network/IPAddr.cc b/dev/Kernel/src/Network/IPAddr.cc
new file mode 100644
index 00000000..ee9cbc43
--- /dev/null
+++ b/dev/Kernel/src/Network/IPAddr.cc
@@ -0,0 +1,129 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NetworkKit/IP.h>
+#include <NewKit/Utils.h>
+
+namespace Kernel
+{
+ char* RawIPAddress::Address()
+ {
+ return fAddr;
+ }
+
+ RawIPAddress::RawIPAddress(char bytes[4])
+ {
+ rt_copy_memory(bytes, fAddr, 4);
+ }
+
+ bool RawIPAddress::operator==(const RawIPAddress& ipv4)
+ {
+ for (Size index = 0; index < 4; ++index)
+ {
+ if (ipv4.fAddr[index] != fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool RawIPAddress::operator!=(const RawIPAddress& ipv4)
+ {
+ for (Size index = 0; index < 4; ++index)
+ {
+ if (ipv4.fAddr[index] == fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ char& RawIPAddress::operator[](const Size& index)
+ {
+ kcout << "[RawIPAddress::operator[]] Fetching Index...\r";
+
+ static char IP_PLACEHOLDER = '0';
+ if (index > 4)
+ return IP_PLACEHOLDER;
+
+ return fAddr[index];
+ }
+
+ RawIPAddress6::RawIPAddress6(char bytes[8])
+ {
+ rt_copy_memory(bytes, fAddr, 8);
+ }
+
+ char& RawIPAddress6::operator[](const Size& index)
+ {
+ kcout << "[RawIPAddress6::operator[]] Fetching Index...\r";
+
+ static char IP_PLACEHOLDER = '0';
+ if (index > 8)
+ return IP_PLACEHOLDER;
+
+ return fAddr[index];
+ }
+
+ bool RawIPAddress6::operator==(const RawIPAddress6& ipv6)
+ {
+ for (SizeT index = 0; index < 8; ++index)
+ {
+ if (ipv6.fAddr[index] != fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6)
+ {
+ for (SizeT index = 0; index < 8; ++index)
+ {
+ if (ipv6.fAddr[index] == fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress6>& ipv6)
+ {
+ auto str = StringBuilder::Construct(ipv6.Leak().Address());
+ return str;
+ }
+
+ ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4)
+ {
+ auto str = StringBuilder::Construct(ipv4.Leak().Address());
+ return str;
+ }
+
+ bool IPFactory::IpCheckVersion4(const Char* ip)
+ {
+ if (!ip)
+ return NO;
+
+ Int32 cnter = 0;
+
+ for (SizeT base = 0; base < rt_string_len(ip); ++base)
+ {
+ if (ip[base] == '.')
+ {
+ cnter = 0;
+ }
+ else
+ {
+ if (cnter == 3)
+ return false;
+
+ ++cnter;
+ }
+ }
+
+ return true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Network/IPCAddr.cc b/dev/Kernel/src/Network/IPCAddr.cc
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/src/Network/IPCAddr.cc
diff --git a/dev/Kernel/src/Network/IPCMsg.cc b/dev/Kernel/src/Network/IPCMsg.cc
new file mode 100644
index 00000000..5e94b050
--- /dev/null
+++ b/dev/Kernel/src/Network/IPCMsg.cc
@@ -0,0 +1,102 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NetworkKit/IPC.h>
+#include <KernelKit/LPC.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ /// @internal
+ /// @brief The internal sanitize function.
+ Bool ipc_int_sanitize_packet(IPC_MSG* pckt)
+ {
+ auto endian = rtl_deduce_endianess(pckt, ((Char*)pckt)[0]);
+
+ switch (endian)
+ {
+ case Endian::kEndianBig: {
+ if (pckt->IpcEndianess == kIPCLittleEndian)
+ goto ipc_check_failed;
+
+ break;
+ }
+ case Endian::kEndianLittle: {
+ if (pckt->IpcEndianess == kIPCBigEndian)
+ goto ipc_check_failed;
+
+ break;
+ }
+ case Endian::kEndianMixed: {
+ if (pckt->IpcEndianess == kIPCMixedEndian)
+ goto ipc_check_failed;
+
+ break;
+ }
+ default:
+ goto ipc_check_failed;
+ }
+
+ if (pckt->IpcFrom == pckt->IpcTo ||
+ pckt->IpcPacketSize > kIPCMsgSize)
+ {
+ goto ipc_check_failed;
+ }
+
+ return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == kIPCHeaderMagic;
+
+ ipc_check_failed:
+ err_local_get() = kErrorIPC;
+ return false;
+ }
+
+ /// @brief Sanitize packet function
+ /// @retval true packet is correct.
+ /// @retval false packet is incorrect and process has crashed.
+ Bool ipc_sanitize_packet(IPC_MSG* pckt)
+ {
+ if (!pckt ||
+ !ipc_int_sanitize_packet(pckt))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /// @brief Construct packet function
+ /// @retval true packet is correct.
+ /// @retval false packet is incorrect and process has crashed.
+ Bool ipc_construct_packet(_Output IPC_MSG** pckt_in)
+ {
+ // don't act if it's not even valid.
+ if (!pckt_in)
+ return false;
+
+ if (!*pckt_in)
+ *pckt_in = new IPC_MSG();
+
+ if (*pckt_in)
+ {
+ auto endian = rtl_deduce_endianess((*pckt_in), ((Char*)(*pckt_in))[0]);
+
+ (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic;
+
+ (*pckt_in)->IpcEndianess = static_cast<UInt8>(endian);
+ (*pckt_in)->IpcPacketSize = sizeof(IPC_MSG);
+
+ (*pckt_in)->IpcTo.UserProcessID = 0;
+ (*pckt_in)->IpcTo.UserProcessTeam = 0;
+
+ (*pckt_in)->IpcFrom.UserProcessID = 0;
+ (*pckt_in)->IpcFrom.UserProcessTeam = 0;
+
+ return Yes;
+ }
+
+ return No;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Network/NetworkDevice.cc b/dev/Kernel/src/Network/NetworkDevice.cc
new file mode 100644
index 00000000..2df3af0b
--- /dev/null
+++ b/dev/Kernel/src/Network/NetworkDevice.cc
@@ -0,0 +1,35 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NetworkKit/NetworkDevice.h>
+#include <NewKit/Utils.h>
+
+namespace Kernel
+{
+ /// \brief Getter for fNetworkName.
+ const Char* NetworkDevice::Name() const
+ {
+ return this->fNetworkName;
+ }
+
+ /// \brief Setter for fNetworkName.
+ Boolean NetworkDevice::Name(const Char* strView)
+ {
+ if (strView == nullptr)
+ return false;
+
+ if (*strView == 0)
+ return false;
+
+ if (rt_string_len(strView) > cNetworkNameLen)
+ return false;
+
+ rt_copy_memory((VoidPtr)strView,
+ (VoidPtr)this->fNetworkName, rt_string_len(strView));
+
+ return true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/New+Delete.cc b/dev/Kernel/src/New+Delete.cc
new file mode 100644
index 00000000..0394112e
--- /dev/null
+++ b/dev/Kernel/src/New+Delete.cc
@@ -0,0 +1,50 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/Heap.h>
+#include <NewKit/New.h>
+
+void* operator new[](size_t sz)
+{
+ if (sz == 0)
+ ++sz;
+
+ return Kernel::mm_new_heap(sz, true, false);
+}
+
+void* operator new(size_t sz)
+{
+ if (sz == 0)
+ ++sz;
+
+ return Kernel::mm_new_heap(sz, true, false);
+}
+
+void operator delete[](void* ptr)
+{
+ if (ptr == nullptr)
+ return;
+
+ Kernel::mm_delete_heap(ptr);
+}
+
+void operator delete(void* ptr)
+{
+ if (ptr == nullptr)
+ return;
+
+ Kernel::mm_delete_heap(ptr);
+}
+
+void operator delete(void* ptr, size_t sz)
+{
+ if (ptr == nullptr)
+ return;
+
+ ZKA_UNUSED(sz);
+
+ Kernel::mm_delete_heap(ptr);
+}
diff --git a/dev/Kernel/src/OwnPtr.cc b/dev/Kernel/src/OwnPtr.cc
new file mode 100644
index 00000000..4feac5b6
--- /dev/null
+++ b/dev/Kernel/src/OwnPtr.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/OwnPtr.h>
diff --git a/dev/Kernel/src/PEFCodeMgr.cc b/dev/Kernel/src/PEFCodeMgr.cc
new file mode 100644
index 00000000..8bcceeee
--- /dev/null
+++ b/dev/Kernel/src/PEFCodeMgr.cc
@@ -0,0 +1,268 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/Heap.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <NewKit/Defines.h>
+#include <NewKit/KernelPanic.h>
+#include <NewKit/OwnPtr.h>
+#include <NewKit/KString.h>
+
+/// @brief PEF stack size symbol.
+#define kPefStackSizeSymbol "__PEFSizeOfReserveStack"
+#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap"
+#define kPefNameSymbol "__PEFProgramName"
+
+namespace Kernel
+{
+ namespace Detail
+ {
+ /***********************************************************************************/
+ /// @brief Get the PEF platform signature according to the compiled architecture.
+ /***********************************************************************************/
+ UInt32 ldr_get_platform(void) noexcept
+ {
+#if defined(__ZKA_32X0__)
+ return kPefArch32x0;
+#elif defined(__ZKA_64X0__)
+ return kPefArch64x0;
+#elif defined(__ZKA_AMD64__)
+ return kPefArchAMD64;
+#elif defined(__ZKA_PPC64__)
+ return kPefArchPowerPC;
+#elif defined(__ZKA_ARM64__)
+ return kPefArchARM64;
+#else
+ return kPefArchInvalid;
+#endif // __32x0__ || __64x0__ || __x86_64__
+ }
+ } // namespace Detail
+
+ /***********************************************************************************/
+ /// @brief PEF loader constructor w/ blob.
+ /// @param blob file blob.
+ /***********************************************************************************/
+ PEFLoader::PEFLoader(const VoidPtr blob)
+ : fCachedBlob(blob)
+ {
+ MUST_PASS(fCachedBlob);
+ fBad = false;
+ }
+
+ /***********************************************************************************/
+ /// @brief PEF loader constructor.
+ /// @param path the filesystem path.
+ /***********************************************************************************/
+ PEFLoader::PEFLoader(const Char* path)
+ : fCachedBlob(nullptr), fBad(false), fFatBinary(false)
+ {
+ fFile.New(const_cast<Char*>(path), kRestrictRB);
+ fPath = StringBuilder::Construct(path).Leak();
+
+ auto kPefHeader = "PEF_CONTAINER";
+
+ fCachedBlob = fFile->Read(kPefHeader, mib_cast(16));
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ if (container->Cpu == Detail::ldr_get_platform() &&
+ container->Magic[0] == kPefMagic[0] &&
+ container->Magic[1] == kPefMagic[1] &&
+ container->Magic[2] == kPefMagic[2] &&
+ container->Magic[3] == kPefMagic[3] &&
+ container->Magic[4] == kPefMagic[4] && container->Abi == kPefAbi)
+ {
+ return;
+ }
+ else if (container->Magic[4] == kPefMagic[0] &&
+ container->Magic[3] == kPefMagic[1] &&
+ container->Magic[2] == kPefMagic[2] &&
+ container->Magic[1] == kPefMagic[3] &&
+ container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi)
+ {
+ /// This is a fat binary.
+ this->fFatBinary = true;
+ return;
+ }
+
+ fBad = true;
+
+ if (fCachedBlob)
+ mm_delete_heap(fCachedBlob);
+
+ kcout << "PEFLoader: warn: Executable format error!\r";
+
+ fCachedBlob = nullptr;
+ }
+
+ /***********************************************************************************/
+ /// @brief PEF destructor.
+ /***********************************************************************************/
+ PEFLoader::~PEFLoader()
+ {
+ if (fCachedBlob)
+ mm_delete_heap(fCachedBlob);
+
+ fFile.Delete();
+ }
+
+ /***********************************************************************************/
+ /// @brief Finds the symbol according to it's name.
+ /// @param name name of symbol.
+ /// @param kind kind of symbol we want.
+ /***********************************************************************************/
+ VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind)
+ {
+ if (!fCachedBlob || fBad || !name)
+ return nullptr;
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ auto blob = fFile->Read(name, mib_cast(16));
+
+ PEFCommandHeader* container_header = reinterpret_cast<PEFCommandHeader*>(blob);
+
+ constexpr auto cMangleCharacter = '$';
+ const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr};
+
+ ErrorOr<KString> error_or_symbol;
+
+ switch (kind)
+ {
+ case kPefCode: {
+ error_or_symbol = StringBuilder::Construct(cContainerKinds[0]); // code symbol.
+ break;
+ }
+ case kPefData: {
+ error_or_symbol = StringBuilder::Construct(cContainerKinds[1]); // data symbol.
+ break;
+ }
+ case kPefZero: {
+ error_or_symbol = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol.
+ break;
+ }
+ default:
+ return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were
+ // a user process.
+ }
+
+ Char* unconst_symbol = const_cast<Char*>(name);
+
+ for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i)
+ {
+ if (unconst_symbol[i] == ' ')
+ {
+ unconst_symbol[i] = cMangleCharacter;
+ }
+ }
+
+ error_or_symbol.Leak().Leak() += name;
+
+ for (SizeT index = 0; index < container->Count; ++index)
+ {
+ if (StringBuilder::Equals(container_header->Name,
+ error_or_symbol.Leak().Leak().CData()))
+ {
+ if (container_header->Kind == kind)
+ {
+ if (container_header->Cpu != Detail::ldr_get_platform())
+ {
+ if (!this->fFatBinary)
+ {
+ mm_delete_heap(blob);
+ return nullptr;
+ }
+ }
+
+ Char* container_blob_value = new Char[container_header->Size];
+
+ rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size);
+ mm_delete_heap(blob);
+
+ kcout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r";
+
+ return container_blob_value;
+ }
+ }
+ }
+
+ mm_delete_heap(blob);
+ return nullptr;
+ }
+
+ /// @brief Finds the executable entrypoint.
+ /// @return
+ ErrorOr<VoidPtr> PEFLoader::FindStart()
+ {
+ if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym)
+ return ErrorOr<VoidPtr>(sym);
+
+ return ErrorOr<VoidPtr>(kErrorExecutable);
+ }
+
+ /// @brief Tells if the executable is loaded or not.
+ /// @return
+ bool PEFLoader::IsLoaded() noexcept
+ {
+ return !fBad && fCachedBlob;
+ }
+
+ const Char* PEFLoader::Path()
+ {
+ return fPath.Leak().CData();
+ }
+
+ const Char* PEFLoader::AsString()
+ {
+#ifdef __32x0__
+ return "32x0 PEF executable.";
+#elif defined(__64x0__)
+ return "64x0 PEF executable.";
+#elif defined(__x86_64__)
+ return "x86_64 PEF executable.";
+#elif defined(__aarch64__)
+ return "AARCH64 PEF executable.";
+#elif defined(__powerpc64__)
+ return "POWER64 PEF executable.";
+#else
+ return "???? PEF executable.";
+#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__
+ }
+
+ const Char* PEFLoader::MIME()
+ {
+ return kPefApplicationMime;
+ }
+
+ ErrorOr<VoidPtr> PEFLoader::GetBlob()
+ {
+ return ErrorOr<VoidPtr>{this->fCachedBlob};
+ }
+
+ namespace Utils
+ {
+ ProcessID rtl_create_process(PEFLoader& exec, const Int32& process_kind) noexcept
+ {
+ auto errOrStart = exec.FindStart();
+
+ if (errOrStart.Error() != kErrorSuccess)
+ return kProcessInvalidID;
+
+ auto id = UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(exec.FindSymbol(kPefNameSymbol, kPefData)), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
+
+ if (id != kProcessInvalidID)
+ {
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind;
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData);
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData);
+ }
+
+ return id;
+ }
+ } // namespace Utils
+} // namespace Kernel
diff --git a/dev/Kernel/src/PRDT.cc b/dev/Kernel/src/PRDT.cc
new file mode 100644
index 00000000..e0403bce
--- /dev/null
+++ b/dev/Kernel/src/PRDT.cc
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/KString.h>
+#include <StorageKit/PRDT.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief constructs a new PRD.
+ /// @param prd PRD reference.
+ /// @note This doesnt construct a valid, please fill it by yourself.
+ /***********************************************************************************/
+ void construct_prdt(Ref<PRDT>& prd)
+ {
+ prd.Leak().fPhysAddress = 0x0;
+ prd.Leak().fSectorCount = 0x0;
+ prd.Leak().fEndBit = 0x0;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/PageMgr.cc b/dev/Kernel/src/PageMgr.cc
new file mode 100644
index 00000000..9ba0ed4a
--- /dev/null
+++ b/dev/Kernel/src/PageMgr.cc
@@ -0,0 +1,110 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/PageMgr.h>
+
+#ifdef __ZKA_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#elif defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Paging.h>
+#endif // ifdef __ZKA_AMD64__ || defined(__ZKA_ARM64__)
+
+namespace Kernel
+{
+ PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr)
+ : fRw(Rw),
+ fUser(User),
+ fExecDisable(ExecDisable),
+ fVirtAddr(VirtAddr),
+ fCache(false),
+ fShareable(false),
+ fWt(false),
+ fPresent(true),
+ fAccessed(false)
+ {
+ }
+
+ PTEWrapper::~PTEWrapper() = default;
+
+ /// @brief Flush virtual address.
+ /// @param VirtAddr
+ Void PageMgr::FlushTLB()
+ {
+#ifndef __ZKA_MINIMAL_OS__
+ hal_flush_tlb();
+#endif // !__ZKA_MINIMAL_OS__
+ }
+
+ /// @brief Reclaim freed page.
+ /// @return
+ Bool PTEWrapper::Reclaim()
+ {
+ if (!this->fPresent)
+ {
+ this->fPresent = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ /// @brief Request a PTE.
+ /// @param Rw r/w?
+ /// @param User user mode?
+ /// @param ExecDisable disable execution on page?
+ /// @return
+ PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz)
+ {
+ // Store PTE wrapper right after PTE.
+ VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, false);
+
+ return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast<UIntPtr>(ptr)};
+ }
+
+ /// @brief Disable BitMap.
+ /// @param wrapper the wrapper.
+ /// @return If the page bitmap was cleared or not.
+ Bool PageMgr::Free(Ref<PTEWrapper>& wrapper)
+ {
+ if (!Kernel::HAL::mm_free_bitmap((VoidPtr)wrapper.Leak().VirtualAddress()))
+ return false;
+
+ return true;
+ }
+
+ /// @brief Virtual PTE address.
+ /// @return The virtual address of the page.
+ const UIntPtr PTEWrapper::VirtualAddress()
+ {
+ return (fVirtAddr);
+ }
+
+ Bool PTEWrapper::Shareable()
+ {
+ return fShareable;
+ }
+
+ Bool PTEWrapper::Present()
+ {
+ return fPresent;
+ }
+
+ Bool PTEWrapper::Access()
+ {
+ return fAccessed;
+ }
+
+ Void PTEWrapper::NoExecute(const bool enable)
+ {
+ fExecDisable = enable;
+ }
+
+ Bool PTEWrapper::NoExecute()
+ {
+ return fExecDisable;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Pmm.cc b/dev/Kernel/src/Pmm.cc
new file mode 100644
index 00000000..ffe58a26
--- /dev/null
+++ b/dev/Kernel/src/Pmm.cc
@@ -0,0 +1,98 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/Pmm.h>
+
+#if defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Processor.h>
+#endif // defined(__ZKA_ARM64__)
+
+#if defined(__ZKA_AMD64__)
+#include <HALKit/AMD64/Processor.h>
+#endif // defined(__ZKA_AMD64__)
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Pmm constructor.
+ /***********************************************************************************/
+ Pmm::Pmm()
+ : fPageMgr()
+ {
+ kcout << "[PMM] Allocate PageMemoryMgr";
+ }
+
+ Pmm::~Pmm() = default;
+
+ /***********************************************************************************/
+ /// @param If this returns Null pointer, enter emergency mode.
+ /// @param user is this a user page?
+ /// @param readWrite is it r/w?
+ /***********************************************************************************/
+ Ref<PTEWrapper> Pmm::RequestPage(Boolean user, Boolean readWrite)
+ {
+ PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize);
+
+ if (pt.fPresent)
+ {
+ kcout << "[PMM]: Allocation failed.\r";
+ return {};
+ }
+
+ return Ref<PTEWrapper>(pt);
+ }
+
+ Boolean Pmm::FreePage(Ref<PTEWrapper> PageRef)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fPresent = false;
+
+ return true;
+ }
+
+ Boolean Pmm::TogglePresent(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fPresent = Enable;
+
+ return true;
+ }
+
+ Boolean Pmm::ToggleUser(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fRw = Enable;
+
+ return true;
+ }
+
+ Boolean Pmm::ToggleRw(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fRw = Enable;
+
+ return true;
+ }
+
+ Boolean Pmm::ToggleShare(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fShareable = Enable;
+
+ return true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Property.cc b/dev/Kernel/src/Property.cc
new file mode 100644
index 00000000..6ff430c1
--- /dev/null
+++ b/dev/Kernel/src/Property.cc
@@ -0,0 +1,45 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <CFKit/Property.h>
+
+namespace CFKit
+{
+ /***********************************************************************************/
+ /// @brief Destructor.
+ /***********************************************************************************/
+ Property::~Property() = default;
+
+ /***********************************************************************************/
+ /// @brief Constructor.
+ /***********************************************************************************/
+ Property::Property() = default;
+
+ /***********************************************************************************/
+ /// @brief Check if property's name equals to name.
+ /// @param name string to check.
+ /***********************************************************************************/
+ Bool Property::StringEquals(KString& name)
+ {
+ return this->fName && this->fName == name;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the key (name) of property.
+ /***********************************************************************************/
+ KString& Property::GetKey()
+ {
+ return this->fName;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the value of the property.
+ /***********************************************************************************/
+ PropertyId& Property::GetValue()
+ {
+ return fValue;
+ }
+} // namespace CFKit
diff --git a/dev/Kernel/src/Ref.cc b/dev/Kernel/src/Ref.cc
new file mode 100644
index 00000000..c25aa786
--- /dev/null
+++ b/dev/Kernel/src/Ref.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Ref.h>
diff --git a/dev/Kernel/src/Semaphore.cc b/dev/Kernel/src/Semaphore.cc
new file mode 100644
index 00000000..b82efbfe
--- /dev/null
+++ b/dev/Kernel/src/Semaphore.cc
@@ -0,0 +1,69 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/Semaphore.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Unlocks process out of the semaphore.
+ /***********************************************************************************/
+ Bool Semaphore::Unlock() noexcept
+ {
+ if (fLockingProcess)
+ fLockingProcess = UserProcess();
+ else
+ return No;
+
+ return Yes;
+ }
+
+ /***********************************************************************************/
+ /// @brief Locks process in the semaphore.
+ /***********************************************************************************/
+ Bool Semaphore::Lock(UserProcess& process)
+ {
+ if (!process || fLockingProcess)
+ return No;
+
+ fLockingProcess = process;
+
+ return Yes;
+ }
+
+ /***********************************************************************************/
+ /// @brief Checks if process is locked.
+ /***********************************************************************************/
+ Bool Semaphore::IsLocked() const
+ {
+ return fLockingProcess;
+ }
+
+ /***********************************************************************************/
+ /// @brief Try lock or wait.
+ /***********************************************************************************/
+ Bool Semaphore::LockOrWait(UserProcess& process, TimerInterface* timer)
+ {
+ if (timer == nullptr)
+ return No;
+
+ this->Lock(process);
+
+ timer->Wait();
+
+ return this->Lock(process);
+ }
+
+ /***********************************************************************************/
+ /// @brief Wait for process to be free.
+ /***********************************************************************************/
+ Void Semaphore::WaitForProcess() noexcept
+ {
+ while (fLockingProcess)
+ ;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/SoftwareTimer.cc b/dev/Kernel/src/SoftwareTimer.cc
new file mode 100644
index 00000000..445ede07
--- /dev/null
+++ b/dev/Kernel/src/SoftwareTimer.cc
@@ -0,0 +1,39 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/Timer.h>
+
+/// @brief SoftwareTimer class, meant to be generic.
+
+using namespace Kernel;
+
+SoftwareTimer::SoftwareTimer(Int64 seconds)
+ : fWaitFor(seconds)
+{
+ fDigitalTimer = new IntPtr();
+ MUST_PASS(fDigitalTimer);
+}
+
+SoftwareTimer::~SoftwareTimer()
+{
+ delete fDigitalTimer;
+ fDigitalTimer = nullptr;
+
+ fWaitFor = 0;
+}
+
+BOOL SoftwareTimer::Wait() noexcept
+{
+ if (fWaitFor < 1)
+ return NO;
+
+ while (*fDigitalTimer < (*fDigitalTimer + fWaitFor))
+ {
+ ++(*fDigitalTimer);
+ }
+
+ return YES;
+}
diff --git a/dev/Kernel/src/Storage/AHCIDeviceInterface.cc b/dev/Kernel/src/Storage/AHCIDeviceInterface.cc
new file mode 100644
index 00000000..7f7392a2
--- /dev/null
+++ b/dev/Kernel/src/Storage/AHCIDeviceInterface.cc
@@ -0,0 +1,35 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/AHCI.h>
+
+using namespace Kernel;
+
+/// @brief Class constructor
+/// @param Out Drive output
+/// @param In Drive input
+/// @param Cleanup Drive cleanup.
+AHCIDeviceInterface::AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket),
+ void (*In)(MountpointInterface* inpacket),
+ void (*Cleanup)(void))
+ : IDeviceObject(Out, In), fCleanup(Cleanup)
+{
+}
+
+/// @brief Class desctructor
+AHCIDeviceInterface::~AHCIDeviceInterface()
+{
+ MUST_PASS(fCleanup);
+ if (fCleanup)
+ fCleanup();
+}
+
+/// @brief Returns the name of the device interface.
+/// @return it's name as a string.
+const Char* AHCIDeviceInterface::Name() const
+{
+ return "AHCIDeviceInterface";
+}
diff --git a/dev/Kernel/src/Storage/ATADeviceInterface.cc b/dev/Kernel/src/Storage/ATADeviceInterface.cc
new file mode 100644
index 00000000..01443939
--- /dev/null
+++ b/dev/Kernel/src/Storage/ATADeviceInterface.cc
@@ -0,0 +1,88 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/ATA.h>
+
+using namespace Kernel;
+
+/// @brief Class constructor
+/// @param Out Drive output
+/// @param In Drive input
+/// @param Cleanup Drive cleanup.
+ATADeviceInterface::ATADeviceInterface(
+ void (*Out)(MountpointInterface* outpacket),
+ void (*In)(MountpointInterface* inpacket),
+ void (*Cleanup)(void))
+ : IDeviceObject(Out, In), fCleanup(Cleanup)
+{
+}
+
+/// @brief Class desctructor
+ATADeviceInterface::~ATADeviceInterface()
+{
+ MUST_PASS(fCleanup);
+ if (fCleanup)
+ fCleanup();
+}
+
+/// @brief Returns the name of the device interface.
+/// @return it's name as a string.
+const Char* ATADeviceInterface::Name() const
+{
+ return "ATADeviceInterface";
+}
+
+/// @brief Output operator.
+/// @param Data
+/// @return
+ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* Data)
+{
+ if (!Data)
+ return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount)
+ {
+ auto interface = Data->GetAddressOf(driveCount);
+ if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0)
+ {
+ continue;
+ }
+ else if ((interface) &&
+ rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0)
+ {
+ return *this;
+ }
+ }
+
+ return (ATADeviceInterface&)IDeviceObject<MountpointInterface*>::operator<<(
+ Data);
+}
+
+/// @brief Input operator.
+/// @param Data
+/// @return
+ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* Data)
+{
+ if (!Data)
+ return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount)
+ {
+ auto interface = Data->GetAddressOf(driveCount);
+ if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0)
+ {
+ continue;
+ }
+ else if ((interface) &&
+ rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0)
+ {
+ return *this;
+ }
+ }
+
+ return (ATADeviceInterface&)IDeviceObject<MountpointInterface*>::operator>>(
+ Data);
+}
diff --git a/dev/Kernel/src/Storage/NVMEDeviceInterface.cc b/dev/Kernel/src/Storage/NVMEDeviceInterface.cc
new file mode 100644
index 00000000..642e581a
--- /dev/null
+++ b/dev/Kernel/src/Storage/NVMEDeviceInterface.cc
@@ -0,0 +1,28 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/NVME.h>
+
+namespace Kernel
+{
+ NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(MountpointInterface* outpacket),
+ void (*in)(MountpointInterface* inpacket),
+ void (*cleanup)(void))
+ : IDeviceObject(out, in), fCleanup(cleanup)
+ {
+ }
+
+ NVMEDeviceInterface::~NVMEDeviceInterface()
+ {
+ if (fCleanup)
+ fCleanup();
+ }
+
+ const Char* NVMEDeviceInterface::Name() const
+ {
+ return ("NVMEDeviceInterface");
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Storage/SCSIDeviceInterface.cc b/dev/Kernel/src/Storage/SCSIDeviceInterface.cc
new file mode 100644
index 00000000..d1d27c9d
--- /dev/null
+++ b/dev/Kernel/src/Storage/SCSIDeviceInterface.cc
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/SCSI.h>
+
+///! @brief ATAPI SCSI packet.
+const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0,
+ 0, 12, 0x40, 0, 0};
diff --git a/dev/Kernel/src/Stream.cc b/dev/Kernel/src/Stream.cc
new file mode 100644
index 00000000..d898c706
--- /dev/null
+++ b/dev/Kernel/src/Stream.cc
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: Stream.cc
+ Purpose: Stream object
+
+ Revision History:
+
+------------------------------------------- */
+
+#include <NewKit/Stream.h>
diff --git a/dev/Kernel/src/System/SwapDisk.cc b/dev/Kernel/src/System/SwapDisk.cc
new file mode 100644
index 00000000..590666e0
--- /dev/null
+++ b/dev/Kernel/src/System/SwapDisk.cc
@@ -0,0 +1,47 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025 Amlal EL Mahrouss Labs, all rights reserved.
+
+------------------------------------------- */
+
+#include <SystemKit/SwapDisk.h>
+#include <KernelKit/FileMgr.h>
+
+namespace Kernel
+{
+ BOOL SwapDisk::Write(const Char* fork_name, const SizeT fork_name_len, SWAP_DISK_HEADER_REF data, const SizeT data_len)
+ {
+ if (!fork_name || !fork_name_len)
+ return NO;
+
+ if (data_len > kSwapBlockMaxSize)
+ return NO;
+
+ if (!data)
+ return NO;
+
+ FileStream file(kSwapPageFile, "wb");
+
+ auto ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data_len);
+
+ if (ret.Error())
+ return NO;
+
+ return YES;
+ }
+
+ SWAP_DISK_HEADER_REF SwapDisk::Read(const Char* fork_name, const SizeT fork_name_len, const SizeT data_len)
+ {
+ if (!fork_name || !fork_name_len)
+ return nullptr;
+
+ if (data_len > kSwapBlockMaxSize)
+ return nullptr;
+
+ FileStream file(kSwapPageFile, "rb");
+
+ VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len);
+
+ return (SWAP_DISK_HEADER_REF)blob;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/ThreadLocalStorage.cc b/dev/Kernel/src/ThreadLocalStorage.cc
new file mode 100644
index 00000000..8bcfe616
--- /dev/null
+++ b/dev/Kernel/src/ThreadLocalStorage.cc
@@ -0,0 +1,67 @@
+/*
+ * ========================================================
+ *
+ * minoskrnl
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <NewKit/KString.h>
+#include <CFKit/Property.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/ThreadLocalStorage.h>
+
+/***********************************************************************************/
+/// @bugs: 0
+/// @file ThreadLocalStorage.cc
+/// @brief Process Thread Local Storage.
+/***********************************************************************************/
+
+using namespace Kernel;
+
+/**
+ * @brief Checks for cookie inside the TIB.
+ * @param tib_ptr the TIB to check.
+ * @return if the cookie is enabled, true; false otherwise
+ */
+
+Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr)
+{
+ if (!tib_ptr ||
+ !tib_ptr->Record)
+ return false;
+
+ ICodec encoder;
+ const Char* tib_as_bytes = encoder.AsBytes(tib_ptr);
+
+ kcout << "TLS: Validating the TIB...\r";
+
+ return tib_as_bytes[kCookieMag0Idx] == kCookieMag0 && tib_as_bytes[kCookieMag1Idx] == kCookieMag1 &&
+ tib_as_bytes[kCookieMag2Idx] == kCookieMag2;
+}
+
+/**
+ * @brief System call implementation of the TLS check.
+ * @param tib_ptr The TIB record.
+ * @return if the TIB record is valid or not.
+ */
+EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept
+{
+ if (!tib_ptr)
+ {
+ kcout << "TLS: Failing because of an invalid TIB...\r";
+ return false;
+ }
+
+ THREAD_INFORMATION_BLOCK* tib = reinterpret_cast<THREAD_INFORMATION_BLOCK*>(tib_ptr);
+
+ if (!tls_check_tib(tib))
+ {
+ kcout << "TLS: Failing because of an invalid TIB...\r";
+ return false;
+ }
+
+ kcout << "TLS Passed checked.\r";
+ return true;
+}
diff --git a/dev/Kernel/src/Timer.cc b/dev/Kernel/src/Timer.cc
new file mode 100644
index 00000000..b33a91d8
--- /dev/null
+++ b/dev/Kernel/src/Timer.cc
@@ -0,0 +1,19 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/Timer.h>
+
+///! BUGS: 0
+///! @file Timer.cc
+///! @brief Software Timer implementation
+
+using namespace Kernel;
+
+/// @brief Unimplemented as it is an interface.
+BOOL TimerInterface::Wait() noexcept
+{
+ return NO;
+}
diff --git a/dev/Kernel/src/User.cc b/dev/Kernel/src/User.cc
new file mode 100644
index 00000000..51aa3c72
--- /dev/null
+++ b/dev/Kernel/src/User.cc
@@ -0,0 +1,188 @@
+/*
+ * ========================================================
+ *
+ * ZKA
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * File: User.cc
+ * Purpose: User class, used to provide authentication and security.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/User.h>
+#include <KernelKit/LPC.h>
+#include <NewKit/KernelPanic.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Heap.h>
+
+#define kStdUserType (0xCE)
+#define kSuperUserType (0xEC)
+
+/// @file User.cc
+/// @brief User support.
+
+namespace Kernel
+{
+ namespace Detail
+ {
+ ////////////////////////////////////////////////////////////
+ /// \brief Constructs a password by hashing the password.
+ /// \param password password to hash.
+ /// \return the hashed password
+ ////////////////////////////////////////////////////////////
+ const Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length)
+ {
+ if (!password || !user)
+ return 1;
+
+ kcout << "cred_construct_token: Hashing user password...\r";
+
+ for (Size i_pass = 0; i_pass < length; ++i_pass)
+ {
+ const Char& cur_chr = in_password[i_pass];
+
+ if (cur_chr == 0)
+ break;
+
+ password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType);
+ }
+
+ kcout << "cred_construct_token: Hashed user password.\r";
+
+ return 0;
+ }
+ } // namespace Detail
+
+ ////////////////////////////////////////////////////////////
+ /// @brief User ring constructor.
+ ////////////////////////////////////////////////////////////
+ User::User(const Int32& sel, const Char* userName)
+ : mUserRing((UserRingKind)sel)
+ {
+ MUST_PASS(sel >= 0);
+ rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName));
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief User ring constructor.
+ ////////////////////////////////////////////////////////////
+ User::User(const UserRingKind& ringKind, const Char* userName)
+ : mUserRing(ringKind)
+ {
+ rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName));
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief User destructor class.
+ ////////////////////////////////////////////////////////////
+ User::~User() = default;
+
+ Bool User::Save(const UserPublicKey password_to_fill) noexcept
+ {
+ if (!password_to_fill ||
+ *password_to_fill == 0)
+ return No;
+
+ SizeT len = rt_string_len(password_to_fill);
+
+ Char* password = new Char[len];
+ MUST_PASS(password);
+
+ // fill data first, generate hash.
+ // return false on error.
+
+ rt_copy_memory((VoidPtr)password_to_fill, password, len);
+
+ if (!Detail::cred_construct_token(password, password_to_fill, this, len))
+ {
+ delete[] password;
+ password = nullptr;
+
+ return No;
+ }
+
+ // then store password.
+
+ rt_copy_memory(password, this->mUserKey, rt_string_len(password_to_fill));
+
+ delete[] password;
+ password = nullptr;
+
+ kcout << "User::Save: Saved password successfully...\r";
+
+ return Yes;
+ }
+
+ Bool User::Matches(const UserPublicKey password_to_fill) noexcept
+ {
+ if (!password_to_fill ||
+ *password_to_fill)
+ return No;
+
+ SizeT len = rt_string_len(password_to_fill);
+
+ Char* password = new Char[len];
+ MUST_PASS(password);
+
+ // fill data first, generate hash.
+ // return false on error.
+
+ rt_copy_memory((VoidPtr)password_to_fill, password, len);
+
+ if (!Detail::cred_construct_token(password, password_to_fill, this, len))
+ {
+ delete[] password;
+ password = nullptr;
+
+ return No;
+ }
+
+ kcout << "User::Matches: Validating hashed passwords...\r";
+
+ // now check if the password matches.
+ if (rt_string_cmp(password, this->mUserKey, rt_string_len(this->mUserKey)) == 0)
+ {
+ kcout << "User::Matches: Password is valid.\r";
+ return Yes;
+ }
+
+ kcout << "User::Matches: Password isn't valid.\r";
+ return No;
+ }
+
+ Bool User::operator==(const User& lhs)
+ {
+ return lhs.mUserRing == this->mUserRing;
+ }
+
+ Bool User::operator!=(const User& lhs)
+ {
+ return lhs.mUserRing != this->mUserRing;
+ }
+
+ Char* User::Name() noexcept
+ {
+ return this->mUserName;
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief Returns the user's ring.
+ /// @return The king of ring the user is attached to.
+ ////////////////////////////////////////////////////////////
+
+ const UserRingKind& User::Ring() noexcept
+ {
+ return this->mUserRing;
+ }
+
+ Bool User::IsStdUser() noexcept
+ {
+ return this->Ring() == UserRingKind::kRingStdUser;
+ }
+
+ Bool User::IsSuperUser() noexcept
+ {
+ return this->Ring() == UserRingKind::kRingSuperUser;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc
new file mode 100644
index 00000000..068e190a
--- /dev/null
+++ b/dev/Kernel/src/UserProcessScheduler.cc
@@ -0,0 +1,607 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ FILE: UserProcessScheduler.cc
+ PURPOSE: Low level/Ring-3 Process scheduler.
+
+------------------------------------------- */
+
+/***********************************************************************************/
+/// @file UserProcessScheduler.cc
+/// @brief Low level/Ring-3 process scheduler.
+/***********************************************************************************/
+
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Heap.h>
+#include <NewKit/KString.h>
+#include <KernelKit/LPC.h>
+
+///! BUGS: 0
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Exit Code global variable.
+ /***********************************************************************************/
+
+ STATIC UInt32 kLastExitCode = 0U;
+
+ /***********************************************************************************/
+ /// @brief User Process scheduler global and external reference of thread scheduler.
+ /***********************************************************************************/
+
+ STATIC UserProcessScheduler kProcessScheduler;
+
+ UserProcess::UserProcess() = default;
+ UserProcess::~UserProcess() = default;
+
+ /// @brief Gets the last exit code.
+ /// @note Not thread-safe.
+ /// @return Int32 the last exit code.
+
+ const UInt32& sched_get_exit_code(void) noexcept
+ {
+ return kLastExitCode;
+ }
+
+ /***********************************************************************************/
+ /// @brief Crashes the current process.
+ /***********************************************************************************/
+
+ Void UserProcess::Crash()
+ {
+ if (this->Status != ProcessStatusKind::kRunning)
+ return;
+
+ kcout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << endl;
+ this->Exit(kErrorProcessFault);
+ }
+
+ /***********************************************************************************/
+ /// @brief boolean operator, check status.
+ /***********************************************************************************/
+
+ UserProcess::operator bool()
+ {
+ return this->Status == ProcessStatusKind::kRunning;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the local last exit code.
+ /// @note Not thread-safe.
+ /// @return Int32 the last exit code.
+ /***********************************************************************************/
+
+ const UInt32& UserProcess::GetExitCode() noexcept
+ {
+ return this->fLastExitCode;
+ }
+
+ /***********************************************************************************/
+ /// @brief Error code variable getter.
+ /***********************************************************************************/
+
+ Int32& UserProcess::GetLocalCode() noexcept
+ {
+ return this->fLocalCode;
+ }
+
+ /***********************************************************************************/
+ /// @brief Wakes process header.
+ /// @param should_wakeup if the program shall wakeup or not.
+ /***********************************************************************************/
+
+ Void UserProcess::Wake(const bool should_wakeup)
+ {
+ this->Status =
+ should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen;
+ }
+
+ /***********************************************************************************/
+ /** @brief Add pointer to entry. */
+ /***********************************************************************************/
+
+ ErrorOr<VoidPtr> UserProcess::New(const SizeT& sz, const SizeT& pad_amount)
+ {
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ auto vm_register = hal_read_cr3();
+ hal_write_cr3(this->VMRegister);
+
+ auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes);
+
+ hal_write_cr3(vm_register);
+#else
+ auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes);
+#endif
+
+ if (!this->ProcessMemoryHeap)
+ {
+ this->ProcessMemoryHeap = new UserProcess::ProcessMemoryHeapList();
+
+ this->ProcessMemoryHeap->MemoryEntryPad = pad_amount;
+ this->ProcessMemoryHeap->MemoryEntrySize = sz;
+
+ this->ProcessMemoryHeap->MemoryEntry = ptr;
+
+ this->ProcessMemoryHeap->MemoryPrev = nullptr;
+ this->ProcessMemoryHeap->MemoryNext = nullptr;
+ }
+ else
+ {
+ ProcessMemoryHeapList* entry = this->ProcessMemoryHeap;
+ ProcessMemoryHeapList* prev_entry = nullptr;
+
+ while (!entry)
+ {
+ if (entry->MemoryEntry == nullptr)
+ break; // chose to break here, when we get an already allocated memory entry for our needs.
+
+ prev_entry = entry;
+ entry = entry->MemoryNext;
+ }
+
+ entry->MemoryNext = new ProcessMemoryHeapList();
+ entry->MemoryNext->MemoryEntry = ptr;
+
+ entry->MemoryNext->MemoryPrev = entry;
+ entry->MemoryNext->MemoryNext = nullptr;
+ }
+
+ this->UsedMemory += sz;
+
+ return ErrorOr<VoidPtr>(ptr);
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the name of the current process.
+ /***********************************************************************************/
+
+ const Char* UserProcess::GetName() noexcept
+ {
+ return this->Name;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the owner of the process.
+ /***********************************************************************************/
+
+ const User* UserProcess::GetOwner() noexcept
+ {
+ return this->Owner;
+ }
+
+ /// @brief UserProcess status getter.
+ const ProcessStatusKind& UserProcess::GetStatus() noexcept
+ {
+ return this->Status;
+ }
+
+ /***********************************************************************************/
+ /**
+ @brief Affinity is the time slot allowed for the process.
+ */
+ /***********************************************************************************/
+
+ const AffinityKind& UserProcess::GetAffinity() noexcept
+ {
+ return this->Affinity;
+ }
+
+ /***********************************************************************************/
+ /**
+ @brief Exit process method.
+ @param exit_code The process's exit code.
+ */
+ /***********************************************************************************/
+
+ Void UserProcess::Exit(const Int32& exit_code)
+ {
+ this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen;
+ this->fLastExitCode = exit_code;
+
+ kLastExitCode = exit_code;
+
+ auto memory_heap_list = this->ProcessMemoryHeap;
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ auto pd = hal_read_cr3();
+ hal_write_cr3(this->VMRegister);
+#endif
+
+ // Deleting memory lists. Make sure to free all of them.
+ while (memory_heap_list)
+ {
+ if (memory_heap_list->MemoryEntry)
+ {
+ MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry));
+ }
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ hal_write_cr3(pd);
+#endif
+
+ auto next = memory_heap_list->MemoryNext;
+
+ mm_delete_heap(memory_heap_list);
+
+ memory_heap_list = nullptr;
+ memory_heap_list = next;
+ }
+
+ //! Free the memory's page directory.
+ HAL::mm_free_bitmap(this->VMRegister);
+
+ //! Delete image if not done already.
+ if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode))
+ mm_delete_heap(this->Image.fCode);
+
+ if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob))
+ mm_delete_heap(this->Image.fBlob);
+
+ if (this->StackFrame && mm_is_valid_heap(this->StackFrame))
+ mm_delete_heap((VoidPtr)this->StackFrame);
+
+ this->Image.fBlob = nullptr;
+ this->Image.fCode = nullptr;
+ this->StackFrame = nullptr;
+
+ if (this->Kind == kExectuableDylibKind)
+ {
+ Bool success = false;
+
+ rtl_fini_dylib(*this, reinterpret_cast<IPEFDylibObject*>(this->DylibDelegate), &success);
+
+ if (!success)
+ {
+ ke_panic(RUNTIME_CHECK_PROCESS);
+ }
+
+ this->DylibDelegate = nullptr;
+ }
+
+ if (this->StackReserve)
+ mm_delete_heap(reinterpret_cast<VoidPtr>(this->StackReserve));
+
+ this->ProcessId = 0;
+ this->Status = ProcessStatusKind::kFinished;
+
+ --this->ProcessParentTeam->mProcessCount;
+
+ delete this;
+ }
+
+ /***********************************************************************************/
+ /// @brief Add process to team.
+ /// @param process the process *Ref* class.
+ /// @return the process index inside the team.
+ /***********************************************************************************/
+
+ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image)
+ {
+ ProcessID pid = this->mTeam.mProcessCount;
+
+ if (pid > kSchedProcessLimitPerTeam)
+ {
+ return kErrorProcessFault;
+ }
+
+ ++this->mTeam.mProcessCount;
+
+ UserProcess& process = this->mTeam.mProcessList[pid];
+
+ process.Image.fCode = code;
+ process.Image.fBlob = image;
+
+ rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, rt_string_len(name));
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ process.VMRegister = new PDE();
+
+ if (!process.VMRegister)
+ {
+ process.Crash();
+ return kErrorProcessFault;
+ }
+
+ UInt32 flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr)process.VMRegister, flags);
+#endif // __ZKA_VIRTUAL_MEMORY_SUPPORT__
+
+ process.StackFrame = new HAL::StackFrame();
+
+ if (!process.StackFrame)
+ {
+ process.Crash();
+ return kErrorProcessFault;
+ }
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr)process.StackFrame, flags);
+#endif // __ZKA_VIRTUAL_MEMORY_SUPPORT__
+
+ // React according to process kind.
+ switch (process.Kind)
+ {
+ case UserProcess::kExectuableDylibKind: {
+ process.DylibDelegate = rtl_init_dylib(process);
+ MUST_PASS(process.DylibDelegate);
+ }
+ default: {
+ kcout << "Unknown process kind: " << number(process.Kind) << endl;
+ break;
+ }
+ }
+
+ process.StackReserve = new UInt8[process.StackSize];
+
+ if (!process.StackReserve)
+ {
+ process.Crash();
+ return kErrorProcessFault;
+ }
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr)process.StackReserve, flags);
+#endif // __ZKA_VIRTUAL_MEMORY_SUPPORT__
+
+ process.ProcessParentTeam = &mTeam;
+
+ process.ProcessId = pid;
+ process.Status = ProcessStatusKind::kStarting;
+ process.PTime = (UIntPtr)AffinityKind::kStandard;
+
+ kcout << "PID: " << number(process.ProcessId) << endl;
+ kcout << "Name: " << process.Name << endl;
+
+ return pid;
+ }
+
+ /***********************************************************************************/
+ /// @brief Retrieves the singleton of the process scheduler.
+ /***********************************************************************************/
+
+ UserProcessScheduler& UserProcessScheduler::The()
+ {
+ return kProcessScheduler;
+ }
+
+ /***********************************************************************************/
+
+ /// @brief Remove process from list.
+ /// @param process_id process slot inside team.
+ /// @retval true process was removed.
+ /// @retval false process doesn't exist in team.
+
+ /***********************************************************************************/
+
+ const Bool UserProcessScheduler::Remove(ProcessID process_id)
+ {
+ // check if process is within range.
+ if (process_id > mTeam.mProcessList.Count())
+ return No;
+
+ mTeam.mProcessList[process_id].Exit(0);
+
+ return Yes;
+ }
+
+ const Bool UserProcessScheduler::IsUser()
+ {
+ return Yes;
+ }
+
+ const Bool UserProcessScheduler::IsKernel()
+ {
+ return No;
+ }
+
+ const Bool UserProcessScheduler::HasMP()
+ {
+ MUST_PASS(kHandoverHeader);
+ return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled;
+ }
+
+ /***********************************************************************************/
+ /// @brief Run User scheduler object.
+ /// @return Process count executed within a team.
+ /***********************************************************************************/
+
+ const SizeT UserProcessScheduler::Run() noexcept
+ {
+ SizeT process_index = 0; //! we store this guy to tell the scheduler how many
+ //! things we have scheduled.
+
+ if (mTeam.mProcessCount < 1)
+ {
+ kcout << "UserProcessScheduler::Run(): This team doesn't have any process!\r";
+ return 0;
+ }
+
+ kcout << "UserProcessScheduler::Run(): This team has a process capacity of: " << number(mTeam.mProcessList.Capacity()) << endl;
+
+ for (; process_index < mTeam.AsArray().Capacity(); ++process_index)
+ {
+ auto& process = mTeam.AsArray()[process_index];
+
+ //! check if the process needs to be run.
+ if (UserProcessHelper::CanBeScheduled(process))
+ {
+ // Set current process header.
+ this->GetCurrentProcess() = process;
+
+ process.PTime = static_cast<Int32>(process.Affinity);
+
+ kcout << "Switch to: '" << process.Name << "'.\r";
+
+ // tell helper to find a core to schedule on.
+ if (!UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame,
+ process.ProcessId))
+ {
+ kcout << "Invalid process (UH OH)\r";
+ process.Crash();
+ }
+ }
+ else
+ {
+ --process.PTime;
+ }
+ }
+
+ return process_index;
+ }
+
+ /// @brief Gets the current scheduled team.
+ /// @return
+ UserProcessTeam& UserProcessScheduler::CurrentTeam()
+ {
+ return mTeam;
+ }
+
+ /// @internal
+
+ /// @brief Gets current running process.
+ /// @return
+ Ref<UserProcess>& UserProcessScheduler::GetCurrentProcess()
+ {
+ return mTeam.AsRef();
+ }
+
+ /// @brief Current proccess id getter.
+ /// @return UserProcess ID integer.
+ ErrorOr<PID> UserProcessHelper::TheCurrentPID()
+ {
+ if (!kProcessScheduler.GetCurrentProcess())
+ return ErrorOr<PID>{kErrorProcessFault};
+
+ kcout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r";
+ return ErrorOr<PID>{kProcessScheduler.GetCurrentProcess().Leak().ProcessId};
+ }
+
+ /// @brief Check if process can be schedulded.
+ /// @param process the process reference.
+ /// @retval true can be schedulded.
+ /// @retval false cannot be schedulded.
+ Bool UserProcessHelper::CanBeScheduled(const UserProcess& process)
+ {
+ if (process.Status == ProcessStatusKind::kKilled ||
+ process.Status == ProcessStatusKind::kFinished ||
+ process.Status == ProcessStatusKind::kStarting ||
+ process.Status == ProcessStatusKind::kFrozen)
+ return No;
+
+ if (process.Status == ProcessStatusKind::kInvalid)
+ return No;
+
+ if (!process.Image.fCode)
+ return No;
+
+ if (!process.Name[0])
+ return No;
+
+ return process.PTime < 1;
+ }
+
+ /***********************************************************************************/
+ /**
+ * @brief Start scheduling current AP.
+ */
+ /***********************************************************************************/
+
+ SizeT UserProcessHelper::StartScheduling()
+ {
+ return kProcessScheduler.Run();
+ }
+
+ /***********************************************************************************/
+ /**
+ * \brief Does a context switch in a CPU.
+ * \param the_stack the stackframe of the running app.
+ * \param new_pid the process's PID.
+ */
+ /***********************************************************************************/
+
+ Bool UserProcessHelper::Switch(VoidPtr image_ptr, UInt8* stack, HAL::StackFramePtr frame_ptr, const PID& new_pid)
+ {
+ for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index)
+ {
+ if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidAP ||
+ HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot)
+ continue;
+
+ // a fallback is a special core for real-time tasks which needs immediate execution.
+ if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPFallback)
+ {
+ if (UserProcessScheduler::The().GetCurrentProcess().Leak().Affinity != AffinityKind::kRealTime)
+ continue;
+
+ if (HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr, new_pid))
+ return YES;
+
+ continue;
+ }
+
+ PID prev_pid = UserProcessHelper::TheCurrentPID();
+ UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid;
+
+ ////////////////////////////////////////////////////////////
+ /// Prepare task switch. ///
+ ////////////////////////////////////////////////////////////
+
+ HardwareThreadScheduler::The()[index].Leak()->Wake(YES);
+ HardwareThreadScheduler::The()[index].Leak()->Busy(NO);
+
+ auto prev_ptime = HardwareThreadScheduler::The()[index].Leak()->fPTime;
+ HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime;
+
+ Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr, new_pid);
+
+ ////////////////////////////////////////////////////////////
+ /// Rollback on fail. ///
+ ////////////////////////////////////////////////////////////
+ if (!ret)
+ {
+ HardwareThreadScheduler::The()[index].Leak()->fPTime = prev_ptime;
+ UserProcessHelper::TheCurrentPID().Leak().Leak() = prev_pid;
+
+ HardwareThreadScheduler::The()[index].Leak()->Busy(NO);
+ }
+
+ HardwareThreadScheduler::The()[index].Leak()->Wake(NO);
+
+ return Yes;
+ }
+
+ return No;
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief this checks if any process is on the team.
+ ////////////////////////////////////////////////////////////
+ UserProcessScheduler::operator bool()
+ {
+ return mTeam.AsArray().Count() > 0;
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief this checks if no process is on the team.
+ ////////////////////////////////////////////////////////////
+ Bool UserProcessScheduler::operator!()
+ {
+ return mTeam.AsArray().Count() == 0;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/UserProcessTeam.cc b/dev/Kernel/src/UserProcessTeam.cc
new file mode 100644
index 00000000..918a62bb
--- /dev/null
+++ b/dev/Kernel/src/UserProcessTeam.cc
@@ -0,0 +1,58 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/***********************************************************************************/
+/// @file UserProcessTeam.cc
+/// @brief Process teams implementation.
+/***********************************************************************************/
+
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ UserProcessTeam::UserProcessTeam()
+ {
+ for (SizeT i = 0U; i < this->mProcessList.Count(); ++i)
+ {
+ this->mProcessList[i] = UserProcess();
+ this->mProcessList[i].Status = ProcessStatusKind::kKilled;
+ }
+
+ this->mProcessCount = 0UL;
+ }
+
+ /***********************************************************************************/
+ /// @brief UserProcess list array getter.
+ /// @return The list of process to schedule.
+ /***********************************************************************************/
+
+ Array<UserProcess, kSchedProcessLimitPerTeam>& UserProcessTeam::AsArray()
+ {
+ return this->mProcessList;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get team ID.
+ /// @return The team's ID.
+ /***********************************************************************************/
+
+ ProcessID& UserProcessTeam::Id() noexcept
+ {
+ return this->mTeamId;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get current process getter as Ref.
+ /// @return The current process header.
+ /***********************************************************************************/
+
+ Ref<UserProcess>& UserProcessTeam::AsRef()
+ {
+ return this->mCurrentProcess;
+ }
+} // namespace Kernel
+
+// last rev 05-03-24
diff --git a/dev/Kernel/src/Utils.cc b/dev/Kernel/src/Utils.cc
new file mode 100644
index 00000000..c5a82305
--- /dev/null
+++ b/dev/Kernel/src/Utils.cc
@@ -0,0 +1,219 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Utils.h>
+
+namespace Kernel
+{
+ Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size)
+ {
+ Int32 counter = 0;
+
+ for (Size index = 0; index < size; ++index)
+ {
+ if (src[index] != cmp[index])
+ ++counter;
+ }
+
+ return counter;
+ }
+
+ Void rt_zero_memory(voidPtr pointer, Size len)
+ {
+ rt_set_memory(pointer, 0, len);
+ }
+
+ SizeT rt_string_len(const Char* str, SizeT _len)
+ {
+ SizeT len{0};
+
+ do
+ {
+ if (len > _len)
+ {
+ return _len;
+ }
+
+ ++len;
+ } while (str[len] != '\0');
+
+ return len;
+ }
+
+ Size rt_string_len(const Char* ptr)
+ {
+ SizeT cnt{0};
+
+ while (ptr[cnt] != 0)
+ ++cnt;
+
+ return cnt;
+ }
+
+ voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len)
+ {
+ UInt32* start = reinterpret_cast<UInt32*>(src);
+
+ while (len)
+ {
+ *start = value;
+ ++start;
+ --len;
+ }
+
+ return (voidPtr)start;
+ }
+
+ Int rt_move_memory(const voidPtr src, voidPtr dst, Size len)
+ {
+ Char* srcChr = reinterpret_cast<Char*>(src);
+ Char* dstChar = reinterpret_cast<Char*>(dst);
+ SizeT index = 0;
+
+ while (index < len)
+ {
+ dstChar[index] = srcChr[index];
+ srcChr[index] = 0;
+
+ ++index;
+ }
+
+ return 0;
+ }
+
+ Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len)
+ {
+ char* srcChr = reinterpret_cast<char*>(src);
+ char* dstChar = reinterpret_cast<char*>(dst);
+ Size index = 0;
+
+ while (index < len)
+ {
+ dstChar[index] = srcChr[index];
+ ++index;
+ }
+
+ dstChar[index] = 0;
+
+ return index;
+ }
+
+ const Char* rt_alloc_string(const Char* src)
+ {
+ const Char* string = new Char[rt_string_len(src) + 1];
+
+ if (!string)
+ return nullptr;
+
+ voidPtr v_src = reinterpret_cast<voidPtr>(const_cast<char*>(src));
+ voidPtr v_dst = reinterpret_cast<voidPtr>(const_cast<char*>(string));
+
+ rt_copy_memory(v_src, v_dst, rt_string_len(src) + 1);
+
+ return string;
+ }
+
+ Int32 rt_to_uppercase(Int32 character)
+ {
+ if (character >= 'a' && character <= 'z')
+ return character - 0x20;
+
+ return character;
+ }
+
+ Int32 rt_to_lower(Int32 character)
+ {
+ if (character >= 'A' && character <= 'Z')
+ return character + 0x20;
+
+ return character;
+ }
+
+ Boolean is_space(Char chr)
+ {
+ return chr == ' ';
+ }
+
+ Boolean is_newln(Char chr)
+ {
+ return chr == '\n';
+ }
+
+ VoidPtr rt_string_in_string(const Char* in, const Char* needle)
+ {
+ for (SizeT i = 0; i < rt_string_len(in); ++i)
+ {
+ if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0)
+ return reinterpret_cast<voidPtr>(const_cast<char*>(in + i));
+ }
+
+ return nullptr;
+ }
+
+ Char rt_to_char(UInt64 base, Int32 limit)
+ {
+ const Char kNumbers[17] = "0123456789ABCDEF";
+ return kNumbers[base % limit];
+ }
+
+ Bool rt_to_string(Char* str, UInt64 base, Int32 limit)
+ {
+#ifdef __ZKA_AMD64__
+ auto i = 0;
+
+ auto final_number = base;
+
+ auto mult = 1;
+ auto elems = 0L;
+
+ base /= 10;
+
+ while (base > 0)
+ {
+ elems++;
+ mult *= 10;
+ base /= 10;
+ }
+
+ while (elems > -1)
+ {
+ final_number = (final_number % mult) * 10 + final_number / mult;
+ str[i] = rt_to_char(final_number, limit);
+
+ --elems;
+ ++i;
+ }
+#endif
+
+ return YES;
+ }
+
+ /// @brief Checks for a string start at the character.
+
+ Char* rt_string_has_char(Char* str, const Char chr)
+ {
+ while (*str != chr)
+ {
+ ++str;
+
+ if (*str == 0)
+ return nullptr;
+ }
+
+ return str;
+ }
+} // namespace Kernel
+
+EXTERN_C void* memset(void* dst, int c, long long unsigned int len)
+{
+ return Kernel::rt_set_memory(dst, c, len);
+}
+
+EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len)
+{
+ Kernel::rt_copy_memory(const_cast<void*>(src), dst, len);
+ return dst;
+}
diff --git a/dev/Kernel/src/Variant.cc b/dev/Kernel/src/Variant.cc
new file mode 100644
index 00000000..7d62cb98
--- /dev/null
+++ b/dev/Kernel/src/Variant.cc
@@ -0,0 +1,33 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Variant.h>
+
+namespace Kernel
+{
+ const Char* Variant::ToString()
+ {
+ switch (fKind)
+ {
+ case VariantKind::kXML:
+ return ("Class:{XML}");
+ case VariantKind::kJson:
+ return ("Class:{Json}");
+ case VariantKind::kString:
+ return ("Class:{String}");
+ case VariantKind::kBlob:
+ return ("Class:{Blob}");
+ default:
+ return ("Class:{Null}");
+ }
+ }
+
+ /// @brief Leak variant's instance.
+ VoidPtr Variant::Leak()
+ {
+ return fPtr;
+ }
+} // namespace Kernel