summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel/src')
-rw-r--r--dev/kernel/src/ACPIFactoryInterface.cc88
-rw-r--r--dev/kernel/src/Array.cc7
-rw-r--r--dev/kernel/src/ArrayList.cc7
-rw-r--r--dev/kernel/src/AsciiUtils.cc161
-rw-r--r--dev/kernel/src/Atom.cc10
-rw-r--r--dev/kernel/src/BinaryMutex.cc70
-rw-r--r--dev/kernel/src/BitMapMgr.cc206
-rw-r--r--dev/kernel/src/CRuntimeOverrides.cc27
-rw-r--r--dev/kernel/src/CodeMgr.cc35
-rw-r--r--dev/kernel/src/Crc32.cc65
-rw-r--r--dev/kernel/src/Defines.cc7
-rw-r--r--dev/kernel/src/DeviceMgr.cc9
-rw-r--r--dev/kernel/src/DriveMgr.cc254
-rw-r--r--dev/kernel/src/ErrorOr.cc12
-rw-r--r--dev/kernel/src/FS/Ext2+IFS.cc1555
-rw-r--r--dev/kernel/src/FS/NeFS+FileMgr.cc276
-rw-r--r--dev/kernel/src/FS/NeFS+FileSystemParser.cc870
-rw-r--r--dev/kernel/src/FS/OpenHeFS+FileMgr.cc191
-rw-r--r--dev/kernel/src/FS/OpenHeFS+FileSystemParser.cc1160
-rw-r--r--dev/kernel/src/FileMgr.cc49
-rw-r--r--dev/kernel/src/GUIDWizard.cc67
-rw-r--r--dev/kernel/src/GUIDWrapper.cc9
-rw-r--r--dev/kernel/src/Gfx/FBDeviceInterface.cc50
-rw-r--r--dev/kernel/src/HardwareThreadScheduler.cc184
-rw-r--r--dev/kernel/src/HeapMgr.cc260
-rw-r--r--dev/kernel/src/IDylibObject.cc13
-rw-r--r--dev/kernel/src/IFS.cc89
-rw-r--r--dev/kernel/src/IPEFDylibObject.cc109
-rw-r--r--dev/kernel/src/IndexableProperty.cc45
-rw-r--r--dev/kernel/src/Json.cc9
-rw-r--r--dev/kernel/src/KPC.cc39
-rw-r--r--dev/kernel/src/KernelTaskScheduler.cc37
-rw-r--r--dev/kernel/src/LockDelegate.cc11
-rw-r--r--dev/kernel/src/MutableArray.cc7
-rw-r--r--dev/kernel/src/Network/IPAddress.cc113
-rw-r--r--dev/kernel/src/Network/IPCAddress.cc27
-rw-r--r--dev/kernel/src/Network/IPCMessage.cc129
-rw-r--r--dev/kernel/src/Network/MACAddressGetter.cc13
-rw-r--r--dev/kernel/src/Network/NetworkDevice.cc29
-rw-r--r--dev/kernel/src/New+Delete.cc48
-rw-r--r--dev/kernel/src/OwnPtr.cc7
-rw-r--r--dev/kernel/src/PE32CodeMgr.cc258
-rw-r--r--dev/kernel/src/PEFCodeMgr.cc335
-rw-r--r--dev/kernel/src/PRDT.cc22
-rw-r--r--dev/kernel/src/PageMgr.cc95
-rw-r--r--dev/kernel/src/Pmm.cc83
-rw-r--r--dev/kernel/src/Property.cc41
-rw-r--r--dev/kernel/src/Ref.cc7
-rw-r--r--dev/kernel/src/Semaphore.cc7
-rw-r--r--dev/kernel/src/SoftwareTimer.cc36
-rw-r--r--dev/kernel/src/Storage/AHCIDeviceInterface.cc87
-rw-r--r--dev/kernel/src/Storage/ATADeviceInterface.cc96
-rw-r--r--dev/kernel/src/Storage/NVMEDeviceInterface.cc22
-rw-r--r--dev/kernel/src/Storage/SCSIDeviceInterface.cc9
-rw-r--r--dev/kernel/src/Stream.cc12
-rw-r--r--dev/kernel/src/Swap/DiskSwap.cc64
-rw-r--r--dev/kernel/src/ThreadLocalStorage.cc52
-rw-r--r--dev/kernel/src/Timer.cc19
-rw-r--r--dev/kernel/src/UserMgr.cc131
-rw-r--r--dev/kernel/src/UserProcessScheduler.cc690
-rw-r--r--dev/kernel/src/UserProcessTeam.cc57
-rw-r--r--dev/kernel/src/UtfUtils.cc62
-rw-r--r--dev/kernel/src/Variant.cc38
-rw-r--r--dev/kernel/src/ZXD.cc7
64 files changed, 0 insertions, 8584 deletions
diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc
deleted file mode 100644
index 42819b7e..00000000
--- a/dev/kernel/src/ACPIFactoryInterface.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <ArchKit/ArchKit.h>
-#include <KernelKit/HeapMgr.h>
-#include <NeKit/KString.h>
-#include <modules/ACPI/ACPIFactoryInterface.h>
-
-namespace Kernel {
-constexpr STATIC const auto kMinACPIVer = 1U;
-
-/// @brief Finds a descriptor table inside ACPI XSDT.
-ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) {
- if (this->fRsdp) return ErrorOr<voidPtr>{-kErrorInvalidData};
- if (!signature) return ErrorOr<voidPtr>{-kErrorInvalidData};
- if (*signature == 0) return ErrorOr<voidPtr>{-kErrorInvalidData};
-
- RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp);
-
- if (rsp_ptr->Revision < kMinACPIVer) return ErrorOr<voidPtr>{-kErrorInvalidData};
-
- 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>{-kErrorInvalidData};
- }
-
- this->fEntries = num;
-
- (Void)(kout << "ACPI: Number of entries: " << number(this->fEntries) << kendl);
- (Void)(kout << "ACPI: Revision: " << number(xsdt->Revision) << kendl);
- (Void)(kout << "ACPI: Signature: " << xsdt->Signature << kendl);
- (Void)(kout << "ACPI: Address of XSDT: " << hex_number((UIntPtr) xsdt) << kendl);
-
- static constexpr const UInt16 cAcpiSignatureLength = 4U;
-
- for (Size index = 0; index < this->fEntries; ++index) {
- SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]);
-
- (Void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl);
- (Void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl);
-
- for (UInt16 signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) {
- if (sdt->Signature[signature_index] != signature[signature_index]) break;
-
- if (signature_index == (cAcpiSignatureLength - 1)) {
- (Void)(kout << "ACPI: SDT Signature: " << sdt->Signature << kendl);
- (Void)(kout << "ACPI: SDT OEM ID: " << sdt->OemId << kendl);
- return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index]));
- }
- }
- }
-
- return ErrorOr<voidPtr>{-kErrorInvalidData};
-}
-
-/***
-@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 || !checksum) return NO;
-
- Char chr = 0;
-
- for (SSizeT index = 0L; index < len; ++index) {
- chr += checksum[index];
- }
-
- return chr == 0;
-}
-
-ErrorOr<voidPtr> ACPIFactoryInterface::operator[](const Char* signature) {
- if (!signature) return ErrorOr<voidPtr>{-kErrorInvalidData};
- return this->Find(signature);
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Array.cc b/dev/kernel/src/Array.cc
deleted file mode 100644
index c792ef93..00000000
--- a/dev/kernel/src/Array.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Array.h>
diff --git a/dev/kernel/src/ArrayList.cc b/dev/kernel/src/ArrayList.cc
deleted file mode 100644
index 37042320..00000000
--- a/dev/kernel/src/ArrayList.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/ArrayList.h>
diff --git a/dev/kernel/src/AsciiUtils.cc b/dev/kernel/src/AsciiUtils.cc
deleted file mode 100644
index 1f1ab0f6..00000000
--- a/dev/kernel/src/AsciiUtils.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Utils.h>
-
-namespace Kernel {
-Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) {
- for (Size i = 0; i < size; ++i) {
- if (src[i] != cmp[i]) return static_cast<Int32>(src[i]) - static_cast<Int32>(cmp[i]);
- }
- return 0;
-}
-
-SizeT rt_string_len(const Char* str, SizeT max_len) {
- SizeT len = 0;
- while (len < max_len && str[len] != '\0') ++len;
- return len;
-}
-
-Size rt_string_len(const Char* ptr) {
- Size cnt = 0;
- while (ptr[cnt] != '\0') ++cnt;
- return cnt;
-}
-
-const Char* rt_alloc_string(const Char* src) {
- SizeT slen = rt_string_len(src);
- Char* buffer = new Char[slen + 1];
- if (!buffer) return nullptr;
-
- if (rt_copy_memory_safe(reinterpret_cast<voidPtr>(const_cast<Char*>(src)),
- reinterpret_cast<voidPtr>(buffer), slen, slen + 1) < 0) {
- delete[] buffer;
- return nullptr;
- }
-
- buffer[slen] = '\0';
- return buffer;
-}
-
-Int32 rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size) {
- if (!src || !dst || len > dst_size) {
- if (dst && dst_size) {
- rt_set_memory_safe(dst, 0, dst_size, dst_size);
- }
- return -1;
- }
-
- auto s = reinterpret_cast<const UInt8*>(src);
- auto d = reinterpret_cast<UInt8*>(dst);
-
- for (Size i = 0; i < len; ++i) d[i] = s[i];
-
- return static_cast<Int>(len);
-}
-
-voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size) {
- if (!dst || len > dst_size) return nullptr;
- auto p = reinterpret_cast<UInt8*>(dst);
- UInt8 v = static_cast<UInt8>(value & 0xFF);
- for (Size i = 0; i < len; ++i) p[i] = v;
- return dst;
-}
-
-Void rt_zero_memory(voidPtr pointer, Size len) {
- rt_set_memory_safe(pointer, 0, len, len);
-}
-
-#ifdef __NE_ENFORCE_DEPRECATED_WARNINGS
-[[deprecated("Use rt_set_memory_safe instead")]]
-#endif
-voidPtr
-rt_set_memory(voidPtr src, UInt32 value, Size len) {
- if (!src) return nullptr;
- auto p = reinterpret_cast<UInt8*>(src);
- UInt8 v = static_cast<UInt8>(value & 0xFF);
- for (Size i = 0; i < len; ++i) p[i] = v;
- return src;
-}
-
-#ifdef __NE_ENFORCE_DEPRECATED_WARNINGS
-[[deprecated("Use rt_copy_memory_safe instead")]]
-#endif
-Int32 rt_copy_memory(const voidPtr src, voidPtr dst, Size len) {
- if (!src || !dst) return -1;
- auto s = reinterpret_cast<const UInt8*>(src);
- auto d = reinterpret_cast<UInt8*>(dst);
-
- for (Size i = 0; i < len; ++i) d[i] = s[i];
-
- return static_cast<Int>(len);
-}
-
-Int32 rt_to_uppercase(Int ch) {
- return (ch >= 'a' && ch <= 'z') ? ch - 0x20 : ch;
-}
-
-Int32 rt_to_lower(Int ch) {
- return (ch >= 'A' && ch <= 'Z') ? ch + 0x20 : ch;
-}
-
-Int32 rt_is_alnum(Int ch) {
- return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9');
-}
-
-Boolean rt_is_space(Int ch) {
- return ch == ' ';
-}
-
-Boolean rt_is_newln(Int ch) {
- return ch == '\n';
-}
-
-Char rt_to_char(UInt64 value, Int32 base) {
- static constexpr Char kDigits[] = "0123456789ABCDEF";
- return kDigits[value % base];
-}
-
-Bool rt_to_string(Char* str, UInt64 value, Int32 base) {
- if (!str || base < 2 || base > 16) return NO;
-
- Int i = 0;
- do {
- str[i++] = rt_to_char(value, base);
- value /= base;
- } while (value);
- str[i] = '\0';
- // in-place
- for (Int j = 0; j < i / 2; ++j) {
- Char tmp = str[j];
- str[j] = str[i - j - 1];
- str[i - j - 1] = tmp;
- }
-
- return YES;
-}
-
-VoidPtr rt_string_in_string(const Char* haystack, const Char* needle) {
- if (!haystack || !needle) return nullptr;
-
- SizeT needle_len = rt_string_len(needle);
- SizeT hay_len = rt_string_len(haystack);
-
- if (needle_len > hay_len) return nullptr;
- for (SizeT i = 0; i <= hay_len - needle_len; ++i) {
- if (rt_string_cmp(haystack + i, needle, needle_len) == 0) {
- return reinterpret_cast<voidPtr>(const_cast<Char*>(haystack + i));
- }
- }
- return nullptr;
-}
-
-Char* rt_string_has_char(Char* str, Char ch) {
- if (!str) return nullptr;
- while (*str && *str != ch) ++str;
- return (*str == ch) ? str : nullptr;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Atom.cc b/dev/kernel/src/Atom.cc
deleted file mode 100644
index c6c1dd40..00000000
--- a/dev/kernel/src/Atom.cc
+++ /dev/null
@@ -1,10 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Atom.h>
-
-// @file Atom.cc
-// @brief Atomic primitives
diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc
deleted file mode 100644
index 3c332b33..00000000
--- a/dev/kernel/src/BinaryMutex.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/BinaryMutex.h>
-#include <KernelKit/ProcessScheduler.h>
-
-namespace Kernel {
-/***********************************************************************************/
-/// @brief Unlocks the binary mutex.
-/***********************************************************************************/
-
-Bool BinaryMutex::Unlock() noexcept {
- if (fLockingProcess->Status == ProcessStatusKind::kRunning) {
- fLockingProcess = nullptr;
-
- return Yes;
- }
-
- return No;
-}
-
-/***********************************************************************************/
-/// @brief Locks process in the binary mutex.
-/***********************************************************************************/
-
-Bool BinaryMutex::Lock(USER_PROCESS* process) {
- if (!process || this->IsLocked()) return No;
-
- this->fLockingProcess = process;
-
- return Yes;
-}
-
-/***********************************************************************************/
-/// @brief Checks if process is locked.
-/***********************************************************************************/
-
-Bool BinaryMutex::IsLocked() const {
- return this->fLockingProcess->Status == ProcessStatusKind::kRunning;
-}
-
-/***********************************************************************************/
-/// @brief Try lock or wait.
-/***********************************************************************************/
-
-Bool BinaryMutex::LockAndWait(USER_PROCESS* process, TimerInterface* timer) {
- if (timer == nullptr) return No;
-
- this->Lock(process);
-
- timer->Wait();
-
- return this->Lock(process);
-}
-
-/***********************************************************************************/
-/// @brief Wait for process **sec** until we check if it's free.
-/// @param sec seconds.
-/***********************************************************************************/
-
-BOOL BinaryMutex::WaitForProcess(const UInt32& sec) noexcept {
- HardwareTimer hw_timer(rtl_milliseconds(sec));
- hw_timer.Wait();
-
- return !this->IsLocked();
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc
deleted file mode 100644
index d7ecb810..00000000
--- a/dev/kernel/src/BitMapMgr.cc
+++ /dev/null
@@ -1,206 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#ifdef __NE_AMD64__
-#include <HALKit/AMD64/Paging.h>
-#elif defined(__NE_ARM64__)
-#include <HALKit/ARM64/Paging.h>
-#endif
-
-#include <ArchKit/ArchKit.h>
-#include <NeKit/KernelPanic.h>
-
-#define kBitMapMagic (0x10210U)
-
-#define kBitMapMagIdx (0U)
-#define kBitMapSizeIdx (1U)
-#define kBitMapUsedIdx (2U)
-
-///! @author Amlal El Mahrouss (amlal@nekernel.org)
-
-namespace Kernel {
-namespace HAL {
- namespace Detail {
- /***********************************************************************************/
- /// \brief Proxy Interface to manage a bitmap allocator.
- /***********************************************************************************/
- class IBitMapProxy final {
- public:
- explicit IBitMapProxy() = default;
- ~IBitMapProxy() = default;
-
- NE_COPY_DELETE(IBitMapProxy)
-
- 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);
-
- kBitMapCursor += ptr_bit_set[kBitMapSizeIdx];
-
- 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 bitmap, until we find a free entry.
- /// @param base_ptr base pointer to look on.
- /// @param size the size of the requested data structure.
- /// @param wr is writable flag?
- /// @param user is user flag?
- /// @param pad additional padding added to **size**
- /// @return The new free address, or nullptr.
- /***********************************************************************************/
- auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user, SizeT pad) -> VoidPtr {
- if (!size) return nullptr;
-
- if (kBitMapCursor > kKernelBitMpSize) {
- err_global_get() = kErrorOutOfBitMapMemory;
-
- (Void)(kout << "Bitmap limit reached, can't allocate more bitmaps." << kendl);
- return nullptr;
- }
-
- VoidPtr base = reinterpret_cast<VoidPtr>((UIntPtr) base_ptr);
- MUST_PASS(base);
-
- if (!base) return nullptr;
-
- STATIC SizeT biggest = 0UL;
-
- while (YES) {
- UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
-
- if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic &&
- ptr_bit_set[kBitMapSizeIdx] == (size + pad)) {
- if (ptr_bit_set[kBitMapUsedIdx] == No) {
- ptr_bit_set[kBitMapSizeIdx] = size + pad;
- ptr_bit_set[kBitMapUsedIdx] = Yes;
-
- this->GetBitMapStatus(ptr_bit_set);
-
- UInt32 flags = this->MakeMMFlags(wr, user);
- mm_map_page(ptr_bit_set, (VoidPtr)mm_get_page_addr(ptr_bit_set), flags);
-
- if (biggest < (size + pad)) biggest = size + pad;
-
- kBitMapCursor += size + pad;
-
- return (VoidPtr) ptr_bit_set;
- }
- } else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) {
- ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
- ptr_bit_set[kBitMapSizeIdx] = (size + pad);
- ptr_bit_set[kBitMapUsedIdx] = Yes;
-
- this->GetBitMapStatus(ptr_bit_set);
-
- UInt32 flags = this->MakeMMFlags(wr, user);
- mm_map_page(ptr_bit_set, (VoidPtr)mm_get_page_addr(ptr_bit_set), flags);
-
- if (biggest < (size + pad)) biggest = (size + pad);
-
- kBitMapCursor += size + pad;
-
- return (VoidPtr) ptr_bit_set;
- }
-
- UIntPtr raw_base = reinterpret_cast<UIntPtr>(base);
- UIntPtr offset = (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
- ? (size + pad)
- : ptr_bit_set[kBitMapSizeIdx];
-
- base = reinterpret_cast<VoidPtr>(raw_base + offset);
- if (base == nullptr) return nullptr;
- }
-
- return nullptr;
- }
-
- /// @brief Print Bitmap status
- auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void {
- if (!this->IsBitMap(ptr_bit_set)) {
- (Void)(kout << "Not a BitMap: " << hex_number((UIntPtr) ptr_bit_set) << kendl);
- return;
- }
-
- (Void)(kout << "Magic: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << kendl);
- (Void)(kout << "Is Allocated? " << (ptr_bit_set[kBitMapUsedIdx] ? "YES" : "NO") << kendl);
- (Void)(kout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << kendl);
- (Void)(kout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx]))
- << kendl);
- (Void)(kout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx]))
- << kendl);
- (Void)(kout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx]))
- << kendl);
- (Void)(kout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx]))
- << kendl);
- (Void)(kout << "BitMap Address: " << hex_number((UIntPtr) ptr_bit_set) << kendl);
- }
- };
- } // namespace Detail
-
- STATIC Detail::IBitMapProxy kBitMapMgr;
-
- auto mm_is_bitmap(VoidPtr ptr) -> BOOL {
- return kBitMapMgr.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, SizeT pad) -> VoidPtr {
- VoidPtr ptr_new = nullptr;
- if (is_page) return nullptr;
-
- ptr_new = kBitMapMgr.FindBitMap(kKernelBitMpStart, size, wr, user, pad);
-
- if (!ptr_new) {
- ke_panic(RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM, "Out of memory bitmap");
- return nullptr;
- }
-
- return ptr_new;
- }
-
- /***********************************************************************************/
- /// @brief Free Bitmap, and mark it as absent.
- /// @param ptr the pointer to free.
- /***********************************************************************************/
- auto mm_free_bitmap(VoidPtr ptr) -> Bool {
- if (!ptr) return No;
-
- Bool ret = kBitMapMgr.FreeBitMap(ptr);
- return ret;
- }
-} // namespace HAL
-} // namespace Kernel
diff --git a/dev/kernel/src/CRuntimeOverrides.cc b/dev/kernel/src/CRuntimeOverrides.cc
deleted file mode 100644
index a773d4f9..00000000
--- a/dev/kernel/src/CRuntimeOverrides.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ========================================
-
- Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Utils.h>
-
-using namespace Kernel;
-
-/// =========================================================== ///
-/// @brief C Standard Library overrides. ///
-/// =========================================================== ///
-
-EXTERN_C void* memset(void* dst, int c, long long unsigned int len) {
- return Kernel::rt_set_memory_safe(dst, c, static_cast<Size>(len), static_cast<Size>(len));
-}
-
-EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) {
- Kernel::rt_copy_memory_safe(const_cast<void*>(src), dst, static_cast<Size>(len),
- static_cast<Size>(len));
- return dst;
-}
-
-EXTERN_C Int32 strcmp(const char* a, const char* b) {
- return Kernel::rt_string_cmp(a, b, rt_string_len(a));
-}
diff --git a/dev/kernel/src/CodeMgr.cc b/dev/kernel/src/CodeMgr.cc
deleted file mode 100644
index 7b7add6d..00000000
--- a/dev/kernel/src/CodeMgr.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/CodeMgr.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <NeKit/Utils.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 The team's process id.
-BOOL rtl_create_kernel_task(HAL::StackFramePtr task, const KID kid) noexcept {
- if (!kid || task == nullptr) return FALSE;
- return KernelTaskHelper::Add(task, kid);
-}
-
-/***********************************************************************************/
-/// @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_user_process(rtl_main_kind main, const Char* process_name) noexcept {
- if (!process_name || *process_name == 0) return kSchedInvalidPID;
- 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
deleted file mode 100644
index 88a9b73a..00000000
--- a/dev/kernel/src/Crc32.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Crc32.h>
-
-#define kCrcCnt (256)
-
-// @file CRC32.cc
-// @brief Check sequence implementation.
-
-namespace Kernel {
-/// @brief The CRC32 seed table.
-UInt32 kChecksumPolys[kCrcCnt] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
-
-/// @brief Calculate CRC32 of p
-/// @param in the data to compute.
-/// @param len the length of the data.
-/// @return CRC32 of **in**.
-UInt32 ke_calculate_crc32(const VoidPtr inp, Int32 len) noexcept {
- if (!inp) return ~0;
-
- UInt32 crc = 0xffffffff;
-
- Char* in = static_cast<Char*>(inp);
-
- while ((len--) > 0) crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF];
-
- return ~crc;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Defines.cc b/dev/kernel/src/Defines.cc
deleted file mode 100644
index 1ae6f12f..00000000
--- a/dev/kernel/src/Defines.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Defines.h>
diff --git a/dev/kernel/src/DeviceMgr.cc b/dev/kernel/src/DeviceMgr.cc
deleted file mode 100644
index b392a4ee..00000000
--- a/dev/kernel/src/DeviceMgr.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/DeviceMgr.h>
-
-namespace Kernel {} // namespace Kernel
diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc
deleted file mode 100644
index 8f2611a4..00000000
--- a/dev/kernel/src/DriveMgr.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <FirmwareKit/GPT.h>
-#include <FirmwareKit/VEPM.h>
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/DriveMgr.h>
-#include <NeKit/Utils.h>
-#include <modules/AHCI/AHCI.h>
-#include <modules/ATA/ATA.h>
-#include <modules/NVME/NVME.h>
-
-/***********************************************************************************/
-/// @file DriveMgr.cc
-/// @brief Drive Manager of NeKernel.
-///! @author Amlal El Mahrouss (amlal@nekernel.org)
-/***********************************************************************************/
-
-namespace Kernel {
-#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
-STATIC UInt16 kATAIO = 0U;
-STATIC UInt8 kATAMaster = 0U;
-#endif
-
-#if defined(__AHCI__)
-STATIC UInt16 kAHCIPortsImplemented [[maybe_unused]] = 0UL;
-#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);
-
- if (err_global_get() != kErrorSuccess) pckt.fPacketGood = NO;
-#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) {
- pckt.fPacketGood = NO;
- return;
- }
-
- // nothing starts before 512 anyways, even an EPM partition.
- if (!pckt.fPacketReadOnly && pckt.fPacketLba == 0) {
- pckt.fPacketGood = NO;
- return;
- }
-
-#ifdef __AHCI__
- drv_std_write(pckt.fPacketLba, (Char*) pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize);
-
- if (err_global_get() != kErrorSuccess) pckt.fPacketGood = NO;
-#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;
-
- kATAMaster = YES;
- kATAIO = ATA_PRIMARY_IO;
-
- if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) {
- pckt.fPacketGood = YES;
- return;
- }
-
- kATAMaster = NO;
- kATAIO = ATA_SECONDARY_IO;
-
- if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) {
- pckt.fPacketGood = YES;
- return;
- }
-
- pckt.fPacketGood = YES;
-#elif defined(__AHCI__)
- kAHCIPortsImplemented = 0;
- drv_std_init(kAHCIPortsImplemented);
-
- pckt.fPacketGood = kAHCIPortsImplemented > 0;
-#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__)
-}
-
-/// @brief Gets the drive kind (ATA, SCSI, AHCI...)
-/// @param void no arguments.
-/// @return no arguments.
-#ifdef __ATA_PIO__
-const Char* io_drv_kind(Void) {
- return "ATA-PIO";
-}
-#elif defined(__ATA_DMA__)
-const Char* io_drv_kind(Void) {
- return "ATA-DMA";
-}
-#elif defined(__AHCI__)
-const Char* io_drv_kind(Void) {
- return "AHCI";
-}
-#else
-const Char* io_drv_kind(Void) {
- return "null";
-}
-#endif
-
-/// @brief Unimplemented drive function.
-/// @param pckt the packet to read.
-Void io_drv_unimplemented(DriveTrait::DrivePacket& pckt) noexcept {
- NE_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 = kInvalidDrive;
-
- trait.fInput = io_drv_unimplemented;
- trait.fOutput = io_drv_unimplemented;
- trait.fVerify = io_drv_unimplemented;
- trait.fInit = io_drv_unimplemented;
- trait.fProtocol = io_drv_kind;
-
- kout << "DriveMgr: Construct: " << trait.fName << "\r";
-
- return trait;
-}
-
-namespace Probe {
- Void io_detect_drive(DriveTrait& trait) {
- trait.fInit(trait.fPacket);
-
- 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.fInput(trait.fPacket);
-
- if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0) {
- trait.fPacket.fPacketReadOnly = NO;
- trait.fKind = kMassStorageDrive | kEPMDrive;
-
- kout << "DriveMgr: Disk is EPM formatted.\r";
-
- trait.fSectorSz = block_struct.SectorSz;
- trait.fLbaEnd = block_struct.LbaEnd;
- trait.fLbaStart = block_struct.LbaStart;
- } else {
- GPT_PARTITION_TABLE gpt_struct;
-
- trait.fPacket.fPacketLba = kEPMBootBlockLba;
- trait.fPacket.fPacketSize = sizeof(GPT_PARTITION_TABLE);
- trait.fPacket.fPacketContent = &gpt_struct;
-
- rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime,
- rt_string_len("fs/detect-packet"));
-
- trait.fInput(trait.fPacket);
-
- if (rt_string_cmp(gpt_struct.Signature, kMagicGPT, kMagicLenGPT) == 0) {
- trait.fPacket.fPacketReadOnly = NO;
- trait.fKind = kMassStorageDrive | kGPTDrive;
-
- kout << "DriveMgr: Disk is GPT formatted.\r";
-
- trait.fSectorSz = gpt_struct.SizeOfEntries;
- trait.fLbaEnd = gpt_struct.LastGPTEntry;
- trait.fLbaStart = gpt_struct.FirstGPTEntry;
- } else {
- kout << "DriveMgr: Disk is unformatted.\r";
-
- trait.fPacket.fPacketReadOnly = YES;
- trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive;
-
- trait.fSectorSz = 512;
- trait.fLbaEnd = drv_std_get_sector_count() - 1;
- trait.fLbaStart = 0x400;
- }
- }
-
- rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime, rt_string_len("*/*"));
-
- trait.fPacket.fPacketLba = 0;
- trait.fPacket.fPacketSize = 0UL;
- trait.fPacket.fPacketContent = nullptr;
- }
-} // namespace Probe
-
-/// @brief Fetches the main drive.
-/// @return the new drive. (returns kEPMDrive if EPM formatted)
-DriveTrait io_construct_main_drive() noexcept {
- constexpr auto kMainDrive = "/media/main/";
-
- DriveTrait trait;
-
- 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.fProtocol = io_drv_kind;
-
- Probe::io_detect_drive(trait);
-
- return trait;
-}
-
-/// @brief Replacement for io_construct_main_drive that works with IMountpoint.
-/// @return the new drive. (returns kEPMDrive if EPM formatted)
-Void io_construct_main_drive(DriveTrait& trait) noexcept {
- constexpr auto kMainDrive = "/media/main/";
-
- 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.fProtocol = io_drv_kind;
-
- Probe::io_detect_drive(trait);
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/ErrorOr.cc b/dev/kernel/src/ErrorOr.cc
deleted file mode 100644
index 9f1b550b..00000000
--- a/dev/kernel/src/ErrorOr.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/ErrorOr.h>
-
-/***********************************************************************************/
-/// @file ErrorOr.cc ///
-/// @brief ErrorOr container class. ///
-/***********************************************************************************/
diff --git a/dev/kernel/src/FS/Ext2+IFS.cc b/dev/kernel/src/FS/Ext2+IFS.cc
deleted file mode 100644
index 106229f7..00000000
--- a/dev/kernel/src/FS/Ext2+IFS.cc
+++ /dev/null
@@ -1,1555 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#ifndef __NE_MINIMAL_OS__
-#ifdef __FSKIT_INCLUDES_EXT2__
-
-#include <FSKit/Ext2+IFS.h>
-#include <FSKit/Ext2.h>
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/FileMgr.h>
-#include <KernelKit/HeapMgr.h>
-#include <NeKit/ErrorOr.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/Utils.h>
-
-constexpr static UInt32 EXT2_DIRECT_BLOCKS = 12;
-constexpr static UInt32 EXT2_SINGLE_INDIRECT_INDEX = 12;
-constexpr static UInt32 EXT2_DOUBLE_INDIRECT_INDEX = 13;
-constexpr ATTRIBUTE(unused) static UInt32 EXT2_TRIPLE_INDIRECT_INDEX = 14;
-constexpr static UInt32 EXT2_ROOT_INODE = 2;
-constexpr ATTRIBUTE(unused) static UInt32 EXT2_SUPERBLOCK_BLOCK = 1;
-constexpr static UInt32 EXT2_GROUP_DESC_BLOCK_SMALL = 2;
-constexpr static UInt32 EXT2_GROUP_DESC_BLOCK_LARGE = 1;
-
-static inline SizeT ext2_min(SizeT a, SizeT b) {
- return a < b ? a : b;
-}
-
-struct Ext2GroupInfo {
- EXT2_GROUP_DESCRIPTOR* groupDesc;
- UInt32 groupDescriptorBlock;
- UInt32 offsetInGroupDescBlock;
- UInt8* blockBuffer;
-};
-
-// Convert EXT2 block number -> LBA (sector index) for Drive I/O.
-static inline UInt32 ext2_block_to_lba(Ext2Context* ctx, UInt32 blockNumber) {
- if (!ctx || !ctx->drive) return 0;
- UInt32 blockSize = ctx->BlockSize();
- UInt32 sectorSize = ctx->drive->fSectorSz;
- UInt32 sectorsPerBlock = blockSize / sectorSize;
- return blockNumber * sectorsPerBlock;
-}
-
-// Read a block and return a pointer to its content
-static ErrorOr<UInt32*> ext2_read_block_ptr(Ext2Context* ctx, UInt32 blockNumber) {
- if (!ctx || !ctx->drive || !ctx->superblock) return ErrorOr<UInt32*>(kErrorInvalidData);
-
- UInt32 blockSize = ctx->BlockSize();
- auto buf = (UInt32*) mm_alloc_ptr(blockSize, true, false);
- if (!buf) return ErrorOr<UInt32*>(kErrorHeapOutOfMemory);
-
- UInt32 lba = ext2_block_to_lba(ctx, blockNumber);
- if (!ext2_read_block(ctx->drive, lba, buf, blockSize)) {
- mm_free_ptr(buf);
- return ErrorOr<UInt32*>(kErrorDisk);
- }
- return ErrorOr<UInt32*>(buf);
-}
-
-// Get the block address for a given logical block index
-static ErrorOr<UInt32> ext2_get_block_address(Ext2Context* ctx, Ext2Node* node,
- UInt32 logicalIndex) {
- if (!ctx || !node || !ctx->drive) return ErrorOr<UInt32>(kErrorInvalidData);
-
- UInt32 blockSize = ctx->BlockSize();
- UInt32 pointersPerBlock = blockSize / sizeof(UInt32);
-
- // Direct blocks
- if (logicalIndex < EXT2_DIRECT_BLOCKS) {
- UInt32 bn = node->inode.fBlock[logicalIndex];
- if (bn == 0) return ErrorOr<UInt32>(kErrorInvalidData);
- return ErrorOr<UInt32>(bn);
- }
-
- // Single indirect blocks
- if (logicalIndex < (EXT2_DIRECT_BLOCKS + pointersPerBlock)) {
- UInt32 iblock = node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX];
- if (iblock == 0) return ErrorOr<UInt32>(kErrorInvalidData);
-
- auto res = ext2_read_block_ptr(ctx, iblock);
- if (!res) return ErrorOr<UInt32>(res.Error());
-
- // Using dereference operator
- UInt32* ptr = *res.Leak(); // operator* returns T (UInt32*)
-
- UInt32 val = ptr[logicalIndex - EXT2_DIRECT_BLOCKS];
- mm_free_ptr(ptr);
-
- if (val == 0) return ErrorOr<UInt32>(kErrorInvalidData);
- return ErrorOr<UInt32>(val);
- }
-
- // Double indirect blocks
- UInt32 doubleStart = EXT2_DIRECT_BLOCKS + pointersPerBlock;
- UInt32 doubleSpan = pointersPerBlock * pointersPerBlock;
- if (logicalIndex < (doubleStart + doubleSpan)) {
- UInt32 db = node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX];
- if (db == 0) return ErrorOr<UInt32>(kErrorInvalidData);
-
- auto dblRes = ext2_read_block_ptr(ctx, db);
- if (!dblRes) return ErrorOr<UInt32>(dblRes.Error());
-
- UInt32* dblPtr = *dblRes.Leak();
-
- UInt32 idxWithin = logicalIndex - doubleStart;
- UInt32 firstIdx = idxWithin / pointersPerBlock;
- UInt32 secondIdx = idxWithin % pointersPerBlock;
- UInt32 singleBlockNum = dblPtr[firstIdx];
-
- mm_free_ptr(dblPtr);
- if (singleBlockNum == 0) return ErrorOr<UInt32>(kErrorInvalidData);
-
- auto singleRes = ext2_read_block_ptr(ctx, singleBlockNum);
- if (!singleRes) return ErrorOr<UInt32>(singleRes.Error());
-
- UInt32* singlePtr = *singleRes.Leak();
- UInt32 val = singlePtr[secondIdx];
- mm_free_ptr(singlePtr);
-
- if (val == 0) return ErrorOr<UInt32>(kErrorInvalidData);
- return ErrorOr<UInt32>(val);
- }
-
- return ErrorOr<UInt32>(kErrorUnimplemented);
-}
-
-static ErrorOr<voidPtr> ext2_read_inode_data(Ext2Context* ctx, Ext2Node* node, SizeT size) {
- if (!ctx || !ctx->drive || !node || size == 0) return ErrorOr<voidPtr>(1);
-
- auto blockSize = ctx->BlockSize();
- SizeT available = (node->inode.fSize > node->cursor) ? (node->inode.fSize - node->cursor) : 0;
- SizeT bytesToRead = (size < available) ? size : available;
- if (bytesToRead == 0) return ErrorOr<voidPtr>(2); // nothing to read
-
- auto buffer = mm_alloc_ptr(bytesToRead, true, false);
- if (!buffer) return ErrorOr<voidPtr>(3); // allocation failed
-
- UInt32 currentOffset = node->cursor;
- SizeT remaining = bytesToRead;
- UInt8* dest = reinterpret_cast<UInt8*>(buffer);
-
- while (remaining > 0) {
- UInt32 logicalIndex = currentOffset / blockSize;
- UInt32 offsetInBlock = currentOffset % blockSize;
-
- auto phys = ext2_get_block_address(ctx, node, logicalIndex);
- if (phys.HasError()) {
- mm_free_ptr(buffer);
- return ErrorOr<voidPtr>(phys.Error());
- }
-
- auto blockNumber = phys.Value();
- UInt32 lba = ext2_block_to_lba(ctx, blockNumber);
-
- auto blockBuf = mm_alloc_ptr(blockSize, true, false);
- if (!blockBuf) {
- mm_free_ptr(buffer);
- return ErrorOr<voidPtr>(4); // block buffer allocation failed
- }
-
- if (!ext2_read_block(ctx->drive, lba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- mm_free_ptr(buffer);
- return ErrorOr<voidPtr>(5); // block read failed
- }
-
- SizeT chunk = ext2_min(remaining, blockSize - offsetInBlock);
- rt_copy_memory_safe(static_cast<void*>(static_cast<UInt8*>(blockBuf) + offsetInBlock),
- static_cast<void*>(dest), chunk, chunk);
-
- mm_free_ptr(blockBuf);
-
- currentOffset += static_cast<UInt32>(chunk);
- dest += chunk;
- remaining -= chunk;
- }
-
- node->cursor += static_cast<UInt32>(bytesToRead);
- return ErrorOr<voidPtr>(buffer);
-}
-
-// Get group descriptor information for a given block/inode number
-static ErrorOr<Ext2GroupInfo*> ext2_get_group_descriptor_info(Ext2Context* ctx,
- UInt32 targetBlockOrInode) {
- if (!ctx || !ctx->superblock || !ctx->drive) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData);
-
- UInt32 blockSize = ctx->BlockSize();
- UInt32 blocksPerGroup = ctx->superblock->fBlocksPerGroup;
- UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup;
- UInt32 totalBlocks = ctx->superblock->fBlockCount;
- UInt32 totalInodes = ctx->superblock->fInodeCount;
-
- if (blocksPerGroup == 0 || inodesPerGroup == 0) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData);
-
- // block group index
- UInt32 groupIndex = 0;
- if (targetBlockOrInode == 0) {
- groupIndex = 0;
- } else if (targetBlockOrInode <= totalInodes) {
- // 1-based
- groupIndex = (targetBlockOrInode - 1) / inodesPerGroup;
- } else {
- // EXT2 block number
- if (targetBlockOrInode < ctx->superblock->fFirstDataBlock) {
- groupIndex = 0;
- } else {
- groupIndex = (targetBlockOrInode - ctx->superblock->fFirstDataBlock) / blocksPerGroup;
- }
- }
-
- // Calculate number of block groups
- UInt32 groupsCount = static_cast<UInt32>((totalBlocks + blocksPerGroup - 1) / blocksPerGroup);
- if (groupIndex >= groupsCount) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData);
-
- // Determine GDT start block
- UInt32 gdtStartBlock =
- (blockSize == 1024) ? EXT2_GROUP_DESC_BLOCK_SMALL : EXT2_GROUP_DESC_BLOCK_LARGE;
-
- // Compute byte offset of descriptor within the GDT
- const UInt32 descSize = sizeof(EXT2_GROUP_DESCRIPTOR);
- UInt64 descByteOffset = static_cast<UInt64>(groupIndex) * descSize;
-
- // Which EXT2 block contains that descriptor?
- UInt32 blockOffsetWithinGdt = static_cast<UInt32>(descByteOffset / blockSize);
- UInt32 offsetInGroupDescBlock = static_cast<UInt32>(descByteOffset % blockSize);
- UInt32 groupDescriptorBlock = gdtStartBlock + blockOffsetWithinGdt;
-
- // Allocate buffer and read the block containing the descriptor
- auto blockBuffer = mm_alloc_ptr(blockSize, true, false);
- if (!blockBuffer) return ErrorOr<Ext2GroupInfo*>(kErrorHeapOutOfMemory);
-
- UInt32 groupDescriptorLba = ext2_block_to_lba(ctx, groupDescriptorBlock);
- if (!ext2_read_block(ctx->drive, groupDescriptorLba, blockBuffer, blockSize)) {
- mm_free_ptr(blockBuffer);
- return ErrorOr<Ext2GroupInfo*>(kErrorDisk);
- }
-
- auto groupInfo = (Ext2GroupInfo*) mm_alloc_ptr(sizeof(Ext2GroupInfo), true, false);
- if (!groupInfo) {
- mm_free_ptr(blockBuffer);
- return ErrorOr<Ext2GroupInfo*>(kErrorHeapOutOfMemory);
- }
-
- groupInfo->groupDesc = reinterpret_cast<EXT2_GROUP_DESCRIPTOR*>(
- reinterpret_cast<UInt8*>(blockBuffer) + offsetInGroupDescBlock);
- groupInfo->groupDescriptorBlock = groupDescriptorBlock;
- groupInfo->offsetInGroupDescBlock = offsetInGroupDescBlock;
- groupInfo->blockBuffer = reinterpret_cast<UInt8*>(blockBuffer);
-
- return ErrorOr<Ext2GroupInfo*>(groupInfo);
-}
-
-// Allocate a new block
-inline ErrorOr<UInt32> ext2_alloc_block(Ext2Context* ctx, EXT2_GROUP_DESCRIPTOR* groupDesc) {
- if (!ctx || !ctx->superblock || !groupDesc) return ErrorOr<UInt32>(kErrorInvalidData);
-
- UInt32 blockSize = ctx->BlockSize();
-
- // for the bitmap
- auto bitmap = mm_alloc_ptr(blockSize, true, false);
- if (!bitmap) return ErrorOr<UInt32>(kErrorHeapOutOfMemory);
-
- // Read block bitmap
- if (!ext2_read_block(ctx->drive, groupDesc->fBlockBitmap, bitmap, blockSize)) {
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(kErrorDisk);
- }
-
- // bit = 0
- for (UInt32 byteIdx = 0; byteIdx < blockSize; ++byteIdx) {
- auto byte = reinterpret_cast<unsigned char*>(bitmap)[byteIdx];
- if (byte != 0xFF) {
- for (int bit = 0; bit < 8; ++bit) {
- if (!(byte & (1 << bit))) {
- // Mark bit as used
- reinterpret_cast<unsigned char*>(bitmap)[byteIdx] |= (1 << bit);
-
- // Compute block number
- UInt32 blockNumber = byteIdx * 8 + bit;
-
- // Write bitmap back
- if (!ext2_write_block(ctx->drive, groupDesc->fBlockBitmap, bitmap, blockSize)) {
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(kErrorDisk);
- }
-
- // Update group descriptor free count
- groupDesc->fFreeBlocksCount--;
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(blockNumber);
- }
- }
- }
- }
-
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(kErrorDiskIsFull);
-}
-
-// Indirect blocks
-static ErrorOr<Void*> ext2_set_block_address(Ext2Context* ctx, Ext2Node* node,
- UInt32 logicalBlockIndex, UInt32 physicalBlockNumber) {
- using namespace Kernel;
-
- if (!ctx || !ctx->drive || !node) return ErrorOr<Void*>(kErrorInvalidData);
-
- auto blockSize = ctx->BlockSize();
- UInt32 blocksPerPointerBlock = blockSize / sizeof(UInt32);
-
- // Direct blocks
- if (logicalBlockIndex < EXT2_DIRECT_BLOCKS) {
- node->inode.fBlock[logicalBlockIndex] = physicalBlockNumber;
- return ErrorOr<Void*>(nullptr);
- }
-
- // Single indirect blocks
- if (logicalBlockIndex < EXT2_DIRECT_BLOCKS + blocksPerPointerBlock) {
- if (node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX] == 0) {
- auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
- if (groupInfoRes.HasError()) return ErrorOr<Void*>(groupInfoRes.Error());
-
- auto groupInfo = groupInfoRes.Leak().Leak(); // Ref<Ext2GroupInfo*>
- auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
- if (newBlockRes.HasError()) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(newBlockRes.Error());
- }
-
- node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX] = newBlockRes.Leak();
-
- UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
- if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- // Zero out new indirect block
- auto zeroBuf = mm_alloc_ptr(blockSize, true, false);
- if (!zeroBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory);
-
- rt_zero_memory(zeroBuf, blockSize);
- UInt32 indirectLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]);
- if (!ext2_write_block(ctx->drive, indirectLba, zeroBuf, blockSize)) {
- mm_free_ptr(zeroBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(zeroBuf);
- }
-
- // Read, modify, and write single indirect block
- auto indirectRes = ext2_read_block_ptr(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]);
- if (indirectRes.HasError()) return ErrorOr<Void*>(indirectRes.Error());
-
- UInt32* indirectPtr = indirectRes.Leak().Leak(); // Ref<UInt32*>
- indirectPtr[logicalBlockIndex - EXT2_DIRECT_BLOCKS] = physicalBlockNumber;
-
- UInt32 indirectLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]);
- if (!ext2_write_block(ctx->drive, indirectLba, indirectPtr, blockSize)) {
- mm_free_ptr(indirectPtr);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(indirectPtr);
- return ErrorOr<Void*>(nullptr);
- }
-
- // Double
- UInt32 doubleStart = EXT2_DIRECT_BLOCKS + blocksPerPointerBlock;
- UInt32 doubleSpan = blocksPerPointerBlock * blocksPerPointerBlock;
- if (logicalBlockIndex < doubleStart + doubleSpan) {
- if (node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX] == 0) {
- auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
- if (groupInfoRes.HasError()) return ErrorOr<Void*>(groupInfoRes.Error());
-
- auto groupInfo = groupInfoRes.Leak().Leak();
- auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
- if (newBlockRes.HasError()) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(newBlockRes.Error());
- }
-
- node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX] = newBlockRes.Leak();
-
- UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
- if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- // Zero new double-indirect block
- auto zeroBuf = mm_alloc_ptr(blockSize, true, false);
- if (!zeroBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory);
-
- rt_zero_memory(zeroBuf, blockSize);
- UInt32 dblLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]);
- if (!ext2_write_block(ctx->drive, dblLba, zeroBuf, blockSize)) {
- mm_free_ptr(zeroBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(zeroBuf);
- }
-
- // Compute indices
- UInt32 idxWithin = logicalBlockIndex - doubleStart;
- UInt32 firstIdx = idxWithin / blocksPerPointerBlock;
- UInt32 secondIdx = idxWithin % blocksPerPointerBlock;
-
- auto doubleRes = ext2_read_block_ptr(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]);
- if (doubleRes.HasError()) return ErrorOr<Void*>(doubleRes.Error());
-
- UInt32* doublePtr = doubleRes.Leak().Leak();
- UInt32 singleIndirectBlock = doublePtr[firstIdx];
-
- // Allocate single-indirect if missing
- if (singleIndirectBlock == 0) {
- auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
- if (groupInfoRes.HasError()) {
- mm_free_ptr(doublePtr);
- return ErrorOr<Void*>(groupInfoRes.Error());
- }
-
- auto groupInfo = groupInfoRes.Leak().Leak();
- auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
- if (newBlockRes.HasError()) {
- mm_free_ptr(doublePtr);
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(newBlockRes.Error());
- }
-
- singleIndirectBlock = newBlockRes.Leak();
- doublePtr[firstIdx] = singleIndirectBlock;
-
- // Write back GDT
- UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
- if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
- mm_free_ptr(doublePtr);
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- // Zero single-indirect block
- auto zeroBuf = mm_alloc_ptr(blockSize, true, false);
- if (!zeroBuf) {
- mm_free_ptr(doublePtr);
- return ErrorOr<Void*>(kErrorHeapOutOfMemory);
- }
-
- rt_zero_memory(zeroBuf, blockSize);
- UInt32 singleLba = ext2_block_to_lba(ctx, singleIndirectBlock);
- if (!ext2_write_block(ctx->drive, singleLba, zeroBuf, blockSize)) {
- mm_free_ptr(zeroBuf);
- mm_free_ptr(doublePtr);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(zeroBuf);
-
- // Write double-indirect back to disk
- UInt32 dblLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]);
- if (!ext2_write_block(ctx->drive, dblLba, doublePtr, blockSize)) {
- mm_free_ptr(doublePtr);
- return ErrorOr<Void*>(kErrorDisk);
- }
- }
-
- mm_free_ptr(doublePtr);
-
- // Write to single-indirect block
- auto singleRes = ext2_read_block_ptr(ctx, singleIndirectBlock);
- if (singleRes.HasError()) return ErrorOr<Void*>(singleRes.Error());
-
- UInt32* singlePtr = singleRes.Leak().Leak();
- singlePtr[secondIdx] = physicalBlockNumber;
-
- UInt32 singleLba = ext2_block_to_lba(ctx, singleIndirectBlock);
- if (!ext2_write_block(ctx->drive, singleLba, singlePtr, blockSize)) {
- mm_free_ptr(singlePtr);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(singlePtr);
- return ErrorOr<Void*>(nullptr);
- }
-
- // Triple indirect blocks not implemented
- return ErrorOr<Void*>(kErrorUnimplemented);
-}
-
-// Find a directory entry by name within a directory inode
-static ErrorOr<EXT2_DIR_ENTRY*> ext2_find_dir_entry(Ext2Context* ctx, Ext2Node* dirNode,
- const char* name) {
- if (!ctx || !ctx->drive || !dirNode || !name) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorInvalidData);
-
- // Check directory type
- auto type = (dirNode->inode.fMode >> 12) & 0xF;
- if (type != kExt2FileTypeDirectory) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorInvalidData);
-
- UInt32 blockSize = ctx->BlockSize();
- auto blockBuf = mm_alloc_ptr(blockSize, true, false);
- if (!blockBuf) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorHeapOutOfMemory);
-
- SizeT nameLen = rt_string_len(name);
- for (UInt32 i = 0; i < EXT2_DIRECT_BLOCKS; ++i) {
- UInt32 blockNum = dirNode->inode.fBlock[i];
- if (blockNum == 0) continue;
-
- UInt32 lba = ext2_block_to_lba(ctx, blockNum);
- if (!ext2_read_block(ctx->drive, lba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- return ErrorOr<EXT2_DIR_ENTRY*>(kErrorDisk);
- }
-
- UInt32 offset = 0;
- while (offset + sizeof(UInt32) + sizeof(UInt16) <= blockSize) {
- auto onDiskEntry = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + offset);
- if (onDiskEntry->fRecordLength == 0) break; // corrupted
-
- if (onDiskEntry->fInode != 0 && onDiskEntry->fNameLength == nameLen) {
- // Compare names
- if (rt_string_cmp(name, onDiskEntry->fName, nameLen) == 0) {
- // Allocate a result sized to hold the name + metadata
- SizeT recSize = sizeof(EXT2_DIR_ENTRY);
- auto found = (EXT2_DIR_ENTRY*) mm_alloc_ptr(recSize, true, false);
- if (!found) {
- mm_free_ptr(blockBuf);
- return ErrorOr<EXT2_DIR_ENTRY*>(kErrorHeapOutOfMemory);
- }
-
- // Copy only record-length bytes
- rt_copy_memory_safe(onDiskEntry, found, onDiskEntry->fRecordLength, recSize);
- mm_free_ptr(blockBuf);
- return ErrorOr<EXT2_DIR_ENTRY*>(found);
- }
- }
- offset += onDiskEntry->fRecordLength;
- }
- }
-
- mm_free_ptr(blockBuf);
- return ErrorOr<EXT2_DIR_ENTRY*>(kErrorFileNotFound);
-}
-
-// Compute ideal record length for a directory name
-static inline UInt16 ext2_dir_entry_ideal_len(UInt8 nameLen) {
- UInt16 raw =
- static_cast<UInt16>(8 + nameLen); // 8 = inode(4)+rec_len(2)+name_len(1)+file_type(1)
- return static_cast<UInt16>((raw + 3) & ~3u); // align up to 4
-}
-
-static ErrorOr<Void*> ext2_add_dir_entry(Ext2Context* ctx, Ext2Node* parentDirNode,
- const char* name, UInt32 inodeNumber, UInt8 fileType) {
- using namespace Kernel;
-
- if (!ctx || !ctx->drive || !parentDirNode || !name) return ErrorOr<Void*>(kErrorInvalidData);
-
- UInt32 blockSize = ctx->BlockSize();
- SizeT nameLen = rt_string_len(name);
- if (nameLen == 0 || nameLen > 255) return ErrorOr<Void*>(kErrorInvalidData);
-
- UInt16 newRecIdeal = ext2_dir_entry_ideal_len(static_cast<UInt8>(nameLen));
-
- auto blockBuf = mm_alloc_ptr(blockSize, true, false);
- if (!blockBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory);
-
- for (UInt32 bi = 0; bi < EXT2_DIRECT_BLOCKS; ++bi) {
- UInt32 blockNum = parentDirNode->inode.fBlock[bi];
-
- if (blockNum == 0) {
- // Allocate new block
- auto groupInfoRes = ext2_get_group_descriptor_info(ctx, parentDirNode->inodeNumber);
- if (!groupInfoRes) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(groupInfoRes.Error());
- }
-
- auto groupInfo = *groupInfoRes.Leak(); // Dereference to get Ext2GroupInfo*
- auto allocBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
- if (!allocBlockRes) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(allocBlockRes.Error());
- }
-
- UInt32 newBlock = *allocBlockRes.Leak(); // Dereference to get UInt32
- UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
-
- if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- // Zero block & insert entry
- rt_zero_memory(blockBuf, blockSize);
- auto entry = reinterpret_cast<EXT2_DIR_ENTRY*>(blockBuf);
- entry->fInode = inodeNumber;
- entry->fNameLength = static_cast<UInt8>(nameLen);
- entry->fFileType = fileType;
- entry->fRecordLength = static_cast<UInt16>(blockSize);
- rt_copy_memory_safe(const_cast<char*>(name), entry->fName, nameLen, blockSize);
-
- UInt32 blockLba = ext2_block_to_lba(ctx, newBlock);
- if (!ext2_write_block(ctx->drive, blockLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- auto setRes = ext2_set_block_address(ctx, parentDirNode, bi, newBlock);
- if (!setRes) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(setRes.Error());
- }
-
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(nullptr);
- }
-
- // read it
- UInt32 blockLba = ext2_block_to_lba(ctx, blockNum);
- if (!ext2_read_block(ctx->drive, blockLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- UInt32 offset = 0;
- EXT2_DIR_ENTRY* lastEntry = nullptr;
- UInt32 lastOffset = 0;
-
- while (offset < blockSize) {
- if (offset + 8 > blockSize) break;
- auto e = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + offset);
- if (e->fRecordLength == 0) break;
- lastEntry = e;
- lastOffset = offset;
- offset += e->fRecordLength;
- }
-
- if (!lastEntry) continue;
-
- UInt16 lastIdeal = ext2_dir_entry_ideal_len(lastEntry->fNameLength);
-
- if (lastEntry->fRecordLength >= (UInt16) (lastIdeal + newRecIdeal)) {
- UInt16 origRec = lastEntry->fRecordLength;
- lastEntry->fRecordLength = lastIdeal;
-
- UInt32 newOffset = lastOffset + lastIdeal;
- auto newEntry = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + newOffset);
- newEntry->fInode = inodeNumber;
- newEntry->fNameLength = static_cast<UInt8>(nameLen);
- newEntry->fFileType = fileType;
- newEntry->fRecordLength = static_cast<UInt16>(origRec - lastIdeal);
- rt_copy_memory_safe(const_cast<char*>(name), newEntry->fName, nameLen,
- newEntry->fRecordLength);
-
- if (!ext2_write_block(ctx->drive, blockLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(nullptr);
- }
- }
-
- // No space in direct blocks -> allocate new block
- int targetIndex = -1;
- for (UInt32 i = 0; i < EXT2_DIRECT_BLOCKS; ++i) {
- if (parentDirNode->inode.fBlock[i] == 0) {
- targetIndex = i;
- break;
- }
- }
- if (targetIndex == -1) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(kErrorUnimplemented);
- }
-
- auto groupInfoResult = ext2_get_group_descriptor_info(ctx, parentDirNode->inodeNumber);
- if (!groupInfoResult) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(groupInfoResult.Error());
- }
-
- auto groupInfo = *groupInfoResult.Leak(); // Dereference to get Ext2GroupInfo*
- auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
- if (!newBlockRes) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(newBlockRes.Error());
- }
-
- UInt32 newBlockNum = *newBlockRes.Leak(); // Dereference to get UInt32
- UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
- if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- rt_zero_memory(blockBuf, blockSize);
- auto entry = reinterpret_cast<EXT2_DIR_ENTRY*>(blockBuf);
- entry->fInode = inodeNumber;
- entry->fNameLength = static_cast<UInt8>(nameLen);
- entry->fFileType = fileType;
- entry->fRecordLength = static_cast<UInt16>(blockSize);
- rt_copy_memory_safe(const_cast<char*>(name), entry->fName, nameLen, blockSize);
-
- UInt32 newBlockLba = ext2_block_to_lba(ctx, newBlockNum);
- if (!ext2_write_block(ctx->drive, newBlockLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- auto setRes = ext2_set_block_address(ctx, parentDirNode, targetIndex, newBlockNum);
- if (!setRes) {
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(setRes.Error());
- }
-
- mm_free_ptr(blockBuf);
- return ErrorOr<Void*>(nullptr);
-}
-
-// Soon
-static ErrorOr<UInt32> ext2_alloc_inode(Ext2Context* ctx, EXT2_GROUP_DESCRIPTOR* groupDesc) {
- if (!ctx || !ctx->superblock || !groupDesc) return ErrorOr<UInt32>(kErrorInvalidData);
-
- UInt32 blockSize = ctx->BlockSize();
-
- // buffer for the inode bitmap
- auto bitmap = mm_alloc_ptr(blockSize, true, false);
- if (!bitmap) return ErrorOr<UInt32>(kErrorHeapOutOfMemory);
-
- // Read inode bitmap
- if (!ext2_read_block(ctx->drive, groupDesc->fInodeBitmap, bitmap, blockSize)) {
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(kErrorDisk);
- }
-
- // Find first free inode (bit = 0)
- for (UInt32 byteIdx = 0; byteIdx < blockSize; ++byteIdx) {
- auto byte = reinterpret_cast<unsigned char*>(bitmap)[byteIdx];
- if (byte != 0xFF) {
- for (int bit = 0; bit < 8; ++bit) {
- if (!(byte & (1 << bit))) {
- // Mark bit as used
- reinterpret_cast<unsigned char*>(bitmap)[byteIdx] |= (1 << bit);
-
- // Compute inode number
- UInt32 inodeNumber = byteIdx * 8 + bit + 1; // Inodes are 1-based
-
- // Write bitmap back
- if (!ext2_write_block(ctx->drive, groupDesc->fInodeBitmap, bitmap, blockSize)) {
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(kErrorDisk);
- }
-
- // Update group descriptor free count
- groupDesc->fFreeInodesCount--;
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(inodeNumber);
- }
- }
- }
- }
-
- mm_free_ptr(bitmap);
- return ErrorOr<UInt32>(kErrorDiskIsFull);
-}
-
-// to write an inode to its correct location on disk
-static ErrorOr<Void*> ext2_write_inode(Ext2Context* ctx, Ext2Node* node) {
- using namespace Kernel;
-
- if (!ctx || !ctx->superblock || !ctx->drive || !node) return ErrorOr<Void*>(kErrorInvalidData);
-
- auto blockSize = ctx->BlockSize();
- UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup;
-
- if (inodesPerGroup == 0) return ErrorOr<Void*>(kErrorInvalidData);
-
- // Calculate which group this inode belongs to
- UInt32 groupIndex = (node->inodeNumber - 1) / inodesPerGroup;
- NE_UNUSED(groupIndex);
- UInt32 inodeIndexInGroup = (node->inodeNumber - 1) % inodesPerGroup;
-
- // Get group descriptor
- auto groupInfoResult = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
- if (!groupInfoResult) return ErrorOr<Void*>(groupInfoResult.Error());
-
- auto groupInfo = *groupInfoResult.Leak(); // Dereference to get Ext2GroupInfo*
-
- // Calculate inode table position
- UInt32 inodeTableBlock = groupInfo->groupDesc->fInodeTable;
- UInt32 inodeSize = ctx->superblock->fInodeSize;
- UInt32 inodesPerBlock = blockSize / inodeSize;
-
- UInt32 blockOffset = inodeIndexInGroup / inodesPerBlock;
- UInt32 offsetInBlock = (inodeIndexInGroup % inodesPerBlock) * inodeSize;
-
- UInt32 inodeBlock = inodeTableBlock + blockOffset;
- UInt32 inodeLba = ext2_block_to_lba(ctx, inodeBlock);
-
- // Read the block containing the inode
- auto blockBuf = mm_alloc_ptr(blockSize, true, false);
- if (!blockBuf) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(kErrorHeapOutOfMemory);
- }
-
- if (!ext2_read_block(ctx->drive, inodeLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- // Copy the updated inode into the block buffer
- rt_copy_memory_safe(&node->inode, static_cast<void*>((UInt8*) blockBuf + offsetInBlock),
- sizeof(EXT2_INODE), blockSize - offsetInBlock);
-
- // Write the block back
- if (!ext2_write_block(ctx->drive, inodeLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return ErrorOr<Void*>(kErrorDisk);
- }
-
- mm_free_ptr(blockBuf);
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- return ErrorOr<Void*>(nullptr);
-}
-
-namespace {
-// new
-struct PathComponents {
- const char** components;
- int count;
- Char* buffer;
-
- PathComponents(const char* path) : components(nullptr), count(0), buffer(nullptr) {
- if (!path || *path == '\0') return;
-
- SizeT pathLen = rt_string_len(path);
- buffer = (Char*) mm_alloc_ptr(pathLen + 1, true, false);
- if (!buffer) return;
-
- rt_copy_memory_safe((void*) path, buffer, pathLen, pathLen + 1);
- buffer[pathLen] = '\0';
-
- // temp array
- const char** temp = (const char**) mm_alloc_ptr(sizeof(char*) * (pathLen + 1), true, false);
- if (!temp) {
- mm_free_ptr(buffer);
- buffer = nullptr;
- return;
- }
-
- UInt32 compCount = 0;
- Char* p = buffer;
-
- while (*p != '\0') {
- // skip slashes
- while (*p == '/') p++;
- if (*p == '\0') break;
-
- Char* start = p;
- while (*p != '/' && *p != '\0') p++;
- Char saved = *p;
- *p = '\0';
-
- // handle ".", "..", or normal
- if (rt_string_cmp(start, ".", 1) == 0) {
- // ignore
- } else if (rt_string_cmp(start, "..", 2) == 0) {
- if (compCount > 0) compCount--; // go up one level
- } else {
- temp[compCount++] = start;
- }
-
- *p = saved;
- }
-
- if (compCount == 0) {
- mm_free_ptr(temp);
- return;
- }
-
- components = (const char**) mm_alloc_ptr(sizeof(char*) * compCount, true, false);
- if (!components) {
- mm_free_ptr(temp);
- return;
- }
-
- for (UInt32 i = 0; i < compCount; i++) components[i] = temp[i];
- count = compCount;
-
- mm_free_ptr(temp);
- }
-
- ~PathComponents() {
- if (components) mm_free_ptr(components);
- if (buffer) mm_free_ptr(buffer);
- }
-};
-} // anonymous namespace
-
-// The Ext2FileSystemParser (not manager!)
-Ext2FileSystemParser::Ext2FileSystemParser(DriveTrait* drive) : fCtx(drive) {
- MUST_PASS(fCtx);
-}
-
-NodePtr Ext2FileSystemParser::Open(const char* path, const char* restrict_type) {
- NE_UNUSED(restrict_type);
- if (!path || *path == '\0' || !this->fCtx.drive) {
- return nullptr;
- }
-
- // Root ("/")
- if (rt_string_len(path) == 1 && rt_string_cmp(path, "/", 1) == 0) {
- auto inodeResult = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE);
- if (!inodeResult) {
- return nullptr;
- }
-
- auto heapNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false);
- if (!heapNode) return nullptr;
-
- *heapNode = *inodeResult.Leak().Leak();
- heapNode->cursor = 0;
- return reinterpret_cast<NodePtr>(heapNode);
- }
-
- PathComponents pathComponents(path);
- if (pathComponents.count == 0) {
- return nullptr;
- }
-
- UInt32 currentInodeNumber = EXT2_ROOT_INODE;
- Ext2Node* currentDirNode = nullptr;
-
- for (UInt32 i = 0; i < (UInt32) pathComponents.count; ++i) {
- auto inodeResult = ext2_load_inode(&this->fCtx, currentInodeNumber);
- if (!inodeResult) {
- if (currentDirNode) mm_free_ptr(currentDirNode);
- return nullptr;
- }
-
- if (currentDirNode) {
- mm_free_ptr(currentDirNode);
- currentDirNode = nullptr;
- }
-
- currentDirNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false);
- if (!currentDirNode) {
- return nullptr;
- }
-
- *currentDirNode = *inodeResult.Leak().Leak();
- currentDirNode->cursor = 0;
-
- if (i < pathComponents.count - 1U) {
- UInt32 type = (currentDirNode->inode.fMode >> 12) & 0xF;
- if (type != kExt2FileTypeDirectory) {
- mm_free_ptr(currentDirNode);
- return nullptr;
- }
- }
-
- auto dirEntryResult =
- ext2_find_dir_entry(&this->fCtx, currentDirNode, pathComponents.components[i]);
- if (!dirEntryResult) {
- mm_free_ptr(currentDirNode);
- return nullptr;
- }
-
- EXT2_DIR_ENTRY* entryPtr = *dirEntryResult.Leak();
- currentInodeNumber = entryPtr->fInode;
- mm_free_ptr(entryPtr);
- }
-
- auto finalInodeResult = ext2_load_inode(&this->fCtx, currentInodeNumber);
- if (!finalInodeResult) {
- if (currentDirNode) mm_free_ptr(currentDirNode);
- return nullptr;
- }
-
- if (currentDirNode) {
- mm_free_ptr(currentDirNode);
- }
-
- auto resultNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false);
- if (!resultNode) {
- return nullptr;
- }
-
- *resultNode = *finalInodeResult.Leak().Leak();
- resultNode->cursor = 0;
- return reinterpret_cast<NodePtr>(resultNode);
-}
-
-void* Ext2FileSystemParser::Read(NodePtr node, Int32 flags, SizeT size) {
- if (!node) return nullptr;
-
- NE_UNUSED(flags);
-
- auto extNode = reinterpret_cast<Ext2Node*>(node);
- auto dataResult = ext2_read_inode_data(&this->fCtx, extNode, size);
-
- if (!dataResult) {
- return nullptr; // error, nothing to return
- }
-
- void* data = *dataResult.Leak();
- if (data) {
- extNode->cursor += static_cast<UInt32>(size);
- }
-
- return data;
-}
-
-void Ext2FileSystemParser::Write(NodePtr node, void* data, Int32 flags, SizeT size) {
- if (!node || !data || size == 0) return;
-
- NE_UNUSED(flags);
-
- auto extNode = reinterpret_cast<Ext2Node*>(node);
- auto blockSize = this->fCtx.BlockSize();
- SizeT bytesWritten = 0;
-
- UInt32 currentOffset = extNode->cursor;
- UInt8* src = reinterpret_cast<UInt8*>(data);
-
- while (bytesWritten < size) {
- UInt32 logicalBlockIndex = currentOffset / blockSize;
- UInt32 offsetInBlock = currentOffset % blockSize;
-
- auto physBlockResult = ext2_get_block_address(&this->fCtx, extNode, logicalBlockIndex);
- UInt32 physicalBlock = 0;
-
- if (!physBlockResult) {
- auto err = physBlockResult.Error();
- if (err == kErrorInvalidData || err == kErrorUnimplemented) {
- auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, extNode->inodeNumber);
- if (!groupInfoResult) {
- return;
- }
-
- auto groupInfo = *groupInfoResult.Leak();
- auto allocResult = ext2_alloc_block(&this->fCtx, groupInfo->groupDesc);
- if (!allocResult) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return;
- }
-
- physicalBlock = *allocResult.Leak();
-
- auto setRes =
- ext2_set_block_address(&this->fCtx, extNode, logicalBlockIndex, physicalBlock);
- if (!setRes) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return;
- }
-
- UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock);
- if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- return;
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- } else {
- return;
- }
- } else {
- physicalBlock = physBlockResult.Value();
- }
-
- UInt32 physicalLba = ext2_block_to_lba(&this->fCtx, physicalBlock);
-
- auto blockBuf = mm_alloc_ptr(blockSize, true, false);
- if (!blockBuf) return;
-
- if (offsetInBlock > 0 || (size - bytesWritten) < blockSize) {
- if (!ext2_read_block(this->fCtx.drive, physicalLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- return;
- }
- } else {
- rt_zero_memory(blockBuf, blockSize);
- }
-
- UInt32 bytesInCurrentBlock =
- static_cast<UInt32>(ext2_min(size - bytesWritten, blockSize - offsetInBlock));
- rt_copy_memory_safe(src, static_cast<void*>((UInt8*) blockBuf + offsetInBlock),
- bytesInCurrentBlock, blockSize - offsetInBlock);
-
- if (!ext2_write_block(this->fCtx.drive, physicalLba, blockBuf, blockSize)) {
- mm_free_ptr(blockBuf);
- return;
- }
-
- mm_free_ptr(blockBuf);
-
- currentOffset += bytesInCurrentBlock;
- src += bytesInCurrentBlock;
- bytesWritten += bytesInCurrentBlock;
- }
-
- if (currentOffset > extNode->inode.fSize) {
- extNode->inode.fSize = currentOffset;
- }
-
- extNode->inode.fBlocks = (extNode->inode.fSize + blockSize - 1) / blockSize;
- extNode->inode.fModifyTime = 0;
-
- auto writeInodeRes = ext2_write_inode(&this->fCtx, extNode);
- if (!writeInodeRes) {
- // Failed to persist inode
- }
-
- extNode->cursor = currentOffset;
-}
-
-bool Ext2FileSystemParser::Seek(NodePtr node, SizeT offset) {
- if (!node) return false;
- auto extNode = reinterpret_cast<Ext2Node*>(node);
- extNode->cursor = static_cast<UInt32>(offset);
- return true;
-}
-
-SizeT Ext2FileSystemParser::Tell(NodePtr node) {
- if (!node) return 0;
- auto extNode = reinterpret_cast<Ext2Node*>(node);
- return extNode->cursor;
-}
-
-bool Ext2FileSystemParser::Rewind(NodePtr node) {
- if (!node) return false;
- auto extNode = reinterpret_cast<Ext2Node*>(node);
- extNode->cursor = 0;
- return true;
-}
-
-void* Ext2FileSystemParser::Read(const char* name, NodePtr node, Int32 flags, SizeT size) {
- NE_UNUSED(name);
- return Read(node, flags, size);
-}
-
-void Ext2FileSystemParser::Write(const char* name, NodePtr node, void* data, Int32 flags,
- SizeT size) {
- NE_UNUSED(name);
- Write(node, data, flags, size);
-}
-
-NodePtr Ext2FileSystemParser::Create(const char* path) {
- if (!path || *path == '\0') return nullptr;
-
- PathComponents pathComponents(path);
- if (pathComponents.count == 0) return nullptr;
-
- const char* filename = pathComponents.components[pathComponents.count - 1];
- if (rt_string_len(filename) > kExt2FSMaxFileNameLen) return nullptr;
-
- // Build parent path
- Char parentPathBuf[256] = {0};
- SizeT currentPathLen = 0;
- for (UInt32 i = 0; (i < pathComponents.count - 1U); ++i) {
- SizeT componentLen = rt_string_len(pathComponents.components[i]);
- if (currentPathLen + componentLen + 1 >= sizeof(parentPathBuf)) return nullptr;
- if (i > 0) parentPathBuf[currentPathLen++] = '/';
- rt_copy_memory_safe(const_cast<char*>(pathComponents.components[i]),
- parentPathBuf + currentPathLen, componentLen,
- sizeof(parentPathBuf) - currentPathLen);
- currentPathLen += componentLen;
- }
- parentPathBuf[currentPathLen] = '\0';
-
- // Open parent directory
- NodePtr parentDirNodePtr = nullptr;
- if (currentPathLen == 0) {
- // root
- auto inodeRes = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE);
- if (!inodeRes) return nullptr;
- parentDirNodePtr = mm_alloc_ptr(sizeof(Ext2Node), true, false);
- if (!parentDirNodePtr) return nullptr;
- *reinterpret_cast<Ext2Node*>(parentDirNodePtr) = *inodeRes.Leak().Leak();
- reinterpret_cast<Ext2Node*>(parentDirNodePtr)->cursor = 0;
- } else {
- parentDirNodePtr = Open(parentPathBuf, "r");
- }
-
- if (!parentDirNodePtr) return nullptr;
-
- auto parentDirNode = reinterpret_cast<Ext2Node*>(parentDirNodePtr);
-
- // Ensure parent is a directory
- UInt32 type = (parentDirNode->inode.fMode >> 12) & 0xF;
- if (type != kExt2FileTypeDirectory) {
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- // Get group info for allocation
- auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, parentDirNode->inodeNumber);
- if (!groupInfoResult) {
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
- auto groupInfo = *groupInfoResult.Leak();
-
- // Allocate new inode
- auto newInodeRes = ext2_alloc_inode(&this->fCtx, groupInfo->groupDesc);
- if (!newInodeRes) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo); // so this works
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
- UInt32 newInodeNumber = newInodeRes.Value();
-
- UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock);
- if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, this->fCtx.BlockSize())) {
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- // Create new Ext2Node
- Ext2Node* newFileNode = reinterpret_cast<Ext2Node*>(mm_alloc_ptr(sizeof(Ext2Node), true, false));
- if (!newFileNode) {
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- newFileNode->inodeNumber = newInodeNumber;
- rt_zero_memory(&newFileNode->inode, sizeof(EXT2_INODE));
-
- newFileNode->inode.fMode = (kExt2FileTypeRegular << 12);
- newFileNode->inode.fUID = 0;
- newFileNode->inode.fGID = 0;
- newFileNode->inode.fLinksCount = 1;
- newFileNode->inode.fSize = 0;
- newFileNode->inode.fBlocks = 0;
- newFileNode->inode.fCreateTime = 0;
- newFileNode->inode.fModifyTime = 0;
-
- // Persist new inode
- auto writeInodeRes = ext2_write_inode(&this->fCtx, newFileNode);
- if (!writeInodeRes) {
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newFileNode);
- return nullptr;
- }
-
- // Add directory entry
- auto addRes = ext2_add_dir_entry(&this->fCtx, parentDirNode, filename, newInodeNumber,
- kExt2FileTypeRegular);
- if (!addRes) {
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newFileNode);
- return nullptr;
- }
-
- // Update parent inode
- auto parentWriteRes = ext2_write_inode(&this->fCtx, parentDirNode);
- // ignore failure
-
- NE_UNUSED(parentWriteRes);
-
- mm_free_ptr(parentDirNode);
- return reinterpret_cast<NodePtr>(newFileNode);
-}
-
-NodePtr Ext2FileSystemParser::CreateDirectory(const char* path) {
- if (!path || *path == '\0') return nullptr;
-
- PathComponents pathComponents(path);
- if (pathComponents.count == 0) {
- kout << "EXT2: Failed to parse path for CreateDirectory.\n";
- return nullptr;
- }
-
- const char* dirname = pathComponents.components[pathComponents.count - 1];
- if (rt_string_len(dirname) > kExt2FSMaxFileNameLen) {
- kout << "EXT2: Directory name too long: " << dirname << ".\n";
- return nullptr;
- }
-
- // Build parent path
- Char parentPathBuf[256];
- SizeT currentPathLen = 0;
- for (UInt32 i = 0; (i < pathComponents.count - 1U); ++i) {
- SizeT componentLen = rt_string_len(pathComponents.components[i]);
- if (currentPathLen + componentLen + 1 >= sizeof(parentPathBuf)) {
- kout << "EXT2: Parent path too long for CreateDirectory.\n";
- return nullptr;
- }
-
- if (i > 0) parentPathBuf[currentPathLen++] = '/';
-
- rt_copy_memory_safe(static_cast<void*>(const_cast<char*>(pathComponents.components[i])),
- static_cast<void*>(parentPathBuf + currentPathLen), componentLen,
- sizeof(parentPathBuf) - currentPathLen);
- currentPathLen += componentLen;
- }
-
- parentPathBuf[currentPathLen] = '\0';
-
- // Open parent directory node
- NodePtr parentDirNodePtr = nullptr;
- if (currentPathLen == 0) {
- auto inodeRes = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE);
- if (!inodeRes) {
- return nullptr;
- }
-
- parentDirNodePtr = reinterpret_cast<NodePtr>(mm_alloc_ptr(sizeof(Ext2Node), true, false));
- if (!parentDirNodePtr) return nullptr;
-
- *reinterpret_cast<Ext2Node*>(parentDirNodePtr) = *inodeRes.Leak().Leak();
- reinterpret_cast<Ext2Node*>(parentDirNodePtr)->cursor = 0;
- } else {
- parentDirNodePtr = Open(parentPathBuf, "r");
- }
-
- if (!parentDirNodePtr) {
- kout << "EXT2: Failed to open parent directory for CreateDirectory: " << parentPathBuf << ".\n";
- return nullptr;
- }
-
- auto parentDirNode = reinterpret_cast<Ext2Node*>(parentDirNodePtr);
-
- // Check parent is a directory
- UInt32 parentType = (parentDirNode->inode.fMode >> 12) & 0xF;
- if (parentType != kExt2FileTypeDirectory) {
- kout << "EXT2: Parent is not a directory: " << parentPathBuf << ".\n";
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- // Allocate inode
- auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, parentDirNode->inodeNumber);
- if (!groupInfoResult) {
- kout << "EXT2: Failed to get group descriptor info for new dir inode.\n";
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- auto groupInfo = *groupInfoResult.Leak();
- auto newInodeRes = ext2_alloc_inode(&this->fCtx, groupInfo->groupDesc);
- if (!newInodeRes) {
- kout << "EXT2: Failed to allocate inode for new directory.\n";
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- UInt32 newInodeNumber = *newInodeRes.Leak();
-
- // Write back group descriptor block
- UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock);
- if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, this->fCtx.BlockSize())) {
- kout << "EXT2: Failed to write group descriptor after inode allocation.\n";
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
- mm_free_ptr(groupInfo);
-
- // Create new Ext2Node and initialize inode fields
- Ext2Node* newDirNode = reinterpret_cast<Ext2Node*>(mm_alloc_ptr(sizeof(Ext2Node), true, false));
- if (!newDirNode) {
- kout << "EXT2: Out of memory for new directory node.\n";
- mm_free_ptr(parentDirNode);
- return nullptr;
- }
-
- newDirNode->inodeNumber = newInodeNumber;
- rt_zero_memory(&newDirNode->inode, sizeof(EXT2_INODE));
- newDirNode->inode.fMode = (kExt2FileTypeDirectory << 12);
- newDirNode->inode.fUID = 0;
- newDirNode->inode.fGID = 0;
- newDirNode->inode.fLinksCount = 2; // . and ..
- newDirNode->inode.fSize = this->fCtx.BlockSize();
- newDirNode->inode.fBlocks = 1;
- newDirNode->inode.fCreateTime = 0;
- newDirNode->inode.fModifyTime = 0;
-
- // Allocate a data block for the new directory
- auto groupForBlockRes = ext2_get_group_descriptor_info(&this->fCtx, newDirNode->inodeNumber);
- if (!groupForBlockRes) {
- kout << "EXT2: Failed to get group info for directory block allocation.\n";
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- auto groupForBlock = *groupForBlockRes.Leak();
- auto newBlockRes = ext2_alloc_block(&this->fCtx, groupForBlock->groupDesc);
- if (!newBlockRes) {
- kout << "EXT2: Failed to allocate block for new directory contents.\n";
- mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer));
- mm_free_ptr(groupForBlock);
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- UInt32 newDirBlockNum = *newBlockRes.Leak();
-
- // Write back GDT
- UInt32 gdtLba2 = ext2_block_to_lba(&this->fCtx, groupForBlock->groupDescriptorBlock);
- if (!ext2_write_block(this->fCtx.drive, gdtLba2, groupForBlock->blockBuffer,
- this->fCtx.BlockSize())) {
- kout << "EXT2: Failed to write GDT after directory block allocation.\n";
- mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer));
- mm_free_ptr(groupForBlock);
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer));
- mm_free_ptr(groupForBlock);
-
- // Set the block in newDirNode
- auto setBlkRes = ext2_set_block_address(&this->fCtx, newDirNode, 0, newDirBlockNum);
- if (!setBlkRes) {
- kout << "EXT2: Failed to set data block for new directory.\n";
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- // Prepare block with '.' and '..'
- auto dirBlockBuf = mm_alloc_ptr(this->fCtx.BlockSize(), true, false);
- if (!dirBlockBuf) {
- kout << "EXT2: Out of memory preparing directory block.\n";
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- rt_zero_memory(dirBlockBuf, this->fCtx.BlockSize());
-
- // '.' entry
- auto dot = reinterpret_cast<EXT2_DIR_ENTRY*>(dirBlockBuf);
- dot->fInode = newInodeNumber;
- dot->fNameLength = 1;
- dot->fFileType = kExt2FileTypeDirectory;
- dot->fRecordLength = ext2_dir_entry_ideal_len(dot->fNameLength);
- dot->fName[0] = '.';
-
- // '..' entry occupies rest of block
- auto dotdot = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) dirBlockBuf + dot->fRecordLength);
- dotdot->fInode = parentDirNode->inodeNumber;
- dotdot->fNameLength = 2;
- dotdot->fFileType = kExt2FileTypeDirectory;
- dotdot->fRecordLength = static_cast<UInt16>(this->fCtx.BlockSize() - dot->fRecordLength);
- dotdot->fName[0] = '.';
- dotdot->fName[1] = '.';
-
- // Write dir block to disk
- UInt32 newDirBlockLba = ext2_block_to_lba(&this->fCtx, newDirBlockNum);
- if (!ext2_write_block(this->fCtx.drive, newDirBlockLba, dirBlockBuf, this->fCtx.BlockSize())) {
- kout << "EXT2: Failed to write directory block to disk.\n";
- mm_free_ptr(dirBlockBuf);
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- mm_free_ptr(dirBlockBuf);
-
- // Persist new directory inode
- auto writeInodeRes = ext2_write_inode(&this->fCtx, newDirNode);
- if (!writeInodeRes) {
- kout << "EXT2: Failed to write new directory inode to disk.\n";
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- // Add directory entry into parent
- auto addRes = ext2_add_dir_entry(&this->fCtx, parentDirNode, dirname, newInodeNumber,
- kExt2FileTypeDirectory);
- if (!addRes) {
- kout << "EXT2: Failed to add directory entry for '" << dirname << "' to parent.\n";
- mm_free_ptr(parentDirNode);
- mm_free_ptr(newDirNode);
- return nullptr;
- }
-
- // Increment parent link count and persist parent inode
- parentDirNode->inode.fLinksCount += 1;
- auto parentWriteRes = ext2_write_inode(&this->fCtx, parentDirNode);
- if (!parentWriteRes) {
- kout << "EXT2: Warning: failed to update parent inode after directory creation.\n";
- }
-
- mm_free_ptr(parentDirNode);
- return reinterpret_cast<NodePtr>(newDirNode);
-}
-
-#endif
-#endif
diff --git a/dev/kernel/src/FS/NeFS+FileMgr.cc b/dev/kernel/src/FS/NeFS+FileMgr.cc
deleted file mode 100644
index 0fdabd6f..00000000
--- a/dev/kernel/src/FS/NeFS+FileMgr.cc
+++ /dev/null
@@ -1,276 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#ifndef __NE_MINIMAL_OS__
-#ifdef __FSKIT_INCLUDES_NEFS__
-
-#include <KernelKit/FileMgr.h>
-#include <KernelKit/HeapMgr.h>
-
-/// @brief NeFS File System Manager.
-/// BUGS: 0
-
-namespace Kernel {
-static inline bool is_valid_nefs_catalog(NodePtr node);
-
-/// @brief C++ constructor
-NeFileSystemMgr::NeFileSystemMgr() {
- mParser = new NeFileSystemParser();
- MUST_PASS(mParser);
-
- kout << "We are done allocating NeFileSystemParser...\n";
-}
-
-NeFileSystemMgr::~NeFileSystemMgr() {
- if (mParser) {
- kout << "Destroying NeFileSystemParser...\n";
- delete mParser;
- mParser = nullptr;
- }
-}
-
-/// @brief Removes a node from the filesystem.
-/// @param path The filename
-/// @return If it was deleted or not.
-bool NeFileSystemMgr::Remove(_Input const Char* path) {
- if (path == nullptr || *path == 0) {
- kout << "NeFS: Remove called with null or empty path\n";
- return false;
- }
- return mParser->RemoveCatalog(path);
-}
-
-/// @brief Creates a node with the specified.
-/// @param path The filename path.
-/// @return The Node pointer.
-NodePtr NeFileSystemMgr::Create(_Input const Char* path) {
- if (!path || *path == 0) {
- kout << "NeFS: Create called with null or empty path\n";
- return nullptr;
- }
- return rtl_node_cast(mParser->CreateCatalog(path));
-}
-
-/// @brief Creates a node which is a directory.
-/// @param path The filename path.
-/// @return The Node pointer.
-NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) {
- if (!path || *path == 0) {
- kout << "NeFS: CreateDirectory called with null or empty path\n";
- return nullptr;
- }
- return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindDir));
-}
-
-/// @brief Creates a node which is an alias.
-/// @param path The filename path.
-/// @return The Node pointer.
-NodePtr NeFileSystemMgr::CreateAlias(const Char* path) {
- if (!path || *path == 0) {
- kout << "NeFS: CreateAlias called with null or empty path\n";
- return nullptr;
- }
- return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindAlias));
-}
-
-NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) {
- if (!path || *path == 0) {
- kout << "NeFS: CreateSwapFile called with null or empty path\n";
- return nullptr;
- }
- return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindPage));
-}
-
-/// @brief Gets the root directory.
-/// @return
-const Char* NeFileSystemHelper::Root() {
- return kNeFSRoot;
-}
-
-/// @brief Gets the up-dir directory.
-/// @return
-const Char* NeFileSystemHelper::UpDir() {
- return kNeFSUpDir;
-}
-
-/// @brief Gets the separator character.
-/// @return
-Char NeFileSystemHelper::Separator() {
- return kNeFSSeparator;
-}
-
-/// @brief Gets the metafile character.
-/// @return
-Char NeFileSystemHelper::MetaFile() {
- return kNeFSMetaFilePrefix;
-}
-
-/// @brief Opens a new file.
-/// @param path
-/// @param r
-/// @return
-_Output NodePtr NeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) {
- if (!path || *path == 0) {
- kout << "NeFS: Open called with null or empty path\n";
- return nullptr;
- }
- if (!r || *r == 0) {
- kout << "NeFS: Open called with null or empty mode string\n";
- return nullptr;
- }
- auto catalog = mParser->GetCatalog(path);
- if (!catalog) {
- kout << "NeFS: Open could not find catalog for path\n";
- return nullptr;
- }
- return rtl_node_cast(catalog);
-}
-
-Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
- _Input SizeT size) {
- if (!is_valid_nefs_catalog(node)) {
- kout << "NeFS: Write called with invalid node pointer\n";
- return;
- }
- if (!data) {
- kout << "NeFS: Write called with null data pointer\n";
- return;
- }
- if (!size || size > kNeFSForkSize) {
- (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size));
- kout << "\n";
- return;
- }
- constexpr auto kDataForkName = kNeFSDataFork;
- this->Write(kDataForkName, node, data, flags, size);
-}
-
-_Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) {
- if (!is_valid_nefs_catalog(node)) {
- kout << "NeFS: Read called with invalid node pointer\n";
- return nullptr;
- }
- if (!size || size > kNeFSForkSize) {
- (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size));
- kout << "\n";
- return nullptr;
- }
- constexpr auto kDataForkName = kNeFSDataFork;
- return this->Read(kDataForkName, node, flags, size);
-}
-
-Void NeFileSystemMgr::Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data,
- _Input Int32 flags, _Input SizeT size) {
- if (!is_valid_nefs_catalog(node)) {
- kout << "NeFS: Write(fork) called with invalid node pointer\n";
- return;
- }
- if (!name || *name == 0) {
- kout << "NeFS: Write(fork) called with null or empty fork name\n";
- return;
- }
- if (!data) {
- kout << "NeFS: Write(fork) called with null data pointer\n";
- return;
- }
- if (!size || size > kNeFSForkSize) {
- (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size));
- kout << "\n";
- return;
- }
- NE_UNUSED(flags);
- auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node);
- if (cat->Kind == kNeFSCatalogKindFile) {
- mParser->WriteCatalog(cat->Name, (flags & kFileFlagRsrc ? true : false), data, size, name);
- }
-}
-
-_Output VoidPtr NeFileSystemMgr::Read(_Input const Char* name, _Input NodePtr node,
- _Input Int32 flags, _Input SizeT sz) {
- if (!is_valid_nefs_catalog(node)) {
- kout << "NeFS: Read(fork) called with invalid node pointer\n";
- return nullptr;
- }
- if (!name || *name == 0) {
- kout << "NeFS: Read(fork) called with null or empty fork name\n";
- return nullptr;
- }
- if (!sz || sz > kNeFSForkSize) {
- (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(sz));
- kout << "\n";
- return nullptr;
- }
- NE_UNUSED(flags);
- auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node);
- if (cat->Kind == kNeFSCatalogKindFile) {
- return mParser->ReadCatalog(cat, (flags & kFileFlagRsrc ? true : false), sz, name);
- }
- return nullptr;
-}
-
-_Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) {
- if (!is_valid_nefs_catalog(node)) {
- kout << "NeFS: Seek called with invalid node pointer\n";
- return false;
- }
- // Allow off == 0
- return mParser->Seek(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node), off);
-}
-
-/// @brief Tell current offset within catalog.
-/// @param node
-/// @return kFileMgrNPos if invalid, else current offset.
-_Output SizeT NeFileSystemMgr::Tell(NodePtr node) {
- if (!is_valid_nefs_catalog(node)) {
- kout << "NeFS: Tell called with invalid node pointer\n";
- return kFileMgrNPos;
- }
- return mParser->Tell(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node));
-}
-
-/// @brief Rewinds the catalog
-/// @param node
-/// @return False if invalid, nah? calls Seek(node, 0).
-_Output Bool NeFileSystemMgr::Rewind(NodePtr node) {
- if (!is_valid_nefs_catalog(node)) {
- kout << "NeFS: Rewind called with invalid node pointer\n";
- return false;
- }
- return this->Seek(node, 0);
-}
-
-/// @brief Returns the parser of NeFS.
-_Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept {
- return mParser;
-}
-
-static inline bool is_valid_nefs_catalog(NodePtr node) {
- if (!node) return false;
- auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node);
- switch (cat->Kind) {
- case kNeFSCatalogKindFile:
- case kNeFSCatalogKindDir:
- case kNeFSCatalogKindAlias:
- case kNeFSCatalogKindPage:
- break;
- default:
- return false;
- }
- bool null_found = false;
- for (int i = 0; i < kNeFSCatalogNameLen; ++i) {
- if (cat->Name[i] == 0) {
- null_found = true;
- break;
- }
- }
- if (!null_found) return false;
- return true;
-}
-
-} // namespace Kernel
-
-#endif // ifdef __FSKIT_INCLUDES_NEFS__
-#endif // ifndef __NE_MINIMAL_OS__
diff --git a/dev/kernel/src/FS/NeFS+FileSystemParser.cc b/dev/kernel/src/FS/NeFS+FileSystemParser.cc
deleted file mode 100644
index bfb8d63a..00000000
--- a/dev/kernel/src/FS/NeFS+FileSystemParser.cc
+++ /dev/null
@@ -1,870 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#ifdef __FSKIT_INCLUDES_NEFS__
-
-#include <FSKit/NeFS.h>
-#include <FirmwareKit/EPM.h>
-
-#include <KernelKit/DriveMgr.h>
-#include <KernelKit/IFS.h>
-#include <KernelKit/KPC.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/UserMgr.h>
-#include <NeKit/Crc32.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/Utils.h>
-#include <modules/AHCI/AHCI.h>
-#include <modules/ATA/ATA.h>
-
-using namespace Kernel;
-
-#ifdef __NE_NO_BUILTIN__
-/***********************************************************************************/
-/**
- Define those external symbols, to make the editor shutup
-*/
-/***********************************************************************************/
-
-/***********************************************************************************/
-/// @brief get sector count.
-/***********************************************************************************/
-Kernel::SizeT drv_std_get_sector_count();
-
-/***********************************************************************************/
-/// @brief get device size.
-/***********************************************************************************/
-Kernel::SizeT drv_std_get_size();
-
-#endif
-
-///! BUGS: 0
-
-/***********************************************************************************/
-/// This file implements the New extended File System.
-/// New extended File System implements a flat linked-list based algorithm.
-/// /
-/// /Path1/ /Path2/
-/// /readme.rtf /ListContents.pef /readme.lnk <-- symlink.
-/// /Path1/readme.rtf
-/***********************************************************************************/
-static inline bool is_valid_size(SizeT size, SizeT max_size) {
- return size > 0 && size <= max_size;
-}
-
-static inline bool is_valid_lba(Lba lba, DriveTrait& drive) {
- NEFS_ROOT_PARTITION_BLOCK part_block;
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part_block);
- drive.fInput(drive.fPacket);
-
- if (!drive.fPacket.fPacketGood) {
- return false;
- }
-
- // Compute the maximum LBA (DiskSize / sector size)
- SizeT sectorSize = drive.fSectorSz;
- Lba maxLba = part_block.DiskSize / sectorSize;
-
- return (lba >= part_block.StartCatalog) && (lba < maxLba);
-}
-
-STATIC IMountpoint kMountpoint;
-/***********************************************************************************/
-/// @brief Creates a new fork inside the New filesystem partition.
-/// @param catalog it's catalog
-/// @param the_fork the fork itself.
-/// @return the fork
-/***********************************************************************************/
-_Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) {
- if (the_fork.ForkName[0] == 0 || the_fork.CatalogName[0] == 0 || the_fork.DataSize == 0) {
- return NO;
- }
-
- auto catalog = this->GetCatalog(the_fork.CatalogName);
- if (!catalog) return NO;
-
- Lba lba = catalog->DataFork;
- if (lba < kNeFSCatalogStartAddress) {
- delete catalog;
- return NO;
- }
-
- auto& drv = kMountpoint.A();
- Lba lba_prev = lba;
- NEFS_FORK_STRUCT prev_fork{};
- NEFS_FORK_STRUCT cur_fork{};
-
- while (true) {
- drv.fPacket.fPacketLba = lba;
- drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&cur_fork);
- drv.fInput(drv.fPacket);
- if (!drv.fPacket.fPacketGood) {
- delete catalog;
- return NO;
- }
-
- if (cur_fork.Flags & kNeFSFlagCreated) {
- if (KStringBuilder::Equals(cur_fork.ForkName, the_fork.ForkName) &&
- KStringBuilder::Equals(cur_fork.CatalogName, the_fork.CatalogName)) {
- break;
- }
- lba_prev = lba;
- lba = cur_fork.NextSibling;
- prev_fork = cur_fork;
- } else {
- if (lba >= kNeFSCatalogStartAddress) {
- prev_fork.NextSibling = lba;
- drv.fPacket.fPacketLba = lba_prev;
- drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&prev_fork);
- drv.fOutput(drv.fPacket);
- }
- break;
- }
- }
-
- SizeT sectorCount = (the_fork.DataSize + kNeFSSectorSz - 1) / kNeFSSectorSz;
- the_fork.DataOffset = lba + 1;
- the_fork.PreviousSibling = lba_prev;
- the_fork.NextSibling = lba + 1 + sectorCount;
- the_fork.Flags |= kNeFSFlagCreated;
-
- drv.fPacket.fPacketLba = lba;
- drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&the_fork);
- drv.fOutput(drv.fPacket);
-
- fs_ifs_write(&kMountpoint, drv, IMountpoint::kDriveIndexA);
-
- delete catalog;
- return YES;
-}
-
-/***********************************************************************************/
-/// @brief Find fork inside filesystem.
-/// @param catalog the catalog.
-/// @param name the fork name.
-/// @return the newly found fork.
-/***********************************************************************************/
-_Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUCT* catalog,
- _Input const Char* name,
- _Input Boolean is_data) {
- if (!catalog || !name) return nullptr;
-
- auto& drive = kMountpoint.A();
- Lba lba = is_data ? catalog->DataFork : catalog->ResourceFork;
- NEFS_FORK_STRUCT local_buf{};
-
- while (lba >= kNeFSCatalogStartAddress) {
- drive.fPacket.fPacketLba = lba;
- drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&local_buf);
-
- rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
-
- if (auto res = fs_ifs_read(&kMountpoint, drive, this->mDriveIndex); res) {
- switch (res) {
- case 1:
- err_global_get() = kErrorDiskReadOnly;
- break;
- case 2:
- err_global_get() = kErrorDiskIsFull;
- break;
- case 3:
- err_global_get() = kErrorNoSuchDisk;
- break;
- default:
- break;
- }
- return nullptr;
- }
-
- if (KStringBuilder::Equals(local_buf.ForkName, name) &&
- KStringBuilder::Equals(local_buf.CatalogName, catalog->Name)) {
- auto result = new NEFS_FORK_STRUCT();
- rt_copy_memory_safe(&local_buf, result, sizeof(NEFS_FORK_STRUCT), sizeof(NEFS_FORK_STRUCT));
- return result;
- }
-
- lba = local_buf.NextSibling;
- }
-
- return nullptr;
-}
-
-/***********************************************************************************/
-/// @brief Simpler factory to create a catalog (assumes you want to create a
-/// file.)
-/// @param name
-/// @return catalog pointer.
-/***********************************************************************************/
-_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) {
- return this->CreateCatalog(name, 0, kNeFSCatalogKindFile);
-}
-
-/***********************************************************************************/
-/// @brief Creates a new catalog into the disk.
-/// @param name the catalog name.
-/// @param flags the flags of the catalog.
-/// @param kind the catalog kind.
-/// @return catalog pointer.
-/***********************************************************************************/
-_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name,
- _Input const Int32& flags,
- _Input const Int32& kind) {
- kout << "CreateCatalog(*...*)\r";
-
- if (!name) return nullptr;
- SizeT nameLen = rt_string_len(name);
- if (nameLen == 0) return nullptr;
-
- Lba out_lba = 0UL;
-
- kout << "Checking for path separator...\r";
-
- /// a directory should have a slash in the end.
- if (kind == kNeFSCatalogKindDir && name[nameLen - 1] != NeFileSystemHelper::Separator())
- return nullptr;
-
- /// a file shouldn't have a slash in the end.
- if (kind != kNeFSCatalogKindDir && name[nameLen - 1] == NeFileSystemHelper::Separator())
- return nullptr;
-
- NEFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba);
-
- if (catalog_copy) {
- kout << "Catalog already exists: " << name << ".\r";
- err_global_get() = kErrorFileExists;
- delete catalog_copy;
- catalog_copy = nullptr;
- return nullptr;
- }
-
- Char* parent_name = (Char*) mm_alloc_ptr(nameLen + 1, Yes, No);
- rt_copy_memory_safe(const_cast<Char*>(name), parent_name, nameLen + 1, nameLen + 1);
-
- if (nameLen < 2) {
- mm_free_ptr(parent_name);
- err_global_get() = kErrorFileNotFound;
- return nullptr;
- }
-
- SizeT index_reverse_copy = nameLen - 1;
- if (parent_name[index_reverse_copy] == NeFileSystemHelper::Separator()) {
- parent_name[index_reverse_copy] = 0;
- --index_reverse_copy;
- }
- while (index_reverse_copy > 0 &&
- parent_name[index_reverse_copy] != NeFileSystemHelper::Separator()) {
- parent_name[index_reverse_copy] = 0;
- --index_reverse_copy;
- }
- if (index_reverse_copy == 0 && parent_name[0] != NeFileSystemHelper::Separator()) {
- mm_free_ptr(parent_name);
- err_global_get() = kErrorFileNotFound;
- return nullptr;
- }
-
- NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba);
- mm_free_ptr(parent_name);
-
- auto& drive = kMountpoint.A();
- if (catalog && catalog->Kind == kNeFSCatalogKindFile) {
- kout << "Parent is a file.\r";
- delete catalog;
- return nullptr;
- } else if (!catalog) {
- Char part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block);
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fInput(drive.fPacket);
-
- NEFS_ROOT_PARTITION_BLOCK* blk_nefs = (NEFS_ROOT_PARTITION_BLOCK*) part_block;
- out_lba = blk_nefs->StartCatalog;
- }
-
- if (drive.fPacket.fPacketReadOnly) {
- delete catalog;
- return nullptr;
- }
-
- NEFS_CATALOG_STRUCT* child_catalog = new NEFS_CATALOG_STRUCT();
- child_catalog->Checksum = 0;
- child_catalog->ResourceForkSize = 0UL;
- child_catalog->DataForkSize = 0UL;
- child_catalog->CatalogFlags = kNeFSStatusUnlocked;
- child_catalog->NextSibling = out_lba;
- child_catalog->PrevSibling = out_lba;
- child_catalog->Kind = kind;
- child_catalog->Flags |= kNeFSFlagCreated;
- child_catalog->CatalogFlags = flags;
-
- SizeT i = nameLen;
- --i;
- if (kind == kNeFSCatalogKindDir) --i;
- while (name[i] != '/') --i;
- rt_copy_memory_safe((VoidPtr) (name + i), (VoidPtr) child_catalog->Name, rt_string_len(name) - i,
- kNeFSCatalogNameLen);
-
- NEFS_CATALOG_STRUCT temporary_catalog{};
- Lba start_free = out_lba;
-
- rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
-
- Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf_part_block);
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fInput(drive.fPacket);
-
- NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) buf_part_block;
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&temporary_catalog);
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
- drive.fInput(drive.fPacket);
-
- if (part_block->FreeCatalog < 1) {
- delete child_catalog;
- delete catalog;
- return nullptr;
- }
-
- kout << "Start finding catalog to allocate or empty space...\r";
-
- SizeT catalogSectors = (sizeof(NEFS_CATALOG_STRUCT) + drive.fSectorSz - 1) / drive.fSectorSz;
- while (start_free < part_block->StartCatalog + (part_block->CatalogCount * catalogSectors)) {
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&temporary_catalog);
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
- drive.fInput(drive.fPacket);
-
- if ((temporary_catalog.Flags & kNeFSFlagCreated) == 0) {
- child_catalog->NextSibling = start_free + catalogSectors;
-
- NEFS_CATALOG_STRUCT placeholder{};
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&placeholder);
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
- drive.fOutput(drive.fPacket);
-
- child_catalog->DataFork = part_block->DiskSize - start_free;
- child_catalog->ResourceFork = child_catalog->DataFork;
-
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(child_catalog);
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
- drive.fOutput(drive.fPacket);
-
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf_part_block);
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fInput(drive.fPacket);
-
- part_block->FreeSectors -= catalogSectors;
- part_block->CatalogCount += 1;
- part_block->FreeCatalog -= 1;
-
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block);
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fOutput(drive.fPacket);
-
- delete catalog;
- NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT();
- rt_copy_memory_safe(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT),
- sizeof(NEFS_CATALOG_STRUCT));
-
- delete child_catalog;
- return found_catalog;
- } else if ((temporary_catalog.Flags & kNeFSFlagCreated) &&
- KStringBuilder::Equals(temporary_catalog.Name, name)) {
- rt_copy_memory_safe(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT),
- sizeof(NEFS_CATALOG_STRUCT));
- delete catalog;
- return child_catalog;
- }
-
- start_free += catalogSectors;
- }
-
- delete child_catalog;
- delete catalog;
- return nullptr;
-}
-
-/***********************************************************************************/
-/// @brief Make a EPM+NeFS drive out of the disk.
-/// @param drive The drive to write on.
-/// @return If it was sucessful, see err_global_get().
-/***********************************************************************************/
-bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
- const Char* part_name) {
- if (!part_name || *part_name == 0) return false;
- NE_UNUSED(flags);
-
- // verify disk.
- drive->fVerify(drive->fPacket);
- rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"), sizeof(drive->fPacket.fPacketMime));
- if (!drive->fPacket.fPacketGood) {
- err_global_get() = kErrorDiskIsCorrupted;
- return false;
- }
-
- Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- Lba start = drive->fLbaStart;
-
- drive->fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf);
- drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive->fPacket.fPacketLba = start;
- drive->fInput(drive->fPacket);
-
- NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf;
- if (rt_string_cmp(kNeFSIdent, part_block->Ident, kNeFSIdentLen) == 0) return true;
-
- const auto kNeFSUntitledHD = part_name;
- rt_copy_memory_safe((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen,
- sizeof(part_block->Ident));
- rt_copy_memory_safe((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName,
- rt_string_len(kNeFSUntitledHD), sizeof(part_block->PartitionName));
-
- SizeT sectorCount = drv_std_get_sector_count();
- SizeT sectorSize = drive->fSectorSz;
- SizeT totalBytes = sectorCount * sectorSize;
- SizeT catalogEntries = totalBytes / sizeof(NEFS_CATALOG_STRUCT);
- SizeT catalogSectors = (sizeof(NEFS_CATALOG_STRUCT) + sectorSize - 1) / sectorSize;
-
- part_block->Version = kNeFSVersionInteger;
- part_block->Kind = kNeFSPartitionTypeStandard;
- part_block->StartCatalog = start + catalogSectors;
- part_block->Flags = 0UL;
- part_block->CatalogCount = catalogEntries;
- part_block->FreeCatalog = catalogEntries - 1;
- part_block->SectorCount = sectorCount;
- part_block->DiskSize = totalBytes;
- part_block->SectorSize = sectorSize;
- part_block->FreeSectors = sectorCount - catalogSectors;
-
- drive->fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf);
- drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive->fPacket.fPacketLba = start;
- drive->fOutput(drive->fPacket);
-
- (Void)(kout << "Drive kind: " << drive->fProtocol() << kendl);
- (Void)(kout << "Partition name: " << part_block->PartitionName << kendl);
- (Void)(kout << "Start catalog: " << hex_number(part_block->StartCatalog) << kendl);
- (Void)(kout << "Number of catalogs: " << hex_number(part_block->CatalogCount) << kendl);
- (Void)(kout << "Free catalog: " << hex_number(part_block->FreeCatalog) << kendl);
- (Void)(kout << "Free sectors: " << hex_number(part_block->FreeSectors) << kendl);
- (Void)(kout << "Sector size: " << hex_number(part_block->SectorSize) << kendl);
-
- return true;
-}
-
-/***********************************************************************************/
-/// @brief Writes the data fork into a specific catalog.
-/// @param catalog the catalog itself
-/// @param data the data.
-/// @return if the catalog wrote the contents successfully.
-/***********************************************************************************/
-bool NeFileSystemParser::WriteCatalog(_Input const Char* catalog_name, Bool is_rsrc_fork,
- _Input VoidPtr data, _Input SizeT size_of_data,
- _Input const Char* fork_name) {
- if (size_of_data < 1) return NO;
-
- auto catalog = this->GetCatalog(catalog_name);
- if (!catalog) {
- kout << "NeFS: WriteCatalog failed to find catalog: " << catalog_name << "\n";
- return false;
- }
-
- SizeT maxSize = is_rsrc_fork ? catalog->ResourceForkSize : catalog->DataForkSize;
-
- if (!is_valid_size(size_of_data, maxSize)) {
- (Void)(kout << "NeFS: WriteCatalog called with invalid size: " << hex_number(size_of_data));
- kout << "\n";
-
- delete catalog;
- return false;
- }
-
- Lba startFork = is_rsrc_fork ? catalog->ResourceFork : catalog->DataFork;
- auto& drive = kMountpoint.A();
-
- if (!is_valid_lba(startFork, drive)) {
- (Void)(kout << "NeFS: WriteCatalog called with invalid LBA: " << hex_number(startFork));
- kout << "\n";
-
- delete catalog;
- return false;
- }
-
- NEFS_ROOT_PARTITION_BLOCK part_block;
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fPacket.fPacketSize = sizeof(part_block);
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part_block);
- drive.fInput(drive.fPacket);
-
- auto buf = new UInt8[size_of_data];
- rt_set_memory(buf, 0, size_of_data);
- rt_copy_memory_safe(data, buf, size_of_data, size_of_data);
- rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
-
- NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT();
- NEFS_FORK_STRUCT prev_fork{};
-
- while (startFork >= part_block.StartCatalog && drive.fPacket.fPacketGood) {
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fork_data_input);
- drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drive.fPacket.fPacketLba = startFork;
- drive.fInput(drive.fPacket);
-
- if (!drive.fPacket.fPacketGood) {
- break;
- }
-
- if ((fork_data_input->Flags & kNeFSFlagCreated) &&
- KStringBuilder::Equals(fork_data_input->ForkName, fork_name) &&
- KStringBuilder::Equals(fork_data_input->CatalogName, catalog_name) &&
- fork_data_input->DataSize == size_of_data) {
- SizeT bytes_left = size_of_data;
- SizeT offset = 0;
- Lba base_lba = fork_data_input->DataOffset;
-
- while (bytes_left > 0) {
- SizeT chunk = (bytes_left > kNeFSSectorSz) ? kNeFSSectorSz : bytes_left;
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf + offset);
- drive.fPacket.fPacketSize = chunk;
- drive.fPacket.fPacketLba = base_lba + (offset / kNeFSSectorSz);
- drive.fOutput(drive.fPacket);
- offset += chunk;
- bytes_left -= chunk;
- }
-
- delete fork_data_input;
- delete[] buf;
- delete catalog;
- return true;
- }
-
- prev_fork = *fork_data_input;
- startFork = fork_data_input->NextSibling;
- }
-
- delete fork_data_input;
- delete[] buf;
- delete catalog;
- return false;
-}
-
-/***********************************************************************************/
-/// @brief
-/// @param catalog_name the catalog name.
-/// @return the newly found catalog.
-/***********************************************************************************/
-_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* catalog_name,
- Lba& out_lba, Bool search_hidden,
- Bool local_search) {
- if (!catalog_name || *catalog_name == 0) return nullptr;
-
- NEFS_ROOT_PARTITION_BLOCK part{};
- auto& drive = kMountpoint.A();
-
- rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part);
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fInput(drive.fPacket);
-
- auto start_catalog_lba = kNeFSCatalogStartAddress;
-
- // Helper lambda to scan from a given LBA
- auto scan_from = [&](Lba lba_start, Bool allow_hidden) -> NEFS_CATALOG_STRUCT* {
- Lba cursor = lba_start;
- NEFS_CATALOG_STRUCT tmp{};
- while (cursor >= part.StartCatalog && drive.fPacket.fPacketGood) {
- drive.fPacket.fPacketLba = cursor;
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&tmp);
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fInput(drive.fPacket);
-
- if (KStringBuilder::Equals(
- tmp.Name, catalog_name + (rt_string_len(catalog_name) - rt_string_len(tmp.Name)))) {
- if (tmp.Status == kNeFSStatusLocked && !allow_hidden) {
- err_global_get() = kErrorFileLocked;
- return nullptr;
- }
- if (!(tmp.Flags & kNeFSFlagCreated)) {
- err_global_get() = kErrorFileNotFound;
- return nullptr;
- }
- NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT();
- rt_copy_memory_safe(&tmp, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT),
- sizeof(NEFS_CATALOG_STRUCT));
- out_lba = cursor;
- return catalog_ptr;
- }
- cursor = tmp.NextSibling;
- }
- return nullptr;
- };
-
- if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search) {
- Char parent_name[kNeFSCatalogNameLen] = {0};
- SizeT nameLen = rt_string_len(catalog_name);
- rt_copy_memory_safe(const_cast<Char*>(catalog_name), parent_name, nameLen + 1,
- kNeFSCatalogNameLen);
-
- SizeT indexReverseCopy = nameLen - 1;
- if (parent_name[indexReverseCopy] == NeFileSystemHelper::Separator()) {
- parent_name[indexReverseCopy] = 0;
- --indexReverseCopy;
- }
- while (indexReverseCopy > 0 &&
- parent_name[indexReverseCopy] != NeFileSystemHelper::Separator()) {
- parent_name[indexReverseCopy] = 0;
- --indexReverseCopy;
- }
- if (indexReverseCopy == 0 && parent_name[0] != NeFileSystemHelper::Separator()) {
- return nullptr;
- }
-
- NEFS_CATALOG_STRUCT* parent_catalog =
- this->FindCatalog(parent_name, out_lba, search_hidden, NO);
- if (parent_catalog) {
- start_catalog_lba = parent_catalog->NextSibling;
- delete parent_catalog;
- NEFS_CATALOG_STRUCT* found = scan_from(start_catalog_lba, search_hidden);
- if (found) return found;
- }
- }
-
- return scan_from(part.StartCatalog, search_hidden);
-}
-
-/***********************************************************************************/
-/// @brief Get catalog from filesystem.
-/// @param name the catalog's name/
-/// @return
-/***********************************************************************************/
-_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::GetCatalog(_Input const Char* name) {
- Lba unused = 0;
- return this->FindCatalog(name, unused, YES, YES);
-}
-
-/***********************************************************************************/
-/// @brief Closes a catalog, (frees it).
-/// @param catalog the catalog to close.
-/// @return
-/***********************************************************************************/
-_Output Boolean NeFileSystemParser::CloseCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog) {
- if (!catalog) return false;
- delete catalog;
- catalog = nullptr;
- return true;
-}
-
-/***********************************************************************************/
-/// @brief Mark catalog as removed.
-/// @param catalog The catalog structure.
-/// @return if the catalog was removed or not.
-/***********************************************************************************/
-_Output Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_name) {
- if (!catalog_name || KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root())) {
- err_global_get() = kErrorInternal;
- return false;
- }
-
- Lba out_lba = 0;
- auto catalog = this->FindCatalog(catalog_name, out_lba, YES, YES);
- if (!catalog) return false;
-
- auto& drive = kMountpoint.A();
- NEFS_FORK_STRUCT fork_buf{};
- Lba fork_lba = catalog->DataFork;
- while (fork_lba >= kNeFSCatalogStartAddress) {
- drive.fPacket.fPacketLba = fork_lba;
- drive.fPacket.fPacketSize = sizeof(fork_buf);
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
- drive.fInput(drive.fPacket);
-
- fork_buf.Flags &= (~kNeFSFlagCreated);
- fork_buf.Flags |= kNeFSFlagDeleted;
-
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
- drive.fPacket.fPacketSize = sizeof(fork_buf);
- drive.fPacket.fPacketLba = fork_lba;
- drive.fOutput(drive.fPacket);
-
- fork_lba = fork_buf.NextSibling;
- }
-
- fork_lba = catalog->ResourceFork;
- while (fork_lba >= kNeFSCatalogStartAddress) {
- drive.fPacket.fPacketLba = fork_lba;
- drive.fPacket.fPacketSize = sizeof(fork_buf);
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
- drive.fInput(drive.fPacket);
-
- fork_buf.Flags &= (~kNeFSFlagCreated);
- fork_buf.Flags |= kNeFSFlagDeleted;
-
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
- drive.fPacket.fPacketSize = sizeof(fork_buf);
- drive.fPacket.fPacketLba = fork_lba;
- drive.fOutput(drive.fPacket);
-
- fork_lba = fork_buf.NextSibling;
- }
-
- if (out_lba >= kNeFSCatalogStartAddress || (catalog->Flags & kNeFSFlagCreated)) {
- catalog->Flags &= (~kNeFSFlagCreated);
- catalog->Flags |= kNeFSFlagDeleted;
-
- rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
- drive.fPacket.fPacketLba = out_lba;
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(catalog);
- drive.fOutput(drive.fPacket);
-
- Char partitionBlockBuf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(partitionBlockBuf);
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fInput(drive.fPacket);
-
- NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) partitionBlockBuf;
- if (part_block->CatalogCount > 0) --part_block->CatalogCount;
- ++part_block->FreeSectors;
-
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block);
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fOutput(drive.fPacket);
-
- delete catalog;
- catalog = nullptr;
- return true;
- }
-
- delete catalog;
- catalog = nullptr;
- return false;
-}
-
-/// ***************************************************************** ///
-/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead.
-/// ***************************************************************** ///
-
-/***********************************************************************************/
-/// @brief Read the catalog data fork.
-/// @param catalog
-/// @param dataSz
-/// @return
-/***********************************************************************************/
-VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog,
- _Input Bool is_rsrc_fork, _Input SizeT dataSz,
- _Input const Char* forkName) {
- if (!catalog) {
- err_global_get() = kErrorInvalidData;
- return nullptr;
- }
- // Validate size against fork size
- SizeT maxSize = is_rsrc_fork ? catalog->ResourceForkSize : catalog->DataForkSize;
- if (!is_valid_size(dataSz, maxSize)) {
- kout << "NeFS: ReadCatalog called with invalid size: ";
- hex_number(dataSz);
- kout << "\n";
- return nullptr;
- }
-
- Lba dataForkLba = is_rsrc_fork ? catalog->ResourceFork : catalog->DataFork;
- auto& drive = kMountpoint.A();
- if (!is_valid_lba(dataForkLba, drive)) {
- kout << "NeFS: ReadCatalog called with invalid LBA: ";
- hex_number(dataForkLba);
- kout << "\n";
- return nullptr;
- }
-
- auto* fs_buf = new NEFS_FORK_STRUCT();
- rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
-
- NEFS_FORK_STRUCT* fs_fork_data = nullptr;
- while (dataForkLba >= kNeFSCatalogStartAddress) {
- drive.fPacket.fPacketLba = dataForkLba;
- drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf);
- drive.fInput(drive.fPacket);
-
- fs_fork_data = fs_buf;
- (Void)(kout << "ForkName: " << fs_fork_data->ForkName << kendl);
- (Void)(kout << "CatalogName: " << fs_fork_data->CatalogName << kendl);
-
- if (KStringBuilder::Equals(forkName, fs_fork_data->ForkName) &&
- KStringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) {
- break;
- }
- dataForkLba = fs_fork_data->NextSibling;
- }
-
- if (dataForkLba < kNeFSCatalogStartAddress) {
- delete fs_buf;
- return nullptr;
- }
- return fs_fork_data;
-}
-
-/***********************************************************************************/
-/// @brief Seek in the data fork.
-/// @param catalog the catalog offset.
-/// @param off where to seek.
-/// @return if the seeking was successful.
-/***********************************************************************************/
-bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off) {
- NE_UNUSED(catalog);
- NE_UNUSED(off);
- err_global_get() = kErrorUnimplemented;
- return false;
-}
-
-/***********************************************************************************/
-/// @brief Tell where we are inside the data fork.
-/// @param catalog
-/// @return The position on the file.
-/***********************************************************************************/
-SizeT NeFileSystemParser::Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog) {
- NE_UNUSED(catalog);
- err_global_get() = kErrorUnimplemented;
- return 0;
-}
-
-namespace Kernel::NeFS {
-/***********************************************************************************/
-/// @brief Construct NeFS drives.
-/***********************************************************************************/
-Boolean fs_init_nefs(Void) noexcept {
- kout << "Creating OpenHeFS disk...\r";
- kMountpoint.A() = io_construct_main_drive();
- if (kMountpoint.A().fPacket.fPacketReadOnly == YES)
- ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main disk cannot be mounted.");
- NeFileSystemParser parser;
- return parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName);
-}
-} // namespace Kernel::NeFS
-
-#endif // ifdef __FSKIT_INCLUDES_NEFS__
diff --git a/dev/kernel/src/FS/OpenHeFS+FileMgr.cc b/dev/kernel/src/FS/OpenHeFS+FileMgr.cc
deleted file mode 100644
index e70e3626..00000000
--- a/dev/kernel/src/FS/OpenHeFS+FileMgr.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#ifndef __NE_MINIMAL_OS__
-#ifdef __FSKIT_INCLUDES_OPENHEFS__
-
-#include <KernelKit/FileMgr.h>
-#include <KernelKit/HeapMgr.h>
-
-/// @brief OpenHeFS File System Manager.
-/// BUGS: 0
-
-namespace Kernel {
-/// @brief C++ constructor
-HeFileSystemMgr::HeFileSystemMgr() {
- mParser = new HeFileSystemParser();
- MUST_PASS(mParser);
-
- kout << "We are done allocating HeFileSystemParser...\n";
-}
-
-HeFileSystemMgr::~HeFileSystemMgr() {
- if (mParser) {
- kout << "Destroying HeFileSystemParser...\n";
- delete mParser;
- mParser = nullptr;
- }
-}
-
-/// @brief Removes a node from the filesystem.
-/// @param path The filename
-/// @return If it was deleted or not.
-bool HeFileSystemMgr::Remove(_Input const Char* path) {
- if (path == nullptr || *path == 0) {
- kout << "OpenHeFS: Remove called with null or empty path\n";
- return false;
- }
-
- return NO;
-}
-
-/// @brief Creates a node with the specified.
-/// @param path The filename path.
-/// @return The Node pointer.
-NodePtr HeFileSystemMgr::Create(_Input const Char* path) {
- if (!path || *path == 0) {
- kout << "OpenHeFS: Create called with null or empty path\n";
- return nullptr;
- }
- return nullptr;
-}
-
-/// @brief Creates a node which is a directory.
-/// @param path The filename path.
-/// @return The Node pointer.
-NodePtr HeFileSystemMgr::CreateDirectory(const Char* path) {
- if (!path || *path == 0) {
- kout << "OpenHeFS: CreateDirectory called with null or empty path\n";
- return nullptr;
- }
- return nullptr;
-}
-
-/// @brief Creates a node which is an alias.
-/// @param path The filename path.
-/// @return The Node pointer.
-NodePtr HeFileSystemMgr::CreateAlias(const Char* path) {
- if (!path || *path == 0) {
- kout << "OpenHeFS: CreateAlias called with null or empty path\n";
- return nullptr;
- }
- return nullptr;
-}
-
-NodePtr HeFileSystemMgr::CreateSwapFile(const Char* path) {
- if (!path || *path == 0) {
- kout << "OpenHeFS: CreateSwapFile called with null or empty path\n";
- return nullptr;
- }
- return nullptr;
-}
-
-/// @brief Gets the root directory.
-/// @return
-const Char* NeFileSystemHelper::Root() {
- return kHeFSRootDirectory;
-}
-
-/// @brief Gets the up-dir directory.
-/// @return
-const Char* NeFileSystemHelper::UpDir() {
- return kHeFSUpDir;
-}
-
-/// @brief Gets the separator character.
-/// @return
-Char NeFileSystemHelper::Separator() {
- return kHeFSSeparator;
-}
-
-/// @brief Gets the metafile character.
-/// @return
-Char NeFileSystemHelper::MetaFile() {
- return '\0';
-}
-
-/// @brief Opens a new file.
-/// @param path
-/// @param r
-/// @return
-_Output NodePtr HeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) {
- if (!path || *path == 0) {
- kout << "OpenHeFS: Open called with null or empty path\n";
- return nullptr;
- }
- if (!r || *r == 0) {
- kout << "OpenHeFS: Open called with null or empty mode string\n";
- return nullptr;
- }
- return nullptr;
-}
-
-Void HeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
- _Input SizeT size) {
- NE_UNUSED(node);
- NE_UNUSED(flags);
- NE_UNUSED(size);
- NE_UNUSED(data);
-}
-
-_Output VoidPtr HeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) {
- NE_UNUSED(node);
- NE_UNUSED(flags);
- NE_UNUSED(size);
-
- return nullptr;
-}
-
-Void HeFileSystemMgr::Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data,
- _Input Int32 flags, _Input SizeT size) {
- NE_UNUSED(node);
- NE_UNUSED(flags);
- NE_UNUSED(size);
- NE_UNUSED(name);
- NE_UNUSED(data);
-}
-
-_Output VoidPtr HeFileSystemMgr::Read(_Input const Char* name, _Input NodePtr node,
- _Input Int32 flags, _Input SizeT sz) {
- NE_UNUSED(node);
- NE_UNUSED(flags);
- NE_UNUSED(sz);
- NE_UNUSED(name);
-
- return nullptr;
-}
-
-_Output Bool HeFileSystemMgr::Seek(NodePtr node, SizeT off) {
- NE_UNUSED(node);
- NE_UNUSED(off);
-
- return false;
-}
-
-/// @brief Tell current offset within catalog.
-/// @param node
-/// @return kFileMgrNPos if invalid, else current offset.
-_Output SizeT HeFileSystemMgr::Tell(NodePtr node) {
- NE_UNUSED(node);
- return kFileMgrNPos;
-}
-
-/// @brief Rewinds the catalog
-/// @param node
-/// @return False if invalid, nah? calls Seek(node, 0).
-_Output Bool HeFileSystemMgr::Rewind(NodePtr node) {
- NE_UNUSED(node);
- return kFileMgrNPos;
-}
-
-/// @brief Returns the parser of OpenHeFS.
-_Output HeFileSystemParser* HeFileSystemMgr::GetParser() noexcept {
- return mParser;
-}
-} // namespace Kernel
-
-#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__
-#endif // ifndef __NE_MINIMAL_OS__
diff --git a/dev/kernel/src/FS/OpenHeFS+FileSystemParser.cc b/dev/kernel/src/FS/OpenHeFS+FileSystemParser.cc
deleted file mode 100644
index d8e22f18..00000000
--- a/dev/kernel/src/FS/OpenHeFS+FileSystemParser.cc
+++ /dev/null
@@ -1,1160 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025 Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#ifdef __FSKIT_INCLUDES_OPENHEFS__
-
-#include <FSKit/OpenHeFS.h>
-#include <FirmwareKit/EPM.h>
-#include <FirmwareKit/GPT.h>
-#include <KernelKit/KPC.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/UserMgr.h>
-#include <NeKit/Crc32.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/Utils.h>
-#include <modules/AHCI/AHCI.h>
-#include <modules/ATA/ATA.h>
-
-namespace Kernel {
-namespace Detail {
- /// @brief Forward declarations of internal functions.
-
- /***********************************************************************************/
- /// @brief Traverse the RB-Tree of the filesystem.
- /// @param dir The directory to traverse.
- /// @param start The starting point of the traversal.
- /// @note This function is used to traverse the RB-Tree of the filesystem.
- /// @internal Internal filesystem use only.
- /***********************************************************************************/
- STATIC ATTRIBUTE(unused) _Output Void
- hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& start_ind,
- Lba& start);
-
- /***********************************************************************************/
- /// @brief Get the index node of a file or directory.
- /// @param boot The boot node of the filesystem.
- /// @param mnt The mnt to read from.
- /// @param dir_name The name of the directory.
- /// @param file_name The name of the file.
- /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic
- /// link, unknown).
- /***********************************************************************************/
- STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefsi_fetch_in(HEFS_BOOT_NODE* boot,
- DriveTrait* mnt,
- const Utf8Char* dir_name,
- const Utf8Char* file_name,
- UInt8 kind);
-
- /***********************************************************************************/
- /// @brief Allocate a new index node->
- /// @param boot The boot node of the filesystem.
- /// @param mnt The mnt to read/write from.
- /// @param dir_name The name of the parent directory.
- /// @return Status, see err_global_get().
- /***********************************************************************************/
- STATIC ATTRIBUTE(unused) _Output BOOL
- hefsi_update_in_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, const Utf8Char* dir_name,
- HEFS_INDEX_NODE* node, const BOOL create_or_delete);
-
- /***********************************************************************************/
- /// @brief Balance RB-Tree of the filesystem.
- /// @param boot The boot node of the filesystem.
- /// @param mnt The mnt to read/write from.
- /// @return Status, see err_global_get().
- /***********************************************************************************/
- STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* boot, DriveTrait* mnt);
-
- /// @brief Alllocate IND from boot node.
- /// @param boot The boot node of the filesystem.
- /// @param mnt The mnt to read from.
- /// @param dir_name The name of the directory.
- /// @param dir_name The parent of the directory.
- /// @param flags Directory flags.
- /// @param delete_or_create Delete or create directory.
- STATIC _Output BOOL hefsi_update_ind_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt,
- const Utf8Char* dir_name, UInt16 flags,
- const BOOL delete_or_create);
-
- /// @brief This helper makes it easier for other machines to understand OpenHeFS encoded hashes.
- STATIC UInt64 hefsi_to_big_endian_64(UInt64 val) {
- return ((val >> 56) & 0x00000000000000FFULL) | ((val >> 40) & 0x000000000000FF00ULL) |
- ((val >> 24) & 0x0000000000FF0000ULL) | ((val >> 8) & 0x00000000FF000000ULL) |
- ((val << 8) & 0x000000FF00000000ULL) | ((val << 24) & 0x0000FF0000000000ULL) |
- ((val << 40) & 0x00FF000000000000ULL) | ((val << 56) & 0xFF00000000000000ULL);
- }
-
- /// @brief Simple algorithm to hash directory entries for INDs.
- /// @param path the directory path.
- /// @return The hashed path.
- template <typename CharT = Utf8Char>
- STATIC UInt64 hefsi_hash_64(const CharT* path) {
- if (!path || *path == 0) return 0;
-
- const UInt64 kFnvBaseOffset = 0xcbf29ce484222325ULL;
- const UInt64 kFnvPrimeNumber = 0x100000001b3ULL;
-
- UInt64 hash = kFnvBaseOffset;
-
- while (*path) {
- hash ^= (CharT) (*path++);
- hash *= kFnvPrimeNumber;
- }
-
- return hefsi_to_big_endian_64(hash);
- }
-
- /// @brief Traverse the RB-Tree of the filesystem.
- /// @param dir The directory to traverse.
- /// @param start The starting point of the traversal.
- /// @note This function is used to traverse the RB-Tree of the filesystem.
- /// @internal Internal filesystem use only.
- STATIC ATTRIBUTE(unused) Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt,
- const Lba& ind_start, Lba& start) {
- if (!mnt || !dir) return;
-
- BOOL check_is_good = NO;
- HEFS_INDEX_NODE_DIRECTORY* dir_tmp = new HEFS_INDEX_NODE_DIRECTORY();
-
- while (YES) {
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir_tmp;
- mnt->fInput(mnt->fPacket);
-
- if (!mnt->fPacket.fPacketGood) break;
-
- if (dir_tmp->fNext != 0) {
- if (check_is_good) break;
-
- start = dir_tmp->fNext;
-
- check_is_good = YES;
- continue;
- } else if (dir_tmp->fPrev != 0) {
- if (check_is_good) break;
-
- start = dir_tmp->fPrev;
- check_is_good = YES;
- continue;
- } else {
- if (dir_tmp->fParent != 0) {
- if (check_is_good) break;
-
- start = dir_tmp->fParent;
- check_is_good = YES;
- continue;
- } else if (dir_tmp->fPrev != 0) {
- if (check_is_good) break;
-
- start = dir_tmp->fPrev;
- check_is_good = YES;
- continue;
- } else {
- if (start == 0) {
- start = ind_start;
- continue;
- }
-
- start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
- break;
- }
- }
- }
-
- delete dir_tmp;
-
- start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
- if (start == 0) start = ind_start;
- }
-
- /***********************************************************************************/
- /// @brief Rotate the RB-Tree to the left or right.
- /// @internal
- /***********************************************************************************/
- STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_tree(Lba& start, DriveTrait* mnt) {
- if (!start || !mnt) return;
-
- HEFS_INDEX_NODE_DIRECTORY* cur =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = cur;
-
- mnt->fInput(mnt->fPacket);
-
- if (cur->fHashPath == 0) return;
-
- HEFS_INDEX_NODE_DIRECTORY* sibling =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = cur->fPrev;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = sibling;
-
- mnt->fInput(mnt->fPacket);
-
- if (sibling->fHashPath == 0) return;
-
- auto child_sibling = sibling->fChild;
- auto child_cur = cur->fChild;
-
- cur->fChild = child_sibling;
- sibling->fChild = child_cur;
-
- sibling->fChecksum = ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY));
- cur->fChecksum = ke_calculate_crc32((Char*) cur, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = cur->fParent;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = sibling;
-
- mnt->fOutput(mnt->fPacket);
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = cur;
-
- mnt->fOutput(mnt->fPacket);
-
- HEFS_INDEX_NODE_DIRECTORY* sibling_child =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = child_sibling;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = sibling_child;
-
- mnt->fInput(mnt->fPacket);
-
- sibling_child->fParent = cur->fParent;
-
- sibling_child->fChecksum =
- ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fOutput(mnt->fPacket);
-
- HEFS_INDEX_NODE_DIRECTORY* cur_child =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = child_cur;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = cur_child;
-
- mnt->fInput(mnt->fPacket);
-
- cur_child->fParent = start;
-
- cur_child->fChecksum = ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fOutput(mnt->fPacket);
-
- kout << "RB-Tree has been rotated.\r";
- }
-
- /// @brief Alllocate IND from boot node.
- /// @param boot The boot node of the filesystem.
- /// @param mnt The mnt to read from.
- /// @param dir_name The name of the directory.
- /// @param dir_name The parent of the directory.
- /// @param flags Directory flags.
- /// @param delete_or_create Delete or create directory.
- STATIC _Output BOOL hefsi_update_ind_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt,
- const Utf8Char* dir_name, UInt16 flags,
- const BOOL delete_or_create) {
- if (mnt) {
- HEFS_INDEX_NODE_DIRECTORY* tmpdir =
- (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
-
- auto start = boot->fStartIND;
- auto prev_location = start;
- auto parent_location = 0UL;
-
- MUST_PASS(boot->fStartIND > mnt->fLbaStart);
-
- while (YES) {
- auto prev_start = start;
-
- if (start)
- mnt->fPacket.fPacketLba = start;
- else
- mnt->fPacket.fPacketLba = prev_location + sizeof(HEFS_INDEX_NODE_DIRECTORY);
-
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = tmpdir;
-
- mnt->fInput(mnt->fPacket);
-
- BOOL expr = NO;
-
- if (!delete_or_create) {
- expr = (!tmpdir->fCreated && tmpdir->fDeleted) || tmpdir->fHashPath == 0;
- } else {
- expr =
- tmpdir->fCreated && !tmpdir->fDeleted && hefsi_hash_64(dir_name) == tmpdir->fHashPath;
- }
-
- if (expr) {
- HEFS_INDEX_NODE_DIRECTORY* dirent =
- (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
-
- rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- dirent->fHashPath = delete_or_create ? 0UL : hefsi_hash_64(dir_name);
- dirent->fAccessed = 0UL;
- dirent->fCreated = delete_or_create ? 0UL : 1UL;
- dirent->fDeleted = delete_or_create ? 1UL : 0UL;
- dirent->fModified = 0UL;
- dirent->fEntryCount = 0UL;
-
- dirent->fReserved = 0;
- dirent->fFlags = flags;
- dirent->fChecksum = 0;
-
- dirent->fEntryCount = 0;
-
- if (parent_location) {
- HEFS_INDEX_NODE_DIRECTORY* tmpend =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = parent_location;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = tmpend;
-
- mnt->fInput(mnt->fPacket);
-
- if (tmpend->fChecksum !=
- ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY)))
- ke_panic(RUNTIME_CHECK_FILESYSTEM, "Bad CRC32 value, aborting.");
-
- if (delete_or_create)
- --tmpend->fEntryCount;
- else
- ++tmpend->fEntryCount;
-
- tmpend->fChecksum =
- ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fOutput(mnt->fPacket);
-
- auto child_first = tmpend->fChild;
-
- while (YES) {
- mnt->fPacket.fPacketLba = child_first;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = tmpend;
-
- mnt->fInput(mnt->fPacket);
-
- if ((!tmpend->fCreated && tmpend->fDeleted) || tmpend->fHashPath == 0) {
- start = child_first;
- break;
- }
-
- hefsi_traverse_tree(tmpend, mnt, boot->fStartIND, child_first);
- }
- }
-
- dirent->fNext = tmpdir->fNext;
- dirent->fPrev = tmpdir->fPrev;
- dirent->fParent = tmpdir->fParent;
- dirent->fChild = tmpdir->fChild;
- dirent->fColor = tmpdir->fColor;
-
- if (dirent->fColor == 0) {
- dirent->fColor = dirent->fNext ? kHeFSRed : kHeFSBlack;
- }
-
- if (dirent->fPrev == 0) {
- dirent->fPrev = boot->fStartIND;
- }
-
- if (dirent->fParent == 0) {
- dirent->fParent = boot->fStartIND;
- }
-
- if (tmpdir->fChild == 0) {
- auto child = dirent->fNext + sizeof(HEFS_INDEX_NODE_DIRECTORY);
-
- HEFS_INDEX_NODE_DIRECTORY* tmpend =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- while (YES) {
- mnt->fPacket.fPacketLba = child;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = tmpend;
-
- mnt->fInput(mnt->fPacket);
-
- if ((!tmpend->fCreated && tmpend->fDeleted) || tmpdir->fHashPath == 0) {
- break;
- }
-
- child += sizeof(HEFS_INDEX_NODE_DIRECTORY);
- if (child > boot->fEndIND) break;
- }
-
- dirent->fColor = kHeFSRed;
- dirent->fChild = child;
-
- if (child > boot->fEndIND) dirent->fChild = boot->fStartIND;
- }
-
- for (SizeT index = 0UL; index < kHeFSSliceCount; ++index) {
- dirent->fINSlices[index] = 0UL;
- }
-
- dirent->fChecksum = ke_calculate_crc32((Char*) dirent, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = prev_start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dirent;
-
- mnt->fOutput(mnt->fPacket);
-
- err_global_get() = kErrorSuccess;
-
- mm_free_ptr(dirent);
- mm_free_ptr(tmpdir);
-
- if (!delete_or_create)
- ++boot->fINDCount;
- else
- --boot->fINDCount;
-
- boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fOutput(mnt->fPacket);
-
- return YES;
- }
-
- prev_location = start;
-
- hefsi_traverse_tree(tmpdir, mnt, boot->fStartIND, start);
- if (start > boot->fEndIND || start == 0) break;
- }
-
- err_global_get() = kErrorDisk;
- mm_free_ptr(tmpdir);
-
- return NO;
- }
-
- err_global_get() = kErrorDiskIsFull;
- return NO;
- }
-
- /// @brief Get the index node of a file or directory.
- /// @param boot The boot node of the filesystem.
- /// @param mnt The mnt to read from.
- /// @param dir_name The name of the directory.
- /// @param file_name The name of the file.
- /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic
- /// link, unknown).
- STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefsi_fetch_in(HEFS_BOOT_NODE* boot,
- DriveTrait* mnt,
- const Utf8Char* dir_name,
- const Utf8Char* file_name,
- UInt8 kind) {
- if (mnt) {
- if (boot->fStartIND > boot->fEndIND) return nullptr;
- if (boot->fStartIN > boot->fEndIN) return nullptr;
-
- auto start = boot->fStartIND;
- HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE();
-
- HEFS_INDEX_NODE_DIRECTORY* dir =
- (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
-
- while (YES) {
- if (err_global_get() == kErrorDiskIsCorrupted) {
- delete dir;
- dir = nullptr;
-
- delete node;
- node = nullptr;
-
- return nullptr;
- }
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fInput(mnt->fPacket);
-
- (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl);
- (Void)(kout << hex_number(dir->fHashPath) << kendl);
-
- if (dir->fHashPath == 0) break;
-
- if (hefsi_hash_64(dir_name) == dir->fHashPath) {
- for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) {
- mnt->fPacket.fPacketLba = dir->fINSlices[inode_index];
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
- mnt->fPacket.fPacketContent = node;
-
- mnt->fInput(mnt->fPacket);
-
- (Void)(kout << hex_number(hefsi_hash_64(file_name)) << kendl);
- (Void)(kout << hex_number(node->fHashPath) << kendl);
-
- if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) {
- delete dir;
- dir = nullptr;
-
- return node;
- }
- }
- }
-
- hefsi_traverse_tree(dir, mnt, boot->fStartIND, start);
- if (start == boot->fStartIND || start == boot->fStartIND) break;
- }
-
- delete node;
- node = nullptr;
-
- delete dir;
- dir = nullptr;
- }
-
- kout << "Error: Failed to find IN.\r";
-
- err_global_get() = kErrorFileNotFound;
-
- return nullptr;
- }
-
- STATIC ATTRIBUTE(unused) _Output BOOL
- hefsi_update_in_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, const Utf8Char* dir_name,
- HEFS_INDEX_NODE* node, BOOL delete_or_create) {
- if (!boot || !mnt) return NO;
-
- auto start = boot->fStartIND;
-
- if (start > boot->fEndIND) return NO;
- if (boot->fStartIN > boot->fEndIN) return NO;
- ;
- if (boot->fStartBlock > boot->fEndBlock) return NO;
-
- if (mnt) {
- HEFS_INDEX_NODE_DIRECTORY* dir =
- (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
-
- auto hash_file = node->fHashPath;
-
- while (YES) {
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fInput(mnt->fPacket);
-
- (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl);
- (Void)(kout << hex_number(dir->fHashPath) << kendl);
-
- if (hefsi_hash_64(dir_name) == dir->fHashPath) {
- for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) {
- if (dir->fINSlices[inode_index] == 0 && !delete_or_create) {
- dir->fINSlices[inode_index] = boot->fStartIN;
-
- ++dir->fEntryCount;
-
- dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fOutput(mnt->fPacket);
-
- auto lba = dir->fINSlices[inode_index];
-
- node->fOffsetSliceLow = (UInt32) (boot->fStartBlock);
- node->fOffsetSliceHigh = (UInt32) (boot->fStartBlock >> 32);
-
- node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE));
-
- mnt->fPacket.fPacketLba = lba;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
- mnt->fPacket.fPacketContent = node;
-
- mnt->fOutput(mnt->fPacket);
-
- boot->fStartIN += sizeof(HEFS_INDEX_NODE);
- boot->fStartBlock += kHeFSBlockLen;
-
- boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fOutput(mnt->fPacket);
-
- mm_free_ptr(dir);
-
- return YES;
- } else if (dir->fINSlices[inode_index] != 0 && delete_or_create) {
- auto lba = dir->fINSlices[inode_index];
-
- HEFS_INDEX_NODE tmp_node{};
-
- mnt->fPacket.fPacketLba = lba;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
- mnt->fPacket.fPacketContent = &tmp_node;
-
- mnt->fInput(mnt->fPacket);
-
- if (tmp_node.fHashPath != hash_file) {
- continue;
- }
-
- node->fOffsetSliceLow = 0;
- node->fOffsetSliceHigh = 0;
-
- boot->fStartIN -= sizeof(HEFS_INDEX_NODE);
- boot->fStartBlock -= kHeFSBlockLen;
-
- boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fOutput(mnt->fPacket);
-
- mnt->fPacket.fPacketLba = lba;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
- mnt->fPacket.fPacketContent = node;
-
- mnt->fOutput(mnt->fPacket);
-
- dir->fINSlices[inode_index] = 0;
-
- if (dir->fEntryCount) --dir->fEntryCount;
-
- dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fOutput(mnt->fPacket);
-
- mm_free_ptr(dir);
-
- return YES;
- }
- }
- }
-
- hefsi_traverse_tree(dir, mnt, boot->fStartIND, start);
- if (start > boot->fEndIND || start == 0) break;
- }
-
- mm_free_ptr(dir);
- err_global_get() = kErrorFileNotFound;
- return NO;
- }
-
- err_global_get() = kErrorDiskIsFull;
- return NO;
- }
-
- /// @brief Balance RB-Tree of the filesystem.
- /// @param boot The boot node of the filesystem.
- /// @param mnt The mnt to read/write from.
- /// @return Status, see err_global_get().
- STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* boot, DriveTrait* mnt) {
- if (mnt) {
- HEFS_INDEX_NODE_DIRECTORY* dir =
- (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- auto start = boot->fStartIND;
-
- while (YES) {
- if (start == 0UL || start > boot->fEndIND) break;
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fInput(mnt->fPacket);
-
- if (!mnt->fPacket.fPacketGood) {
- err_global_get() = kErrorDiskIsCorrupted;
-
- return NO;
- }
-
- if (start == boot->fStartIND) {
- dir->fColor = kHeFSBlack;
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fOutput(mnt->fPacket);
- }
-
- if (dir->fColor == kHeFSBlack && dir->fChild != 0UL) {
- dir->fColor = kHeFSRed;
- hefsi_rotate_tree(start, mnt);
- } else if (dir->fColor == kHeFSBlack && dir->fChild == 0UL) {
- dir->fColor = kHeFSBlack;
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fOutput(mnt->fPacket);
- }
-
- if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != dir->fChecksum) {
- dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY));
-
- mnt->fPacket.fPacketLba = start;
- mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
- mnt->fPacket.fPacketContent = dir;
-
- mnt->fOutput(mnt->fPacket);
- }
-
- hefsi_traverse_tree(dir, mnt, boot->fStartIND, start);
- }
-
- err_global_get() = kErrorSuccess;
- return YES;
- }
-
- err_global_get() = kErrorDisk;
- return NO;
- }
-} // namespace Detail
-} // namespace Kernel
-
-/// @note OpenHeFS will allocate inodes and ind in advance, to avoid having to allocate them in
-/// real-time.
-/// @note This is certainly take longer to format a disk with it, but worth-it in the long run.
-
-namespace Kernel {
-/// @brief Make a EPM+OpenHeFS mnt out of the disk.
-/// @param mnt The mnt to write on.
-/// @return If it was sucessful, see err_local_get().
-_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input const Int32 flags,
- _Input const Utf8Char* vol_name) {
- // Verify Disk.
- mnt->fVerify(mnt->fPacket);
-
- // if disk isn't good, then error out.
- if (false == mnt->fPacket.fPacketGood) {
- err_global_get() = kErrorDiskIsCorrupted;
- return NO;
- }
-
- if (drv_std_get_size() < kHeFSMinimumDiskSize) {
- (Void)(kout << "OpenHeFS recommends at least 128 GiB of free space." << kendl);
- }
-
- HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fInput(mnt->fPacket);
-
- if (!mnt->fPacket.fPacketGood) {
- err_global_get() = kErrorDiskIsCorrupted;
-
- return NO;
- }
-
- // Check if the disk is already formatted.
-
- if (KStringBuilder::Equals(boot->fMagic, kHeFSMagic) && boot->fVersion == kHeFSVersion) {
- if (ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)) != boot->fChecksum &&
- boot->fChecksum > 0) {
- err_global_get() = kErrorDiskIsCorrupted;
- return NO;
- }
-
- err_global_get() = kErrorSuccess;
- return YES;
- }
-
- if (ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)) != boot->fChecksum &&
- boot->fChecksum > 0) {
- err_global_get() = kErrorDiskIsCorrupted;
- return NO;
- }
-
- rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
- rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
-
- urt_copy_memory((VoidPtr) vol_name, boot->fVolName, urt_string_len(vol_name) + 1);
- rt_copy_memory_safe((VoidPtr) kHeFSMagic, boot->fMagic, kHeFSMagicLen - 1, sizeof(boot->fMagic));
-
- if (mnt->fLbaStart > mnt->fLbaEnd) {
- err_global_get() = kErrorDiskIsCorrupted;
-
- return NO;
- }
-
- boot->fBadSectors = 0;
-
- boot->fSectorCount = drv_std_get_sector_count();
- boot->fSectorSize = mnt->fSectorSz;
-
- MUST_PASS(boot->fSectorSize);
-
- /// @note all OpenHeFS strucutres are equal to 512, so here it's fine, unless fSectoSize is 2048.
- const SizeT max_lba = (drv_std_get_size()) / boot->fSectorSize;
-
- const SizeT dir_max = max_lba / 300; // 5% for directory inodes
- const SizeT inode_max = max_lba / 400; // 5% for inodes
-
- boot->fStartIND = mnt->fLbaStart + kHeFSINDStartOffset;
- boot->fEndIND = boot->fStartIND + dir_max;
-
- boot->fStartIN = boot->fEndIND;
- boot->fEndIN = boot->fStartIN + inode_max;
-
- boot->fStartBlock = boot->fEndIN;
- boot->fEndBlock = drv_std_get_size();
-
- boot->fINDCount = 0;
-
- boot->fDiskSize = drv_std_get_size();
- boot->fDiskStatus = kHeFSStatusUnlocked;
-
- boot->fDiskFlags = flags;
-
- if (mnt->fKind & kMassStorageDrive) {
- boot->fDiskKind = kHeFSMassStorageDevice;
- } else if (mnt->fKind & kHeFSOpticalDrive) {
- boot->fDiskKind = kHeFSOpticalDrive;
- } else {
- boot->fDiskKind = kHeFSUnknown;
- }
-
- boot->fVersion = kHeFSVersion;
-
- boot->fVID = kHeFSInvalidVID;
-
- boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fOutput(mnt->fPacket);
-
- (Void)(kout << "Protocol: " << mnt->fProtocol() << kendl);
- (Void)(kout8 << u8"Volume Name: " << boot->fVolName << kendl8);
- (Void)(kout << "Start IND: " << hex_number(boot->fStartIND) << kendl);
- (Void)(kout << "End IND: " << hex_number(boot->fEndIND) << kendl);
- (Void)(kout << "Start IN: " << hex_number(boot->fStartIN) << kendl);
- (Void)(kout << "End IN: " << hex_number(boot->fEndIN) << kendl);
- (Void)(kout << "Start Block: " << hex_number(boot->fStartBlock) << kendl);
- (Void)(kout << "End Block: " << hex_number(boot->fEndBlock) << kendl);
- (Void)(kout << "Number of IND: " << hex_number(boot->fINDCount) << kendl);
- (Void)(kout << "Sector Size: " << hex_number(boot->fSectorSize) << kendl);
- (Void)(kout << "Drive Kind: " << Detail::hefs_drive_kind_to_string(boot->fDiskKind) << kendl);
-
- if (!mnt->fPacket.fPacketGood) {
- err_global_get() = kErrorDiskIsCorrupted;
- return NO;
- }
-
- /// AMLALE: Better way to create default directories than before.
- const Utf8Char* kFileMap[] = {u8"/", u8"/boot", u8"/system", u8"/network",
- u8"/devices", u8"/media", u8"/dev", (Utf8Char*) nullptr};
-
- SizeT i = 0;
- while (kFileMap[++i] != nullptr) {
- this->CreateINodeDirectory(mnt, kHeFSEncodingFlagsUTF8, kFileMap[i]);
- }
-
- err_global_get() = kErrorSuccess;
-
- return YES;
-}
-
-/// @brief Create a new directory on the disk.
-/// @param mnt The mnt to write on.
-/// @param flags The flags to use.
-/// @param dir The directory to create the file in.
-/// @return If it was sucessful, see err_local_get().
-_Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt,
- _Input const Int32 flags,
- const Utf8Char* dir,
- const BOOL delete_or_create) {
- if (urt_string_len(dir) > kHeFSFileNameLen) {
- err_global_get() = kErrorDisk;
- return NO;
- }
-
- HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) mm_alloc_ptr(sizeof(HEFS_BOOT_NODE), Yes, No);
-
- rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
- rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fInput(mnt->fPacket);
-
- if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) {
- err_global_get() = kErrorDisk;
- return YES;
- }
-
- if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) {
- err_global_get() = kErrorDiskIsCorrupted;
-
- kout << "Invalid Boot Node, this can't continue!\r";
-
- return NO;
- }
-
- if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) {
- kout << "Error: Invalid directory name.\r";
-
- err_global_get() = kErrorInvalidData;
-
- return NO;
- }
-
- if (Detail::hefsi_update_ind_status(boot, mnt, dir, flags, delete_or_create)) {
- // todo: make it smarter for high-throughput.
- Detail::hefsi_balance_ind(boot, mnt);
-
- mm_free_ptr((VoidPtr) boot);
- return YES;
- }
-
- mm_free_ptr((VoidPtr) boot);
- return NO;
-}
-
-_Output Bool HeFileSystemParser::RemoveINodeDirectory(_Input DriveTrait* mnt,
- _Input const Int32 flags,
- const Utf8Char* dir) {
- return this->INodeDirectoryCtlManip(mnt, flags, dir, YES);
-}
-
-_Output Bool HeFileSystemParser::CreateINodeDirectory(_Input DriveTrait* mnt,
- _Input const Int32 flags,
- const Utf8Char* dir) {
- return this->INodeDirectoryCtlManip(mnt, flags, dir, NO);
-}
-
-_Output Bool HeFileSystemParser::DeleteINode(_Input DriveTrait* mnt, _Input const Int32 flags,
- const Utf8Char* dir, const Utf8Char* name,
- const UInt8 kind) {
- return this->INodeCtlManip(mnt, flags, dir, name, YES, kind);
-}
-
-_Output Bool HeFileSystemParser::CreateINode(_Input DriveTrait* mnt, _Input const Int32 flags,
- const Utf8Char* dir, const Utf8Char* name,
- const UInt8 kind) {
- return this->INodeCtlManip(mnt, flags, dir, name, NO, kind);
-}
-
-_Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr block, SizeT block_sz,
- const Utf8Char* dir, const Utf8Char* name,
- const UInt8 kind, const BOOL is_input) {
- if (urt_string_len(dir) > kHeFSFileNameLen) {
- err_global_get() = kErrorDisk;
- return NO;
- }
-
- if (urt_string_len(name) > kHeFSFileNameLen) {
- err_global_get() = kErrorDisk;
- return NO;
- }
-
- HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) mm_alloc_ptr(sizeof(HEFS_BOOT_NODE), Yes, No);
-
- if (!boot) {
- err_global_get() = kErrorInvalidData;
- return NO;
- }
-
- rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
- rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fInput(mnt->fPacket);
-
- if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) {
- (Void)(kout << "Invalid Boot Node, OpenHeFS partition is invalid." << kendl);
- mm_free_ptr((VoidPtr) boot);
- err_global_get() = kErrorDisk;
- return NO;
- }
-
- auto start = Detail::hefsi_fetch_in(boot, mnt, dir, name, kind);
-
- if (start) {
- (Void)(kout << hex_number(start->fHashPath) << kendl);
- (Void)(kout << hex_number(start->fOffsetSliceLow) << kendl);
-
- if (start->fOffsetSliceLow && start->fHashPath) {
- mnt->fPacket.fPacketLba = ((UInt64) start->fOffsetSliceHigh << 32) | start->fOffsetSliceLow;
- mnt->fPacket.fPacketSize = block_sz;
- mnt->fPacket.fPacketContent = block;
-
- if (is_input) {
- mnt->fInput(mnt->fPacket);
- } else {
- if (start->fFlags & kHeFSFlagsReadOnly) {
- mm_free_ptr((VoidPtr) boot);
- delete start;
-
- kout << "Error: File is read-only\r";
-
- return NO;
- }
-
- mnt->fOutput(mnt->fPacket);
- }
- }
- }
-
- mm_free_ptr((VoidPtr) boot);
- delete start;
- return YES;
-}
-
-/// @brief Create a new file on the disk.
-/// @param mnt The mnt to write on.
-/// @param flags The flags to use.
-/// @param dir The directory to create the file in.
-/// @param name The name of the file.
-/// @return If it was sucessful, see err_local_get().
-_Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input const Int32 flags,
- const Utf8Char* dir, const Utf8Char* name,
- const BOOL delete_or_create, const UInt8 kind) {
- if (urt_string_len(name) > kHeFSFileNameLen) {
- err_global_get() = kErrorDisk;
- return NO;
- }
-
- if (urt_string_len(dir) > kHeFSFileNameLen) {
- err_global_get() = kErrorDisk;
- return NO;
- }
-
- HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE), Yes, No);
-
- if (!node) {
- err_global_get() = kErrorInvalidData;
- return NO;
- }
-
- rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE));
-
- HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
-
- if (!boot) {
- mm_free_ptr((VoidPtr) node);
- err_global_get() = kErrorInvalidData;
-
- return NO;
- }
-
- rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
- rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
-
- mnt->fPacket.fPacketLba = mnt->fLbaStart;
- mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
- mnt->fPacket.fPacketContent = boot;
-
- mnt->fInput(mnt->fPacket);
-
- if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) {
- err_global_get() = kErrorDisk;
- return YES;
- }
-
- if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) {
- kout << "Error: Invalid file name.\r";
-
- err_global_get() = kErrorInvalidData;
- return NO;
- }
-
- for (SizeT i_name = 0UL; i_name < urt_string_len(name); ++i_name) {
- if (name[i_name] == u'/') {
- err_global_get() = kErrorInvalidData;
- return NO;
- }
- }
-
- if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) {
- kout << "Error: Invalid directory name.\r";
-
- err_global_get() = kErrorInvalidData;
- return NO;
- }
-
- node->fAccessed = 0;
- node->fCreated = delete_or_create ? NO : YES;
- node->fDeleted = delete_or_create ? 1UL : NO;
- node->fModified = 0;
- node->fSize = 0;
- node->fKind = kind;
- node->fFlags = flags;
- node->fChecksum = 0;
- node->fGID = 0;
- node->fUID = 0;
- node->fHashPath = Detail::hefsi_hash_64(name);
-
- if (Detail::hefsi_update_in_status(boot, mnt, dir, node, delete_or_create)) {
- mm_free_ptr((VoidPtr) node);
-
- Detail::hefsi_balance_ind(boot, mnt);
-
- err_global_get() = kErrorSuccess;
- return YES;
- }
-
- mm_free_ptr((VoidPtr) node);
- err_global_get() = kErrorDirectoryNotFound;
-
- return NO;
-}
-
-STATIC IMountpoint kMountpoint;
-
-/// @brief Initialize the OpenHeFS filesystem.
-/// @return To check its status, see err_local_get().
-Boolean OpenHeFS::fs_init_openhefs(Void) noexcept {
- io_construct_main_drive(kMountpoint.A());
-
- if (kMountpoint.A().fPacket.fPacketReadOnly == YES) {
- kout << "Main disk cannot be mounted (read-only media).\r";
- return YES;
- }
-
- return HeFileSystemParser{}.Format(&kMountpoint.A(), kHeFSEncodingFlagsUTF8, kHeFSDefaultVolumeName);
-}
-} // namespace Kernel
-
-#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__
diff --git a/dev/kernel/src/FileMgr.cc b/dev/kernel/src/FileMgr.cc
deleted file mode 100644
index 88b17470..00000000
--- a/dev/kernel/src/FileMgr.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/FileMgr.h>
-#include <NeKit/Utils.h>
-
-/***********************************************************************************/
-/// @file FileMgr.cc
-//! @brief File System Manager API.
-///! @author Amlal El Mahrouss (amlal@nekernel.org)
-/***********************************************************************************/
-
-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
deleted file mode 100644
index 2d1218ed..00000000
--- a/dev/kernel/src/GUIDWizard.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
- File: GUIDWizard.cc
- Purpose: GUID helper code
-
- Revision History:
-
-======================================== */
-
-#include <CFKit/GUIDWizard.h>
-#include <NeKit/Ref.h>
-
-// begin of ascii 'readable' characters. (A, C, C, 1, 2)
-#define kGUIDAsciiBegin 47
-// @brief Size of UUID.
-#define kGUIDSize 37
-
-namespace Kernel::CF::XRN::Version1 {
-auto cf_make_sequence(const ArrayList<UInt32>& uuidSeq) -> Ref<GUIDSequence*> {
- GUIDSequence* seq = new GUIDSequence();
- MUST_PASS(seq);
-
- Ref<GUIDSequence*> seq_ref{seq};
-
- if (!seq) return seq_ref;
-
- seq_ref.Leak()->fUuid.fMs1 = uuidSeq[0];
- seq_ref.Leak()->fUuid.fMs2 = uuidSeq[1];
- seq_ref.Leak()->fUuid.fMs3 = uuidSeq[2];
- seq_ref.Leak()->fUuid.fMs4[0] = uuidSeq[3];
- seq_ref.Leak()->fUuid.fMs4[1] = uuidSeq[4];
- seq_ref.Leak()->fUuid.fMs4[2] = uuidSeq[5];
- seq_ref.Leak()->fUuid.fMs4[3] = uuidSeq[6];
- seq_ref.Leak()->fUuid.fMs4[4] = uuidSeq[7];
- seq_ref.Leak()->fUuid.fMs4[5] = uuidSeq[8];
- seq_ref.Leak()->fUuid.fMs4[6] = uuidSeq[9];
- seq_ref.Leak()->fUuid.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[kGUIDSize];
-
- for (SizeT index = 0; index < 16; ++index) {
- buf[index] = seq.Leak()->fU8[index] + kGUIDAsciiBegin;
- }
-
- for (SizeT index = 16; index < 24; ++index) {
- buf[index] = seq.Leak()->fU16[index] + kGUIDAsciiBegin;
- }
-
- for (SizeT index = 24; index < 28; ++index) {
- buf[index] = seq.Leak()->fU32[index] + kGUIDAsciiBegin;
- }
-
- auto view = KStringBuilder::Construct(buf);
-
- if (view) return ErrorOr<Ref<KString>>{view.Leak()};
-
- return ErrorOr<Ref<KString>>{kErrorInvalidData};
-}
-} // namespace Kernel::CF::XRN::Version1
diff --git a/dev/kernel/src/GUIDWrapper.cc b/dev/kernel/src/GUIDWrapper.cc
deleted file mode 100644
index ee29f911..00000000
--- a/dev/kernel/src/GUIDWrapper.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <CFKit/GUIDWrapper.h>
-
-namespace Kernel::CF::XRN {}
diff --git a/dev/kernel/src/Gfx/FBDeviceInterface.cc b/dev/kernel/src/Gfx/FBDeviceInterface.cc
deleted file mode 100644
index c5fac330..00000000
--- a/dev/kernel/src/Gfx/FBDeviceInterface.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <GfxKit/FB.h>
-
-using namespace Kernel;
-
-/// @brief Class constructor
-/// @param Out Drive output
-/// @param In Drive input
-/// @param Cleanup Drive cleanup.
-FBDeviceInterface::FBDeviceInterface(void (*out)(DeviceInterface* self, FBDevicePacket* outpacket),
- void (*in)(DeviceInterface* self, FBDevicePacket* inpacket))
- : DeviceInterface(out, in) {}
-
-/// @brief Class desctructor
-FBDeviceInterface::~FBDeviceInterface() = default;
-
-/// @brief Output operator.
-/// @param mnt the disk mountpoint.
-/// @return the class itself after operation.
-FBDeviceInterface& FBDeviceInterface::operator<<(FBDevicePacket* pckt) {
- if (!pckt) return *this;
-
- if (pckt->fHeight == 0 || pckt->fWidth == 0) return *this;
-
- this->fOut(this, pckt);
-
- return *this;
-}
-
-/// @brief Input operator.
-/// @param mnt the disk mountpoint.
-/// @return the class itself after operation.
-FBDeviceInterface& FBDeviceInterface::operator>>(FBDevicePacket* pckt) {
- if (!pckt) return *this;
-
- this->fIn(this, pckt);
-
- return *this;
-}
-
-/// @brief Returns the name of the device interface.
-/// @return it's name as a string.
-const Char* FBDeviceInterface::Name() const {
- return "/devices/fb{}";
-} \ No newline at end of file
diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc
deleted file mode 100644
index 41d927f6..00000000
--- a/dev/kernel/src/HardwareThreadScheduler.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <ArchKit/ArchKit.h>
-#include <CFKit/Property.h>
-#include <KernelKit/HardwareThreadScheduler.h>
-#include <KernelKit/ProcessScheduler.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_task(HAL::StackFramePtr frame);
-EXTERN_C Bool mp_register_task(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.
-/***********************************************************************************/
-ThreadID& HardwareThread::ID() noexcept {
- return fID;
-}
-
-/***********************************************************************************/
-//! @brief returns the kind of thread we have.
-/***********************************************************************************/
-ThreadKind& HardwareThread::Kind() noexcept {
- return fKind;
-}
-
-/***********************************************************************************/
-//! @brief is the thread busy?
-//! @return whether the thread is busy or not.
-/***********************************************************************************/
-Bool HardwareThread::IsBusy() noexcept {
- return fBusy;
-}
-
-/***********************************************************************************/
-/// @brief Get processor stack frame.
-/***********************************************************************************/
-
-HAL::StackFramePtr HardwareThread::StackFrame() noexcept {
- MUST_PASS(this->fStack);
- return this->fStack;
-}
-
-Void HardwareThread::Busy(Bool busy) noexcept {
- this->fBusy = busy;
-}
-
-HardwareThread::operator bool() {
- return this->fStack && !this->fBusy;
-}
-
-/***********************************************************************************/
-/// @brief Wakeup the processor.
-/***********************************************************************************/
-
-Void HardwareThread::Wake(const bool wakeup) noexcept {
- this->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(HAL::StackFramePtr frame) {
- if (!frame) {
- return NO;
- }
-
- if (!hal_check_task(frame)) {
- return NO;
- }
-
- this->fStack = frame;
- return mp_register_task(fStack, this->fID);
-}
-
-/***********************************************************************************/
-///! @brief Tells if processor is waked up.
-/***********************************************************************************/
-bool HardwareThread::IsWakeup() noexcept {
- return this->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[fCurrentThreadIdx].fStack;
-}
-
-/***********************************************************************************/
-/**
- * Get Hardware thread at index.
- * @param idx the index
- * @return the reference to the hardware thread.
- */
-/***********************************************************************************/
-Ref<HardwareThread*> HardwareThreadScheduler::operator[](SizeT idx) {
- if (idx > kMaxAPInsideSched) {
- HardwareThread* kFakeThread = nullptr;
- return {kFakeThread};
- }
-
- fCurrentThreadIdx = idx;
- 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/HeapMgr.cc b/dev/kernel/src/HeapMgr.cc
deleted file mode 100644
index 848a0377..00000000
--- a/dev/kernel/src/HeapMgr.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <ArchKit/ArchKit.h>
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/HeapMgr.h>
-#include <KernelKit/KPC.h>
-#include <NeKit/Crc32.h>
-#include <NeKit/PageMgr.h>
-#include <NeKit/Utils.h>
-
-/* ========================================
-
- Revision History:
- 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field.
- 20/10/24: FIX: Fix mm_new_ and mm_delete_ APIs inside HeapMgr.h header. (amlal)
- 27/01/25: REFACTOR: Reworked code as the memory manager.
- 25/03/25: REFACTOR: Refactor HeapMgr code and log freed address location.
-
- ======================================== */
-
-//! @file HeapMgr.cc
-//! @brief Heap system that serves as the main memory manager.
-
-#define kHeapMgrMagic (0xD4D75)
-#define kHeapMgrAlignSz (4U)
-
-namespace Kernel {
-/// @brief Implementation details.
-namespace Detail {
- struct PACKED MM_INFORMATION_BLOCK;
-
- /// @brief Kernel heap information block.
- /// Located before the address bytes.
- /// | HIB | CLASS/STRUCT/DATA TYPES... |
- struct PACKED MM_INFORMATION_BLOCK final {
- ///! @brief 32-bit value which contains the magic number of the heap.
- UInt32 fMagic : 24;
-
- ///! @brief Is the heap present?
- UInt8 fPresent : 1;
-
- /// @brief Is this value writable?
- UInt8 fWriteRead : 1;
-
- /// @brief Is this value owned by the user?
- UInt8 fUser : 1;
-
- /// @brief Is this a page pointer?
- UInt8 fPage : 1;
-
- /// @brief 32-bit CRC checksum.
- UInt32 fCRC32;
-
- /// @brief 64-bit Allocation flags.
- UInt16 fFlags;
-
- /// @brief 64-bit pointer size.
- SizeT fSize;
-
- /// @brief 64-bit target offset pointer.
- UIntPtr fOffset;
-
- /// @brief Padding.
- UInt32 fPad;
-
- /// @brief Padding bytes for header.
- UInt8 fPadding[kHeapMgrAlignSz];
- };
-
- /// @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_ptr_address(VoidPtr heap_ptr) -> Bool {
- if (!heap_ptr) return false;
-
- IntPtr base_ptr = ((IntPtr) heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK);
-
- /// Add that check in case we're having an integer underflow. ///
-
- if (base_ptr < 0) {
- return false;
- }
-
- return true;
- }
-
- typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR;
-} // namespace Detail
-
-STATIC PageMgr kPageMgr;
-
-/// @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_alloc_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount) {
- auto sz_fix = sz;
-
- if (sz_fix == 0) return nullptr;
-
- sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK);
-
- auto wrapper = kPageMgr.Request(wr, user, No, sz_fix, pad_amount);
-
- Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
- reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>(wrapper.VirtualAddress() +
- sizeof(Detail::MM_INFORMATION_BLOCK));
-
- heap_info_ptr->fSize = sz_fix;
- heap_info_ptr->fMagic = kHeapMgrMagic;
- heap_info_ptr->fCRC32 = 0U; // dont fill it for now.
- heap_info_ptr->fOffset =
- reinterpret_cast<UIntPtr>(heap_info_ptr) + sizeof(Detail::MM_INFORMATION_BLOCK);
- heap_info_ptr->fPage = No;
- heap_info_ptr->fWriteRead = wr;
- heap_info_ptr->fUser = user;
- heap_info_ptr->fPresent = Yes;
- heap_info_ptr->fPad = pad_amount;
-
- rt_set_memory(heap_info_ptr->fPadding, 0, kHeapMgrAlignSz);
-
- auto result = reinterpret_cast<VoidPtr>(heap_info_ptr->fOffset);
-
- (Void)(kout << "HeapMgr: Registered heap address: "
- << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl);
-
- 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_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent;
-
- Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
- reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
- sizeof(Detail::MM_INFORMATION_BLOCK));
-
- if (!heap_info_ptr) return kErrorHeapNotPresent;
-
- heap_info_ptr->fPage = true;
-
- (Void)(kout << "HeapMgr: Registered page from heap address: "
- << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl);
-
- 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_set_ptr_flags(VoidPtr heap_ptr, UInt64 flags) {
- if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent;
-
- Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
- reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
- sizeof(Detail::MM_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_ptr_flags(VoidPtr heap_ptr) {
- Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
- reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
- sizeof(Detail::MM_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_free_ptr(VoidPtr heap_ptr) {
- if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent;
-
- Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
- reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) (heap_ptr) -
- sizeof(Detail::MM_INFORMATION_BLOCK));
-
- if (heap_info_ptr && heap_info_ptr->fMagic == kHeapMgrMagic) {
- if (!heap_info_ptr->fPresent) {
- return kErrorHeapNotPresent;
- }
-
- heap_info_ptr->fSize = 0UL;
- heap_info_ptr->fPresent = No;
- heap_info_ptr->fOffset = 0;
- heap_info_ptr->fCRC32 = 0;
- heap_info_ptr->fWriteRead = No;
- heap_info_ptr->fUser = No;
- heap_info_ptr->fMagic = 0;
- heap_info_ptr->fPad = 0;
-
- (Void)(kout << "HeapMgr: Freed heap address: "
- << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl);
-
- PTEWrapper page_wrapper(
- No, No, No,
- reinterpret_cast<UIntPtr>(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK));
-
- Ref<PTEWrapper> pte_address{page_wrapper};
-
- kPageMgr.Free(pte_address);
-
- 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_ptr(VoidPtr heap_ptr) {
- if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) {
- Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
- reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) (heap_ptr) -
- sizeof(Detail::MM_INFORMATION_BLOCK));
-
- return (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kHeapMgrMagic);
- }
-
- 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_ptr(VoidPtr heap_ptr) {
- if (heap_ptr) {
- Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
- reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
- sizeof(Detail::MM_INFORMATION_BLOCK));
-
- /// if valid, present and is heap header, then compute crc32
- if (heap_info_ptr && heap_info_ptr->fPresent && kHeapMgrMagic == heap_info_ptr->fMagic) {
- heap_info_ptr->fCRC32 =
- ke_calculate_crc32((Char*) heap_info_ptr->fOffset, heap_info_ptr->fSize);
-
- return Yes;
- }
- }
-
- return No;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/IDylibObject.cc b/dev/kernel/src/IDylibObject.cc
deleted file mode 100644
index 61191af1..00000000
--- a/dev/kernel/src/IDylibObject.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * ========================================================
- *
- * NeKernel
- * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
- *
- * ========================================================
- */
-
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/IDylibObject.h>
-
-using namespace Kernel;
diff --git a/dev/kernel/src/IFS.cc b/dev/kernel/src/IFS.cc
deleted file mode 100644
index 4679b8a3..00000000
--- a/dev/kernel/src/IFS.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/DriveMgr.h>
-#include <KernelKit/FileMgr.h>
-
-/*************************************************************
- *
- * File: IFS.cc
- * Purpose: Filesystem to mountpoint interface.
- * Date: 05/26/2025
- *
- * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
- *
- *************************************************************/
-
-/// Useful macros regarding the IFS.
-
-#define fsi_ifs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS)
-#define fsi_ifs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS)
-
-namespace Kernel {
-/// @brief Read from fs disk.
-/// @param Mnt mounted interface.
-/// @param DrvTrait drive info
-/// @param DrvIndex drive index.
-/// @return
-Int32 fs_ifs_read(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) {
- if (!Mnt) return kErrorDisk;
-
- DrvTrait.fPacket.fPacketGood = false;
-
- switch (DrvIndex) {
- case IMountpoint::kDriveIndexA: {
- fsi_ifs_read(A, DrvTrait.fPacket, Mnt);
- break;
- }
- case IMountpoint::kDriveIndexB: {
- fsi_ifs_read(B, DrvTrait.fPacket, Mnt);
- break;
- }
- case IMountpoint::kDriveIndexC: {
- fsi_ifs_read(C, DrvTrait.fPacket, Mnt);
- break;
- }
- case IMountpoint::kDriveIndexD: {
- fsi_ifs_read(D, DrvTrait.fPacket, Mnt);
- break;
- }
- }
-
- return DrvTrait.fPacket.fPacketGood ? kErrorSuccess : kErrorDisk;
-}
-
-/// @brief Write to fs disk.
-/// @param Mnt mounted interface.
-/// @param DrvTrait drive info
-/// @param DrvIndex drive index.
-/// @return
-Int32 fs_ifs_write(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) {
- if (!Mnt) return kErrorDisk;
-
- DrvTrait.fPacket.fPacketGood = false;
-
- switch (DrvIndex) {
- case IMountpoint::kDriveIndexA: {
- fsi_ifs_write(A, DrvTrait.fPacket, Mnt);
- break;
- }
- case IMountpoint::kDriveIndexB: {
- fsi_ifs_write(B, DrvTrait.fPacket, Mnt);
- break;
- }
- case IMountpoint::kDriveIndexC: {
- fsi_ifs_write(C, DrvTrait.fPacket, Mnt);
- break;
- }
- case IMountpoint::kDriveIndexD: {
- fsi_ifs_write(D, DrvTrait.fPacket, Mnt);
- break;
- }
- }
-
- return DrvTrait.fPacket.fPacketGood ? kErrorSuccess : kErrorDisk;
-}
-} // namespace Kernel \ No newline at end of file
diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc
deleted file mode 100644
index 4ba9278d..00000000
--- a/dev/kernel/src/IPEFDylibObject.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * ========================================================
- *
- * NeKernel
- * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
- *
- * ========================================================
- */
-
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/IPEFDylibObject.h>
-#include <KernelKit/PEF.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/ThreadLocalStorage.h>
-#include <NeKit/Defines.h>
-
-/* ========================================
-
- Revision History:
-
- 01/02/24: Reworked dll ABI, expect a rtl_init_dylib_pef and
- rtl_fini_dylib_pef (amlel)
-
- 15/02/24: Breaking changes, changed the name of the
- routines. (amlel)
-
- 07/28/24: Replace rt_library_free with rtl_fini_dylib_pef
-
- 10/8/24: FIX: Fix log comment.
-
- ======================================== */
-
-using namespace Kernel;
-
-/***********************************************************************************/
-/// @file IPEFDylibObject.cc
-/// @brief PEF's Dylib runtime.
-///! @author Amlal El Mahrouss (amlal@nekernel.org)
-/***********************************************************************************/
-
-/***********************************************************************************/
-/** @brief Library initializer. */
-/***********************************************************************************/
-
-EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) {
- IDylibRef dll_obj = tls_new_class<IPEFDylibObject>();
-
- if (!dll_obj) {
- process.Crash();
- return nullptr;
- }
-
- dll_obj->Mount(new IPEFDylibObject::DylibTraits());
-
- if (!dll_obj->Get()) {
- tls_delete_class(dll_obj);
- dll_obj = nullptr;
-
- process.Crash();
-
- return nullptr;
- }
-
- dll_obj->Get()->ImageObject = process.Image.LeakBlob().Leak().Leak();
-
- if (!dll_obj->Get()->ImageObject) {
- delete dll_obj->Get();
-
- tls_delete_class(dll_obj);
- dll_obj = nullptr;
-
- process.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_pef(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) {
- MUST_PASS(successful);
-
- if (!successful) {
- return;
- }
-
- // sanity check (will also trigger a bug check if this fails)
- if (dll_obj == nullptr) {
- *successful = false;
- process.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
deleted file mode 100644
index 85207d4b..00000000
--- a/dev/kernel/src/IndexableProperty.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <CompilerKit/CompilerKit.h>
-#include <FSKit/IndexableProperty.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/MutableArray.h>
-#include <NeKit/Utils.h>
-
-/// @brief File indexer API for fast path access.
-/// BUGS: 0
-
-#define kMaxLenIndexer (256U)
-
-namespace Kernel {
-namespace Indexer {
- Index& IndexableProperty::Leak() noexcept { return fIndex; }
-
- Void IndexableProperty::AddFlag(UInt16 flag) { fFlags |= flag; }
-
- Void IndexableProperty::RemoveFlag(UInt16 flag) { fFlags &= ~(flag); }
-
- UInt16 IndexableProperty::HasFlag(UInt16 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.RemoveFlag(kIndexerUnclaimed);
- indexer.AddFlag(kIndexerClaimed);
- rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(filename)),
- (VoidPtr) indexer.Leak().Path, filenameLen, kIndexerCatalogNameLength);
-
- (Void)(kout << "FSKit: Indexed new file: " << filename << kendl);
- }
- }
-} // namespace Indexer
-} // namespace Kernel
diff --git a/dev/kernel/src/Json.cc b/dev/kernel/src/Json.cc
deleted file mode 100644
index 198aed99..00000000
--- a/dev/kernel/src/Json.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Json.h>
-
-namespace Kernel {} \ No newline at end of file
diff --git a/dev/kernel/src/KPC.cc b/dev/kernel/src/KPC.cc
deleted file mode 100644
index 4318b9cd..00000000
--- a/dev/kernel/src/KPC.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/HeapMgr.h>
-#include <KernelKit/KPC.h>
-#include <NeKit/KernelPanic.h>
-
-namespace Kernel {
-STATIC Bool kRaiseOnBugCheck = false;
-
-/// @brief Does a system wide bug check.
-/// @param void no params are needed.
-/// @return if error-free: false, otherwise true.
-Boolean err_bug_check_raise(Void) noexcept {
- Char* ptr = new Char[512];
-
- if (ptr == nullptr) goto bug_check_fail;
-
- if (!mm_is_valid_ptr(ptr)) goto bug_check_fail;
-
- delete[] ptr;
-
- return Yes;
-
-bug_check_fail:
- if (ptr) delete[] ptr;
-
- ptr = nullptr;
-
- if (kRaiseOnBugCheck) {
- ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR);
- }
-
- return No;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/KernelTaskScheduler.cc b/dev/kernel/src/KernelTaskScheduler.cc
deleted file mode 100644
index c3628765..00000000
--- a/dev/kernel/src/KernelTaskScheduler.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ========================================
-
- Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
- FILE: KernelTaskScheduler.cc
- PURPOSE: Kernel Task scheduler.
-
-======================================== */
-
-#include <KernelKit/KernelTaskScheduler.h>
-
-/***********************************************************************************/
-/// @file KernelTaskScheduler.cc
-/// @brief Kernel Task scheduler.
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/***********************************************************************************/
-
-namespace Kernel {
-EXTERN_C Void hal_switch_kernel_task(HAL::StackFramePtr frame, KID kid);
-
-Bool KernelTaskHelper::Add(HAL::StackFramePtr frame_ptr, KID new_kid) {
- NE_UNUSED(frame_ptr);
- NE_UNUSED(new_kid);
-
- return NO;
-}
-
-Bool KernelTaskHelper::Remove(const KID kid) {
- NE_UNUSED(kid);
-
- return NO;
-}
-
-Bool KernelTaskHelper::CanBeScheduled(const KERNEL_TASK& task) {
- return task.Kid > 0 && task.Image.HasCode();
-}
-} // namespace Kernel \ No newline at end of file
diff --git a/dev/kernel/src/LockDelegate.cc b/dev/kernel/src/LockDelegate.cc
deleted file mode 100644
index 2fe2b464..00000000
--- a/dev/kernel/src/LockDelegate.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#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
deleted file mode 100644
index 3c86e8b8..00000000
--- a/dev/kernel/src/MutableArray.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/MutableArray.h>
diff --git a/dev/kernel/src/Network/IPAddress.cc b/dev/kernel/src/Network/IPAddress.cc
deleted file mode 100644
index 98279979..00000000
--- a/dev/kernel/src/Network/IPAddress.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Utils.h>
-#include <NetworkKit/IP.h>
-
-namespace Kernel {
-UInt8* RawIPAddress::Address() {
- return fAddr;
-}
-
-RawIPAddress::RawIPAddress(UInt8 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;
-}
-
-UInt8& RawIPAddress::operator[](const Size& index) {
- kout << "[RawIPAddress::operator[]] Fetching Index...\r";
-
- static UInt8 IP_PLACEHOLDER = '0';
- if (index >= 4) return IP_PLACEHOLDER;
-
- return fAddr[index];
-}
-
-RawIPAddress6::RawIPAddress6(UInt8 bytes[16]) {
- rt_copy_memory(bytes, fAddr, 16);
-}
-
-UInt8& RawIPAddress6::operator[](const Size& index) {
- kout << "[RawIPAddress6::operator[]] Fetching Index...\r";
-
- static UInt8 IP_PLACEHOLDER = '0';
- if (index >= 16) return IP_PLACEHOLDER;
-
- return fAddr[index];
-}
-
-bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) {
- for (SizeT index = 0; index < 16; ++index) {
- if (ipv6.fAddr[index] != fAddr[index]) return false;
- }
-
- return true;
-}
-
-bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) {
- for (SizeT index = 0; index < 16; ++index) {
- if (ipv6.fAddr[index] == fAddr[index]) return false;
- }
-
- return true;
-}
-
-/// @todo
-ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress6>& ipv6) {
- NE_UNUSED(ipv6);
- auto str = KStringBuilder::Construct("");
- return str;
-}
-
-/// @todo
-ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4) {
- NE_UNUSED(ipv4);
- auto str = KStringBuilder::Construct("");
- return str;
-}
-
-/// @note Doesn't catch IPs such as 256.999.0.1, UNSAFE!
-bool IPFactory::IpCheckVersion4(const Char* ip) {
- if (!ip) return NO;
-
- Int32 cnter = 0;
- Int32 dot_cnter = 0;
-
- constexpr const auto kIP4DotCharacter = '.';
-
- for (SizeT base = 0; base < rt_string_len(ip); ++base) {
- if (ip[base] == kIP4DotCharacter) {
- cnter = 0;
- ++dot_cnter;
- } else {
- if (ip[base] > '5' || ip[base] < '0') return NO;
- if (!rt_is_alnum(ip[base])) return NO;
- if (cnter == 3) return NO;
-
- ++cnter;
- }
- }
-
- if (dot_cnter != 3) return NO;
-
- return YES;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Network/IPCAddress.cc b/dev/kernel/src/Network/IPCAddress.cc
deleted file mode 100644
index 2da5ac0a..00000000
--- a/dev/kernel/src/Network/IPCAddress.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
- ======================================== */
-
-#include <KernelKit/KPC.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <NetworkKit/IPC.h>
-
-namespace Kernel {
-bool IPC_ADDR::operator==(const IPC_ADDR& addr) noexcept {
- return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam;
-}
-
-bool IPC_ADDR::operator==(IPC_ADDR& addr) noexcept {
- return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam;
-}
-
-bool IPC_ADDR::operator!=(const IPC_ADDR& addr) noexcept {
- return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam;
-}
-
-bool IPC_ADDR::operator!=(IPC_ADDR& addr) noexcept {
- return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Network/IPCMessage.cc b/dev/kernel/src/Network/IPCMessage.cc
deleted file mode 100644
index b376b7c8..00000000
--- a/dev/kernel/src/Network/IPCMessage.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/KPC.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <NetworkKit/IPC.h>
-
-namespace Kernel {
-/***********************************************************************************/
-/// @internal internal use for IPC system only.
-/// @brief The internal sanitize function.
-/***********************************************************************************/
-Bool ipc_int_sanitize_packet(IPC_MSG* pckt) {
- auto endian = RTL_ENDIAN(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();
-
- MUST_PASS(*pckt_in);
-
- if (*pckt_in) {
- const auto endianess = RTL_ENDIAN((*pckt_in), ((Char*) (*pckt_in))[0]);
-
- (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic;
-
- (*pckt_in)->IpcEndianess = static_cast<UInt8>(endianess);
- (*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;
-
- (*pckt_in)->IpcLock = kIPCLockFree;
-
- return Yes;
- }
-
- return No;
-}
-
-/***********************************************************************************/
-/// @brief Pass message from **src** to **target**
-/// @param src Source message.
-/// @param target Target message.
-/***********************************************************************************/
-Bool IPC_MSG::Pass(IPC_MSG* src, IPC_MSG* target) noexcept {
- if (src && target && (target != src)) {
- if (src->IpcMsgSz > target->IpcMsgSz) return No;
- if (target->IpcMsgSz > src->IpcMsgSz) return No;
-
- auto timeout = 0U;
-
- const auto kLimitTimeout = 1000000U;
-
- while ((target->IpcLock % kIPCLockUsed) != 0) {
- if (timeout > kLimitTimeout) {
- return No;
- }
- }
-
- ++target->IpcLock;
-
- rt_copy_memory_safe(src->IpcData, target->IpcData, src->IpcMsgSz, kIPCMsgSize);
-
- --target->IpcLock;
-
- return Yes;
- }
-
- return No;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Network/MACAddressGetter.cc b/dev/kernel/src/Network/MACAddressGetter.cc
deleted file mode 100644
index 09d82a78..00000000
--- a/dev/kernel/src/Network/MACAddressGetter.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NetworkKit/MAC.h>
-
-namespace Kernel {
-Array<UInt8, kMACAddrLen>& MacAddressGetter::AsBytes() {
- return this->fMacAddress;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Network/NetworkDevice.cc b/dev/kernel/src/Network/NetworkDevice.cc
deleted file mode 100644
index 450c0191..00000000
--- a/dev/kernel/src/Network/NetworkDevice.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Utils.h>
-#include <NetworkKit/NetworkDevice.h>
-
-namespace Kernel {
-/// \brief Getter for fNetworkName.
-/// \return Network device name.
-const Char* NetworkDevice::Name() const {
- return "/devices/net/net{}";
-}
-
-/// \brief Setter for fNetworkName.
-Boolean NetworkDevice::Name(const Char* name) {
- if (name == nullptr) return NO;
-
- if (*name == 0) return NO;
-
- if (rt_string_len(name) > rt_string_len(this->Name())) return NO;
-
- rt_copy_memory((VoidPtr) name, (VoidPtr) this->Name(), rt_string_len(this->Name()));
-
- return YES;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/New+Delete.cc b/dev/kernel/src/New+Delete.cc
deleted file mode 100644
index ba37e7ec..00000000
--- a/dev/kernel/src/New+Delete.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/HeapMgr.h>
-#include <NeKit/New.h>
-
-void* operator new[](size_t sz) {
- if (sz == 0) ++sz;
-
- return Kernel::mm_alloc_ptr(sz, true, false);
-}
-
-void* operator new(size_t sz) {
- if (sz == 0) ++sz;
-
- return Kernel::mm_alloc_ptr(sz, true, false);
-}
-
-void operator delete[](void* ptr) noexcept {
- if (ptr == nullptr) return;
-
- Kernel::mm_free_ptr(ptr);
-}
-
-void operator delete(void* ptr) noexcept {
- if (ptr == nullptr) return;
-
- Kernel::mm_free_ptr(ptr);
-}
-
-void operator delete(void* ptr, size_t sz) {
- if (ptr == nullptr) return;
-
- NE_UNUSED(sz);
-
- Kernel::mm_free_ptr(ptr);
-}
-
-void operator delete[](void* ptr, size_t sz) {
- if (ptr == nullptr) return;
-
- NE_UNUSED(sz);
-
- Kernel::mm_free_ptr(ptr);
-}
diff --git a/dev/kernel/src/OwnPtr.cc b/dev/kernel/src/OwnPtr.cc
deleted file mode 100644
index e223d448..00000000
--- a/dev/kernel/src/OwnPtr.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/OwnPtr.h>
diff --git a/dev/kernel/src/PE32CodeMgr.cc b/dev/kernel/src/PE32CodeMgr.cc
deleted file mode 100644
index a8440c23..00000000
--- a/dev/kernel/src/PE32CodeMgr.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-/* ========================================
-
- Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <CFKit/Utils.h>
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/HeapMgr.h>
-#include <KernelKit/PE32CodeMgr.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <NeKit/Defines.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/OwnPtr.h>
-
-namespace Kernel {
-namespace Detail {
- /***********************************************************************************/
- /// @brief Get the PE32+ platform signature according to the compiled architecture.
- /***********************************************************************************/
-
- UInt32 ldr_get_platform_pe(void) noexcept {
-#if defined(__NE_AMD64__)
- return kPEPlatformAMD64;
-#elif defined(__NE_ARM64__)
- return kPEPlatformARM64;
-#else
- return kPEPlatformInvalid;
-#endif // __32x0__ || __64x0__ || __x86_64__
- }
-} // namespace Detail
-
-/***********************************************************************************/
-/// @brief PE32+ loader constructor w/ blob.
-/// @param blob file blob.
-/***********************************************************************************/
-
-PE32Loader::PE32Loader(const VoidPtr blob) : fCachedBlob(blob) {
- MUST_PASS(fCachedBlob);
- fBad = false;
-}
-
-/***********************************************************************************/
-/// @brief PE32+ loader constructor.
-/// @param path the filesystem path.
-/***********************************************************************************/
-
-PE32Loader::PE32Loader(const Char* path) : fCachedBlob(nullptr), fBad(false) {
- fFile.New(const_cast<Char*>(path), kRestrictRB);
- fPath = KStringBuilder::Construct(path).Leak();
-
- auto kPefHeader = "PE32_BLOB";
- fCachedBlob = fFile->Read(kPefHeader, 0);
-
- if (!fCachedBlob) fBad = YES;
-}
-
-/***********************************************************************************/
-/// @brief PE32+ destructor.
-/***********************************************************************************/
-
-PE32Loader::~PE32Loader() {
- if (fCachedBlob) mm_free_ptr(fCachedBlob);
-
- fFile.Delete();
-}
-
-/***********************************************************************************/
-/// @brief Finds the section according to its name.
-/// @param name name of section.
-/***********************************************************************************/
-
-ErrorOr<VoidPtr> PE32Loader::FindSectionByName(const Char* name) {
- if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header((const Char*) fCachedBlob);
- LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header((const Char*) fCachedBlob);
-
- if (!header_ptr || !opt_header_ptr) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
-#ifdef __NE_AMD64__
- if (header_ptr->Machine != kPeMachineAMD64 || header_ptr->Signature != kPeSignature) {
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
-
-#elif defined(__NE_ARM64__)
- if (header_ptr->Machine != kPeMachineARM64 || header_ptr->Signature != kPeSignature) {
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
-#endif // __NE_AMD64__ || __NE_ARM64__
-
- if (header_ptr->NumberOfSections < 1) {
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
-
- LDR_SECTION_HEADER_PTR secs =
- (LDR_SECTION_HEADER_PTR) (((Char*) opt_header_ptr) + header_ptr->SizeOfOptionalHeader);
-
- for (SizeT sectIndex = 0; sectIndex < header_ptr->NumberOfSections; ++sectIndex) {
- LDR_SECTION_HEADER_PTR sect = &secs[sectIndex];
-
- if (KStringBuilder::Equals(name, sect->Name)) {
- return ErrorOr<VoidPtr>(sect);
- }
- }
-
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-}
-
-/***********************************************************************************/
-/// @brief Finds the symbol according to it's name.
-/// @param name name of symbol.
-/// @param kind kind of symbol we want.
-/***********************************************************************************/
-
-ErrorOr<VoidPtr> PE32Loader::FindSymbol(const Char* name, Int32 kind) {
- if (!name || *name == 0) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- auto section_name = "\0";
-
- switch (kind) {
- case kPETypeData:
- section_name = ".data";
- break;
- case kPETypeBSS:
- section_name = ".bss";
- break;
- case kPETypeText:
- section_name = ".text";
- break;
- default:
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
-
- auto sec = this->FindSectionByName(section_name);
- LDR_SECTION_HEADER_PTR* sec_ptr = (LDR_SECTION_HEADER_PTR*) sec.Leak().Leak();
-
- if (!sec_ptr || !*sec_ptr) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header((const Char*) fCachedBlob);
-
- if (opt_header_ptr) {
- LDR_DATA_DIRECTORY_PTR data_dirs =
- (LDR_DATA_DIRECTORY_PTR) ((UInt8*) opt_header_ptr + sizeof(LDR_OPTIONAL_HEADER));
-
- LDR_DATA_DIRECTORY_PTR export_dir_entry = &data_dirs[0];
-
- if (export_dir_entry->VirtualAddress == 0 || export_dir_entry->Size == 0)
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- LDR_EXPORT_DIRECTORY* export_dir =
- (LDR_EXPORT_DIRECTORY*) ((UIntPtr) fCachedBlob + export_dir_entry->VirtualAddress);
-
- UInt32* name_table = (UInt32*) ((UIntPtr) fCachedBlob + export_dir->AddressOfNames);
- UInt16* ordinal_table = (UInt16*) ((UIntPtr) fCachedBlob + export_dir->AddressOfNameOrdinal);
- UInt32* function_table = (UInt32*) ((UIntPtr) fCachedBlob + export_dir->AddressOfFunctions);
-
- for (UInt32 i = 0; i < export_dir->NumberOfNames; ++i) {
- const char* exported_name = (const char*) ((UIntPtr) fCachedBlob + name_table[i]);
-
- if (KStringBuilder::Equals(exported_name, name)) {
- UInt16 ordinal = ordinal_table[i];
- UInt32 rva = function_table[ordinal];
-
- VoidPtr symbol_addr = (VoidPtr) ((UIntPtr) fCachedBlob + rva);
-
- return ErrorOr<VoidPtr>{symbol_addr};
- }
- }
- }
-
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-}
-
-/// @brief Finds the executable entrypoint.
-/// @return
-ErrorOr<VoidPtr> PE32Loader::FindStart() {
- if (auto sym = this->FindSymbol(kPeImageStart, 0); sym) return sym;
-
- return ErrorOr<VoidPtr>(kErrorExecutable);
-}
-
-/// @brief Tells if the executable is loaded or not.
-/// @return Whether it's not bad and is cached.
-bool PE32Loader::IsLoaded() noexcept {
- return !fBad && fCachedBlob;
-}
-
-const Char* PE32Loader::Path() {
- return fPath.Leak().CData();
-}
-
-const Char* PE32Loader::AsString() {
-#ifdef __32x0__
- return "32x0 PE";
-#elif defined(__64x0__)
- return "64x0 PE";
-#elif defined(__x86_64__)
- return "x86_64 PE";
-#elif defined(__aarch64__)
- return "AARCH64 PE";
-#elif defined(__powerpc64__)
- return "POWER64 PE";
-#else
- return "???? PE";
-#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__
-}
-
-const Char* PE32Loader::MIME() {
- return kPeApplicationMime;
-}
-
-ErrorOr<VoidPtr> PE32Loader::GetBlob() {
- return ErrorOr<VoidPtr>{this->fCachedBlob};
-}
-
-namespace Utils {
- ProcessID rtl_create_user_process(PE32Loader& exec, const Int32& process_kind) noexcept {
- auto errOrStart = exec.FindStart();
-
- if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID;
-
- auto symname = exec.FindSymbol(kPeImageStart, 0);
-
- if (!symname) {
- symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS_PE32+")};
- }
-
- auto id =
- UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()),
- errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
-
- mm_free_ptr(symname.Leak().Leak());
-
- if (id != kSchedInvalidPID) {
- auto stacksym = exec.FindSymbol(kPeStackSizeSymbol, 0);
-
- if (!stacksym) {
- stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)};
- }
-
- if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) {
- *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz;
- }
-
- UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].Kind = process_kind;
- UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].StackSize =
- *(UIntPtr*) stacksym.Leak().Leak();
-
- mm_free_ptr(stacksym.Leak().Leak());
- stacksym.Leak().Leak() = nullptr;
- }
-
- return id;
- }
-} // namespace Utils
-} // namespace Kernel \ No newline at end of file
diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc
deleted file mode 100644
index c0a79c32..00000000
--- a/dev/kernel/src/PEFCodeMgr.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
- Copyright (C) 2025, Amlal El Mahrouss & NeKernel contributors, licensed under the Apache 2.0
-license.
-
-======================================== */
-
-#include <ArchKit/ArchKit.h>
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/HeapMgr.h>
-#include <KernelKit/PEFCodeMgr.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <NeKit/Defines.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/OwnPtr.h>
-#include <NeKit/Utils.h>
-
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/// @brief PEF backend for the Code Manager.
-/// @file PEFCodeMgr.cc
-
-/// @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.
- /***********************************************************************************/
- static UInt32 ldr_get_platform(void) noexcept {
-#if defined(__NE_32X0__)
- return kPefArch32x0;
-#elif defined(__NE_64X0__)
- return kPefArch64x0;
-#elif defined(__NE_AMD64__)
- return kPefArchAMD64;
-#elif defined(__NE_PPC64__)
- return kPefArchPowerPC;
-#elif defined(__NE_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);
-
- if (!fCachedBlob) {
- this->fBad = YES;
- return;
- }
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- if (container->Abi == kPefAbi &&
- container->Count >=
- 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */
- 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]) {
- return;
- } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] &&
- container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] &&
- container->Magic[4] == kPefMagicFat[4]) {
- /// This is a fat binary. Treat it as such.
- this->fFatBinary = YES;
- return;
- }
- }
-
- kout << "PEFLoader: warning: Binary format error!\r";
-
- this->fFatBinary = NO;
- this->fBad = YES;
-
- if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob);
- this->fCachedBlob = nullptr;
-}
-
-/***********************************************************************************/
-/// @brief PEF loader constructor.
-/// @param path the filesystem path.
-/***********************************************************************************/
-PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false), fBad(false) {
- fFile.New(const_cast<Char*>(path), kRestrictRB);
- fPath = KStringBuilder::Construct(path).Leak();
-
- constexpr auto kPefHeader = "PEF_CONTAINER";
-
- /// @note zero here means that the FileMgr will read every container header inside the file.
- fCachedBlob = fFile->Read(kPefHeader, 0UL);
-
- if (!fCachedBlob) {
- this->fBad = YES;
- return;
- }
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- if (container->Abi == kPefAbi &&
- container->Count >=
- 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */
- 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]) {
- return;
- } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] &&
- container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] &&
- container->Magic[4] == kPefMagicFat[4]) {
- /// This is a fat binary, treat it as such.
- this->fFatBinary = YES;
- return;
- }
- }
-
- kout << "PEFLoader: warning: Binary format error!\r";
-
- this->fFatBinary = NO;
- this->fBad = YES;
-
- if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob);
- this->fCachedBlob = nullptr;
-}
-
-/***********************************************************************************/
-/// @brief PEF destructor.
-/***********************************************************************************/
-PEFLoader::~PEFLoader() {
- if (fCachedBlob) mm_free_ptr(fCachedBlob);
-
- fFile.Delete();
-}
-
-/***********************************************************************************/
-/// @brief Finds the symbol according to it's name.
-/// @param name name of symbol.
-/// @param kind kind of symbol we want.
-/***********************************************************************************/
-ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) {
- if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- auto blob = fFile->Read(name, sizeof(PEFCommandHeader));
-
- if (!blob) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- if (!container) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- PEFCommandHeader* command_header = reinterpret_cast<PEFCommandHeader*>(blob);
-
- if (command_header->VMSize < 1 || command_header->VMAddress == 0)
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- /// fat binary check.
- if (command_header->Cpu != container->Cpu && !this->fFatBinary)
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- const auto kMangleCharacter = '$';
- const Char* kContainerKinds[] = {".code64", ".data64", ".zero64", nullptr};
-
- ErrorOr<KString> error_or_symbol;
-
- switch (kind) {
- case kPefCode: {
- error_or_symbol = KStringBuilder::Construct(kContainerKinds[0]); // code symbol.
- break;
- }
- case kPefData: {
- error_or_symbol = KStringBuilder::Construct(kContainerKinds[1]); // data symbol.
- break;
- }
- case kPefZero: {
- error_or_symbol = KStringBuilder::Construct(kContainerKinds[2]); // block starting symbol.
- break;
- }
- default:
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- // 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 (rt_is_space(unconst_symbol[i])) {
- unconst_symbol[i] = kMangleCharacter;
- }
- }
-
- error_or_symbol.Leak().Leak() += name;
-
- if (KStringBuilder::Equals(command_header->Name, error_or_symbol.Leak().Leak().CData())) {
- if (command_header->Kind == kind) {
- if (command_header->Cpu != Detail::ldr_get_platform()) {
- if (!this->fFatBinary) {
- mm_free_ptr(blob);
- blob = nullptr;
-
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
- }
-
- Char* container_blob_value = new Char[command_header->VMSize];
-
- rt_copy_memory_safe((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value,
- command_header->VMSize, command_header->VMSize);
-
- mm_free_ptr(blob);
-
- kout << "PEFLoader: info: Load stub: " << command_header->Name << "!\r";
-
- Int32 ret = 0;
- SizeT pages_count = (command_header->VMSize + kPageSize - 1) / kPageSize;
-
- for (SizeT i_vm{}; i_vm < pages_count; ++i_vm) {
- ret = HAL::mm_map_page(
- (VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)),
- (VoidPtr) (HAL::mm_get_page_addr(container_blob_value) + (i_vm * kPageSize)),
- HAL::kMMFlagsPresent | HAL::kMMFlagsUser);
-
- if (ret != kErrorSuccess) {
- /// We set the VMAddress to nullptr, if the mapping fail here.
- for (SizeT i_vm_unmap{}; i_vm_unmap < i_vm; ++i_vm_unmap) {
- ret = HAL::mm_map_page((VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)),
- nullptr, HAL::kMMFlagsPresent | HAL::kMMFlagsUser);
- }
-
- delete[] container_blob_value;
- container_blob_value = nullptr;
-
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
- }
-
- return ErrorOr<VoidPtr>{container_blob_value};
- }
- }
-
- mm_free_ptr(blob);
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-}
-
-/// @brief Finds the executable entrypoint.
-/// @return
-ErrorOr<VoidPtr> PEFLoader::FindStart() {
- if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return sym;
-
- return ErrorOr<VoidPtr>(kErrorExecutable);
-}
-
-/// @brief Tells if the executable is loaded or not.
-/// @return Whether it's not bad and is cached.
-bool PEFLoader::IsLoaded() noexcept {
- return !fBad && fCachedBlob;
-}
-
-const Char* PEFLoader::Path() {
- return fPath.Leak().CData();
-}
-
-const Char* PEFLoader::AsString() {
-#ifdef __32x0__
- return "32x0 PEF";
-#elif defined(__64x0__)
- return "64x0 PEF";
-#elif defined(__x86_64__)
- return "x86_64 PEF";
-#elif defined(__aarch64__)
- return "AARCH64 PEF";
-#elif defined(__powerpc64__)
- return "POWER64 PEF";
-#else
- return "???? PEF";
-#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_user_process(PEFLoader& exec, const Int32& process_kind) noexcept {
- auto errOrStart = exec.FindStart();
-
- if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID;
-
- auto symname = exec.FindSymbol(kPefNameSymbol, kPefData);
-
- if (!symname) {
- symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS_PEF")};
- }
-
- ProcessID id =
- UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()),
- errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
-
- mm_free_ptr(symname.Leak().Leak());
-
- if (id != kSchedInvalidPID) {
- auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData);
-
- if (!stacksym) {
- stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)};
- }
-
- if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) {
- *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz;
- }
-
- UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].Kind = process_kind;
- UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].StackSize =
- *(UIntPtr*) stacksym.Leak().Leak();
-
- mm_free_ptr(stacksym.Leak().Leak());
- }
-
- return id;
- }
-} // namespace Utils
-} // namespace Kernel
diff --git a/dev/kernel/src/PRDT.cc b/dev/kernel/src/PRDT.cc
deleted file mode 100644
index 626a7e16..00000000
--- a/dev/kernel/src/PRDT.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/DebugOutput.h>
-#include <NeKit/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
deleted file mode 100644
index 81833ee2..00000000
--- a/dev/kernel/src/PageMgr.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/DebugOutput.h>
-#include <NeKit/PageMgr.h>
-
-#ifdef __NE_AMD64__
-#include <HALKit/AMD64/Paging.h>
-#elif defined(__NE_ARM64__)
-#include <HALKit/ARM64/Paging.h>
-#endif // ifdef __NE_AMD64__ || defined(__NE_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() {
-#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- hal_flush_tlb();
-#endif // !__NE_VIRTUAL_MEMORY_SUPPORT__
-}
-
-/// @brief Reclaim freed page.
-/// @return
-Bool PTEWrapper::Reclaim() {
- if (!this->fPresent) {
- this->fPresent = true;
- return true;
- }
-
- return false;
-}
-
-/// @brief Request a PTE.
-/// @param Rw Is it read write? or is it read only?
-/// @param User user mode?
-/// @param ExecDisable disable execution on page?
-/// @return
-PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad) {
- // Store PTE wrapper right after PTE.
- VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, NO, Pad);
-
- 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.
-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
deleted file mode 100644
index 84086929..00000000
--- a/dev/kernel/src/Pmm.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/DebugOutput.h>
-#include <NeKit/Pmm.h>
-
-#if defined(__NE_ARM64__)
-#include <HALKit/ARM64/Processor.h>
-#endif // defined(__NE_ARM64__)
-
-#if defined(__NE_AMD64__)
-#include <HALKit/AMD64/Processor.h>
-#endif // defined(__NE_AMD64__)
-
-namespace Kernel {
-/***********************************************************************************/
-/// @brief Pmm constructor.
-/***********************************************************************************/
-Pmm::Pmm() : fPageMgr() {
- kout << "[PMM] Allocate PageMemoryMgr.\r";
-}
-
-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, 0);
-
- if (pt.fPresent) {
- kout << "[PMM]: Allocation failed.\r";
- return {pt};
- }
-
- 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
deleted file mode 100644
index 8b7454fe..00000000
--- a/dev/kernel/src/Property.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <CFKit/Property.h>
-
-namespace Kernel::CF {
-/***********************************************************************************/
-/// @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(KBasicString<>& name) {
- return this->fName && this->fName == name;
-}
-
-/***********************************************************************************/
-/// @brief Gets the key (name) of property.
-/***********************************************************************************/
-KBasicString<>& Property::GetKey() {
- return this->fName;
-}
-
-/***********************************************************************************/
-/// @brief Gets the value of the property.
-/***********************************************************************************/
-PropertyId& Property::GetValue() {
- return fValue;
-}
-} // namespace Kernel::CF
diff --git a/dev/kernel/src/Ref.cc b/dev/kernel/src/Ref.cc
deleted file mode 100644
index 90b1c22d..00000000
--- a/dev/kernel/src/Ref.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Ref.h>
diff --git a/dev/kernel/src/Semaphore.cc b/dev/kernel/src/Semaphore.cc
deleted file mode 100644
index 484c89ca..00000000
--- a/dev/kernel/src/Semaphore.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/Semaphore.h> \ No newline at end of file
diff --git a/dev/kernel/src/SoftwareTimer.cc b/dev/kernel/src/SoftwareTimer.cc
deleted file mode 100644
index eafe8db6..00000000
--- a/dev/kernel/src/SoftwareTimer.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/Timer.h>
-
-/// ================================================================================
-/// @brief SoftwareTimer class, meant to be generic.
-///! @author Amlal El Mahrouss (amlal@nekernel.org)
-/// ================================================================================
-
-using namespace Kernel;
-
-SoftwareTimer::SoftwareTimer(Int64 seconds) : fWaitFor(seconds) {
- fDigitalTimer = new UIntPtr();
- 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
deleted file mode 100644
index 02b39fb5..00000000
--- a/dev/kernel/src/Storage/AHCIDeviceInterface.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#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)(DeviceInterface* self, IMountpoint* outpacket),
- void (*in)(DeviceInterface* self, IMountpoint* inpacket))
- : DeviceInterface(out, in) {}
-
-/// @brief Class desctructor
-AHCIDeviceInterface::~AHCIDeviceInterface() = default;
-
-/// @brief Returns the name of the device interface.
-/// @return it's name as a string.
-const Char* AHCIDeviceInterface::Name() const {
- return "/devices/sda{}";
-}
-
-/// @brief Output operator.
-/// @param mnt the disk mountpoint.
-/// @return the class itself after operation.
-AHCIDeviceInterface& AHCIDeviceInterface::operator<<(IMountpoint* mnt) {
- if (!mnt) return *this;
-
- for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
- auto interface = mnt->GetAddressOf(driveCount);
-
- if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) == 0) {
- continue;
- } else if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) != 0) {
- return *this;
- }
- }
-
- return (AHCIDeviceInterface&) DeviceInterface<IMountpoint*>::operator<<(mnt);
-}
-
-/// @brief Input operator.
-/// @param mnt the disk mountpoint.
-/// @return the class itself after operation.
-AHCIDeviceInterface& AHCIDeviceInterface::operator>>(IMountpoint* mnt) {
- if (!mnt) return *this;
-
- for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
- auto interface = mnt->GetAddressOf(driveCount);
-
- // really check if it's ATA.
- if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) == 0) {
- continue;
- } else if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) != 0) {
- return *this;
- }
- }
-
- return (AHCIDeviceInterface&) DeviceInterface<IMountpoint*>::operator>>(mnt);
-}
-
-const UInt16& AHCIDeviceInterface::GetPortsImplemented() {
- return this->fPortsImplemented;
-}
-
-Void AHCIDeviceInterface::SetPortsImplemented(const UInt16& pi) {
- MUST_PASS(pi > 0);
- this->fPortsImplemented = pi;
-}
-
-const UInt32& AHCIDeviceInterface::GetIndex() {
- return this->fDriveIndex;
-}
-
-Void AHCIDeviceInterface::SetIndex(const UInt32& drv) {
- MUST_PASS(IMountpoint::kDriveIndexInvalid < drv);
- this->fDriveIndex = drv;
-} \ No newline at end of file
diff --git a/dev/kernel/src/Storage/ATADeviceInterface.cc b/dev/kernel/src/Storage/ATADeviceInterface.cc
deleted file mode 100644
index 8e15fdea..00000000
--- a/dev/kernel/src/Storage/ATADeviceInterface.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#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)(DeviceInterface*, IMountpoint* outpacket),
- void (*In)(DeviceInterface*, IMountpoint* inpacket))
- : DeviceInterface(Out, In) {}
-
-/// @brief Class desctructor
-ATADeviceInterface::~ATADeviceInterface() = default;
-
-/// @brief Returns the name of the device interface.
-/// @return it's name as a string.
-const Char* ATADeviceInterface::Name() const {
- return "/devices/hda{}";
-}
-
-/// @brief Output operator.
-/// @param Data the disk mountpoint.
-/// @return the class itself after operation.
-ATADeviceInterface& ATADeviceInterface::operator<<(IMountpoint* Data) {
- if (!Data) return *this;
-
- for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
- auto interface = Data->GetAddressOf(driveCount);
-
- if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) == 0) {
- continue;
- } else if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) != 0) {
- return *this;
- }
- }
-
- return (ATADeviceInterface&) DeviceInterface<IMountpoint*>::operator<<(Data);
-}
-
-/// @brief Input operator.
-/// @param Data the disk mountpoint.
-/// @return the class itself after operation.
-ATADeviceInterface& ATADeviceInterface::operator>>(IMountpoint* Data) {
- if (!Data) return *this;
-
- for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
- auto interface = Data->GetAddressOf(driveCount);
-
- // really check if it's ATA.
- if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) == 0) {
- continue;
- } else if ((interface) &&
- rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) != 0) {
- return *this;
- }
- }
-
- return (ATADeviceInterface&) DeviceInterface<IMountpoint*>::operator>>(Data);
-}
-
-const UInt32& ATADeviceInterface::GetIndex() {
- return this->fDriveIndex;
-}
-
-Void ATADeviceInterface::SetIndex(const UInt32& drv) {
- MUST_PASS(IMountpoint::kDriveIndexInvalid < drv);
- this->fDriveIndex = drv;
-}
-
-const UInt16& ATADeviceInterface::GetIO() {
- return this->fIO;
-}
-
-Void ATADeviceInterface::SetIO(const UInt16& drv) {
- MUST_PASS(0xFFFF != drv);
- this->fIO = drv;
-}
-
-const UInt16& ATADeviceInterface::GetMaster() {
- return this->fIO;
-}
-
-Void ATADeviceInterface::SetMaster(const UInt16& drv) {
- MUST_PASS(0xFFFF != drv);
- this->fMaster = drv;
-} \ No newline at end of file
diff --git a/dev/kernel/src/Storage/NVMEDeviceInterface.cc b/dev/kernel/src/Storage/NVMEDeviceInterface.cc
deleted file mode 100644
index f05d384e..00000000
--- a/dev/kernel/src/Storage/NVMEDeviceInterface.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <StorageKit/NVME.h>
-
-namespace Kernel {
-NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(DeviceInterface*, IMountpoint* outpacket),
- void (*in)(DeviceInterface*, IMountpoint* inpacket),
- void (*cleanup)(void))
- : DeviceInterface(out, in), fCleanup(cleanup) {}
-
-NVMEDeviceInterface::~NVMEDeviceInterface() {
- if (fCleanup) fCleanup();
-}
-
-const Char* NVMEDeviceInterface::Name() const {
- return ("/devices/nvme{}");
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Storage/SCSIDeviceInterface.cc b/dev/kernel/src/Storage/SCSIDeviceInterface.cc
deleted file mode 100644
index 2e331ae9..00000000
--- a/dev/kernel/src/Storage/SCSIDeviceInterface.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <StorageKit/SCSI.h>
-
-using namespace Kernel;
diff --git a/dev/kernel/src/Stream.cc b/dev/kernel/src/Stream.cc
deleted file mode 100644
index 8572e222..00000000
--- a/dev/kernel/src/Stream.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
- File: Stream.cc
- Purpose: Stream object
-
- Revision History:
-
-======================================== */
-
-#include <NeKit/Stream.h>
diff --git a/dev/kernel/src/Swap/DiskSwap.cc b/dev/kernel/src/Swap/DiskSwap.cc
deleted file mode 100644
index f0fa5915..00000000
--- a/dev/kernel/src/Swap/DiskSwap.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025 Amlal El Mahrouss , licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/FileMgr.h>
-#include <SwapKit/DiskSwap.h>
-
-namespace Kernel {
-static constexpr UInt32 kSwapDiskHeaderMagic = 0x44535750; // 'DSWP'
-
-/***********************************************************************************/
-/// @brief Write memory chunk onto disk.
-/// @param fork_name The swap name to recognize this memory region.
-/// @param fork_name_len length of fork name.
-/// @param data the data packet.
-/// @return Whether the swap was written to disk, or not.
-/***********************************************************************************/
-BOOL DiskSwapInterface::Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data) {
- if (!fork_name || !fork_name_len) return NO;
-
- if (*fork_name == 0) return NO;
-
- if (!data || data->fMagic != kSwapDiskHeaderMagic) return NO;
-
- FileStream file(kSwapPageFilePath, kRestrictWRB);
-
- ErrorOr<Int64> ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz);
-
- if (ret.Error()) return NO;
-
- return YES;
-}
-
-/***********************************************************************************/
-/// @brief Read memory chunk from disk.
-/// @param fork_name The swap name to recognize this memory region.
-/// @param fork_name_len length of fork name.
-/// @param data the data packet length.
-/// @return Whether the swap was fetched to disk, or not.
-/***********************************************************************************/
-SWAP_DISK_HEADER* DiskSwapInterface::Read(const Char* fork_name, SizeT fork_name_len,
- SizeT data_len) {
- if (!fork_name || !fork_name_len) return nullptr;
-
- if (*fork_name == 0) return nullptr;
-
- if (data_len > kSwapBlockMaxSize) return nullptr;
-
- if (data_len == 0) return nullptr;
-
- FileStream file(kSwapPageFilePath, kRestrictRB);
-
- VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len);
-
- if (!blob || ((SWAP_DISK_HEADER*) blob)->fMagic != kSwapDiskHeaderMagic) {
- if (blob) mm_free_ptr(blob);
- return nullptr;
- }
-
- return reinterpret_cast<SWAP_DISK_HEADER*>(blob);
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/ThreadLocalStorage.cc b/dev/kernel/src/ThreadLocalStorage.cc
deleted file mode 100644
index fa445d84..00000000
--- a/dev/kernel/src/ThreadLocalStorage.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ========================================================
- *
- * NeKernel
- * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
- *
- * ========================================================
- */
-
-#include <CFKit/Property.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/ThreadLocalStorage.h>
-#include <NeKit/KString.h>
-
-/***********************************************************************************/
-/// @bugs: 0
-/// @file ThreadLocalStorage.cc
-/// @brief NeKernel Thread Local Storage.
-///! @author Amlal El Mahrouss (amlal@nekernel.org)
-/***********************************************************************************/
-
-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) return false;
-
- return tib_ptr->Cookie[kCookieMag0Idx] == kCookieMag0 &&
- tib_ptr->Cookie[kCookieMag1Idx] == kCookieMag1 &&
- tib_ptr->Cookie[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) {
- kout << "TLS: Failed because of an invalid TIB...\r";
- return No;
- }
-
- THREAD_INFORMATION_BLOCK* tib = reinterpret_cast<THREAD_INFORMATION_BLOCK*>(tib_ptr);
-
- return tls_check_tib(tib);
-}
diff --git a/dev/kernel/src/Timer.cc b/dev/kernel/src/Timer.cc
deleted file mode 100644
index 648cc92b..00000000
--- a/dev/kernel/src/Timer.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/Timer.h>
-
-///! BUGS: 0
-///! @file Timer.cc
-///! @brief Software Timer implementation
-///! @author Amlal El Mahrouss (amlal@nekernel.org)
-
-using namespace Kernel;
-
-/// @brief Unimplemented as it is an interface.
-BOOL TimerInterface::Wait() noexcept {
- return NO;
-}
diff --git a/dev/kernel/src/UserMgr.cc b/dev/kernel/src/UserMgr.cc
deleted file mode 100644
index 103e8ec9..00000000
--- a/dev/kernel/src/UserMgr.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * ========================================================
- *
- * NeKernel
- * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
- *
- * File: UserMgr.cc
- * Purpose: User Manager, used to provide authentication and security.
- *
- * ========================================================
- */
-
-#include <KernelKit/FileMgr.h>
-#include <KernelKit/HeapMgr.h>
-#include <KernelKit/KPC.h>
-#include <KernelKit/ThreadLocalStorage.h>
-#include <KernelKit/UserMgr.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/Utils.h>
-
-#define kStdUserType (0xEE)
-#define kSuperUserType (0xEF)
-
-/// @file UserMgr.cc
-/// @brief Multi-user support.
-
-namespace Kernel {
-namespace Detail {
- ////////////////////////////////////////////////////////////
- /// \brief Constructs a password by hashing the password.
- /// \param password password to hash.
- /// \return the hashed password
- ////////////////////////////////////////////////////////////
- STATIC UInt64 user_fnv_generator(const Char* password, User* user) {
- if (!password || !user) return 0;
- if (*password == 0) return 0;
-
- kout << "user_fnv_generator: Hashing user password...\r";
-
- const UInt64 kFnvOffsetBasis = 0xcbf29ce484222325ULL;
- const UInt64 fFnvPrime = 0x100000001b3ULL;
-
- UInt64 hash = kFnvOffsetBasis;
-
- while (*password) {
- hash ^= (Char) (*password++);
- hash *= fFnvPrime;
- }
-
- kout << "user_fnv_generator: Hashed user password.\r";
-
- return hash;
- }
-} // namespace Detail
-
-////////////////////////////////////////////////////////////
-/// @brief User ring constructor.
-////////////////////////////////////////////////////////////
-User::User(const Int32& sel, const Char* user_name) : mUserRing((UserRingKind) sel) {
- MUST_PASS(sel >= 0);
- rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name),
- kMaxUserNameLen);
-}
-
-////////////////////////////////////////////////////////////
-/// @brief User ring constructor.
-////////////////////////////////////////////////////////////
-User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) {
- rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name),
- kMaxUserNameLen);
-}
-
-////////////////////////////////////////////////////////////
-/// @brief User destructor class.
-////////////////////////////////////////////////////////////
-User::~User() = default;
-
-Bool User::Save(const UserPublicKey password) noexcept {
- if (!password || *password == 0) return No;
-
- this->mUserFNV = Detail::user_fnv_generator(password, this);
-
- kout << "User::Save: Saved password successfully...\r";
-
- return Yes;
-}
-
-Bool User::Login(const UserPublicKey password) noexcept {
- if (!password || !*password) return No;
-
- auto ret = this->mUserFNV == Detail::user_fnv_generator(password, this);
-
- // now check if the password matches.
- kout << (ret ? "User::Login: Password matches.\r" : "User::Login: Password doesn't match.\r");
- return ret;
-}
-
-Bool User::operator==(const User& lhs) {
- return lhs.mUserRing == this->mUserRing;
-}
-
-Bool User::operator!=(const User& lhs) {
- return lhs.mUserRing != this->mUserRing;
-}
-
-////////////////////////////////////////////////////////////
-/// @brief Returns the user's name.
-////////////////////////////////////////////////////////////
-
-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
deleted file mode 100644
index 264bddf3..00000000
--- a/dev/kernel/src/UserProcessScheduler.cc
+++ /dev/null
@@ -1,690 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
- FILE: UserProcessScheduler.cc
- PURPOSE: Low-Privilege/Ring-3 process scheduler.
-
-======================================== */
-
-/***********************************************************************************/
-/// @file UserProcessScheduler.cc
-/// @brief Unprivileged/Ring-3 process scheduler.
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/***********************************************************************************/
-
-#include <ArchKit/ArchKit.h>
-#include <KernelKit/HardwareThreadScheduler.h>
-#include <KernelKit/HeapMgr.h>
-#include <KernelKit/IPEFDylibObject.h>
-#include <KernelKit/KPC.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <NeKit/KString.h>
-#include <NeKit/Utils.h>
-#include <SignalKit/Signals.h>
-
-///! BUGS: 0
-
-namespace Kernel {
-USER_PROCESS::USER_PROCESS() = default;
-USER_PROCESS::~USER_PROCESS() = default;
-
-/// @brief Gets the last exit code.
-/// @note Not thread-safe.
-/// @return Int32 the last exit code.
-
-/***********************************************************************************/
-/// @brief Crashes the current process.
-/***********************************************************************************/
-
-Void USER_PROCESS::Crash() {
- if (this->Status != ProcessStatusKind::kRunning) return;
-
- this->Status = ProcessStatusKind::kKilled;
-
- (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl);
-}
-
-/***********************************************************************************/
-/// @brief boolean operator, check status.
-/***********************************************************************************/
-
-USER_PROCESS::operator bool() {
- return this->Status == ProcessStatusKind::kRunning;
-}
-
-/***********************************************************************************/
-/// @brief Gets the local last exit code.
-/// @note Not thread-safe.
-/// @return Int32 the last exit code.
-/***********************************************************************************/
-
-KPCError& USER_PROCESS::GetExitCode() noexcept {
- return this->LastExitCode;
-}
-
-/***********************************************************************************/
-/// @brief Error code variable getter.
-/***********************************************************************************/
-
-KPCError& USER_PROCESS::GetLocalCode() noexcept {
- return this->LocalCode;
-}
-
-/***********************************************************************************/
-/// @brief Wakes process header.
-/// @param should_wakeup if the program shall wakeup or not.
-/***********************************************************************************/
-
-Void USER_PROCESS::Wake(Bool should_wakeup) {
- this->Status = should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen;
-}
-
-/***********************************************************************************/
-/** @brief Allocate pointer to heap tree. */
-/** @param tree The tree to calibrate */
-/***********************************************************************************/
-
-template <typename T>
-STATIC T* sched_try_go_upper_ptr_tree(T* tree) {
- if (!tree) {
- return nullptr;
- }
-
- tree = tree->Parent;
-
- if (tree) {
- auto tree_tmp = tree->Next;
-
- if (!tree_tmp) {
- return tree;
- }
-
- return tree_tmp;
- }
-
- return tree;
-}
-
-/***********************************************************************************/
-/** @brief Allocate pointer to heap/file tree. */
-/***********************************************************************************/
-
-ErrorOr<VoidPtr> USER_PROCESS::New(SizeT sz, SizeT pad_amount) {
- if (this->UsedMemory > kSchedMaxMemoryLimit) return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
-
-#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- auto vm_register = kKernelVM;
-
- hal_write_cr3(this->VMRegister);
-
- auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount);
-
- hal_write_cr3(vm_register);
-#else
- auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount);
-#endif
-
- if (!this->HeapTree) {
- this->HeapTree = new PROCESS_HEAP_TREE<VoidPtr>();
-
- if (!this->HeapTree) {
- this->Crash();
- return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
- }
-
- this->HeapTree->EntryPad = pad_amount;
- this->HeapTree->EntrySize = sz;
-
- this->HeapTree->Entry = ptr;
-
- this->HeapTree->Color = kBlackTreeKind;
-
- this->HeapTree->Prev = nullptr;
- this->HeapTree->Next = nullptr;
- this->HeapTree->Parent = nullptr;
- this->HeapTree->Child = nullptr;
- } else {
- PROCESS_HEAP_TREE<VoidPtr>* entry = this->HeapTree;
- PROCESS_HEAP_TREE<VoidPtr>* prev_entry = entry;
-
- BOOL is_parent = NO;
-
- while (entry) {
- if (entry->EntrySize < 1) break;
-
- prev_entry = entry;
-
- if (entry->Child && entry->Child->EntrySize > 0 && entry->Child->EntrySize == sz) {
- entry = entry->Child;
- is_parent = YES;
- } else if (entry->Next && entry->Next->EntrySize > 0 && entry->Next->EntrySize == sz) {
- is_parent = NO;
- entry = entry->Next;
- } else {
- entry = sched_try_go_upper_ptr_tree(entry);
- if (entry && entry->Color == kBlackTreeKind) break;
- }
- }
-
- auto new_entry = new PROCESS_HEAP_TREE<VoidPtr>();
-
- if (!new_entry) {
- this->Crash();
- return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
- }
-
- new_entry->Entry = ptr;
- new_entry->EntrySize = sz;
- new_entry->EntryPad = pad_amount;
- new_entry->Parent = entry;
- new_entry->Child = nullptr;
- new_entry->Next = nullptr;
- new_entry->Prev = nullptr;
-
- new_entry->Color = kBlackTreeKind;
- prev_entry->Color = kRedTreeKind;
-
- if (is_parent) {
- prev_entry->Child = new_entry;
- new_entry->Parent = prev_entry;
- } else {
- prev_entry->Next = new_entry;
- new_entry->Prev = prev_entry;
- }
- }
-
- this->UsedMemory += sz;
-
- return ErrorOr<VoidPtr>(ptr);
-}
-
-/***********************************************************************************/
-/// @brief Gets the name of the current process.
-/***********************************************************************************/
-
-const Char* USER_PROCESS::GetName() noexcept {
- return this->Name;
-}
-
-/***********************************************************************************/
-/// @brief Gets the owner of the process.
-/***********************************************************************************/
-
-const User* USER_PROCESS::GetOwner() noexcept {
- return this->Owner;
-}
-
-/// @brief USER_PROCESS status getter.
-const ProcessStatusKind& USER_PROCESS::GetStatus() noexcept {
- return this->Status;
-}
-
-/***********************************************************************************/
-/**
-@brief Affinity is the time slot allowed for the process.
-*/
-/***********************************************************************************/
-
-const AffinityKind& USER_PROCESS::GetAffinity() noexcept {
- return this->Affinity;
-}
-
-/***********************************************************************************/
-/** @brief Free heap tree. */
-/***********************************************************************************/
-
-template <typename T>
-STATIC Void sched_free_ptr_tree(T* tree) {
- // Deleting memory lists. Make sure to free all of them.
- while (tree) {
- if (tree->Entry) {
- MUST_PASS(mm_free_ptr(tree->Entry));
- }
-
- auto next = tree->Next;
-
- if (next->Child) sched_free_ptr_tree(next->Child);
-
- tree->Child = nullptr;
-
- mm_free_ptr(tree);
-
- tree = nullptr;
- tree = next;
- }
-}
-
-/***********************************************************************************/
-/**
-@brief Exit process method.
-@param exit_code The process's exit code.
-*/
-/***********************************************************************************/
-
-Void USER_PROCESS::Exit(const Int32& exit_code) {
- this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen;
- this->LastExitCode = exit_code;
-
-#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- auto pd = kKernelVM;
- hal_write_cr3(this->VMRegister);
-#endif
-
- sched_free_ptr_tree(this->HeapTree);
- this->HeapTree = nullptr;
-
- sched_free_ptr_tree(this->FileTree);
- this->FileTree = nullptr;
-
-#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- hal_write_cr3(pd);
-#endif
-
-#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- //! Free the memory's page directory.
- if (this->VMRegister) HAL::mm_free_bitmap(this->VMRegister);
-#endif
-
- //! Delete image if not done already.
- if (this->Image.fCode && mm_is_valid_ptr(this->Image.fCode)) mm_free_ptr(this->Image.fCode);
-
- //! Delete blob too.
- if (this->Image.fBlob && mm_is_valid_ptr(this->Image.fBlob)) mm_free_ptr(this->Image.fBlob);
-
- //! Delete stack frame.
- if (this->StackFrame && mm_is_valid_ptr(this->StackFrame))
- mm_free_ptr((VoidPtr) this->StackFrame);
-
- //! Avoid use after free.
- this->Image.fBlob = nullptr;
- this->Image.fCode = nullptr;
- this->StackFrame = nullptr;
-
- if (this->Kind == kExecutableDylibKind) {
- Bool success = false;
-
- rtl_fini_dylib_pef(*this, reinterpret_cast<IPEFDylibObject*>(this->DylibDelegate), &success);
-
- if (!success) {
- ke_panic(RUNTIME_CHECK_PROCESS);
- }
-
- this->DylibDelegate = nullptr;
- }
-
- this->ProcessId = 0UL;
- this->Status = ProcessStatusKind::kFinished;
-
- --this->ParentTeam->mProcessCur;
-}
-
-/***********************************************************************************/
-/// @brief Add dylib to the process object.
-/***********************************************************************************/
-
-Bool USER_PROCESS::InitDylib() {
- // React according to the process's kind.
- switch (this->Kind) {
- case USER_PROCESS::kExecutableDylibKind: {
- this->DylibDelegate = rtl_init_dylib_pef(*this);
-
- if (!this->DylibDelegate) {
- this->Crash();
- return NO;
- }
-
- return YES;
- }
- case USER_PROCESS::kExecutableKind: {
- return NO;
- }
- default: {
- break;
- }
- }
-
- (Void)(kout << "Unknown process kind: " << hex_number(this->Kind) << kendl);
- this->Crash();
-
- return NO;
-}
-
-/***********************************************************************************/
-/// @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) {
- if (!name || !code) {
- return -kErrorProcessFault;
- }
-
- if (*name == 0) {
- return -kErrorProcessFault;
- }
-
- ProcessID pid = this->mTeam.mProcessCur;
-
- if (pid > kSchedProcessLimitPerTeam) {
- return -kErrorProcessFault;
- }
-
- ++this->mTeam.mProcessCur;
-
- USER_PROCESS& process = this->mTeam.mProcessList[pid];
-
- process.Image.fCode = code;
- process.Image.fBlob = image;
-
- SizeT len = rt_string_len(name);
-
- if (len > kSchedNameLen) {
- return -kErrorProcessFault;
- }
-
- rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, len,
- kSchedNameLen);
-
-#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- process.VMRegister = kKernelVM;
-#else
- process.VMRegister = 0UL;
-#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
-
- process.StackFrame = new HAL::StackFrame();
-
- if (!process.StackFrame) {
- process.Crash();
- return -kErrorProcessFault;
- }
-
- rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame));
-
- process.StackFrame->IP = reinterpret_cast<UIntPtr>(code);
- process.StackFrame->SP = reinterpret_cast<UIntPtr>(&process.StackReserve[0] + process.StackSize);
-
-#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- HAL::mm_map_page((VoidPtr) process.StackFrame->IP,
- (VoidPtr) HAL::mm_get_page_addr((VoidPtr) process.StackFrame->IP),
- HAL::kMMFlagsUser | HAL::kMMFlagsPresent);
- HAL::mm_map_page((VoidPtr) process.StackFrame->SP,
- (VoidPtr) HAL::mm_get_page_addr((VoidPtr) process.StackFrame->SP),
- HAL::kMMFlagsUser | HAL::kMMFlagsPresent);
-#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
-
- process.StackSize = kSchedMaxStackSz;
-
- rt_set_memory(process.StackReserve, 0, process.StackSize);
-
- process.ParentTeam = &mTeam;
-
- process.ProcessId = pid;
- process.Status = ProcessStatusKind::kRunning;
- process.PTime = 0;
- process.UTime = 0;
- process.RTime = 0;
-
- if (!process.FileTree) {
- process.FileTree = new PROCESS_FILE_TREE<VoidPtr>();
-
- if (!process.FileTree) {
- process.Crash();
- return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
- }
-
- /// @todo File Tree allocation and dispose methods (amlal)
- }
-
- (Void)(kout << "ProcessID: " << number(process.ProcessId) << kendl);
- (Void)(kout << "ProcesName: " << process.Name << kendl);
-
- return pid;
-}
-
-/***********************************************************************************/
-/// @brief Retrieves the singleton of the process scheduler.
-/***********************************************************************************/
-
-UserProcessScheduler& UserProcessScheduler::The() {
- STATIC UserProcessScheduler kScheduler;
- return kScheduler;
-}
-
-/***********************************************************************************/
-
-/// @brief Remove process from the team.
-/// @param process_id process slot inside team.
-/// @retval true process was removed.
-/// @retval false process doesn't exist in team.
-
-/***********************************************************************************/
-
-Void UserProcessScheduler::Remove(ProcessID process_id) {
- if (process_id < 0 || process_id > kSchedProcessLimitPerTeam) return;
- if (this->mTeam.mProcessList[process_id].Status == ProcessStatusKind::kInvalid) return;
-
- mTeam.mProcessList[process_id].Exit(kErrorSuccess);
-}
-
-/// @brief Is it a user scheduler?
-
-Bool UserProcessScheduler::IsUser() {
- return Yes;
-}
-
-/// @brief Is it a kernel scheduler?
-
-Bool UserProcessScheduler::IsKernel() {
- return No;
-}
-
-/// @brief Is it a SMP scheduler?
-
-Bool UserProcessScheduler::HasMP() {
- MUST_PASS(kHandoverHeader);
- return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled;
-}
-
-/***********************************************************************************/
-/// @brief Run User scheduler object.
-/// @return USER_PROCESS count executed within a team.
-/***********************************************************************************/
-
-SizeT UserProcessScheduler::Run() noexcept {
- if (mTeam.mProcessCur < 1) {
- return 0UL;
- }
-
- SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many
- //! things we have scheduled.
-
- 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)) {
- kout << process.Name << " will be run...\r";
-
- //! Increase the usage time of the process.
- if (process.UTime < process.PTime) {
- ++process.UTime;
- }
-
- this->TheCurrentProcess() = process;
-
- if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) {
- process.PTime = static_cast<Int32>(process.Affinity);
-
- // We add a bigger cooldown according to the RTime and affinity here.
- if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) {
- if (process.RTime < (Int32) AffinityKind::kVeryHigh)
- process.RTime += (Int32) AffinityKind::kLowUsage;
- else if (process.RTime < (Int32) AffinityKind::kHigh)
- process.RTime += (Int32) AffinityKind::kStandard;
- else if (process.RTime < (Int32) AffinityKind::kStandard)
- process.RTime += (Int32) AffinityKind::kHigh;
-
- process.PTime -= process.RTime;
- process.RTime = 0UL;
- }
- }
- } else {
- ++process.RTime;
- --process.PTime;
- }
- }
-
- return process_index;
-}
-
-/// @brief Gets the current scheduled team.
-/// @return
-UserProcessTeam& UserProcessScheduler::TheCurrentTeam() {
- return mTeam;
-}
-
-/***********************************************************************************/
-/// @brief Switches the current team.
-/// @param team the new team to switch to.
-/// @retval true team was switched.
-/// @retval false team was not switched.
-/***********************************************************************************/
-
-BOOL UserProcessScheduler::SwitchTeam(UserProcessTeam& team) {
- if (team.AsArray().Count() < 1) return No;
-
- this->mTeam = team;
-
- return Yes;
-}
-
-/// @brief Gets current running process.
-/// @return
-Ref<USER_PROCESS>& UserProcessScheduler::TheCurrentProcess() {
- return mTeam.AsRef();
-}
-
-/// @brief Current proccess id getter.
-/// @return USER_PROCESS ID integer.
-ErrorOr<ProcessID> UserProcessHelper::TheCurrentPID() {
- if (!UserProcessScheduler::The().TheCurrentProcess())
- return ErrorOr<ProcessID>{-kErrorProcessFault};
-
- kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r";
- return ErrorOr<ProcessID>{UserProcessScheduler::The().TheCurrentProcess().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 USER_PROCESS& process) {
- if (process.Affinity == AffinityKind::kRealTime) return Yes;
-
- if (process.Status != ProcessStatusKind::kRunning) return No;
- if (process.Affinity == AffinityKind::kInvalid) return No;
- if (process.StackSize > kSchedMaxStackSz) return No;
- if (!process.Name[0]) return No;
- if (process.Signal.SignalID == sig_generate_unique<SIGTRAP>()) return No;
-
- return process.PTime < 1;
-}
-
-/***********************************************************************************/
-/**
- * @brief Start scheduling the current team.
- */
-/***********************************************************************************/
-
-SizeT UserProcessHelper::StartScheduling() {
- return UserProcessScheduler::The().Run();
-}
-
-/***********************************************************************************/
-/**
- * \brief Does a context switch in a CPU.
- * \param the_stack the stackframe of the running app.
- * \param new_pid the process's ProcessID.
- */
-/***********************************************************************************/
-
-Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid) {
- (Void)(kout << "IP: " << hex_number(frame_ptr->IP) << kendl);
-
- for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) {
- if (!HardwareThreadScheduler::The()[index].Leak()) continue;
-
- if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid ||
- HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot)
- continue;
-
- (Void)(kout << "AP_" << hex_number(index) << kendl);
-
- if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) {
- (Void)(kout << "AP_" << hex_number(index));
- kout << " is busy\r";
-
- continue;
- }
-
- (Void)(kout << "AP_" << hex_number(index));
- kout << " is now trying to run a new task!\r";
-
- ////////////////////////////////////////////////////////////
- /// Prepare task switch. ///
- ////////////////////////////////////////////////////////////
-
- HardwareThreadScheduler::The()[index].Leak()->Busy(YES);
-
- Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr);
-
- ////////////////////////////////////////////////////////////
- /// Rollback on fail. ///
- ////////////////////////////////////////////////////////////
-
- if (!ret) continue;
-
- UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid;
-
- HardwareThreadScheduler::The()[index].Leak()->fPTime =
- UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime;
-
- (Void)(kout << "AP_" << hex_number(index));
- kout << " is now running a new task!\r";
-
- return YES;
- }
-
- kout << "Couldn't find a suitable core for the current process!\r";
-
- return NO;
-}
-
-////////////////////////////////////////////////////////////
-/// @brief this checks if any process is on the team.
-////////////////////////////////////////////////////////////
-UserProcessScheduler::operator bool() {
- for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) {
- auto& process = mTeam.AsArray()[process_index];
- if (UserProcessHelper::CanBeScheduled(process)) return true;
- }
-
- return false;
-}
-
-////////////////////////////////////////////////////////////
-/// @brief this checks if no process is on the team.
-////////////////////////////////////////////////////////////
-Bool UserProcessScheduler::operator!() {
- SInt64 cnt = 0UL;
-
- for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) {
- auto& process = mTeam.AsArray()[process_index];
- if (UserProcessHelper::CanBeScheduled(process)) ++cnt;
- }
-
- return cnt == 0L;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/UserProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc
deleted file mode 100644
index e5b7a7eb..00000000
--- a/dev/kernel/src/UserProcessTeam.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-/***********************************************************************************/
-/// @file UserProcessTeam.cc
-/// @brief Process teams implementation.
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/***********************************************************************************/
-
-#include <KernelKit/UserProcessScheduler.h>
-
-namespace Kernel {
-UserProcessTeam::UserProcessTeam() {
- for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) {
- this->mProcessList[i] = USER_PROCESS();
- this->mProcessList[i].PTime = 0;
- this->mProcessList[i].RTime = 0;
- this->mProcessList[i].UTime = 0;
- this->mProcessList[i].Status = ProcessStatusKind::kKilled;
- this->mProcessList[i].ParentTeam = this;
- }
-
- this->mProcessCur = 0UL;
-}
-
-/***********************************************************************************/
-/// @brief Process list array getter.
-/// @return The list of process to schedule.
-/***********************************************************************************/
-
-Array<USER_PROCESS, 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<USER_PROCESS>& UserProcessTeam::AsRef() {
- return this->mCurrentProcess;
-}
-} // namespace Kernel
-
-// last rev 05-03-24
diff --git a/dev/kernel/src/UtfUtils.cc b/dev/kernel/src/UtfUtils.cc
deleted file mode 100644
index 47ac2729..00000000
--- a/dev/kernel/src/UtfUtils.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ========================================
-
- Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Utils.h>
-
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-
-namespace Kernel {
-Size urt_string_len(const Utf8Char* str) {
- if (!str) return 0;
-
- SizeT len{0};
-
- while (str[len] != u8'\0') ++len;
-
- return len;
-}
-
-Void urt_set_memory(const voidPtr src, UInt32 dst, Size len) {
- if (!src) return;
-
- Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src);
- Size index = 0;
-
- while (index < len) {
- srcChr[index] = dst;
- ++index;
- }
-}
-
-Int32 urt_string_cmp(const Utf8Char* src, const Utf8Char* cmp, Size size) {
- if (!src) return 0;
-
- Int32 counter = 0;
-
- for (Size index = 0; index < size; ++index) {
- if (src[index] != cmp[index]) ++counter;
- }
-
- return counter;
-}
-
-Int32 urt_copy_memory(const VoidPtr src, VoidPtr dst, Size len) {
- if (!src) return 0;
- if (!dst) return 0;
-
- Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src);
- Utf8Char* dstChar = reinterpret_cast<Utf8Char*>(dst);
-
- Size index = 0;
-
- while (index < len) {
- dstChar[index] = srcChr[index];
- ++index;
- }
-
- return index;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/Variant.cc b/dev/kernel/src/Variant.cc
deleted file mode 100644
index fcf2f443..00000000
--- a/dev/kernel/src/Variant.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <NeKit/Variant.h>
-
-namespace Kernel {
-const Char* Variant::ToString() {
- switch (fKind) {
- case VariantKind::kTOML:
- return ("Class:{TOML}");
- case VariantKind::kJson:
- return ("Class:{Json}");
- case VariantKind::kString:
- return ("Class:{String}");
- case VariantKind::kBlob:
- return ("Class:{Blob}");
- case VariantKind::kNull:
- return ("Class:{Null}");
- case VariantKind::kSwap:
- return ("Class:{Swap}");
- default:
- return ("Class:{Unknown}");
- }
-}
-
-/// @brief Return variant's kind.
-Variant::VariantKind& Variant::Kind() {
- return this->fKind;
-}
-
-/// @brief Leak variant's instance.
-VoidPtr Variant::Leak() {
- return this->fPtr;
-}
-} // namespace Kernel
diff --git a/dev/kernel/src/ZXD.cc b/dev/kernel/src/ZXD.cc
deleted file mode 100644
index 1baa18f3..00000000
--- a/dev/kernel/src/ZXD.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-/* ========================================
-
- Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <KernelKit/ZXD.h>