summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel/src')
-rw-r--r--dev/kernel/src/ACPIFactoryInterface.cc172
-rw-r--r--dev/kernel/src/Array.cc2
-rw-r--r--dev/kernel/src/ArrayList.cc2
-rw-r--r--dev/kernel/src/Atom.cc2
-rw-r--r--dev/kernel/src/BinaryMutex.cc126
-rw-r--r--dev/kernel/src/BitMapMgr.cc356
-rw-r--r--dev/kernel/src/CodeMgr.cc33
-rw-r--r--dev/kernel/src/Crc32.cc106
-rw-r--r--dev/kernel/src/CxxAbi-AMD64.cc111
-rw-r--r--dev/kernel/src/CxxAbi-ARM64.cc127
-rw-r--r--dev/kernel/src/Defines.cc2
-rw-r--r--dev/kernel/src/DeviceMgr.cc2
-rw-r--r--dev/kernel/src/DriveMgr+IO.cc127
-rw-r--r--dev/kernel/src/DriveMgr.cc332
-rw-r--r--dev/kernel/src/ErrorOr.cc2
-rw-r--r--dev/kernel/src/FS/Ext2+FileMgr.cc6
-rw-r--r--dev/kernel/src/FS/Ext2.cc17
-rw-r--r--dev/kernel/src/FS/HeFS+FileMgr.cc6
-rw-r--r--dev/kernel/src/FS/HeFS.cc1146
-rw-r--r--dev/kernel/src/FS/NeFS+FileMgr.cc423
-rw-r--r--dev/kernel/src/FS/NeFS.cc1267
-rw-r--r--dev/kernel/src/FileMgr.cc76
-rw-r--r--dev/kernel/src/GUIDWizard.cc107
-rw-r--r--dev/kernel/src/GUIDWrapper.cc6
-rw-r--r--dev/kernel/src/Gfx/FBDeviceInterface.cc44
-rw-r--r--dev/kernel/src/HardwareThreadScheduler.cc401
-rw-r--r--dev/kernel/src/IDylibObject.cc2
-rw-r--r--dev/kernel/src/IPEFDylibObject.cc93
-rw-r--r--dev/kernel/src/IndexableProperty.cc76
-rw-r--r--dev/kernel/src/Json.cc4
-rw-r--r--dev/kernel/src/KPC.cc50
-rw-r--r--dev/kernel/src/KString.cc376
-rw-r--r--dev/kernel/src/KernelProcessScheduler.cc10
-rw-r--r--dev/kernel/src/LockDelegate.cc9
-rw-r--r--dev/kernel/src/MemoryMgr.cc462
-rw-r--r--dev/kernel/src/MutableArray.cc2
-rw-r--r--dev/kernel/src/Network/IPAddr.cc213
-rw-r--r--dev/kernel/src/Network/IPCAddr.cc35
-rw-r--r--dev/kernel/src/Network/IPCMsg.cc215
-rw-r--r--dev/kernel/src/Network/MACAddressGetter.cc14
-rw-r--r--dev/kernel/src/Network/NetworkDevice.cc49
-rw-r--r--dev/kernel/src/New+Delete.cc54
-rw-r--r--dev/kernel/src/OwnPtr.cc2
-rw-r--r--dev/kernel/src/PEFCodeMgr.cc476
-rw-r--r--dev/kernel/src/PRDT.cc28
-rw-r--r--dev/kernel/src/PageMgr.cc181
-rw-r--r--dev/kernel/src/Pmm.cc115
-rw-r--r--dev/kernel/src/ProcessTeam.cc59
-rw-r--r--dev/kernel/src/Property.cc72
-rw-r--r--dev/kernel/src/Ref.cc2
-rw-r--r--dev/kernel/src/SoftwareTimer.cc34
-rw-r--r--dev/kernel/src/Storage/AHCIDeviceInterface.cc119
-rw-r--r--dev/kernel/src/Storage/ATADeviceInterface.cc130
-rw-r--r--dev/kernel/src/Storage/NVMEDeviceInterface.cc33
-rw-r--r--dev/kernel/src/Storage/SCSIDeviceInterface.cc6
-rw-r--r--dev/kernel/src/Stream.cc8
-rw-r--r--dev/kernel/src/Swap/DiskSwap.cc84
-rw-r--r--dev/kernel/src/ThreadLocalStorage.cc48
-rw-r--r--dev/kernel/src/Timer.cc7
-rw-r--r--dev/kernel/src/User.cc271
-rw-r--r--dev/kernel/src/UserProcessScheduler.cc1138
-rw-r--r--dev/kernel/src/UserProcessTeam.cc53
-rw-r--r--dev/kernel/src/UtfUtils.cc31
-rw-r--r--dev/kernel/src/Utils.cc349
-rw-r--r--dev/kernel/src/Variant.cc63
65 files changed, 5266 insertions, 4708 deletions
diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc
index b85d6ab3..a76caff2 100644
--- a/dev/kernel/src/ACPIFactoryInterface.cc
+++ b/dev/kernel/src/ACPIFactoryInterface.cc
@@ -1,101 +1,87 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#include <modules/ACPI/ACPIFactoryInterface.h>
-#include <NewKit/KString.h>
#include <ArchKit/ArchKit.h>
#include <KernelKit/MemoryMgr.h>
+#include <NewKit/KString.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+
+namespace Kernel {
+/// @brief Finds a descriptor table inside ACPI XSDT.
+ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) {
+ MUST_PASS(this->fRsdp);
+
+ if (!signature) return ErrorOr<voidPtr>{-1};
+
+ if (*signature == 0) return ErrorOr<voidPtr>{-1};
+
+ RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp);
+
+ if (rsp_ptr->Revision <= 1) return ErrorOr<voidPtr>{-1};
+
+ RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress);
+
+ Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64);
+
+ /***
+ crucial to avoid underflows.
+ */
+ if (num < 1) {
+ /// stop here, we should have entries...
+ ke_panic(RUNTIME_CHECK_ACPI);
+ return ErrorOr<voidPtr>{-1};
+ }
+
+ this->fEntries = num;
+
+ (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);
+
+ const short cAcpiSignatureLength = 4;
+
+ 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 (short 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>{-1};
+}
+
+/***
+@brief Checksum on SDT header.
+@param checksum the header to checksum
+@param len the length of it.
+*/
+bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) {
+ if (len == 0) return 1;
+
+ char chr = 0;
+
+ for (int index = 0; index < len; ++index) {
+ chr += checksum[index];
+ }
+
+ return chr == 0;
+}
-namespace Kernel
-{
- /// @brief Finds a descriptor table inside ACPI XSDT.
- ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature)
- {
- MUST_PASS(this->fRsdp);
-
- if (!signature)
- return ErrorOr<voidPtr>{-1};
-
- if (*signature == 0)
- return ErrorOr<voidPtr>{-1};
-
- RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp);
-
- if (rsp_ptr->Revision <= 1)
- return ErrorOr<voidPtr>{-1};
-
- RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress);
-
- Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64);
-
- /***
- crucial to avoid underflows.
- */
- if (num < 1)
- {
- /// stop here, we should have entries...
- ke_panic(RUNTIME_CHECK_ACPI);
- return ErrorOr<voidPtr>{-1};
- }
-
- this->fEntries = num;
-
- (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);
-
- const short cAcpiSignatureLength = 4;
-
- 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 (short 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>{-1};
- }
-
- /***
- @brief Checksum on SDT header.
- @param checksum the header to checksum
- @param len the length of it.
- */
- bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len)
- {
- if (len == 0)
- return 1;
-
- char chr = 0;
-
- for (int index = 0; index < len; ++index)
- {
- chr += checksum[index];
- }
-
- return chr == 0;
- }
-
- ErrorOr<voidPtr> ACPIFactoryInterface::operator[](const Char* signature)
- {
- return this->Find(signature);
- }
-} // namespace Kernel
+ErrorOr<voidPtr> ACPIFactoryInterface::operator[](const Char* signature) {
+ return this->Find(signature);
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/Array.cc b/dev/kernel/src/Array.cc
index 334231f0..7cb1b156 100644
--- a/dev/kernel/src/Array.cc
+++ b/dev/kernel/src/Array.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/ArrayList.cc b/dev/kernel/src/ArrayList.cc
index ee9dab93..269dc47e 100644
--- a/dev/kernel/src/ArrayList.cc
+++ b/dev/kernel/src/ArrayList.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/Atom.cc b/dev/kernel/src/Atom.cc
index bbeebd45..8968a2c2 100644
--- a/dev/kernel/src/Atom.cc
+++ b/dev/kernel/src/Atom.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc
index 1ed08fa9..8bf1432e 100644
--- a/dev/kernel/src/BinaryMutex.cc
+++ b/dev/kernel/src/BinaryMutex.cc
@@ -1,74 +1,66 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#include <KernelKit/ProcessScheduler.h>
#include <KernelKit/BinaryMutex.h>
+#include <KernelKit/ProcessScheduler.h>
+
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Unlocks the binary mutex.
+/***********************************************************************************/
+Bool BinaryMutex::Unlock() noexcept {
+ if (fLockingProcess) {
+ fLockingProcess = USER_PROCESS();
+ fLockingProcess.Status = ProcessStatusKind::kFrozen;
+
+ 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::LockOrWait(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 Int16& sec) noexcept {
+ HardwareTimer hw_timer(rtl_milliseconds(sec));
+ hw_timer.Wait();
-namespace Kernel
-{
- /***********************************************************************************/
- /// @brief Unlocks the semaphore.
- /***********************************************************************************/
- Bool BinaryMutex::Unlock() noexcept
- {
- if (fLockingProcess)
- {
- fLockingProcess = Process();
- fLockingProcess.Status = ProcessStatusKind::kFrozen;
- return Yes;
- }
-
- return No;
- }
-
- /***********************************************************************************/
- /// @brief Locks process in the semaphore.
- /***********************************************************************************/
- Bool BinaryMutex::Lock(Process& process)
- {
- if (!process || fLockingProcess)
- return No;
-
- fLockingProcess = process;
-
- return Yes;
- }
-
- /***********************************************************************************/
- /// @brief Checks if process is locked.
- /***********************************************************************************/
- Bool BinaryMutex::IsLocked() const
- {
- return fLockingProcess.Status == ProcessStatusKind::kRunning;
- }
-
- /***********************************************************************************/
- /// @brief Try lock or wait.
- /***********************************************************************************/
- Bool BinaryMutex::LockOrWait(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 Int16& sec) noexcept
- {
- HardwareTimer hw_timer(rtl_seconds(sec));
- hw_timer.Wait();
-
- return !this->IsLocked();
- }
-} // namespace Kernel
+ return !this->IsLocked();
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc
index 96cbb803..7cbcf376 100644
--- a/dev/kernel/src/BitMapMgr.cc
+++ b/dev/kernel/src/BitMapMgr.cc
@@ -1,219 +1,191 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#include <ArchKit/ArchKit.h>
-
#ifdef __NE_AMD64__
#include <HALKit/AMD64/Paging.h>
#elif defined(__NE_ARM64__)
#include <HALKit/ARM64/Paging.h>
#endif
-#include <NewKit/Defines.h>
+#include <ArchKit/ArchKit.h>
#include <NewKit/KernelPanic.h>
-#define kBitMapMagic (0x10210U)
-#define kBitMapPadSize (mib_cast(16))
+#define kBitMapMagic (0x10210U)
-#define kBitMapMagIdx (0U)
+#define kBitMapMagIdx (0U)
#define kBitMapSizeIdx (1U)
#define kBitMapUsedIdx (2U)
-namespace Kernel
-{
- namespace HAL
- {
- namespace Detail
- {
- /***********************************************************************************/
- /// \brief Proxy Interface to manage a bitmap allocator.
- /***********************************************************************************/
- class IBitMapProxy final
- {
- public:
- explicit IBitMapProxy() = default;
- ~IBitMapProxy() = default;
+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);
+
+ 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;
- NE_COPY_DELETE(IBitMapProxy)
+ if (wr) flags |= kMMFlagsWr;
- auto IsBitMap(VoidPtr page_ptr) -> Bool
- {
- if (!page_ptr)
- return No;
+ if (user) flags |= kMMFlagsUser;
- UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+ return flags;
+ }
- if (!ptr_bit_set[kBitMapMagIdx] ||
- ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
- return No;
+ /***********************************************************************************/
+ /// @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;
- return Yes;
- }
+ VoidPtr base = reinterpret_cast<VoidPtr>((UIntPtr) base_ptr);
- auto FreeBitMap(VoidPtr page_ptr) -> Bool
- {
- if (this->IsBitMap(page_ptr) == No)
- return No;
+ MUST_PASS(base);
- UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+ static SizeT biggest = 0UL;
- ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
- ptr_bit_set[kBitMapUsedIdx] = No;
+ while (YES) {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
- this->GetBitMapStatus(ptr_bit_set);
-
- return Yes;
- }
+ 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;
- UInt32 MakeMMFlags(Bool wr, Bool user)
- {
- UInt32 flags = kMMFlagsPresent;
-
- if (wr)
- flags |= kMMFlagsWr;
-
- if (user)
- flags |= kMMFlagsUser;
-
- flags |= HAL::kMMFlagsPCD;
-
- 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;
-
- VoidPtr base = reinterpret_cast<VoidPtr>((UIntPtr)base_ptr);
-
- MUST_PASS(base);
-
- 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, ptr_bit_set, flags);
-
- if (biggest < (size + pad))
- biggest = 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, ptr_bit_set, flags);
-
- if (biggest < (size + pad))
- biggest = (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
-
- auto mm_is_bitmap(VoidPtr ptr) -> BOOL
- {
- Detail::IBitMapProxy bitmp;
- return bitmp.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;
- Detail::IBitMapProxy bitmp;
-
- NE_UNUSED(is_page);
-
- ptr_new = bitmp.FindBitMap(kKernelBitMpStart, size, wr, user, pad);
- return (UIntPtr*)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;
-
- Detail::IBitMapProxy bitmp;
- Bool ret = bitmp.FreeBitMap(ptr);
-
- return ret;
- }
- } // namespace HAL
-} // namespace Kernel
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeMMFlags(wr, user);
+ mm_map_page(ptr_bit_set, ptr_bit_set, flags);
+
+ if (biggest < (size + pad)) biggest = 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, ptr_bit_set, flags);
+
+ if (biggest < (size + pad)) biggest = (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;
+ }
+
+#ifdef __NE_VERBOSE_BITMAP__
+ (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);
+#endif
+ }
+ };
+ } // namespace Detail
+
+ auto mm_is_bitmap(VoidPtr ptr) -> BOOL {
+ Detail::IBitMapProxy bitmp;
+ return bitmp.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;
+ Detail::IBitMapProxy bitmp;
+
+ NE_UNUSED(is_page);
+
+ ptr_new = bitmp.FindBitMap(kKernelBitMpStart, size, wr, user, pad);
+ return (UIntPtr*) 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;
+
+ Detail::IBitMapProxy bitmp;
+ Bool ret = bitmp.FreeBitMap(ptr);
+
+ return ret;
+ }
+} // namespace HAL
+} // namespace Kernel
diff --git a/dev/kernel/src/CodeMgr.cc b/dev/kernel/src/CodeMgr.cc
index 3604df30..c4ac011c 100644
--- a/dev/kernel/src/CodeMgr.cc
+++ b/dev/kernel/src/CodeMgr.cc
@@ -1,28 +1,25 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <KernelKit/CodeMgr.h>
-#include <NewKit/Utils.h>
#include <KernelKit/ProcessScheduler.h>
+#include <NewKit/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 if the process was started or not.
- /***********************************************************************************/
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Executes a new process from a function. Kernel code only.
+/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be
+/// accessible.
+/// @param main the start of the process.
+/// @return if the process was started or not.
+/***********************************************************************************/
- ProcessID rtl_create_user_process(rtl_main_kind main, const Char* process_name) noexcept
- {
- if (!process_name ||
- *process_name == 0)
- return kSchedInvalidPID;
+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
+ 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
index cd22a762..332faa33 100644
--- a/dev/kernel/src/Crc32.cc
+++ b/dev/kernel/src/Crc32.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -9,57 +9,53 @@
// @file CRC32.cpp
// @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 Char* in, Int32 len) noexcept
- {
- if (!in || *in == 0)
- return ~0;
-
- UInt32 crc = 0xffffffff;
-
- while ((len--) > 0)
- crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF];
-
- return ~crc;
- }
-} // namespace Kernel
+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 Char* in, Int32 len) noexcept {
+ if (!in || *in == 0) return ~0;
+
+ UInt32 crc = 0xffffffff;
+
+ while ((len--) > 0) crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF];
+
+ return ~crc;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/CxxAbi-AMD64.cc b/dev/kernel/src/CxxAbi-AMD64.cc
index 6bf5d009..452f23cd 100644
--- a/dev/kernel/src/CxxAbi-AMD64.cc
+++ b/dev/kernel/src/CxxAbi-AMD64.cc
@@ -1,14 +1,14 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#ifdef __NE_AMD64__
#include <KernelKit/DebugOutput.h>
-#include <NewKit/CxxAbi.h>
#include <KernelKit/KPC.h>
+#include <NewKit/CxxAbi.h>
atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors];
@@ -17,74 +17,61 @@ uarch_t __atexit_func_count;
/// @brief dynamic shared object Handle.
Kernel::UIntPtr __dso_handle;
-EXTERN_C Kernel::Void __cxa_pure_virtual(void* self)
-{
- (void)(Kernel::kout << "object: " << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self)));
- (void)(Kernel::kout << ", has unimplemented virtual functions.\r");
+EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) {
+ (Kernel::Void)(Kernel::kout << "object: "
+ << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self)));
+ (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r");
}
-EXTERN_C void ___chkstk_ms(void)
-{
- (void)(Kernel::kout << "Stack smashing detected!\r");
- dbg_break_point();
+EXTERN_C void ___chkstk_ms(void) {
+ (Kernel::Void)(Kernel::kout << "Stack smashing detected!\r");
+ dbg_break_point();
}
-EXTERN_C int atexit(void (*f)())
-{
- if (__atexit_func_count >= kAtExitMacDestructors)
- return 1;
+EXTERN_C int atexit(void (*f)()) {
+ if (__atexit_func_count >= kAtExitMacDestructors) return 1;
+
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+
+ __atexit_func_count++;
- __atexit_funcs[__atexit_func_count].destructor_func = f;
+ return 0;
+}
+
+EXTERN_C void __cxa_finalize(void* f) {
+ uarch_t i = __atexit_func_count;
+ if (!f) {
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)();
+ };
+ }
+
+ return;
+ }
+
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)();
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+}
- __atexit_func_count++;
+namespace cxxabiv1 {
+EXTERN_C int __cxa_guard_acquire(__guard* g) {
+ (void) g;
+ return 0;
+}
- return 0;
+EXTERN_C int __cxa_guard_release(__guard* g) {
+ *(char*) g = 1;
+ return 0;
}
-EXTERN_C void __cxa_finalize(void* f)
-{
- uarch_t i = __atexit_func_count;
- if (!f)
- {
- while (i--)
- {
- if (__atexit_funcs[i].destructor_func)
- {
- (*__atexit_funcs[i].destructor_func)();
- };
- }
-
- return;
- }
-
- while (i--)
- {
- if (__atexit_funcs[i].destructor_func)
- {
- (*__atexit_funcs[i].destructor_func)();
- __atexit_funcs[i].destructor_func = 0;
- };
- }
+EXTERN_C void __cxa_guard_abort(__guard* g) {
+ (void) g;
}
+} // namespace cxxabiv1
-namespace cxxabiv1
-{
- EXTERN_C int __cxa_guard_acquire(__guard* g)
- {
- (void)g;
- return 0;
- }
-
- EXTERN_C int __cxa_guard_release(__guard* g)
- {
- *(char*)g = 1;
- return 0;
- }
-
- EXTERN_C void __cxa_guard_abort(__guard* g)
- {
- (void)g;
- }
-} // namespace cxxabiv1
-
-#endif // ifdef __NE_AMD64__
+#endif // ifdef __NE_AMD64__
diff --git a/dev/kernel/src/CxxAbi-ARM64.cc b/dev/kernel/src/CxxAbi-ARM64.cc
index 34dab83a..1605692b 100644
--- a/dev/kernel/src/CxxAbi-ARM64.cc
+++ b/dev/kernel/src/CxxAbi-ARM64.cc
@@ -1,14 +1,14 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#ifdef __NE_ARM64__
#include <KernelKit/DebugOutput.h>
-#include <NewKit/CxxAbi.h>
#include <KernelKit/KPC.h>
+#include <NewKit/CxxAbi.h>
atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors];
@@ -17,91 +17,74 @@ uarch_t __atexit_func_count;
/// @brief dynamic shared object Handle.
Kernel::UIntPtr __dso_handle;
-EXTERN_C void __chkstk(void)
-{
-}
+EXTERN_C void __chkstk(void) {}
-EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso)
-{
- if (__atexit_func_count >= kAtExitMacDestructors)
- return 1;
+EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso) {
+ if (__atexit_func_count >= kAtExitMacDestructors) return 1;
- __atexit_funcs[__atexit_func_count].destructor_func = f;
- __atexit_funcs[__atexit_func_count].obj_ptr = arg;
- __atexit_funcs[__atexit_func_count].dso_handle = dso;
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+ __atexit_funcs[__atexit_func_count].obj_ptr = arg;
+ __atexit_funcs[__atexit_func_count].dso_handle = dso;
- __atexit_func_count++;
+ __atexit_func_count++;
+
+ return 0;
+}
+
+EXTERN_C void __cxa_finalize(void* f) {
+ uarch_t i = __atexit_func_count;
+ if (!f) {
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ };
+ }
+
+ return;
+ }
+
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+}
+
+namespace cxxabiv1 {
+EXTERN_C int __cxa_guard_acquire(__guard* g) {
+ (void) g;
+ return 0;
+}
- return 0;
+EXTERN_C int __cxa_guard_release(__guard* g) {
+ *(char*) g = 1;
+ return 0;
}
-EXTERN_C void __cxa_finalize(void* f)
-{
- uarch_t i = __atexit_func_count;
- if (!f)
- {
- while (i--)
- {
- if (__atexit_funcs[i].destructor_func)
- {
- (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
- };
- }
-
- return;
- }
-
- while (i--)
- {
- if (__atexit_funcs[i].destructor_func)
- {
- (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
- __atexit_funcs[i].destructor_func = 0;
- };
- }
+EXTERN_C void __cxa_guard_abort(__guard* g) {
+ (void) g;
}
+} // namespace cxxabiv1
-namespace cxxabiv1
-{
- EXTERN_C int __cxa_guard_acquire(__guard* g)
- {
- (void)g;
- return 0;
- }
-
- EXTERN_C int __cxa_guard_release(__guard* g)
- {
- *(char*)g = 1;
- return 0;
- }
-
- EXTERN_C void __cxa_guard_abort(__guard* g)
- {
- (void)g;
- }
-} // namespace cxxabiv1
-
-EXTERN_C Kernel::Void _purecall(void* self)
-{
- kout << "object: " << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self));
- kout << ", has unimplemented virtual functions.\r";
+EXTERN_C Kernel::Void _purecall(void* self) {
+ (Kernel::Void)(Kernel::kout << "object: "
+ << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self)));
+ (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r");
}
-EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj)
-{
- NE_UNUSED(thread_obj);
+EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj) {
+ NE_UNUSED(thread_obj);
}
-EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void)
-{
- NE_UNUSED(0);
+EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void) {
+ NE_UNUSED(0);
}
-EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj)
-{
- NE_UNUSED(0);
+EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) {
+ NE_UNUSED(0);
}
EXTERN_C Kernel::Int _tls_index = 0UL;
-#endif // ifdef __NE_ARM64__
+#endif // ifdef __NE_ARM64__
diff --git a/dev/kernel/src/Defines.cc b/dev/kernel/src/Defines.cc
index ab832d80..7f6e571d 100644
--- a/dev/kernel/src/Defines.cc
+++ b/dev/kernel/src/Defines.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/DeviceMgr.cc b/dev/kernel/src/DeviceMgr.cc
index 8594d051..c137552e 100644
--- a/dev/kernel/src/DeviceMgr.cc
+++ b/dev/kernel/src/DeviceMgr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/DriveMgr+IO.cc b/dev/kernel/src/DriveMgr+IO.cc
index 99f947bf..4c9b20e0 100644
--- a/dev/kernel/src/DriveMgr+IO.cc
+++ b/dev/kernel/src/DriveMgr+IO.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -20,77 +20,70 @@
/// Useful macros.
#define rtl_nefs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS)
-#define rtl_nefs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS)
+#define rtl_nefs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS)
-namespace Kernel
-{
- /// @brief Read from newfs disk.
- /// @param Mnt mounted interface.
- /// @param DrvTrait drive info
- /// @param DrvIndex drive index.
- /// @return
- Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex)
- {
- if (!Mnt)
- return 1;
+namespace Kernel {
+/// @brief Read from newfs disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) {
+ if (!Mnt) return 1;
- DrvTrait.fPacket.fPacketGood = false;
+ DrvTrait.fPacket.fPacketGood = false;
- switch (DrvIndex)
- {
- case MountpointInterface::kDriveIndexA: {
- rtl_nefs_read(A, DrvTrait.fPacket, Mnt);
- break;
- }
- case MountpointInterface::kDriveIndexB: {
- rtl_nefs_read(B, DrvTrait.fPacket, Mnt);
- break;
- }
- case MountpointInterface::kDriveIndexC: {
- rtl_nefs_read(C, DrvTrait.fPacket, Mnt);
- break;
- }
- case MountpointInterface::kDriveIndexD: {
- rtl_nefs_read(D, DrvTrait.fPacket, Mnt);
- break;
- }
- }
+ switch (DrvIndex) {
+ case MountpointInterface::kDriveIndexA: {
+ rtl_nefs_read(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexB: {
+ rtl_nefs_read(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexC: {
+ rtl_nefs_read(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexD: {
+ rtl_nefs_read(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
- return DrvTrait.fPacket.fPacketGood;
- }
+ return DrvTrait.fPacket.fPacketGood;
+}
- /// @brief Write to newfs disk.
- /// @param Mnt mounted interface.
- /// @param DrvTrait drive info
- /// @param DrvIndex drive index.
- /// @return
- Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex)
- {
- if (!Mnt)
- return 1;
+/// @brief Write to newfs disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) {
+ if (!Mnt) return 1;
- DrvTrait.fPacket.fPacketGood = false;
+ DrvTrait.fPacket.fPacketGood = false;
- switch (DrvIndex)
- {
- case MountpointInterface::kDriveIndexA: {
- rtl_nefs_write(A, DrvTrait.fPacket, Mnt);
- break;
- }
- case MountpointInterface::kDriveIndexB: {
- rtl_nefs_write(B, DrvTrait.fPacket, Mnt);
- break;
- }
- case MountpointInterface::kDriveIndexC: {
- rtl_nefs_write(C, DrvTrait.fPacket, Mnt);
- break;
- }
- case MountpointInterface::kDriveIndexD: {
- rtl_nefs_write(D, DrvTrait.fPacket, Mnt);
- break;
- }
- }
+ switch (DrvIndex) {
+ case MountpointInterface::kDriveIndexA: {
+ rtl_nefs_write(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexB: {
+ rtl_nefs_write(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexC: {
+ rtl_nefs_write(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexD: {
+ rtl_nefs_write(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
- return DrvTrait.fPacket.fPacketGood;
- }
-} // namespace Kernel \ No newline at end of file
+ return DrvTrait.fPacket.fPacketGood;
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc
index b5a8e9e4..f26890b5 100644
--- a/dev/kernel/src/DriveMgr.cc
+++ b/dev/kernel/src/DriveMgr.cc
@@ -1,16 +1,16 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
+#include <FirmwareKit/EPM.h>
+#include <FirmwareKit/GPT.h>
#include <KernelKit/DebugOutput.h>
#include <KernelKit/DriveMgr.h>
#include <NewKit/Utils.h>
-#include <FirmwareKit/EPM.h>
-#include <FirmwareKit/GPT.h>
-#include <modules/ATA/ATA.h>
#include <modules/AHCI/AHCI.h>
+#include <modules/ATA/ATA.h>
#include <modules/NVME/NVME.h>
/***********************************************************************************/
@@ -18,233 +18,225 @@
/// @brief Drive Manager of kernel.
/***********************************************************************************/
-namespace Kernel
-{
+namespace Kernel {
#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
- STATIC UInt16 kATAIO = 0U;
- STATIC UInt8 kATAMaster = 0U;
+STATIC UInt16 kATAIO = 0U;
+STATIC UInt8 kATAMaster = 0U;
#endif
#if defined(__AHCI__)
- STATIC UInt16 kAHCIPortsImplemented = 0UL;
+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)
- {
+/// @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);
+ 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);
+ 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;
- }
+}
+
+/// @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);
+ 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);
+ 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)
- {
- NE_UNUSED(pckt);
+/// @brief Executes a disk check on the ATA drive.
+/// @param pckt the packet to read.
+/// @return
+Void io_drv_init(DriveTrait::DrivePacket& pckt) {
+ NE_UNUSED(pckt);
#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
- kATAMaster = 0;
- kATAIO = 0;
+ kATAMaster = 0;
+ kATAIO = 0;
- kATAMaster = YES;
- kATAIO = ATA_PRIMARY_IO;
+ kATAMaster = YES;
+ kATAIO = ATA_PRIMARY_IO;
- if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster))
- {
- pckt.fPacketGood = YES;
- return;
- }
+ if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) {
+ pckt.fPacketGood = YES;
+ return;
+ }
- kATAMaster = NO;
- kATAIO = ATA_SECONDARY_IO;
+ kATAMaster = NO;
+ kATAIO = ATA_SECONDARY_IO;
- if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster))
- {
- pckt.fPacketGood = YES;
- return;
- }
+ if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) {
+ pckt.fPacketGood = YES;
+ return;
+ }
- pckt.fPacketGood = YES;
+ pckt.fPacketGood = YES;
#elif defined(__AHCI__)
- kAHCIPortsImplemented = 0;
+ kAHCIPortsImplemented = 0;
- if (drv_std_init(kAHCIPortsImplemented))
- {
- pckt.fPacketGood = YES;
- }
-#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__)
- }
+ if (drv_std_init(kAHCIPortsImplemented)) {
+ pckt.fPacketGood = YES;
+ }
+#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";
- }
+const Char* io_drv_kind(Void) {
+ return "ATA-PIO";
+}
#elif defined(__ATA_DMA__)
- const Char* io_drv_kind(Void)
- {
- return "ATA-DMA";
- }
+const Char* io_drv_kind(Void) {
+ return "ATA-DMA";
+}
#elif defined(__AHCI__)
- const Char* io_drv_kind(Void)
- {
- return "AHCI";
- }
+const Char* io_drv_kind(Void) {
+ return "AHCI";
+}
#else
- const Char* io_drv_kind(Void)
- {
- return "null";
- }
+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 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;
- /// @brief Makes a new drive.
- /// @return the new blank drive.
- DriveTrait io_construct_blank_drive() noexcept
- {
- DriveTrait trait;
+ constexpr auto kBlankDrive = "/media/blank/";
- constexpr auto kBlankDrive = "/media/blank/";
+ rt_copy_memory((VoidPtr) kBlankDrive, trait.fName, rt_string_len(kBlankDrive));
+ trait.fKind = kInvalidDrive;
- 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;
- 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 << "Construct: " << trait.fName << "\r";
- kout << "Construct: " << trait.fName << "\r";
+ return trait;
+}
- return trait;
- }
+namespace Detail {
+ Void io_detect_drive(DriveTrait& trait) {
+ trait.fInit(trait.fPacket);
- namespace Detail
- {
- Void io_detect_drive(DriveTrait& trait)
- {
- trait.fInit(trait.fPacket);
+ EPM_PART_BLOCK block_struct;
- EPM_PART_BLOCK block_struct;
+ trait.fPacket.fPacketLba = kEPMBootBlockLba;
+ trait.fPacket.fPacketSize = sizeof(EPM_PART_BLOCK);
+ trait.fPacket.fPacketContent = &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"));
- rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime,
- rt_string_len("fs/detect-packet"));
+ trait.fInput(trait.fPacket);
- trait.fInput(trait.fPacket);
+ if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0) {
+ trait.fPacket.fPacketReadOnly = NO;
+ trait.fKind = kMassStorageDrive | kEPMDrive;
- if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0)
- {
- trait.fPacket.fPacketReadOnly = NO;
- trait.fKind = kMassStorageDrive | kEPMDrive;
+ kout << "Disk is EPM formatted.\r";
- kout << "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.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;
- 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"));
- rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime,
- rt_string_len("fs/detect-packet"));
+ trait.fInput(trait.fPacket);
- trait.fInput(trait.fPacket);
+ if (rt_string_cmp(gpt_struct.Signature, kMagicGPT, kMagicLenGPT) == 0) {
+ trait.fPacket.fPacketReadOnly = NO;
+ trait.fKind = kMassStorageDrive | kGPTDrive;
- if (rt_string_cmp(gpt_struct.Signature, kMagicGPT, kMagicLenGPT) == 0)
- {
- trait.fPacket.fPacketReadOnly = NO;
- trait.fKind = kMassStorageDrive | kGPTDrive;
+ kout << "Disk is GPT formatted.\r";
- kout << "Disk is GPT formatted.\r";
+ trait.fSectorSz = gpt_struct.SizeOfEntries;
+ trait.fLbaEnd = gpt_struct.LastGPTEntry;
+ trait.fLbaStart = gpt_struct.FirstGPTEntry;
+ } else {
+ kout << "Disk is unformatted.\r";
- trait.fSectorSz = gpt_struct.SizeOfEntries;
- trait.fLbaEnd = gpt_struct.LastGPTEntry;
- trait.fLbaStart = gpt_struct.FirstGPTEntry;
- }
- else
- {
- kout << "Disk is unformatted.\r";
+ trait.fPacket.fPacketReadOnly = YES;
+ trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive;
- 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("*/*"));
+ rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime, rt_string_len("*/*"));
- trait.fPacket.fPacketLba = 0;
- trait.fPacket.fPacketSize = 0UL;
- trait.fPacket.fPacketContent = nullptr;
- }
- } // namespace Detail
+ trait.fPacket.fPacketLba = 0;
+ trait.fPacket.fPacketSize = 0UL;
+ trait.fPacket.fPacketContent = nullptr;
+ }
+} // namespace Detail
- /// @brief Fetches the main drive.
- /// @return the new drive. (returns kEPMDrive if EPM formatted)
- DriveTrait io_construct_main_drive() noexcept
- {
- DriveTrait trait;
+/// @brief Fetches the main drive.
+/// @return the new drive. (returns kEPMDrive if EPM formatted)
+DriveTrait io_construct_main_drive() noexcept {
+ DriveTrait trait;
- constexpr auto kMainDrive = "/media/main/";
+ constexpr auto kMainDrive = "/media/main/";
- rt_copy_memory((VoidPtr)kMainDrive, trait.fName, rt_string_len(kMainDrive));
+ rt_copy_memory((VoidPtr) kMainDrive, trait.fName, rt_string_len(kMainDrive));
- MUST_PASS(trait.fName[0] != 0);
+ 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;
+ 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;
- kout << "Detecting partition scheme of: " << trait.fName << ".\r";
+ kout << "Detecting partition scheme of: " << trait.fName << ".\r";
- Detail::io_detect_drive(trait);
+ Detail::io_detect_drive(trait);
- return trait;
- }
-} // namespace Kernel
+ return trait;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/ErrorOr.cc b/dev/kernel/src/ErrorOr.cc
index 97c19ca3..69668b2f 100644
--- a/dev/kernel/src/ErrorOr.cc
+++ b/dev/kernel/src/ErrorOr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/FS/Ext2+FileMgr.cc b/dev/kernel/src/FS/Ext2+FileMgr.cc
index cb17b587..a55d917a 100644
--- a/dev/kernel/src/FS/Ext2+FileMgr.cc
+++ b/dev/kernel/src/FS/Ext2+FileMgr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -10,5 +10,5 @@
#include <KernelKit/FileMgr.h>
#include <KernelKit/MemoryMgr.h>
-#endif // ifdef __FSKIT_INCLUDES_EXT2__
-#endif // ifndef __NE_MINIMAL_OS__
+#endif // ifdef __FSKIT_INCLUDES_EXT2__
+#endif // ifndef __NE_MINIMAL_OS__
diff --git a/dev/kernel/src/FS/Ext2.cc b/dev/kernel/src/FS/Ext2.cc
index 5de8c842..b6d04f46 100644
--- a/dev/kernel/src/FS/Ext2.cc
+++ b/dev/kernel/src/FS/Ext2.cc
@@ -1,22 +1,21 @@
/* -------------------------------------------
- Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#ifdef __FSKIT_INCLUDES_EXT2__
-#include <modules/AHCI/AHCI.h>
-#include <modules/ATA/ATA.h>
-#include <modules/Flash/Flash.h>
#include <FSKit/Ext2.h>
+#include <FirmwareKit/EPM.h>
#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/User.h>
#include <NewKit/Crc32.h>
-#include <NewKit/KernelPanic.h>
#include <NewKit/KString.h>
+#include <NewKit/KernelPanic.h>
#include <NewKit/Utils.h>
-#include <FirmwareKit/EPM.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/User.h>
+#include <modules/AHCI/AHCI.h>
+#include <modules/ATA/ATA.h>
-#endif // ifdef __FSKIT_INCLUDES_EXT2__
+#endif // ifdef __FSKIT_INCLUDES_EXT2__
diff --git a/dev/kernel/src/FS/HeFS+FileMgr.cc b/dev/kernel/src/FS/HeFS+FileMgr.cc
index e6719e1b..e0b92a8d 100644
--- a/dev/kernel/src/FS/HeFS+FileMgr.cc
+++ b/dev/kernel/src/FS/HeFS+FileMgr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -10,5 +10,5 @@
#include <KernelKit/FileMgr.h>
#include <KernelKit/MemoryMgr.h>
-#endif // ifdef __FSKIT_INCLUDES_HEFS__
-#endif // ifndef __NE_MINIMAL_OS__
+#endif // ifdef __FSKIT_INCLUDES_HEFS__
+#endif // ifndef __NE_MINIMAL_OS__
diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc
index 1c82548c..ca655b8b 100644
--- a/dev/kernel/src/FS/HeFS.cc
+++ b/dev/kernel/src/FS/HeFS.cc
@@ -1,22 +1,1148 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#ifdef __FSKIT_INCLUDES_HeFS__
+#ifdef __FSKIT_INCLUDES_HEFS__
-#include <modules/AHCI/AHCI.h>
-#include <modules/ATA/ATA.h>
-#include <modules/Flash/Flash.h>
#include <FSKit/HeFS.h>
+#include <FirmwareKit/EPM.h>
+#include <FirmwareKit/GPT.h>
#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/User.h>
#include <NewKit/Crc32.h>
-#include <NewKit/KernelPanic.h>
#include <NewKit/KString.h>
+#include <NewKit/KernelPanic.h>
#include <NewKit/Utils.h>
-#include <FirmwareKit/EPM.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/User.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, const BOOL try_new = NO);
+
+ /// @brief Get the index node of a file or directory.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive 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_index_node(
+ HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf8Char* dir_name, const Utf8Char* file_name,
+ UInt8 kind, SizeT* cnt) noexcept;
+
+ /// @brief Get the index node size.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive 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 SizeT
+ hefsi_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf8Char* dir_name,
+ const Utf8Char* file_name, UInt8 kind) noexcept;
+
+ /// @brief Allocate a new index node->
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive to read/write from.
+ /// @param parent_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* root, DriveTrait* mnt, const Utf8Char* parent_dir_name,
+ HEFS_INDEX_NODE* node, const BOOL create_or_delete) noexcept;
+
+ /// @brief Balance RB-Tree of the filesystem.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive to read/write from.
+ /// @return Status, see err_global_get().
+ STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt);
+
+ /// @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, const BOOL try_new) {
+ if (!mnt || !dir) return;
+
+ BOOL check_is_good = NO;
+
+ while (YES) {
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+ mnt->fInput(mnt->fPacket);
+
+ if (!mnt->fPacket.fPacketGood) break;
+
+ if (*dir->fName != 0 && try_new) break;
+
+ if (dir->fNext != 0) {
+ if (check_is_good) break;
+
+ start = dir->fNext;
+
+ check_is_good = YES;
+ continue;
+ } else if (dir->fPrev != 0) {
+ if (check_is_good) break;
+
+ start = dir->fPrev;
+ check_is_good = YES;
+ continue;
+ } else {
+ if (dir->fParent != 0) {
+ if (check_is_good) break;
+
+ start = dir->fParent;
+ check_is_good = YES;
+ continue;
+ } else if (dir->fPrev != 0) {
+ if (check_is_good) break;
+
+ start = dir->fPrev;
+ check_is_good = YES;
+ continue;
+ } else {
+ if (!try_new) break;
+
+ if (start == 0) {
+ start = ind_start;
+ continue;
+ }
+
+ start += kHeFSINDStartOffset;
+ break;
+ }
+ }
+ }
+
+ if (*dir->fName != 0 && try_new) start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ if (start == 0) start = ind_start;
+
+ (Void)(kout << "LBA_" << number(start) << kendl);
+ }
+
+ /***********************************************************************************/
+ /// @brief Rotate the RB-Tree to the left.
+ /// @internal
+ /***********************************************************************************/
+ STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_tree(Lba& start, DriveTrait* mnt, Bool left) {
+ if (!start || !mnt) return;
+
+ HEFS_INDEX_NODE_DIRECTORY* parent =
+ (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 = parent;
+
+ mnt->fInput(mnt->fPacket);
+
+ HEFS_INDEX_NODE_DIRECTORY* grand_parent =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = parent->fParent;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = grand_parent;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (parent->fParent == 0) return;
+
+ HEFS_INDEX_NODE_DIRECTORY* cousin =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = left ? grand_parent->fPrev : grand_parent->fNext;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = cousin;
+
+ mnt->fInput(mnt->fPacket);
+
+ HEFS_INDEX_NODE_DIRECTORY* cousin_child =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = cousin->fChild;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = cousin;
+
+ mnt->fInput(mnt->fPacket);
+
+ grand_parent->fChild = cousin->fChild;
+ cousin_child->fParent = parent->fParent;
+
+ parent->fParent = cousin->fParent;
+ cousin->fChild = start;
+
+ cousin_child->fChecksum =
+ ke_calculate_crc32((Char*) cousin_child, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ grand_parent->fChecksum =
+ ke_calculate_crc32((Char*) grand_parent, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ parent->fChecksum = ke_calculate_crc32((Char*) parent, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ cousin->fChecksum = ke_calculate_crc32((Char*) cousin, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = parent->fParent;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = grand_parent;
+
+ mnt->fOutput(mnt->fPacket);
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = parent;
+
+ mnt->fOutput(mnt->fPacket);
+
+ kout << "Rotate tree has been done.\r";
+ }
+
+ /// @brief Get the index node size.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive 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 SizeT
+ hefsi_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf8Char* dir_name,
+ const Utf8Char* file_name, UInt8 kind) noexcept {
+ if (mnt) {
+ HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE));
+ HEFS_INDEX_NODE_DIRECTORY* dir =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ SizeT sz = 0UL;
+
+ auto start = root->fStartIND;
+
+ while (YES) {
+ 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() = kErrorFileNotFound;
+
+ return 0;
+ }
+
+ if (dir->fKind == kHeFSFileKindDirectory) {
+ if (KStringBuilder::Equals(dir_name, dir->fName) ||
+ KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) {
+ for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; inode_index += 2) {
+ mnt->fPacket.fPacketLba = dir->fIndexNode[inode_index];
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = node;
+ mnt->fInput(mnt->fPacket);
+
+ if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) {
+ if (node->fKind == kHeFSFileKindDirectory) {
+ sz += hefsi_fetch_index_node_size(root, mnt, dir_name, file_name, kind);
+ } else {
+ sz = node->fSize;
+ }
+
+ return sz;
+ }
+ }
+ }
+ }
+ }
+
+ err_global_get() = kErrorSuccess;
+ return sz;
+ }
+
+ err_global_get() = kErrorFileNotFound;
+ return 0;
+ }
+
+ /// @brief Alllocate IND from boot node.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive 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* root, DriveTrait* mnt,
+ const Utf8Char* dir_name,
+ const Utf8Char* parent_dir_fmt, UInt16 flags,
+ const BOOL delete_or_create) noexcept {
+ if (urt_string_len(dir_name) >= kHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ if (mnt) {
+ HEFS_INDEX_NODE_DIRECTORY* tmpdir =
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
+
+ auto start = root->fStartIND;
+ auto prev_location = start;
+ auto parent_location = 0UL;
+
+ MUST_PASS(root->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->fName == 0;
+ } else {
+ expr = tmpdir->fCreated && !tmpdir->fDeleted &&
+ KStringBuilder::Equals(tmpdir->fName, dir_name);
+
+ if (parent_dir_fmt && !delete_or_create && !parent_location) {
+ if (KStringBuilder::Equals(tmpdir->fName, parent_dir_fmt)) {
+ if (tmpdir->fChild == 0) {
+ ke_panic(RUNTIME_CHECK_FILESYSTEM,
+ "Filesystem has a corrupted child entry on RB-Tree IND.");
+ } else {
+ parent_location = start;
+ continue;
+ }
+ }
+ }
+ }
+
+ if (expr) {
+ HEFS_INDEX_NODE_DIRECTORY* dirent =
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
+
+ rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ if (!delete_or_create)
+ urt_copy_memory((VoidPtr) dir_name, dirent->fName, urt_string_len(dir_name) + 1);
+
+ dirent->fAccessed = 0UL;
+ dirent->fCreated = delete_or_create ? 0UL : 1UL;
+ dirent->fDeleted = delete_or_create ? 1UL : 0UL;
+ dirent->fModified = 0UL;
+ dirent->fEntryCount = 0UL;
+
+ dirent->fKind = kHeFSFileKindDirectory;
+ 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");
+
+ 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->fName == 0) {
+ start = child_first;
+ break;
+ }
+
+ hefsi_traverse_tree(tmpend, mnt, root->fStartIND, child_first, YES);
+ }
+ }
+
+ dirent->fNext = tmpdir->fNext;
+ dirent->fPrev = tmpdir->fPrev;
+ dirent->fParent = tmpdir->fParent;
+ dirent->fChild = tmpdir->fChild;
+ dirent->fColor = tmpdir->fColor;
+
+ if (dirent->fColor < kHeFSRed) {
+ dirent->fColor = kHeFSBlack;
+ }
+
+ if (dirent->fPrev == 0) {
+ dirent->fPrev = root->fStartIND;
+ }
+
+ if (dirent->fNext == 0) {
+ dirent->fNext = prev_start + sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ }
+
+ if (dirent->fParent == 0) {
+ dirent->fParent = root->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->fName == 0) {
+ break;
+ }
+
+ child += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ if (child > root->fEndIND) break;
+ }
+
+ dirent->fColor = kHeFSRed;
+ dirent->fChild = child;
+
+ if (child > root->fEndIND) dirent->fChild = root->fStartIND;
+ }
+
+ for (SizeT index = 0UL; index < kHeFSSliceCount; ++index) {
+ dirent->fIndexNode[index] = 0;
+ }
+
+ 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_delete_heap(dirent);
+ mm_delete_heap(tmpdir);
+
+ if (!delete_or_create)
+ ++root->fINDCount;
+ else
+ --root->fINDCount;
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
+
+ mnt->fOutput(mnt->fPacket);
+
+ return YES;
+ }
+
+ prev_location = start;
+
+ hefsi_traverse_tree(tmpdir, mnt, root->fStartIND, start, YES);
+ if (start > root->fEndIND) break;
+ }
+
+ err_global_get() = kErrorDisk;
+ mm_delete_heap(tmpdir);
+
+ return NO;
+ }
+
+ err_global_get() = kErrorDiskIsFull;
+ return NO;
+ }
+
+ /// @brief Get the index node of a file or directory.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive 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_index_node(
+ HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf8Char* dir_name, const Utf8Char* file_name,
+ UInt8 kind, SizeT* cnt) noexcept {
+ if (mnt) {
+ HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt];
+
+ if (!node_arr) {
+ return nullptr;
+ }
+
+ HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE));
+ HEFS_INDEX_NODE_DIRECTORY* dir =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ auto start = root->fStartIND;
+
+ auto start_cnt = 0UL;
+
+ while (YES) {
+ 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() = kErrorFileNotFound;
+
+ delete[] node_arr;
+ return nullptr;
+ }
+
+ if (dir->fKind == kHeFSFileKindDirectory) {
+ if (KStringBuilder::Equals(dir_name, dir->fName) ||
+ KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) {
+ if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) !=
+ dir->fChecksum)
+ ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 failure on HeFS IND!");
+
+ for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) {
+ if (dir->fIndexNode[inode_index] != 0) {
+ if (mnt->fPacket.fPacketGood) {
+ if (ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)) != node->fChecksum)
+ ke_panic(RUNTIME_CHECK_FILESYSTEM, "CRC32 failure on HeFS IND!");
+
+ if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) {
+ node_arr[start_cnt] = *node;
+ ++start_cnt;
+
+ if (start_cnt > *cnt) {
+ return node_arr;
+ }
+ }
+ } else {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ delete[] node_arr;
+
+ node_arr = nullptr;
+
+ return nullptr;
+ }
+ }
+ }
+ }
+ }
+
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES);
+ if (start > root->fEndIND || start == 0) break;
+ }
+ }
+
+ kout << "Error: Failed to find index node->\r";
+
+ err_global_get() = kErrorFileNotFound;
+
+ return nullptr;
+ }
+
+ /// @brief Allocate a new index node.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive to read from.
+ /// @param parent_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* root, DriveTrait* mnt, const Utf8Char* parent_dir_name,
+ HEFS_INDEX_NODE* node, BOOL delete_or_create) noexcept {
+ if (!root) return NO;
+
+ auto start = root->fStartIND;
+
+ if (start >= root->fEndIND) return NO;
+ if (root->fStartIN > root->fEndIN) return NO;
+
+ if (mnt) {
+ HEFS_INDEX_NODE_DIRECTORY* dir =
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
+
+ Utf8Char file_name[kHeFSFileNameLen] = {0};
+
+ urt_copy_memory(node->fName, file_name, urt_string_len(node->fName) + 1);
+
+ while (YES) {
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (KStringBuilder::Equals(dir->fName, parent_dir_name)) {
+ for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) {
+ if (dir->fIndexNode[inode_index] == 0 && !delete_or_create) {
+ dir->fIndexNode[inode_index] = root->fStartIN;
+
+ ++dir->fEntryCount;
+
+ root->fStartIN += sizeof(HEFS_INDEX_NODE);
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
+
+ mnt->fOutput(mnt->fPacket);
+
+ 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->fIndexNode[inode_index];
+
+ mnt->fPacket.fPacketLba = lba;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = node;
+
+ mnt->fOutput(mnt->fPacket);
+
+ mm_delete_heap(dir);
+
+ if (mnt->fPacket.fPacketGood) {
+ return YES;
+ }
+
+ return NO;
+ } else if (dir->fIndexNode[inode_index] != 0 && delete_or_create) {
+ auto lba = dir->fIndexNode[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 (!KStringBuilder::Equals(tmp_node.fName, file_name)) {
+ continue;
+ }
+
+ root->fStartIN -= sizeof(HEFS_INDEX_NODE);
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = root;
+
+ mnt->fOutput(mnt->fPacket);
+
+ mnt->fPacket.fPacketLba = lba;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = node;
+
+ mnt->fOutput(mnt->fPacket);
+
+ dir->fIndexNode[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_delete_heap(dir);
+
+ if (mnt->fPacket.fPacketGood) {
+ return YES;
+ }
+
+ return NO;
+ }
+ }
+ }
+
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES);
+ if (start > root->fEndIND || start == 0) break;
+ }
+
+ mm_delete_heap(dir);
+ err_global_get() = kErrorFileNotFound;
+ return NO;
+ }
+
+ err_global_get() = kErrorDiskIsFull;
+ return NO;
+ }
+
+ /// @brief Balance RB-Tree of the filesystem.
+ /// @param root The root node of the filesystem.
+ /// @param mnt The drive to read/write from.
+ /// @return Status, see err_global_get().
+ STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* root, DriveTrait* mnt) {
+ if (mnt) {
+ HEFS_INDEX_NODE_DIRECTORY* dir =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+ HEFS_INDEX_NODE_DIRECTORY* parent_dir_fmt =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ auto start = root->fStartIND;
+
+ while (YES) {
+ if (start == 0) 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 (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);
+ }
+
+ if (start == root->fStartIND) {
+ dir->fColor = kHeFSBlack;
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fOutput(mnt->fPacket);
+ }
+
+ mnt->fPacket.fPacketLba = dir->fParent;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = parent_dir_fmt;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!mnt->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ HEFS_INDEX_NODE_DIRECTORY* dir_uncle =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = parent_dir_fmt->fNext;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir_uncle;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!mnt->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ if (parent_dir_fmt->fNext == start) {
+ hefsi_rotate_tree(start, mnt, YES);
+ hefsi_traverse_tree(parent_dir_fmt, mnt, root->fStartIND, start);
+
+ if (start > root->fEndIND || start == 0) break;
+
+ continue;
+ }
+
+ parent_dir_fmt->fColor = kHeFSBlack;
+
+ parent_dir_fmt->fChecksum =
+ ke_calculate_crc32((Char*) parent_dir_fmt, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ if (dir->fParent == 0) {
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES);
+ continue;
+ }
+
+ mnt->fPacket.fPacketLba = dir->fParent;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = parent_dir_fmt;
+
+ mnt->fOutput(mnt->fPacket);
+
+ if (!mnt->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ hefsi_rotate_tree(start, mnt, NO);
+
+ hefsi_traverse_tree(dir, mnt, root->fStartIND, start, YES);
+ if (start > root->fEndIND || start == 0) break;
+ }
+
+ return YES;
+ }
+
+ return NO;
+ }
+} // namespace Detail
+} // namespace Kernel
+
+/// @note HeFS 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::HeFS {
+/// @brief Make a EPM+HeFS drive out of the disk.
+/// @param drive The drive to write on.
+/// @return If it was sucessful, see err_local_get().
+_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
+ _Input const Utf8Char* part_name) {
+ NE_UNUSED(drive);
+ NE_UNUSED(flags);
+ NE_UNUSED(part_name);
+
+ // Verify Disk.
+ drive->fVerify(drive->fPacket);
+
+ // if disk isn't good, then error out.
+ if (false == drive->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return false;
+ }
+
+ if (drv_std_get_size() < kHeFSMinimumDiskSize) {
+ err_global_get() = kErrorDiskIsTooTiny;
+ kout << "Error: Failed to allocate memory for boot node->\r";
+ return NO;
+ }
+
+ HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
+
+ drive->fPacket.fPacketLba = drive->fLbaStart;
+ drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ drive->fPacket.fPacketContent = root;
+
+ drive->fInput(drive->fPacket);
+
+ if (!drive->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ // Check if the disk is already formatted.
+
+ if (KStringBuilder::Equals(root->fMagic, kHeFSMagic) && root->fVersion == kHeFSVersion) {
+ err_global_get() = kErrorSuccess;
+ return YES;
+ }
+
+ if (ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE)) != root->fChecksum &&
+ root->fChecksum > 0) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return NO;
+ }
+
+ rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"));
+
+ urt_copy_memory((VoidPtr) part_name, root->fVolName, urt_string_len(part_name) + 1);
+ rt_copy_memory((VoidPtr) kHeFSMagic, root->fMagic, kHeFSMagicLen - 1);
+
+ if (drive->fLbaStart > drive->fLbaEnd) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ root->fBadSectors = 0;
+
+ root->fSectorCount = drv_std_get_sector_count();
+ root->fSectorSize = drive->fSectorSz;
+
+ MUST_PASS(root->fSectorSize);
+
+ const SizeT max_lba = drive->fLbaEnd / root->fSectorSize;
+
+ const SizeT dir_max = max_lba / 20; // 20% for directory metadata
+ const SizeT inode_max = max_lba / 20; // 10% for inodes
+
+ root->fStartIND = drive->fLbaStart + kHeFSINDStartOffset;
+ root->fEndIND = root->fStartIND + dir_max;
+
+ root->fStartIN = root->fEndIND + sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ root->fEndIN = root->fStartIN + inode_max;
+
+ constexpr SizeT kHeFSPreallocateCount = 0x7UL;
+
+ root->fINDCount = 0;
+
+ // let's lie here.
+ root->fDiskSize = drive->fLbaEnd;
+ root->fDiskStatus = kHeFSStatusUnlocked;
+
+ root->fDiskFlags = flags;
+
+ if (drive->fKind & kMassStorageDrive) {
+ } else if (drive->fKind & kHeFSOpticalDrive) {
+ root->fDiskKind = kHeFSOpticalDrive;
+ } else {
+ root->fDiskKind = kHeFSUnknown;
+ }
+
+ root->fReserved = 0;
+ root->fReserved1 = 0;
+
+ root->fVersion = kHeFSVersion;
+
+ root->fVID = kHeFSInvalidVID;
+
+ root->fChecksum = ke_calculate_crc32((Char*) root, sizeof(HEFS_BOOT_NODE));
+
+ drive->fPacket.fPacketLba = drive->fLbaStart;
+ drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ drive->fPacket.fPacketContent = root;
+
+ drive->fOutput(drive->fPacket);
+
+ (Void)(kout << "Drive kind: " << drive->fProtocol() << kendl);
+ (Void)(kout8 << u8"Volume name: " << root->fVolName << kendl8);
+ (Void)(kout << "Start IND: " << hex_number(root->fStartIND) << kendl);
+ (Void)(kout << "Number of IND: " << hex_number(root->fINDCount) << kendl);
+ (Void)(kout << "Sector size: " << hex_number(root->fSectorSize) << kendl);
+
+ if (!drive->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ const Utf8Char* kFileMap[kHeFSPreallocateCount] = {
+ u8"/", u8"boot", u8"system", u8"network", u8"devices", u8"media", u8"vm",
+ };
+
+ for (SizeT i = 0; i < kHeFSPreallocateCount; ++i) {
+ this->CreateDirectory(drive, kHeFSEncodingUTF8, kFileMap[i], (i == 0) ? nullptr : u8"/");
+ }
+
+ err_global_get() = kErrorSuccess;
+
+ if (drive->fPacket.fPacketGood) return YES;
+
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+}
+
+/// @brief Create a new directory on the disk.
+/// @param drive The drive 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::DirectoryCtl_(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* parent_dir,
+ const BOOL delete_or_create) {
+ HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_heap(sizeof(HEFS_BOOT_NODE), Yes, No);
+
+ rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"));
+
+ drive->fPacket.fPacketLba = drive->fLbaStart;
+ drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ drive->fPacket.fPacketContent = root;
+
+ drive->fInput(drive->fPacket);
+
+ if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ kout << "Invalid Boot Node, this can't continue!\r";
+
+ return NO;
+ }
+
+ if (KStringBuilder::Equals(dir, kHeFSSearchAllStr) ||
+ KStringBuilder::Equals(parent_dir, kHeFSSearchAllStr)) {
+ kout << "Error: Invalid directory name.\r";
+
+ err_global_get() = kErrorInvalidData;
+
+ return NO;
+ }
+
+ if (Detail::hefsi_update_ind_status(root, drive, dir, parent_dir, flags, delete_or_create)) {
+ // todo: make it smarter for high-throughput.
+ Detail::hefsi_balance_ind(root, drive);
+
+ mm_delete_heap((VoidPtr) root);
+ return YES;
+ }
+
+ mm_delete_heap((VoidPtr) root);
+ return NO;
+}
+
+_Output Bool HeFileSystemParser::RemoveDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir,
+ const Utf8Char* parent_dir_fmt) {
+ return this->DirectoryCtl_(drive, flags, dir, parent_dir_fmt, YES);
+}
+
+_Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir,
+ const Utf8Char* parent_dir_fmt) {
+ return this->DirectoryCtl_(drive, flags, dir, parent_dir_fmt, NO);
+}
+
+_Output Bool HeFileSystemParser::DeleteFile(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* parent_dir_fmt,
+ const Utf8Char* name) {
+ return this->FileCtl_(drive, flags, dir, parent_dir_fmt, name, YES);
+}
+
+_Output Bool HeFileSystemParser::CreateFile(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* parent_dir_fmt,
+ const Utf8Char* name) {
+ return this->FileCtl_(drive, flags, dir, parent_dir_fmt, name, NO);
+}
+
+/// @brief Create a new file on the disk.
+/// @param drive The drive 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::FileCtl_(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* parent_dir_fmt,
+ const Utf8Char* name, const BOOL delete_or_create) {
+ NE_UNUSED(parent_dir_fmt);
+
+ HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) mm_new_heap(sizeof(HEFS_INDEX_NODE), Yes, No);
+
+ rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE));
+
+ HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
+
+ MUST_PASS(root && node);
+
+ rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"));
+
+ drive->fPacket.fPacketLba = drive->fLbaStart;
+ drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ drive->fPacket.fPacketContent = root;
+
+ drive->fInput(drive->fPacket);
+
+ if (KStringBuilder::Equals(name, kHeFSSearchAllStr)) {
+ kout << "Error: Invalid file name.\r";
+
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+
+ if (KStringBuilder::Equals(dir, kHeFSSearchAllStr) ||
+ KStringBuilder::Equals(parent_dir_fmt, kHeFSSearchAllStr)) {
+ kout << "Error: Invalid directory name.\r";
+
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+
+ node->fAccessed = 0;
+ node->fCreated = delete_or_create ? 0UL : 1UL;
+ node->fDeleted = delete_or_create ? 1UL : 0UL;
+ node->fModified = 0;
+ node->fSize = 0;
+ node->fKind = kHeFSFileKindRegular;
+ node->fFlags = flags;
+ node->fChecksum = 0;
+ node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE));
+ node->fGID = 0;
+ node->fUID = 0;
+
+ urt_copy_memory((VoidPtr) name, node->fName, urt_string_len(name) + 1);
+
+ if (Detail::hefsi_update_in_status(root, drive, dir, node, delete_or_create)) {
+ mm_delete_heap((VoidPtr) node);
+
+ Detail::hefsi_balance_ind(root, drive);
+ err_global_get() = kErrorSuccess;
+ return YES;
+ }
+
+ mm_delete_heap((VoidPtr) node);
+ err_global_get() = kErrorDirectoryNotFound;
+ return NO;
+}
+
+STATIC DriveTrait kMountPoint;
+
+/// @brief Initialize the HeFS filesystem.
+/// @return To check its status, see err_local_get().
+Boolean fs_init_hefs(Void) noexcept {
+ kout << "Creating HeFS disk...\r";
+
+ kMountPoint = io_construct_main_drive();
+
+ if (kMountPoint.fPacket.fPacketReadOnly == YES)
+ ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main disk cannot be mounted (read-only media).");
+
+ HeFileSystemParser parser;
+
+ parser.Format(&kMountPoint, kHeFSEncodingUTF8, kHeFSDefaultVoluneName);
+
+ parser.CreateFile(&kMountPoint, kHeFSEncodingBinary, u8"vm", u8"/", u8"pagefile.sys");
+
+ return YES;
+}
+} // namespace Kernel::HeFS
-#endif // ifdef __FSKIT_INCLUDES_HeFS__
+#endif // ifdef __FSKIT_INCLUDES_HEFS__
diff --git a/dev/kernel/src/FS/NeFS+FileMgr.cc b/dev/kernel/src/FS/NeFS+FileMgr.cc
index 348ae61b..c92d6727 100644
--- a/dev/kernel/src/FS/NeFS+FileMgr.cc
+++ b/dev/kernel/src/FS/NeFS+FileMgr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -10,236 +10,195 @@
#include <KernelKit/FileMgr.h>
#include <KernelKit/MemoryMgr.h>
-/// @brief NeFS File manager.
+/// @brief NeFS File System Manager.
/// BUGS: 0
-namespace Kernel
-{
- /// @brief C++ constructor
- NeFileSystemMgr::NeFileSystemMgr()
- {
- NeFileSystemParser* mParser = new NeFileSystemParser();
- MUST_PASS(mParser);
-
- kout << "We are done allocating NeFileSystemParser...\r";
- }
-
- NeFileSystemMgr::~NeFileSystemMgr()
- {
- if (mParser)
- {
- kout << "Destroying NeFileSystemParser...\r";
- mm_delete_class(&mParser);
- }
- }
-
- /// @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)
- 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)
- {
- return node_cast(mParser->CreateCatalog(path));
- }
-
- /// @brief Creates a node with is a directory.
- /// @param path The filename path.
- /// @return The Node pointer.
- NodePtr NeFileSystemMgr::CreateDirectory(const Char* path)
- {
- return node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindDir));
- }
-
- /// @brief Creates a node with is a alias.
- /// @param path The filename path.
- /// @return The Node pointer.
- NodePtr NeFileSystemMgr::CreateAlias(const Char* path)
- {
- return node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindAlias));
- }
-
- /// @brief Creates a node with is a page file.
- /// @param path The filename path.
- /// @return The Node pointer.
- NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path)
- {
- return 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)
- return nullptr;
-
- if (!r || *r == 0)
- return nullptr;
-
- auto catalog = mParser->GetCatalog(path);
-
- return node_cast(catalog);
- }
-
- /// @brief Writes to a catalog's fork.
- /// @param node the node ptr.
- /// @param data the data.
- /// @param flags the size.
- /// @return
- Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size)
- {
- if (!node)
- return;
- if (!size)
- return;
-
- constexpr auto kDataForkName = kNeFSDataFork;
- this->Write(kDataForkName, node, data, flags, size);
- }
-
- /// @brief Read from filesystem fork.
- /// @param node the catalog node.
- /// @param flags the flags with it.
- /// @param sz the size to read.
- /// @return
- _Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size)
- {
- if (!node)
- return nullptr;
- if (!size)
- 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 (!size ||
- size > kNeFSForkSize)
- return;
-
- if (!data)
- return;
-
- NE_UNUSED(flags);
-
- if ((reinterpret_cast<NEFS_CATALOG_STRUCT*>(node))->Kind == kNeFSCatalogKindFile)
- mParser->WriteCatalog(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node)->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 (sz > kNeFSForkSize)
- return nullptr;
-
- if (!sz)
- return nullptr;
-
- NE_UNUSED(flags);
-
- if ((reinterpret_cast<NEFS_CATALOG_STRUCT*>(node))->Kind == kNeFSCatalogKindFile)
- return mParser->ReadCatalog(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node), (flags & kFileFlagRsrc ? true : false), sz,
- name);
-
- return nullptr;
- }
-
- /// @brief Seek from Catalog.
- /// @param node
- /// @param off
- /// @retval true always returns false, this is unimplemented.
- /// @retval false always returns this, it is unimplemented.
-
- _Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off)
- {
- if (!node || off == 0)
- return false;
-
- return mParser->Seek(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node), off);
- }
-
- /// @brief Tell where the catalog is.
- /// @param node
- /// @retval true always returns false, this is unimplemented.
- /// @retval false always returns this, it is unimplemented.
-
- _Output SizeT NeFileSystemMgr::Tell(NodePtr node)
- {
- if (!node)
- return kNPos;
-
- return mParser->Tell(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node));
- }
-
- /// @brief Rewinds the catalog.
- /// @param node
- /// @retval true always returns false, this is unimplemented.
- /// @retval false always returns this, it is unimplemented.
-
- _Output Bool NeFileSystemMgr::Rewind(NodePtr node)
- {
- if (!node)
- return false;
-
- return this->Seek(node, 0);
- }
-
- /// @brief Returns the filesystem parser.
- /// @return the Filesystem parser class.
- _Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept
- {
- return mParser;
- }
-} // namespace Kernel
-
-#endif // ifdef __FSKIT_INCLUDES_NEFS__
-#endif // ifndef __NE_MINIMAL_OS__
+namespace Kernel {
+/// @brief C++ constructor
+NeFileSystemMgr::NeFileSystemMgr() {
+ NeFileSystemParser* mParser = new NeFileSystemParser();
+ MUST_PASS(mParser);
+
+ kout << "We are done allocating NeFileSystemParser...\r";
+}
+
+NeFileSystemMgr::~NeFileSystemMgr() {
+ if (mParser) {
+ kout << "Destroying NeFileSystemParser...\r";
+ mm_delete_class(&mParser);
+ }
+}
+
+/// @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) 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) {
+ return rtl_node_cast(mParser->CreateCatalog(path));
+}
+
+/// @brief Creates a node with is a directory.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) {
+ return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindDir));
+}
+
+/// @brief Creates a node with is a alias.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr NeFileSystemMgr::CreateAlias(const Char* path) {
+ return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindAlias));
+}
+
+/// @brief Creates a node with is a page file.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) {
+ 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) return nullptr;
+
+ if (!r || *r == 0) return nullptr;
+
+ auto catalog = mParser->GetCatalog(path);
+
+ return rtl_node_cast(catalog);
+}
+
+/// @brief Writes to a catalog's fork.
+/// @param node the node ptr.
+/// @param data the data.
+/// @param flags the size.
+/// @return
+Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) {
+ if (!node) return;
+ if (!size) return;
+
+ constexpr auto kDataForkName = kNeFSDataFork;
+ this->Write(kDataForkName, node, data, flags, size);
+}
+
+/// @brief Read from filesystem fork.
+/// @param node the catalog node.
+/// @param flags the flags with it.
+/// @param sz the size to read.
+/// @return
+_Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) {
+ if (!node) return nullptr;
+ if (!size) 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 (!size || size > kNeFSForkSize) return;
+
+ if (!data) return;
+
+ NE_UNUSED(flags);
+
+ if ((reinterpret_cast<NEFS_CATALOG_STRUCT*>(node))->Kind == kNeFSCatalogKindFile)
+ mParser->WriteCatalog(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node)->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 (sz > kNeFSForkSize) return nullptr;
+
+ if (!sz) return nullptr;
+
+ NE_UNUSED(flags);
+
+ if ((reinterpret_cast<NEFS_CATALOG_STRUCT*>(node))->Kind == kNeFSCatalogKindFile)
+ return mParser->ReadCatalog(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node),
+ (flags & kFileFlagRsrc ? true : false), sz, name);
+
+ return nullptr;
+}
+
+/// @brief Seek from Catalog.
+/// @param node
+/// @param off
+/// @retval true always returns false, this is unimplemented.
+/// @retval false always returns this, it is unimplemented.
+
+_Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) {
+ if (!node || off == 0) return false;
+
+ return mParser->Seek(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node), off);
+}
+
+/// @brief Tell where the catalog is.
+/// @param node
+/// @retval true always returns false, this is unimplemented.
+/// @retval false always returns this, it is unimplemented.
+
+_Output SizeT NeFileSystemMgr::Tell(NodePtr node) {
+ if (!node) return kFileMgrNPos;
+
+ return mParser->Tell(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node));
+}
+
+/// @brief Rewinds the catalog.
+/// @param node
+/// @retval true always returns false, this is unimplemented.
+/// @retval false always returns this, it is unimplemented.
+
+_Output Bool NeFileSystemMgr::Rewind(NodePtr node) {
+ if (!node) return false;
+
+ return this->Seek(node, 0);
+}
+
+/// @brief Returns the filesystem parser.
+/// @return the Filesystem parser class.
+_Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept {
+ return mParser;
+}
+} // namespace Kernel
+
+#endif // ifdef __FSKIT_INCLUDES_NEFS__
+#endif // ifndef __NE_MINIMAL_OS__
diff --git a/dev/kernel/src/FS/NeFS.cc b/dev/kernel/src/FS/NeFS.cc
index 9cab99c5..4d9a2be1 100644
--- a/dev/kernel/src/FS/NeFS.cc
+++ b/dev/kernel/src/FS/NeFS.cc
@@ -1,44 +1,43 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#include "NewKit/Macros.h"
#ifdef __FSKIT_INCLUDES_NEFS__
#include <FSKit/NeFS.h>
#include <FirmwareKit/EPM.h>
-#include <modules/AHCI/AHCI.h>
-#include <modules/ATA/ATA.h>
+#include <KernelKit/DriveMgr.h>
#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/User.h>
#include <NewKit/Crc32.h>
-#include <NewKit/KernelPanic.h>
#include <NewKit/KString.h>
+#include <NewKit/KernelPanic.h>
#include <NewKit/Utils.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/User.h>
-#include <KernelKit/DriveMgr.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
+ Define those external symbols, to make the editor shutup
*/
/***********************************************************************************/
/***********************************************************************************/
/// @brief get sector count.
/***********************************************************************************/
-Kernel::SizeT drv_get_sector_count();
+Kernel::SizeT drv_std_get_sector_count();
/***********************************************************************************/
/// @brief get device size.
/***********************************************************************************/
-Kernel::SizeT drv_get_size();
+Kernel::SizeT drv_std_get_size();
#endif
@@ -61,99 +60,87 @@ STATIC MountpointInterface kMountpoint;
/// @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)
- {
- auto catalog = this->GetCatalog(the_fork.CatalogName);
+_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) {
+ auto catalog = this->GetCatalog(the_fork.CatalogName);
- if (!catalog)
- return NO;
+ if (!catalog) return NO;
- Lba lba = catalog->DataFork;
+ Lba lba = catalog->DataFork;
- (void)(kout << "Fork LBA: " << hex_number(lba) << kendl);
+ (Void)(kout << "Fork LBA: " << hex_number(lba) << kendl);
- if (lba < kNeFSCatalogStartAddress)
- return NO;
+ if (lba < kNeFSCatalogStartAddress) return NO;
- auto& drv = kMountpoint.A();
+ auto& drv = kMountpoint.A();
- Lba lba_prev = lba;
+ Lba lba_prev = lba;
- NEFS_FORK_STRUCT prev_fork;
- NEFS_FORK_STRUCT cur_fork;
+ NEFS_FORK_STRUCT prev_fork;
+ NEFS_FORK_STRUCT cur_fork;
- /// do not check for anything. Loop until we get what we want, that is a free fork zone.
- while (drv.fPacket.fPacketGood)
- {
- drv.fPacket.fPacketLba = lba;
- drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drv.fPacket.fPacketContent = &cur_fork;
+ /// do not check for anything. Loop until we get what we want, that is a free fork zone.
+ while (drv.fPacket.fPacketGood) {
+ drv.fPacket.fPacketLba = lba;
+ drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drv.fPacket.fPacketContent = &cur_fork;
- drv.fInput(drv.fPacket);
+ drv.fInput(drv.fPacket);
- (void)(kout << "Next fork: " << hex_number(cur_fork.NextSibling) << kendl);
+ (Void)(kout << "Next fork: " << hex_number(cur_fork.NextSibling) << kendl);
- if (cur_fork.Flags & kNeFSFlagCreated)
- {
- kout << "Error: Fork does exists, not overwriting this one.\r";
+ if (cur_fork.Flags & kNeFSFlagCreated) {
+ kout << "Error: Fork does exists, not overwriting this one.\r";
- /// sanity check.
- if (KStringBuilder::Equals(cur_fork.ForkName, the_fork.ForkName) &&
- KStringBuilder::Equals(cur_fork.CatalogName, the_fork.CatalogName))
- break;
+ /// sanity check.
+ 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;
+ lba_prev = lba;
+ lba = cur_fork.NextSibling;
- prev_fork = cur_fork;
- }
- else
- {
- /// This is a check that we have, in order to link the previous fork
- /// entry.
- if (lba >= kNeFSCatalogStartAddress)
- {
- drv.fPacket.fPacketLba = lba_prev;
- drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drv.fPacket.fPacketContent = &prev_fork;
+ prev_fork = cur_fork;
+ } else {
+ /// This is a check that we have, in order to link the previous fork
+ /// entry.
+ if (lba >= kNeFSCatalogStartAddress) {
+ drv.fPacket.fPacketLba = lba_prev;
+ drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drv.fPacket.fPacketContent = &prev_fork;
- prev_fork.NextSibling = lba;
+ prev_fork.NextSibling = lba;
- /// write to disk.
- drv.fOutput(drv.fPacket);
- }
+ /// write to disk.
+ drv.fOutput(drv.fPacket);
+ }
- break;
- }
- }
+ break;
+ }
+ }
- the_fork.Flags |= kNeFSFlagCreated;
- the_fork.DataOffset = lba - sizeof(NEFS_FORK_STRUCT);
- the_fork.PreviousSibling = lba_prev;
- the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize;
+ the_fork.Flags |= kNeFSFlagCreated;
+ the_fork.DataOffset = lba - sizeof(NEFS_FORK_STRUCT);
+ the_fork.PreviousSibling = lba_prev;
+ the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize;
- drv.fPacket.fPacketLba = lba;
- drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drv.fPacket.fPacketContent = &the_fork;
+ drv.fPacket.fPacketLba = lba;
+ drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drv.fPacket.fPacketContent = &the_fork;
- drv.fOutput(drv.fPacket);
+ drv.fOutput(drv.fPacket);
- fs_ifs_write(&kMountpoint, drv, MountpointInterface::kDriveIndexA);
+ fs_ifs_write(&kMountpoint, drv, MountpointInterface::kDriveIndexA);
- /// log what we have now.
- (void)(kout << "Fork offset is at: " << hex_number(the_fork.DataOffset)
- << kendl);
+ /// log what we have now.
+ (Void)(kout << "Fork offset is at: " << hex_number(the_fork.DataOffset) << kendl);
- (void)(kout << "Wrote fork metadata at: " << hex_number(lba) << kendl);
+ (Void)(kout << "Wrote fork metadata at: " << hex_number(lba) << kendl);
- return YES;
- }
+ return YES;
+ }
- return NO;
+ return NO;
}
/***********************************************************************************/
@@ -163,53 +150,46 @@ _Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork)
/// @return the newly found fork.
/***********************************************************************************/
_Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUCT* catalog,
- _Input const Char* name,
- _Input Boolean is_data)
-{
- auto& drive = kMountpoint.A();
- NEFS_FORK_STRUCT* the_fork = nullptr;
-
- Lba lba = is_data ? catalog->DataFork : catalog->ResourceFork;
-
- while (lba != 0)
- {
- drive.fPacket.fPacketLba = lba;
- drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drive.fPacket.fPacketContent = (VoidPtr)the_fork;
-
- rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, 16);
-
- 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(the_fork->ForkName, name))
- {
- break;
- }
-
- lba = the_fork->NextSibling;
- }
-
- return the_fork;
+ _Input const Char* name,
+ _Input Boolean is_data) {
+ auto& drive = kMountpoint.A();
+ NEFS_FORK_STRUCT* the_fork = nullptr;
+
+ Lba lba = is_data ? catalog->DataFork : catalog->ResourceFork;
+
+ while (lba != 0) {
+ drive.fPacket.fPacketLba = lba;
+ drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drive.fPacket.fPacketContent = (VoidPtr) the_fork;
+
+ rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, 16);
+
+ 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(the_fork->ForkName, name)) {
+ break;
+ }
+
+ lba = the_fork->NextSibling;
+ }
+
+ return the_fork;
}
/***********************************************************************************/
@@ -218,9 +198,8 @@ _Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUC
/// @param name
/// @return catalog pointer.
/***********************************************************************************/
-_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name)
-{
- return this->CreateCatalog(name, 0, kNeFSCatalogKindFile);
+_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) {
+ return this->CreateCatalog(name, 0, kNeFSCatalogKindFile);
}
/***********************************************************************************/
@@ -230,729 +209,601 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char
/// @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";
-
- Lba out_lba = 0UL;
-
- kout << "Checking for path separator...\r";
+_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name,
+ _Input const Int32& flags,
+ _Input const Int32& kind) {
+ kout << "CreateCatalog(*...*)\r";
- /// a directory should have a slash in the end.
- if (kind == kNeFSCatalogKindDir &&
- name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator())
- return nullptr;
+ Lba out_lba = 0UL;
- /// a file shouldn't have a slash in the end.
- if (kind != kNeFSCatalogKindDir &&
- name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator())
- return nullptr;
+ kout << "Checking for path separator...\r";
- NEFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba);
+ /// a directory should have a slash in the end.
+ if (kind == kNeFSCatalogKindDir &&
+ name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator())
+ return nullptr;
- if (catalog_copy)
- {
- kout << "Catalog already exists: " << name << ".\r";
- err_global_get() = kErrorFileExists;
+ /// a file shouldn't have a slash in the end.
+ if (kind != kNeFSCatalogKindDir &&
+ name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator())
+ return nullptr;
- delete catalog_copy;
- catalog_copy = nullptr;
+ NEFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba);
- return nullptr;
- }
+ if (catalog_copy) {
+ kout << "Catalog already exists: " << name << ".\r";
+ err_global_get() = kErrorFileExists;
- Char parent_name[kNeFSCatalogNameLen] = {0};
+ delete catalog_copy;
+ catalog_copy = nullptr;
- for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName)
- {
- parent_name[indexName] = name[indexName];
- }
+ return nullptr;
+ }
- if (*parent_name == 0)
- {
- kout << "Parent name is NUL.\r";
- err_global_get() = kErrorFileNotFound;
- return nullptr;
- }
+ Char parent_name[kNeFSCatalogNameLen] = {0};
- /// Locate parent catalog, to then allocate right after it.
+ for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) {
+ parent_name[indexName] = name[indexName];
+ }
- for (SizeT index_fill = 0; index_fill < rt_string_len(name); ++index_fill)
- {
- parent_name[index_fill] = name[index_fill];
- }
+ if (*parent_name == 0) {
+ kout << "Parent name is NUL.\r";
+ err_global_get() = kErrorFileNotFound;
+ return nullptr;
+ }
- SizeT index_reverse_copy = rt_string_len(parent_name);
+ /// Locate parent catalog, to then allocate right after it.
- // zero character it.
- parent_name[--index_reverse_copy] = 0;
+ for (SizeT index_fill = 0; index_fill < rt_string_len(name); ++index_fill) {
+ parent_name[index_fill] = name[index_fill];
+ }
- // mandatory / character, zero it.
- parent_name[--index_reverse_copy] = 0;
+ SizeT index_reverse_copy = rt_string_len(parent_name);
- while (parent_name[index_reverse_copy] != NeFileSystemHelper::Separator())
- {
- parent_name[index_reverse_copy] = 0;
- --index_reverse_copy;
- }
+ // zero character it.
+ parent_name[--index_reverse_copy] = 0;
- NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba);
+ // mandatory / character, zero it.
+ parent_name[--index_reverse_copy] = 0;
- auto& drive = kMountpoint.A();
+ while (parent_name[index_reverse_copy] != NeFileSystemHelper::Separator()) {
+ parent_name[index_reverse_copy] = 0;
+ --index_reverse_copy;
+ }
- constexpr auto kNeFSCatalogPadding = 4;
+ NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba);
- if (catalog && catalog->Kind == kNeFSCatalogKindFile)
- {
- kout << "Parent is a file.\r";
- delete catalog;
+ auto& drive = kMountpoint.A();
- return nullptr;
- }
- else if (!catalog)
- {
- Char part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
+ if (catalog && catalog->Kind == kNeFSCatalogKindFile) {
+ kout << "Parent is a file.\r";
+ delete catalog;
- drive.fPacket.fPacketContent = part_block;
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ return nullptr;
+ } else if (!catalog) {
+ Char part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- drive.fInput(drive.fPacket);
+ drive.fPacket.fPacketContent = part_block;
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- NEFS_ROOT_PARTITION_BLOCK* blk_nefs = (NEFS_ROOT_PARTITION_BLOCK*)part_block;
- out_lba = blk_nefs->StartCatalog;
- }
+ drive.fInput(drive.fPacket);
- if (drive.fPacket.fPacketReadOnly)
- return nullptr;
+ NEFS_ROOT_PARTITION_BLOCK* blk_nefs = (NEFS_ROOT_PARTITION_BLOCK*) part_block;
+ out_lba = blk_nefs->StartCatalog;
+ }
- NEFS_CATALOG_STRUCT* child_catalog = new NEFS_CATALOG_STRUCT();
+ if (drive.fPacket.fPacketReadOnly) return nullptr;
- 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;
+ NEFS_CATALOG_STRUCT* child_catalog = new NEFS_CATALOG_STRUCT();
- SizeT i = rt_string_len(name);
+ 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;
- // get rid pf \0
- --i;
+ SizeT i = rt_string_len(name);
- if (kind == kNeFSCatalogKindDir)
- --i;
+ // get rid pf \0
+ --i;
- while (name[i] != '/')
- --i;
+ if (kind == kNeFSCatalogKindDir) --i;
- rt_copy_memory((VoidPtr)(name + i), (VoidPtr)child_catalog->Name,
- rt_string_len(name));
+ while (name[i] != '/') --i;
- NEFS_CATALOG_STRUCT temporary_catalog{};
+ rt_copy_memory((VoidPtr) (name + i), (VoidPtr) child_catalog->Name, rt_string_len(name));
- Lba start_free = out_lba;
+ NEFS_CATALOG_STRUCT temporary_catalog{};
- rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"));
+ Lba start_free = out_lba;
- Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
+ rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"));
- drive.fPacket.fPacketContent = buf_part_block;
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- drive.fInput(drive.fPacket);
+ drive.fPacket.fPacketContent = buf_part_block;
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*)buf_part_block;
+ drive.fInput(drive.fPacket);
- drive.fPacket.fPacketContent = &temporary_catalog;
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
+ NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) buf_part_block;
- drive.fInput(drive.fPacket);
+ drive.fPacket.fPacketContent = &temporary_catalog;
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
- if (part_block->FreeCatalog < 1)
- {
- delete child_catalog;
- child_catalog = nullptr;
+ drive.fInput(drive.fPacket);
- return nullptr;
- }
+ if (part_block->FreeCatalog < 1) {
+ delete child_catalog;
+ child_catalog = nullptr;
- kout << "Start finding catalog to allocate or empty space...\r";
+ return nullptr;
+ }
- while (start_free >= part_block->StartCatalog)
- {
- // ========================== //
- // Allocate catalog now...
- // ========================== //
- if ((temporary_catalog.Flags & kNeFSFlagCreated) == 0)
- {
- child_catalog->NextSibling =
- start_free + (sizeof(NEFS_CATALOG_STRUCT) * kNeFSCatalogPadding);
+ kout << "Start finding catalog to allocate or empty space...\r";
- drive.fPacket.fPacketContent = &temporary_catalog;
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
+ while (start_free >= part_block->StartCatalog) {
+ // ========================== //
+ // Allocate catalog now...
+ // ========================== //
+ if ((temporary_catalog.Flags & kNeFSFlagCreated) == 0) {
+ child_catalog->NextSibling = start_free + sizeof(NEFS_CATALOG_STRUCT);
- drive.fOutput(drive.fPacket);
+ drive.fPacket.fPacketContent = &temporary_catalog;
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
- child_catalog->DataFork = part_block->DiskSize - start_free;
- child_catalog->ResourceFork = child_catalog->DataFork;
+ drive.fOutput(drive.fPacket);
- drive.fPacket.fPacketContent = child_catalog;
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
+ child_catalog->DataFork = part_block->DiskSize - start_free;
+ child_catalog->ResourceFork = child_catalog->DataFork;
- drive.fOutput(drive.fPacket);
+ drive.fPacket.fPacketContent = child_catalog;
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
- // Get NeFS partition's block.
+ drive.fOutput(drive.fPacket);
- drive.fPacket.fPacketContent = buf_part_block;
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ // Get NeFS partition's block.
- drive.fInput(drive.fPacket);
+ drive.fPacket.fPacketContent = buf_part_block;
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- part_block->FreeSectors -= 1;
- part_block->CatalogCount += 1;
- part_block->FreeCatalog -= 1;
+ drive.fInput(drive.fPacket);
- drive.fOutput(drive.fPacket);
+ part_block->FreeSectors -= 1;
+ part_block->CatalogCount += 1;
+ part_block->FreeCatalog -= 1;
- delete catalog;
- catalog = nullptr;
+ drive.fOutput(drive.fPacket);
- NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT();
- rt_copy_memory(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT));
+ delete catalog;
+ catalog = nullptr;
- return found_catalog;
- }
- else if ((temporary_catalog.Flags & kNeFSFlagCreated) &&
- KStringBuilder::Equals(temporary_catalog.Name, name))
- {
- rt_copy_memory(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT));
+ NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT();
+ rt_copy_memory(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT));
- return child_catalog;
- }
+ return found_catalog;
+ } else if ((temporary_catalog.Flags & kNeFSFlagCreated) &&
+ KStringBuilder::Equals(temporary_catalog.Name, name)) {
+ rt_copy_memory(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT));
- start_free = start_free + (sizeof(NEFS_CATALOG_STRUCT) * kNeFSCatalogPadding);
+ return child_catalog;
+ }
- drive.fPacket.fPacketContent = &temporary_catalog;
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fPacket.fPacketLba = start_free;
+ start_free = start_free + sizeof(NEFS_CATALOG_STRUCT);
- drive.fInput(drive.fPacket);
- }
-
- delete catalog;
- return nullptr;
-}
+ drive.fPacket.fPacketContent = &temporary_catalog;
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
-_Output Bool NeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name)
-{
- NE_UNUSED(drive);
- NE_UNUSED(end_lba);
- NE_UNUSED(flags);
- NE_UNUSED(part_name);
-
- (void)(kout << "FormatGPT: Not implemented yet.\r");
+ drive.fInput(drive.fPacket);
+ }
- return NO;
+ 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::FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name)
-{
- if (*part_name == 0 ||
- endLba == 0)
- return false;
-
- // verify disk.
- drive->fVerify(drive->fPacket);
-
- rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"));
-
- // if disk isn't good, then error out.
- if (false == drive->fPacket.fPacketGood)
- {
- err_global_get() = kErrorDiskIsCorrupted;
- return false;
- }
-
- Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
-
- Lba start = kNeFSRootCatalogStartAddress;
+bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
+ const Char* part_name) {
+ if (*part_name == 0) return false;
- drive->fPacket.fPacketContent = fs_buf;
- drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive->fPacket.fPacketLba = start;
+ NE_UNUSED(flags);
- drive->fInput(drive->fPacket);
+ // verify disk.
+ drive->fVerify(drive->fPacket);
- if (flags & kNeFSPartitionTypeBoot)
- {
- // make it bootable when needed.
- Char buf_epm[kNeFSSectorSz] = {0};
+ rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"));
- EPM_PART_BLOCK* epm_boot = (EPM_PART_BLOCK*)buf_epm;
+ // if disk isn't good, then error out.
+ if (false == drive->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return false;
+ }
- // Write a new EPM entry.
+ Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- constexpr auto kFsName = "NeFS";
- constexpr auto kBlockName = "NeKernel:";
+ Lba start = drive->fLbaStart;
- epm_boot->FsVersion = kNeFSVersionInteger;
- epm_boot->LbaStart = start;
- epm_boot->SectorSz = kNeFSSectorSz;
+ drive->fPacket.fPacketContent = fs_buf;
+ drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive->fPacket.fPacketLba = start;
- rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(kFsName)), epm_boot->Fs, rt_string_len(kFsName));
- rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(kBlockName)), epm_boot->Name, rt_string_len(kBlockName));
- rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(kEPMMagic)), epm_boot->Magic, rt_string_len(kEPMMagic));
+ drive->fInput(drive->fPacket);
- Lba outEpmLba = kEPMBootBlockLba;
+ NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf;
- Char buf[kNeFSSectorSz] = {0};
+ const auto kNeFSUntitledHD = part_name;
- Lba prevStart = 0;
- SizeT cnt = 0;
+ rt_copy_memory((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen);
- while (drive->fPacket.fPacketGood)
- {
- drive->fPacket.fPacketContent = buf;
- drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK);
- drive->fPacket.fPacketLba = outEpmLba;
+ rt_copy_memory((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName,
+ rt_string_len(kNeFSUntitledHD));
- drive->fInput(drive->fPacket);
+ SizeT sectorCount = drv_std_get_sector_count();
+ SizeT diskSize = drv_std_get_size();
- if (buf[0] == 0)
- {
- epm_boot->LbaStart = prevStart;
+ part_block->Version = kNeFSVersionInteger;
- if (epm_boot->LbaStart)
- epm_boot->LbaStart = outEpmLba;
+ part_block->Kind = kNeFSPartitionTypeStandard;
+ part_block->StartCatalog = start + sizeof(NEFS_CATALOG_STRUCT);
+ part_block->Flags = 0UL;
+ part_block->CatalogCount = sectorCount / sizeof(NEFS_CATALOG_STRUCT);
+ part_block->FreeSectors = sectorCount / sizeof(NEFS_CATALOG_STRUCT) - 1;
+ part_block->SectorCount = sectorCount;
+ part_block->DiskSize = diskSize;
+ part_block->FreeCatalog = sectorCount / sizeof(NEFS_CATALOG_STRUCT) - 1;
- epm_boot->LbaEnd = endLba;
- epm_boot->NumBlocks = cnt;
+ drive->fPacket.fPacketContent = fs_buf;
+ drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive->fPacket.fPacketLba = start;
- drive->fPacket.fPacketContent = buf_epm;
- drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK);
- drive->fPacket.fPacketLba = outEpmLba;
+ drive->fOutput(drive->fPacket);
- 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);
- break;
- }
- else
- {
- prevStart = ((EPM_PART_BLOCK*)buf)->LbaStart + ((EPM_PART_BLOCK*)buf)->LbaEnd;
- }
+ NEFS_CATALOG_STRUCT root{};
- outEpmLba += sizeof(EPM_PART_BLOCK);
- ++cnt;
- }
- }
+ rt_set_memory(&root, 0, sizeof(NEFS_CATALOG_STRUCT));
- // disk isnt faulty and data has been fetched.
- while (drive->fPacket.fPacketGood)
- {
- NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*)fs_buf;
+ root.PrevSibling = part_block->StartCatalog;
+ root.NextSibling = 0UL;
- // check for an empty partition here.
- if (part_block->PartitionName[0] == 0 &&
- rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen))
- {
- // partition is free and valid.
+ root.Kind = kNeFSCatalogKindDir;
+ root.Flags |= kNeFSFlagCreated;
+ root.CatalogFlags |= kNeFSStatusUnlocked;
- part_block->Version = kNeFSVersionInteger;
+ root.Name[0] = '/';
+ root.Name[1] = 0;
- const auto kNeFSUntitledHD = part_name;
+ drive->fPacket.fPacketLba = part_block->StartCatalog;
+ drive->fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive->fPacket.fPacketContent = &root;
- rt_copy_memory((VoidPtr)kNeFSIdent, (VoidPtr)part_block->Ident,
- kNeFSIdentLen);
+ drive->fOutput(drive->fPacket);
- rt_copy_memory((VoidPtr)kNeFSUntitledHD, (VoidPtr)part_block->PartitionName,
- rt_string_len(kNeFSUntitledHD));
-
- SizeT sectorCount = drv_get_sector_count();
- SizeT diskSize = drv_get_size();
-
- part_block->Kind = kNeFSPartitionTypeStandard;
- part_block->StartCatalog = kNeFSCatalogStartAddress;
- part_block->Flags = kNeFSPartitionTypeStandard;
- part_block->CatalogCount = sectorCount / sizeof(NEFS_CATALOG_STRUCT);
- part_block->FreeSectors = sectorCount / sizeof(NEFS_CATALOG_STRUCT);
- part_block->SectorCount = sectorCount;
- part_block->DiskSize = diskSize;
- part_block->FreeCatalog = sectorCount / sizeof(NEFS_CATALOG_STRUCT);
-
- drive->fPacket.fPacketContent = fs_buf;
- drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive->fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
-
- drive->fOutput(drive->fPacket);
-
- (void)(kout << "drive kind: " << drive->fProtocol() << kendl);
-
- (void)(kout << "partition name: " << part_block->PartitionName << kendl);
- (void)(kout << "start: " << 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);
-
- // write the root catalog.
- this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir);
-
- return true;
- }
-
- kout << "partition block already exists.\r";
-
- start += part_block->DiskSize;
-
- drive->fPacket.fPacketContent = fs_buf;
- drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive->fPacket.fPacketLba = start;
-
- drive->fInput(drive->fPacket);
- }
-
- return false;
+ return true;
}
/// @brief Writes the data fork into a specific catalog.
/// @param catalog the catalog itself
/// @param data the data.
/// @return if the catalog w rote 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;
+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 buf = new UInt8[size_of_data];
+ rt_set_memory(buf, 0, size_of_data);
+
+ rt_copy_memory(data, buf, size_of_data);
- auto buf = new UInt8[size_of_data];
- rt_set_memory(buf, 0, size_of_data);
+ auto& drive = kMountpoint.A();
- rt_copy_memory(data, buf, size_of_data);
+ rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"));
- auto& drive = kMountpoint.A();
+ auto catalog = this->GetCatalog(catalog_name);
- rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"));
+ if (!catalog) {
+ delete[] buf;
+ buf = nullptr;
+ return NO;
+ }
- auto catalog = this->GetCatalog(catalog_name);
+ auto startFork = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork;
- if (!catalog)
- {
- delete[] buf;
- buf = nullptr;
- return NO;
- }
+ delete catalog;
+ catalog = nullptr;
- auto startFork = (!is_rsrc_fork) ? catalog->DataFork
- : catalog->ResourceFork;
+ NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT();
+ NEFS_FORK_STRUCT prev_fork{};
- delete catalog;
- catalog = nullptr;
+ (Void)(kout << hex_number(startFork) << kendl);
- NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT();
- NEFS_FORK_STRUCT prev_fork{};
+ // sanity check of the fork position as the condition to run the loop.
+ while (startFork >= kNeFSCatalogStartAddress) {
+ drive.fPacket.fPacketContent = fork_data_input;
+ drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drive.fPacket.fPacketLba = startFork;
- (void)(kout << hex_number(startFork) << kendl);
+ drive.fInput(drive.fPacket);
- // sanity check of the fork position as the condition to run the loop.
- while (startFork >= kNeFSCatalogStartAddress)
- {
- drive.fPacket.fPacketContent = fork_data_input;
- drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drive.fPacket.fPacketLba = startFork;
+ (Void)(kout << hex_number(fork_data_input->DataSize) << kendl);
+ (Void)(kout << hex_number(size_of_data) << kendl);
+ (Void)(kout << hex_number(fork_data_input->Flags) << kendl);
+ (Void)(kout << fork_name << kendl);
+ (Void)(kout << fork_data_input->ForkName << kendl);
+ (Void)(kout << fork_data_input->CatalogName << kendl);
+ (Void)(kout << catalog_name << kendl);
- drive.fInput(drive.fPacket);
+ 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) {
+ // ===================================================== //
+ // Store the blob now, into chunks.
+ // ===================================================== //
- (void)(kout << hex_number(fork_data_input->DataSize) << kendl);
- (void)(kout << hex_number(size_of_data) << kendl);
- (void)(kout << hex_number(fork_data_input->Flags) << kendl);
- (void)(kout << fork_name << kendl);
- (void)(kout << fork_data_input->ForkName << kendl);
- (void)(kout << fork_data_input->CatalogName << kendl);
- (void)(kout << catalog_name << kendl);
+ auto cnt = size_of_data / kNeFSSectorSz;
+ auto cnter = 0UL;
+ auto compute_sz = kNeFSSectorSz;
- 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)
- {
- // ===================================================== //
- // Store the blob now.
- // ===================================================== //
+ if (cnt < 1) break;
- drive.fPacket.fPacketContent = buf;
- drive.fPacket.fPacketSize = size_of_data;
- drive.fPacket.fPacketLba = fork_data_input->DataOffset;
+ while (compute_sz) {
+ drive.fPacket.fPacketContent = buf + (cnter * kNeFSSectorSz);
+ drive.fPacket.fPacketSize = compute_sz;
+ drive.fPacket.fPacketLba = fork_data_input->DataOffset;
- (void)(kout << "data offset: " << hex_number(fork_data_input->DataOffset) << kendl);
+ (Void)(kout << "data offset: " << hex_number(cnt * kNeFSSectorSz) << kendl);
- drive.fOutput(drive.fPacket);
+ drive.fOutput(drive.fPacket);
- (void)(kout << "wrote data at offset: " << hex_number(fork_data_input->DataOffset) << kendl);
+ compute_sz /= (size_of_data / cnt);
+ ++cnter;
+ }
- delete fork_data_input;
- delete[] buf;
+ (Void)(kout << "wrote data at offset: " << hex_number(fork_data_input->DataOffset) << kendl);
- return true;
- }
+ delete fork_data_input;
+ delete[] buf;
- // stumble upon a fork, store it.
+ return true;
+ }
- prev_fork = *fork_data_input;
+ // stumble upon a fork, store it.
- startFork = fork_data_input->NextSibling;
- }
+ prev_fork = *fork_data_input;
- delete[] buf;
- delete fork_data_input;
+ startFork = fork_data_input->NextSibling;
+ }
- return false;
+ delete[] buf;
+ delete fork_data_input;
+
+ 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;
+ 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();
+ NEFS_ROOT_PARTITION_BLOCK part{};
+ auto& drive = kMountpoint.A();
- rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"));
+ rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"));
- drive.fPacket.fPacketContent = &part;
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fPacket.fPacketContent = &part;
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fInput(drive.fPacket);
+ drive.fInput(drive.fPacket);
- auto start_catalog_lba = kNeFSCatalogStartAddress;
+ auto start_catalog_lba = kNeFSCatalogStartAddress;
- if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search)
- {
- Char parent_name[kNeFSCatalogNameLen] = {0};
+ if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search) {
+ Char parent_name[kNeFSCatalogNameLen] = {0};
- for (SizeT indexFill = 0; indexFill < rt_string_len(catalog_name); ++indexFill)
- {
- parent_name[indexFill] = catalog_name[indexFill];
- }
+ for (SizeT indexFill = 0; indexFill < rt_string_len(catalog_name); ++indexFill) {
+ parent_name[indexFill] = catalog_name[indexFill];
+ }
- SizeT indexReverseCopy = rt_string_len(parent_name);
+ SizeT indexReverseCopy = rt_string_len(parent_name);
- // zero character.
- parent_name[--indexReverseCopy] = 0;
+ // zero character.
+ parent_name[--indexReverseCopy] = 0;
- // mandatory '/' character.
- parent_name[--indexReverseCopy] = 0;
+ // mandatory '/' character.
+ parent_name[--indexReverseCopy] = 0;
- while (parent_name[indexReverseCopy] != NeFileSystemHelper::Separator())
- {
- parent_name[indexReverseCopy] = 0;
- --indexReverseCopy;
- }
+ while (parent_name[indexReverseCopy] != NeFileSystemHelper::Separator()) {
+ parent_name[indexReverseCopy] = 0;
+ --indexReverseCopy;
+ }
- NEFS_CATALOG_STRUCT* parent_catalog = this->FindCatalog(parent_name, out_lba);
+ NEFS_CATALOG_STRUCT* parent_catalog = this->FindCatalog(parent_name, out_lba);
- if (parent_catalog &&
- !KStringBuilder::Equals(parent_name, NeFileSystemHelper::Root()))
- {
- start_catalog_lba = parent_catalog->NextSibling;
+ if (parent_catalog && !KStringBuilder::Equals(parent_name, NeFileSystemHelper::Root())) {
+ start_catalog_lba = parent_catalog->NextSibling;
- delete parent_catalog;
- parent_catalog = nullptr;
+ delete parent_catalog;
+ parent_catalog = nullptr;
- local_search = YES;
- }
- else if (parent_catalog)
- {
- start_catalog_lba = parent_catalog->NextSibling;
+ local_search = YES;
+ } else if (parent_catalog) {
+ start_catalog_lba = parent_catalog->NextSibling;
- local_search = YES;
+ local_search = YES;
- delete parent_catalog;
- parent_catalog = nullptr;
- }
- else if (!parent_catalog)
- {
- return nullptr;
- }
- }
+ delete parent_catalog;
+ parent_catalog = nullptr;
+ } else if (!parent_catalog) {
+ return nullptr;
+ }
+ }
- NEFS_CATALOG_STRUCT temporary_catalog{};
+ NEFS_CATALOG_STRUCT temporary_catalog{};
- SizeT i = rt_string_len(catalog_name);
+ SizeT i = rt_string_len(catalog_name);
- // get rid of \0
- --i;
+ // get rid of \0
+ --i;
- if (catalog_name[i] == '/')
- --i;
+ if (catalog_name[i] == '/') --i;
- while (catalog_name[i] != '/')
- --i;
+ while (catalog_name[i] != '/') --i;
- const Char* tmp_name = (catalog_name + i);
+ const Char* tmp_name = (catalog_name + i);
kNeFSSearchThroughCatalogList:
- while (drive.fPacket.fPacketGood)
- {
- drive.fPacket.fPacketLba = start_catalog_lba;
- drive.fPacket.fPacketContent = &temporary_catalog;
- drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ while (drive.fPacket.fPacketGood) {
+ drive.fPacket.fPacketLba = start_catalog_lba;
+ drive.fPacket.fPacketContent = &temporary_catalog;
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
- drive.fInput(drive.fPacket);
+ drive.fInput(drive.fPacket);
- if (KStringBuilder::Equals(tmp_name, temporary_catalog.Name))
- {
- if (temporary_catalog.Status == kNeFSStatusLocked &&
- !search_hidden)
- {
- err_global_get() = kErrorFileLocked;
+ if (KStringBuilder::Equals(tmp_name, temporary_catalog.Name)) {
+ if (temporary_catalog.Status == kNeFSStatusLocked && !search_hidden) {
+ err_global_get() = kErrorFileLocked;
- goto NeFSContinueSearch;
- }
+ goto NeFSContinueSearch;
+ }
- /// ignore unallocated catalog, break
- if (!(temporary_catalog.Flags & kNeFSFlagCreated))
- {
- err_global_get() = kErrorFileNotFound;
+ /// ignore unallocated catalog, break
+ if (!(temporary_catalog.Flags & kNeFSFlagCreated)) {
+ err_global_get() = kErrorFileNotFound;
- goto NeFSContinueSearch;
- }
+ goto NeFSContinueSearch;
+ }
- (void)(kout << "Found available catalog at: " << hex_number(start_catalog_lba) << kendl);
- (void)(kout << "Found available catalog at: " << temporary_catalog.Name << kendl);
+ (Void)(kout << "Found available catalog at: " << hex_number(start_catalog_lba) << kendl);
+ (Void)(kout << "Found available catalog at: " << temporary_catalog.Name << kendl);
- NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT();
- rt_copy_memory(&temporary_catalog, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT));
+ NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT();
+ rt_copy_memory(&temporary_catalog, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT));
- out_lba = start_catalog_lba;
- return catalog_ptr;
- }
+ out_lba = start_catalog_lba;
+ return catalog_ptr;
+ }
- NeFSContinueSearch:
- start_catalog_lba = temporary_catalog.NextSibling;
+ NeFSContinueSearch:
+ start_catalog_lba = temporary_catalog.NextSibling;
- if (start_catalog_lba < part.StartCatalog)
- break;
- }
+ if (start_catalog_lba < part.StartCatalog) break;
+ }
- if (local_search)
- {
- local_search = false;
- start_catalog_lba = part.StartCatalog;
+ if (local_search) {
+ local_search = false;
+ start_catalog_lba = part.StartCatalog;
- goto kNeFSSearchThroughCatalogList;
- }
+ goto kNeFSSearchThroughCatalogList;
+ }
- err_global_get() = kErrorFileNotFound;
+ err_global_get() = kErrorFileNotFound;
- out_lba = 0UL;
+ out_lba = 0UL;
- return nullptr;
+ return nullptr;
}
/// @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);
+_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::GetCatalog(_Input const Char* name) {
+ Lba unused = 0;
+ return this->FindCatalog(name, unused, 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;
+_Output Boolean NeFileSystemParser::CloseCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog) {
+ if (!catalog) return false;
- delete catalog;
- catalog = nullptr;
+ delete catalog;
+ catalog = nullptr;
- return true;
+ 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;
- }
+_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);
+ Lba out_lba = 0;
+ auto catalog = this->FindCatalog(catalog_name, out_lba);
- if (out_lba >= kNeFSCatalogStartAddress ||
- catalog->Flags & kNeFSFlagCreated)
- {
- catalog->Flags &= (~kNeFSFlagCreated);
- catalog->Flags |= kNeFSFlagDeleted;
+ if (out_lba >= kNeFSCatalogStartAddress || catalog->Flags & kNeFSFlagCreated) {
+ catalog->Flags &= (~kNeFSFlagCreated);
+ catalog->Flags |= kNeFSFlagDeleted;
- auto& drive = kMountpoint.A();
+ auto& drive = kMountpoint.A();
- rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"));
+ rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"));
- drive.fPacket.fPacketLba = out_lba; // the catalog position.
- drive.fPacket.fPacketSize =
- sizeof(NEFS_CATALOG_STRUCT); // size of catalog. roughly the sector size.
- drive.fPacket.fPacketContent = catalog; // the catalog itself.
+ drive.fPacket.fPacketLba = out_lba; // the catalog position.
+ drive.fPacket.fPacketSize =
+ sizeof(NEFS_CATALOG_STRUCT); // size of catalog. roughly the sector size.
+ drive.fPacket.fPacketContent = catalog; // the catalog itself.
- drive.fOutput(drive.fPacket); // send packet.
+ drive.fOutput(drive.fPacket); // send packet.
- Char partitionBlockBuf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
+ Char partitionBlockBuf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
- drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
- drive.fPacket.fPacketContent = partitionBlockBuf;
- drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fPacket.fPacketContent = partitionBlockBuf;
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
- drive.fInput(drive.fPacket);
+ drive.fInput(drive.fPacket);
- NEFS_ROOT_PARTITION_BLOCK* part_block =
- reinterpret_cast<NEFS_ROOT_PARTITION_BLOCK*>(partitionBlockBuf);
+ NEFS_ROOT_PARTITION_BLOCK* part_block =
+ reinterpret_cast<NEFS_ROOT_PARTITION_BLOCK*>(partitionBlockBuf);
- --part_block->CatalogCount;
- ++part_block->FreeSectors;
+ --part_block->CatalogCount;
+ ++part_block->FreeSectors;
- drive.fOutput(drive.fPacket);
+ drive.fOutput(drive.fPacket);
- return true;
- }
+ return true;
+ }
- delete catalog;
- catalog = nullptr;
+ delete catalog;
+ catalog = nullptr;
- return false;
+ return false;
}
/// ***************************************************************** ///
@@ -967,55 +818,50 @@ _Output Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_nam
/***********************************************************************************/
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;
- }
+ _Input Bool is_rsrc_fork, _Input SizeT dataSz,
+ _Input const Char* forkName) {
+ if (!catalog) {
+ err_global_get() = kErrorInvalidData;
+ return nullptr;
+ }
- NE_UNUSED(dataSz);
+ NE_UNUSED(dataSz);
- Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork;
+ Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork;
- NEFS_FORK_STRUCT* fs_buf = new NEFS_FORK_STRUCT();
- auto& drive = kMountpoint.A();
+ NEFS_FORK_STRUCT* fs_buf = new NEFS_FORK_STRUCT();
+ auto& drive = kMountpoint.A();
- rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
- rt_string_len("fs/nefs-packet"));
+ rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"));
- NEFS_FORK_STRUCT* fs_fork_data = nullptr;
+ NEFS_FORK_STRUCT* fs_fork_data = nullptr;
- while (dataForkLba > kNeFSCatalogStartAddress)
- {
- drive.fPacket.fPacketLba = dataForkLba;
- drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
- drive.fPacket.fPacketContent = fs_buf;
+ while (dataForkLba > kNeFSCatalogStartAddress) {
+ drive.fPacket.fPacketLba = dataForkLba;
+ drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drive.fPacket.fPacketContent = fs_buf;
- drive.fInput(drive.fPacket);
+ drive.fInput(drive.fPacket);
- fs_fork_data = fs_buf;
+ fs_fork_data = fs_buf;
- (void)(kout << "ForkName: " << fs_fork_data->ForkName << kendl);
- (void)(kout << "CatalogName: " << fs_fork_data->CatalogName << kendl);
+ (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;
+ if (KStringBuilder::Equals(forkName, fs_fork_data->ForkName) &&
+ KStringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName))
+ break;
- dataForkLba = fs_fork_data->NextSibling;
- }
+ dataForkLba = fs_fork_data->NextSibling;
+ }
- if (dataForkLba < kNeFSCatalogStartAddress)
- {
- delete fs_buf;
- return nullptr;
- }
+ if (dataForkLba < kNeFSCatalogStartAddress) {
+ delete fs_buf;
+ return nullptr;
+ }
- return fs_fork_data;
+ return fs_fork_data;
}
/***********************************************************************************/
@@ -1025,13 +871,12 @@ VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* cata
/// @return if the seeking was successful.
/***********************************************************************************/
-bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off)
-{
- NE_UNUSED(catalog);
- NE_UNUSED(off);
+bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off) {
+ NE_UNUSED(catalog);
+ NE_UNUSED(off);
- err_global_get() = kErrorUnimplemented;
- return false;
+ err_global_get() = kErrorUnimplemented;
+ return false;
}
/***********************************************************************************/
@@ -1040,30 +885,30 @@ bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT
/// @return The position on the file.
/***********************************************************************************/
-SizeT NeFileSystemParser::Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog)
-{
- NE_UNUSED(catalog);
+SizeT NeFileSystemParser::Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog) {
+ NE_UNUSED(catalog);
- err_global_get() = kErrorUnimplemented;
- return 0;
+ err_global_get() = kErrorUnimplemented;
+ return 0;
}
-namespace Kernel::NeFS
-{
- /***********************************************************************************/
- /// @brief Construct NeFS drives.
- /***********************************************************************************/
- Boolean fs_init_nefs(Void) noexcept
- {
- kout << "Creating main disk...\r";
+namespace Kernel::NeFS {
+/***********************************************************************************/
+/// @brief Construct NeFS drives.
+/***********************************************************************************/
+Boolean fs_init_nefs(Void) noexcept {
+ kout << "Creating main disk...\r";
- kMountpoint.A() = io_construct_main_drive();
+ kMountpoint.A() = io_construct_main_drive();
- if (kMountpoint.A().fPacket.fPacketReadOnly == YES)
- ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main filesystem cannot be mounted.");
+ if (kMountpoint.A().fPacket.fPacketReadOnly == YES)
+ ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main disk cannot be mounted.");
- return YES;
- }
-} // namespace Kernel::NeFS
+ NeFileSystemParser parser;
+ parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName);
+
+ return YES;
+}
+} // namespace Kernel::NeFS
-#endif // ifdef __FSKIT_INCLUDES_NEFS__
+#endif // ifdef __FSKIT_INCLUDES_NEFS__
diff --git a/dev/kernel/src/FileMgr.cc b/dev/kernel/src/FileMgr.cc
index 1a1ee6b8..06d19e5b 100644
--- a/dev/kernel/src/FileMgr.cc
+++ b/dev/kernel/src/FileMgr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -12,43 +12,37 @@
//! @brief File System Manager API.
/***********************************************************************************/
-namespace Kernel
-{
- STATIC IFilesystemMgr* kMountedFilesystem = nullptr;
-
- /// @brief FilesystemMgr getter.
- /// @return The mounted filesystem.
- _Output IFilesystemMgr* IFilesystemMgr::GetMounted()
- {
- return kMountedFilesystem;
- }
-
- /// @brief Unmount filesystem.
- /// @return The unmounted filesystem.
- _Output IFilesystemMgr* IFilesystemMgr::Unmount()
- {
- if (kMountedFilesystem)
- {
- auto mount = kMountedFilesystem;
- kMountedFilesystem = nullptr;
-
- return mount;
- }
-
- return nullptr;
- }
-
- /// @brief Mount filesystem.
- /// @param mount_ptr The filesystem to mount.
- /// @return if it succeeded true, otherwise false.
- _Output Bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr)
- {
- if (mount_ptr != nullptr)
- {
- kMountedFilesystem = mount_ptr;
- return Yes;
- }
-
- return No;
- }
-} // namespace Kernel
+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
index b14f637f..48ee1ec6 100644
--- a/dev/kernel/src/GUIDWizard.cc
+++ b/dev/kernel/src/GUIDWizard.cc
@@ -1,11 +1,11 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
- File: GUIDWizard.cc
- Purpose: GUID helper code
+ File: GUIDWizard.cc
+ Purpose: GUID helper code
- Revision History:
+ Revision History:
------------------------------------------- */
@@ -17,56 +17,49 @@
// @brief Size of UUID.
#define kUUIDSize 37
-namespace 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};
-
- 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[kUUIDSize];
-
- for (SizeT index = 0; index < 16; ++index)
- {
- buf[index] = seq.Leak()->fU8[index] + kUUIDAsciiBegin;
- }
-
- for (SizeT index = 16; index < 24; ++index)
- {
- buf[index] = seq.Leak()->fU16[index] + kUUIDAsciiBegin;
- }
-
- for (SizeT index = 24; index < 28; ++index)
- {
- buf[index] = seq.Leak()->fU32[index] + kUUIDAsciiBegin;
- }
-
- auto view = KStringBuilder::Construct(buf);
-
- if (view)
- return ErrorOr<Ref<KString>>{view.Leak()};
-
- return ErrorOr<Ref<KString>>{-1};
- }
-} // namespace CF::XRN::Version1
+namespace 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};
+
+ 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[kUUIDSize];
+
+ for (SizeT index = 0; index < 16; ++index) {
+ buf[index] = seq.Leak()->fU8[index] + kUUIDAsciiBegin;
+ }
+
+ for (SizeT index = 16; index < 24; ++index) {
+ buf[index] = seq.Leak()->fU16[index] + kUUIDAsciiBegin;
+ }
+
+ for (SizeT index = 24; index < 28; ++index) {
+ buf[index] = seq.Leak()->fU32[index] + kUUIDAsciiBegin;
+ }
+
+ auto view = KStringBuilder::Construct(buf);
+
+ if (view) return ErrorOr<Ref<KString>>{view.Leak()};
+
+ return ErrorOr<Ref<KString>>{-1};
+}
+} // namespace CF::XRN::Version1
diff --git a/dev/kernel/src/GUIDWrapper.cc b/dev/kernel/src/GUIDWrapper.cc
index f36df112..f87a1bdd 100644
--- a/dev/kernel/src/GUIDWrapper.cc
+++ b/dev/kernel/src/GUIDWrapper.cc
@@ -1,11 +1,9 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <CFKit/GUIDWrapper.h>
-namespace CF::XRN
-{
-}
+namespace CF::XRN {}
diff --git a/dev/kernel/src/Gfx/FBDeviceInterface.cc b/dev/kernel/src/Gfx/FBDeviceInterface.cc
index b3b52934..d588e8c8 100644
--- a/dev/kernel/src/Gfx/FBDeviceInterface.cc
+++ b/dev/kernel/src/Gfx/FBDeviceInterface.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -13,10 +13,8 @@ using namespace Kernel;
/// @param In Drive input
/// @param Cleanup Drive cleanup.
FBDeviceInterface::FBDeviceInterface(void (*out)(IDeviceObject* self, FBDevicePacket* outpacket),
- void (*in)(IDeviceObject* self, FBDevicePacket* inpacket))
- : IDeviceObject(out, in)
-{
-}
+ void (*in)(IDeviceObject* self, FBDevicePacket* inpacket))
+ : IDeviceObject(out, in) {}
/// @brief Class desctructor
FBDeviceInterface::~FBDeviceInterface() = default;
@@ -24,43 +22,29 @@ 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;
+FBDeviceInterface& FBDeviceInterface::operator<<(FBDevicePacket* pckt) {
+ if (!pckt) return *this;
- if (pckt->fX > kHandoverHeader->f_GOP.f_Width ||
- pckt->fY > kHandoverHeader->f_GOP.f_Height)
- return *this;
+ if (pckt->fHeight == 0 || pckt->fWidth == 0) return *this;
- this->fOut(this, pckt);
+ this->fOut(this, pckt);
- return *this;
+ 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;
-
- if (pckt->fX > kHandoverHeader->f_GOP.f_Width ||
- pckt->fY > kHandoverHeader->f_GOP.f_Height)
- return *this;
+FBDeviceInterface& FBDeviceInterface::operator>>(FBDevicePacket* pckt) {
+ if (!pckt) return *this;
- this->fIn(this, pckt);
+ this->fIn(this, pckt);
- return *this;
+ return *this;
}
/// @brief Returns the name of the device interface.
/// @return it's name as a string.
-const Char* FBDeviceInterface::Name() const
-{
- return "/dev/fb{}";
+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
index 96c80c77..c49c3081 100644
--- a/dev/kernel/src/HardwareThreadScheduler.cc
+++ b/dev/kernel/src/HardwareThreadScheduler.cc
@@ -1,13 +1,13 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <ArchKit/ArchKit.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/HardwareThreadScheduler.h>
#include <CFKit/Property.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/ProcessScheduler.h>
/***********************************************************************************/
///! @file HardwareThreadScheduler.cc
@@ -15,211 +15,190 @@
///! @brief Multi processing is needed for multi-tasking operations.
/***********************************************************************************/
-namespace Kernel
-{
- /***********************************************************************************/
- /// @note Those symbols are needed in order to switch and validate the stack.
- /***********************************************************************************/
-
- EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame);
- EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid);
-
- STATIC HardwareThreadScheduler kHardwareThreadScheduler;
-
- ///! A HardwareThread class takes care of it's owned hardware thread.
- ///! It has a stack for it's core.
-
- /***********************************************************************************/
- ///! @brief C++ constructor.
- /***********************************************************************************/
- HardwareThread::HardwareThread() = default;
-
- /***********************************************************************************/
- ///! @brief C++ destructor.
- /***********************************************************************************/
- HardwareThread::~HardwareThread() = default;
-
- /***********************************************************************************/
- //! @brief returns the id of the thread.
- /***********************************************************************************/
- const ThreadID& HardwareThread::ID() noexcept
- {
- return fID;
- }
-
- /***********************************************************************************/
- //! @brief returns the kind of thread we have.
- /***********************************************************************************/
- const ThreadKind& HardwareThread::Kind() noexcept
- {
- return fKind;
- }
-
- /***********************************************************************************/
- //! @brief is the thread busy?
- //! @return whether the thread is busy or not.
- /***********************************************************************************/
- Bool HardwareThread::IsBusy() noexcept
- {
- STATIC Int64 busy_timer = 0U;
- constexpr Int64 kTimeoutMax = 0x1000000; // an arbitrary value used to tell if the timeout hasn't been reached yet.
-
- if (fBusy && (busy_timer > kTimeoutMax))
- {
- busy_timer = 0U;
- fBusy = No;
-
- return No;
- }
-
- ++busy_timer;
-
- 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(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid)
- {
- if (this->IsBusy())
- return NO;
-
- this->fStack = frame;
- this->fPID = pid;
-
- this->fStack->BP = reinterpret_cast<UIntPtr>(image_ptr);
- this->fStack->SP = reinterpret_cast<UIntPtr>(stack_ptr);
-
- Bool ret = mp_register_process(fStack, this->fPID);
-
- if (ret)
- this->Busy(YES);
-
- return ret;
- }
-
- /***********************************************************************************/
- ///! @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[fCurrentThread].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 == 0)
- {
- if (fThreadList[idx].Kind() != kAPSystemReserved)
- {
- fThreadList[idx].fKind = kAPBoot;
- }
- }
- else if (idx >= kMaxAPInsideSched)
- {
- static HardwareThread* kFakeThread = nullptr;
- return {kFakeThread};
- }
-
- 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
+namespace Kernel {
+/***********************************************************************************/
+/// @note Those symbols are needed in order to switch and validate the stack.
+/***********************************************************************************/
+
+EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame);
+EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid);
+
+STATIC HardwareThreadScheduler kHardwareThreadScheduler;
+
+///! A HardwareThread class takes care of it's owned hardware thread.
+///! It has a stack for it's core.
+
+/***********************************************************************************/
+///! @brief C++ constructor.
+/***********************************************************************************/
+HardwareThread::HardwareThread() = default;
+
+/***********************************************************************************/
+///! @brief C++ destructor.
+/***********************************************************************************/
+HardwareThread::~HardwareThread() = default;
+
+/***********************************************************************************/
+//! @brief returns the id of the thread.
+/***********************************************************************************/
+const ThreadID& HardwareThread::ID() noexcept {
+ return fID;
+}
+
+/***********************************************************************************/
+//! @brief returns the kind of thread we have.
+/***********************************************************************************/
+const ThreadKind& HardwareThread::Kind() noexcept {
+ return fKind;
+}
+
+/***********************************************************************************/
+//! @brief is the thread busy?
+//! @return whether the thread is busy or not.
+/***********************************************************************************/
+Bool HardwareThread::IsBusy() noexcept {
+ STATIC Int64 busy_timer = 0U;
+ constexpr Int64 kTimeoutMax =
+ 0x1000000; // an arbitrary value used to tell if the timeout hasn't been reached yet.
+
+ if (fBusy && (busy_timer > kTimeoutMax)) {
+ busy_timer = 0U;
+ fBusy = No;
+
+ return No;
+ }
+
+ ++busy_timer;
+
+ 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(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame,
+ const ThreadID& pid) {
+ if (this->IsBusy()) return NO;
+
+ this->fStack = frame;
+ this->fPID = pid;
+
+ this->fStack->BP = reinterpret_cast<UIntPtr>(image_ptr);
+ this->fStack->SP = reinterpret_cast<UIntPtr>(stack_ptr);
+
+ Bool ret = mp_register_process(fStack, this->fPID);
+
+ if (ret) this->Busy(YES);
+
+ return ret;
+}
+
+/***********************************************************************************/
+///! @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[fCurrentThread].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 == 0) {
+ if (fThreadList[idx].Kind() != kAPSystemReserved) {
+ fThreadList[idx].fKind = kAPBoot;
+ }
+ } else if (idx >= kMaxAPInsideSched) {
+ static HardwareThread* kFakeThread = nullptr;
+ return {kFakeThread};
+ }
+
+ 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/IDylibObject.cc b/dev/kernel/src/IDylibObject.cc
index ef4d5ecf..6def3fcf 100644
--- a/dev/kernel/src/IDylibObject.cc
+++ b/dev/kernel/src/IDylibObject.cc
@@ -7,7 +7,7 @@
* ========================================================
*/
-#include <KernelKit/IDylibObject.h>
#include <KernelKit/DebugOutput.h>
+#include <KernelKit/IDylibObject.h>
using namespace Kernel;
diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc
index 3dd956c9..f9cd758c 100644
--- a/dev/kernel/src/IPEFDylibObject.cc
+++ b/dev/kernel/src/IPEFDylibObject.cc
@@ -1,15 +1,15 @@
/*
* ========================================================
*
-* NeKernel
+ * NeKernel
* Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
*
* ========================================================
*/
#include <KernelKit/DebugOutput.h>
-#include <KernelKit/PEF.h>
#include <KernelKit/IPEFDylibObject.h>
+#include <KernelKit/PEF.h>
#include <KernelKit/ProcessScheduler.h>
#include <KernelKit/ThreadLocalStorage.h>
#include <NewKit/Defines.h>
@@ -18,15 +18,15 @@
Revision History:
- 01/02/24: Reworked dll ABI, expect a rtl_init_dylib and
- rtl_fini_dylib (amlel)
-
- 15/02/24: Breaking changes, changed the name of the
+ 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
+ 07/28/24: Replace rt_library_free with rtl_fini_dylib_pef
- 10/8/24: FIX: Fix log comment.
+ 10/8/24: FIX: Fix log comment.
------------------------------------------- */
@@ -41,47 +41,42 @@ using namespace Kernel;
/** @brief Library initializer. */
/***********************************************************************************/
-EXTERN_C IDylibRef rtl_init_dylib(Process& process)
-{
- IDylibRef dll_obj = tls_new_class<IPEFDylibObject>();
+EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) {
+ IDylibRef dll_obj = tls_new_class<IPEFDylibObject>();
- if (!dll_obj)
- {
- process.Crash();
- return nullptr;
- }
+ if (!dll_obj) {
+ process.Crash();
+ return nullptr;
+ }
- dll_obj->Mount(new IPEFDylibObject::DLL_TRAITS());
+ dll_obj->Mount(new IPEFDylibObject::DLL_TRAITS());
- if (!dll_obj->Get())
- {
- tls_delete_class(dll_obj);
- dll_obj = nullptr;
+ if (!dll_obj->Get()) {
+ tls_delete_class(dll_obj);
+ dll_obj = nullptr;
- process.Crash();
+ process.Crash();
- return nullptr;
- }
+ return nullptr;
+ }
- dll_obj->Get()->ImageObject =
- process.Image.fBlob;
+ dll_obj->Get()->ImageObject = process.Image.LeakBlob().Leak().Leak();
- if (!dll_obj->Get()->ImageObject)
- {
- delete dll_obj->Get();
+ if (!dll_obj->Get()->ImageObject) {
+ delete dll_obj->Get();
- tls_delete_class(dll_obj);
- dll_obj = nullptr;
+ tls_delete_class(dll_obj);
+ dll_obj = nullptr;
- process.Crash();
+ process.Crash();
- return nullptr;
- }
+ return nullptr;
+ }
- dll_obj->Get()->ImageEntrypointOffset =
- dll_obj->Load<VoidPtr>(kPefStart, rt_string_len(kPefStart, 0), kPefCode);
+ dll_obj->Get()->ImageEntrypointOffset =
+ dll_obj->Load<VoidPtr>(kPefStart, rt_string_len(kPefStart, 0), kPefCode);
- return dll_obj;
+ return dll_obj;
}
/***********************************************************************************/
@@ -91,21 +86,19 @@ EXTERN_C IDylibRef rtl_init_dylib(Process& process)
/** @param successful Reports if successful or not. */
/***********************************************************************************/
-EXTERN_C Void rtl_fini_dylib(Process& process, IDylibRef dll_obj, BOOL* successful)
-{
- MUST_PASS(successful);
+EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) {
+ MUST_PASS(successful);
- // sanity check (will also trigger a bug check if this fails)
- if (dll_obj == nullptr)
- {
- *successful = false;
- process.Crash();
- }
+ // 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;
+ delete dll_obj->Get();
+ delete dll_obj;
- dll_obj = nullptr;
+ dll_obj = nullptr;
- *successful = true;
+ *successful = true;
}
diff --git a/dev/kernel/src/IndexableProperty.cc b/dev/kernel/src/IndexableProperty.cc
index d586398d..8dd216c8 100644
--- a/dev/kernel/src/IndexableProperty.cc
+++ b/dev/kernel/src/IndexableProperty.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -14,44 +14,36 @@
#define kMaxLenIndexer (256U)
-namespace Kernel
-{
- namespace Indexer
- {
- Index& IndexableProperty::Leak() noexcept
- {
- return fIndex;
- }
-
- Void IndexableProperty::AddFlag(Int16 flag)
- {
- fFlags |= flag;
- }
-
- Void IndexableProperty::RemoveFlag(Int16 flag)
- {
- fFlags &= flag;
- }
-
- Int16 IndexableProperty::HasFlag(Int16 flag)
- {
- return fFlags & flag;
- }
-
- /// @brief Index a file into the indexer instance.
- /// @param filename filesystem path to access.
- /// @param filenameLen used bytes in path.
- /// @param indexer the filesystem indexer.
- /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)).
- Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer)
- {
- if (!indexer.HasFlag(kIndexerClaimed))
- {
- indexer.AddFlag(kIndexerClaimed);
- rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen);
-
- (void)(kout << "FSKit: Indexed new file: " << filename << kendl);
- }
- }
- } // namespace Indexer
-} // namespace Kernel
+namespace Kernel {
+namespace Indexer {
+ Index& IndexableProperty::Leak() noexcept {
+ return fIndex;
+ }
+
+ Void IndexableProperty::AddFlag(Int16 flag) {
+ fFlags |= flag;
+ }
+
+ Void IndexableProperty::RemoveFlag(Int16 flag) {
+ fFlags &= flag;
+ }
+
+ Int16 IndexableProperty::HasFlag(Int16 flag) {
+ return fFlags & flag;
+ }
+
+ /// @brief Index a file into the indexer instance.
+ /// @param filename filesystem path to access.
+ /// @param filenameLen used bytes in path.
+ /// @param indexer the filesystem indexer.
+ /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)).
+ Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) {
+ if (!indexer.HasFlag(kIndexerClaimed)) {
+ indexer.AddFlag(kIndexerClaimed);
+ rt_copy_memory((VoidPtr) indexer.Leak().Path, (VoidPtr) filename, filenameLen);
+
+ (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
index 187da6fd..9264b2b8 100644
--- a/dev/kernel/src/Json.cc
+++ b/dev/kernel/src/Json.cc
@@ -1,10 +1,10 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <NewKit/Json.h>
/// @brief Undefined object, is null in length.
-rtl_init_object(Kernel::Json::kNull, Kernel::Json);
+RTL_INIT_OBJECT(Kernel::Json::kNull, Kernel::Json);
diff --git a/dev/kernel/src/KPC.cc b/dev/kernel/src/KPC.cc
index 0e6c45bb..8937d19a 100644
--- a/dev/kernel/src/KPC.cc
+++ b/dev/kernel/src/KPC.cc
@@ -1,45 +1,39 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <KernelKit/KPC.h>
-#include <NewKit/KernelPanic.h>
#include <KernelKit/MemoryMgr.h>
+#include <NewKit/KernelPanic.h>
-namespace Kernel
-{
- STATIC Bool kRaiseOnBugCheck = false;
+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];
+/// @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 (ptr == nullptr) goto bug_check_fail;
- if (!mm_is_valid_heap(ptr))
- goto bug_check_fail;
+ if (!mm_is_valid_heap(ptr)) goto bug_check_fail;
- delete[] ptr;
+ delete[] ptr;
- return Yes;
+ return Yes;
- bug_check_fail:
- if (ptr)
- delete[] ptr;
+bug_check_fail:
+ if (ptr) delete[] ptr;
- ptr = nullptr;
+ ptr = nullptr;
- if (kRaiseOnBugCheck)
- {
- ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR);
- }
+ if (kRaiseOnBugCheck) {
+ ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR);
+ }
- return No;
- }
-} // namespace Kernel
+ return No;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/KString.cc b/dev/kernel/src/KString.cc
index c1a8db65..479eb2fc 100644
--- a/dev/kernel/src/KString.cc
+++ b/dev/kernel/src/KString.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -10,209 +10,171 @@
/// @file KString.cc
/// @brief Kernel String manipulation file.
-namespace Kernel
-{
- Char* KString::Data()
- {
- return this->fData;
- }
-
- const Char* KString::CData() const
- {
- return const_cast<const Char*>(this->fData);
- }
-
- Size KString::Length() const
- {
- return this->fDataSz;
- }
-
- bool KString::operator==(const KString& rhs) const
- {
- if (rhs.Length() != this->Length())
- return false;
-
- for (Size index = 0; index < this->Length(); ++index)
- {
- if (rhs.fData[index] != this->fData[index])
- return false;
- }
-
- return true;
- }
-
- bool KString::operator==(const Char* rhs) const
- {
- if (rt_string_len(rhs) != this->Length())
- return false;
-
- for (Size index = 0; index < rt_string_len(rhs); ++index)
- {
- if (rhs[index] != this->fData[index])
- return false;
- }
-
- return true;
- }
-
- bool KString::operator!=(const KString& rhs) const
- {
- if (rhs.Length() != this->Length())
- return false;
-
- for (Size index = 0; index < rhs.Length(); ++index)
- {
- if (rhs.fData[index] == this->fData[index])
- return false;
- }
-
- return true;
- }
-
- bool KString::operator!=(const Char* rhs) const
- {
- if (rt_string_len(rhs) != this->Length())
- return false;
-
- for (Size index = 0; index < rt_string_len(rhs); ++index)
- {
- if (rhs[index] == this->fData[index])
- return false;
- }
-
- return true;
- }
-
- ErrorOr<KString> KStringBuilder::Construct(const Char* data)
- {
- if (!data || *data == 0)
- return {};
-
- KString* view = new KString(rt_string_len(data));
- (*view) += data;
-
- return ErrorOr<KString>(*view);
- }
-
- const Char* KStringBuilder::FromBool(const Char* fmt, bool i)
- {
- if (!fmt)
- return ("?");
-
- const Char* boolean_expr = i ? "YES" : "NO";
- Char* ret = (Char*)RTL_ALLOCA(rt_string_len(boolean_expr) + rt_string_len(fmt));
-
- if (!ret)
- return ("?");
-
- const auto fmt_len = rt_string_len(fmt);
- const auto res_len = rt_string_len(boolean_expr);
-
- for (Size idx = 0; idx < fmt_len; ++idx)
- {
- if (fmt[idx] == '%')
- {
- SizeT result_cnt = idx;
-
- for (auto y_idx = idx; y_idx < res_len; ++y_idx)
- {
- ret[result_cnt] = boolean_expr[y_idx];
- ++result_cnt;
- }
-
- break;
- }
-
- ret[idx] = fmt[idx];
- }
-
- return ret;
- }
-
- bool KStringBuilder::Equals(const Char* lhs, const Char* rhs)
- {
- if (rt_string_len(rhs) != rt_string_len(lhs))
- return false;
-
- for (Size index = 0; index < rt_string_len(rhs); ++index)
- {
- if (rhs[index] != lhs[index])
- return false;
- }
-
- return true;
- }
-
- bool KStringBuilder::Equals(const WideChar* lhs, const WideChar* rhs)
- {
- for (Size index = 0; rhs[index] != 0; ++index)
- {
- if (rhs[index] != lhs[index])
- return false;
- }
-
- return true;
- }
-
- const Char* KStringBuilder::Format(const Char* fmt, const Char* fmt2)
- {
- if (!fmt || !fmt2)
- return ("?");
-
- Char* ret =
- (Char*)RTL_ALLOCA(sizeof(char) * (rt_string_len(fmt2) + rt_string_len(fmt)));
-
- if (!ret)
- return ("?");
-
- const auto len = rt_string_len(fmt);
-
- for (Size idx = 0; idx < len; ++idx)
- {
- if (fmt[idx] == '%' && idx < rt_string_len(fmt) && fmt[idx] == 's')
- {
- Size result_cnt = idx;
-
- for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx)
- {
- ret[result_cnt] = fmt2[y_idx];
- ++result_cnt;
- }
- }
-
- ret[idx] = fmt[idx];
- }
-
- return ret;
- }
-
- STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur)
- {
- SizeT sz_rhs = rt_string_len(rhs);
- SizeT rhs_i = 0;
-
- for (; rhs_i < sz_rhs; ++rhs_i)
- {
- lhs[rhs_i + cur] = rhs[rhs_i];
- }
- }
-
- KString& KString::operator+=(const Char* rhs)
- {
- rt_string_append(this->fData, rhs, this->fCur);
- this->fCur += rt_string_len(rhs);
-
- return *this;
- }
-
- KString& KString::operator+=(const KString& rhs)
- {
- if (rt_string_len(rhs.fData) > this->Length())
- return *this;
-
- rt_string_append(this->fData, const_cast<Char*>(rhs.fData), this->fCur);
- this->fCur += rt_string_len(const_cast<Char*>(rhs.fData));
-
- return *this;
- }
-} // namespace Kernel
+namespace Kernel {
+Char* KString::Data() {
+ return this->fData;
+}
+
+const Char* KString::CData() const {
+ return const_cast<const Char*>(this->fData);
+}
+
+Size KString::Length() const {
+ return this->fDataSz;
+}
+
+bool KString::operator==(const KString& rhs) const {
+ if (rhs.Length() != this->Length()) return false;
+
+ for (Size index = 0; index < this->Length(); ++index) {
+ if (rhs.fData[index] != this->fData[index]) return false;
+ }
+
+ return true;
+}
+
+bool KString::operator==(const Char* rhs) const {
+ if (rt_string_len(rhs) != this->Length()) return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index) {
+ if (rhs[index] != this->fData[index]) return false;
+ }
+
+ return true;
+}
+
+bool KString::operator!=(const KString& rhs) const {
+ if (rhs.Length() != this->Length()) return false;
+
+ for (Size index = 0; index < rhs.Length(); ++index) {
+ if (rhs.fData[index] == this->fData[index]) return false;
+ }
+
+ return true;
+}
+
+bool KString::operator!=(const Char* rhs) const {
+ if (rt_string_len(rhs) != this->Length()) return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index) {
+ if (rhs[index] == this->fData[index]) return false;
+ }
+
+ return true;
+}
+
+ErrorOr<KString> KStringBuilder::Construct(const Char* data) {
+ if (!data || *data == 0) return {};
+
+ KString* view = new KString(rt_string_len(data));
+ (*view) += data;
+
+ return ErrorOr<KString>(*view);
+}
+
+const Char* KStringBuilder::FromBool(const Char* fmt, bool i) {
+ if (!fmt) return ("?");
+
+ const Char* boolean_expr = i ? "YES" : "NO";
+ Char* ret = (Char*) RTL_ALLOCA(rt_string_len(boolean_expr) + rt_string_len(fmt));
+
+ if (!ret) return ("?");
+
+ const auto fmt_len = rt_string_len(fmt);
+ const auto res_len = rt_string_len(boolean_expr);
+
+ for (Size idx = 0; idx < fmt_len; ++idx) {
+ if (fmt[idx] == '%') {
+ SizeT result_cnt = idx;
+
+ for (auto y_idx = idx; y_idx < res_len; ++y_idx) {
+ ret[result_cnt] = boolean_expr[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+}
+
+bool KStringBuilder::Equals(const Char* lhs, const Char* rhs) {
+ if (rt_string_len(rhs) != rt_string_len(lhs)) return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index) {
+ if (rhs[index] != lhs[index]) return false;
+ }
+
+ return true;
+}
+
+/// @note This is unsafe!!!
+bool KStringBuilder::Equals(const Utf8Char* lhs, const Utf8Char* rhs) {
+ for (Size index = 0; index < urt_string_len(rhs); ++index) {
+ if (rhs[index] != lhs[index]) return false;
+ }
+
+ return true;
+}
+
+bool KStringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) {
+ for (Size index = 0; rhs[index] != 0; ++index) {
+ if (rhs[index] != lhs[index]) return false;
+ }
+
+ return true;
+}
+
+const Char* KStringBuilder::Format(const Char* fmt, const Char* fmt2) {
+ if (!fmt || !fmt2) return ("?");
+
+ Char* ret = (Char*) RTL_ALLOCA(sizeof(char) * (rt_string_len(fmt2) + rt_string_len(fmt)));
+
+ if (!ret) return ("?");
+
+ const auto len = rt_string_len(fmt);
+
+ for (Size idx = 0; idx < len; ++idx) {
+ if (fmt[idx] == '%' && idx < rt_string_len(fmt) && fmt[idx] == 's') {
+ Size result_cnt = idx;
+
+ for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx) {
+ ret[result_cnt] = fmt2[y_idx];
+ ++result_cnt;
+ }
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+}
+
+STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur) {
+ SizeT sz_rhs = rt_string_len(rhs);
+ SizeT rhs_i = 0;
+
+ for (; rhs_i < sz_rhs; ++rhs_i) {
+ lhs[rhs_i + cur] = rhs[rhs_i];
+ }
+}
+
+KString& KString::operator+=(const Char* rhs) {
+ rt_string_append(this->fData, rhs, this->fCur);
+ this->fCur += rt_string_len(rhs);
+
+ return *this;
+}
+
+KString& KString::operator+=(const KString& rhs) {
+ if (rt_string_len(rhs.fData) > this->Length()) return *this;
+
+ rt_string_append(this->fData, const_cast<Char*>(rhs.fData), this->fCur);
+ this->fCur += rt_string_len(const_cast<Char*>(rhs.fData));
+
+ return *this;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/KernelProcessScheduler.cc b/dev/kernel/src/KernelProcessScheduler.cc
index a1185a91..d0abfce0 100644
--- a/dev/kernel/src/KernelProcessScheduler.cc
+++ b/dev/kernel/src/KernelProcessScheduler.cc
@@ -1,9 +1,9 @@
/* -------------------------------------------
- Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
- FILE: KernelProcessScheduler.cc
- PURPOSE: Privileged/Ring-0 process scheduler.
+ FILE: KernelProcessScheduler.cc
+ PURPOSE: Privileged/Ring-0 process scheduler.
------------------------------------------- */
@@ -15,6 +15,4 @@
/// @author Amlal El Mahrouss (amlal@nekernel.org)
/***********************************************************************************/
-namespace Kernel
-{
-} // namespace Kernel \ No newline at end of file
+namespace Kernel {} // namespace Kernel \ No newline at end of file
diff --git a/dev/kernel/src/LockDelegate.cc b/dev/kernel/src/LockDelegate.cc
index 6afce8a2..d02de3e4 100644
--- a/dev/kernel/src/LockDelegate.cc
+++ b/dev/kernel/src/LockDelegate.cc
@@ -1,12 +1,11 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <KernelKit/LockDelegate.h>
-namespace Kernel
-{
- /// @note Leave it empty for now.
-} // namespace Kernel
+namespace Kernel {
+/// @note Leave it empty for now.
+} // namespace Kernel
diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc
index 8020ca1c..cb33753d 100644
--- a/dev/kernel/src/MemoryMgr.cc
+++ b/dev/kernel/src/MemoryMgr.cc
@@ -1,296 +1,274 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
+#include <ArchKit/ArchKit.h>
#include <KernelKit/DebugOutput.h>
#include <KernelKit/KPC.h>
#include <KernelKit/MemoryMgr.h>
#include <NewKit/Crc32.h>
#include <NewKit/PageMgr.h>
#include <NewKit/Utils.h>
-#include <ArchKit/ArchKit.h>
/* -------------------------------------------
Revision History:
- 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field.
- 20/10/24: FIX: Fix mm_new_ and mm_delete_ APIs inside MemoryMgr.h header. (amlal)
- 27/01/25: REFACTOR: Reworked code as the memory manager.
- 25/03/25: REFACTOR: Refactor MemoryMgr code and log freed address location.
+ 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 MemoryMgr.h header. (amlal)
+ 27/01/25: REFACTOR: Reworked code as the memory manager.
+ 25/03/25: REFACTOR: Refactor MemoryMgr code and log freed address location.
------------------------------------------- */
//! @file MemoryMgr.cc
//! @brief Heap algorithm that serves as the main memory manager.
-#define kMemoryMgrMagic (0xD4D75)
+#define kMemoryMgrMagic (0xD4D75)
#define kMemoryMgrAlignSz (4)
-namespace Kernel
-{
- /// @brief Implementation details.
- namespace Detail
- {
- struct PACKED MM_INFORMATION_BLOCK;
+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[kMemoryMgrAlignSz];
+ };
+
+ /// @brief Check for heap address validity.
+ /// @param heap_ptr The address_ptr to check.
+ /// @return Bool if the pointer is valid or not.
+ _Output auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool {
+ if (!heap_ptr) return false;
+
+ IntPtr base_heap = ((IntPtr) heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK);
+
+ /// Add that check in case we're having an integer underflow. ///
+
+ if (base_heap < 0) {
+ return false;
+ }
+
+ return true;
+ }
- /// @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;
+ typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR;
+} // namespace Detail
- ///! @brief Is the heap present?
- UInt8 fPresent : 1;
+/// @brief Declare a new size for ptr_heap.
+/// @param ptr_heap the pointer.
+/// @return Newly allocated heap header.
+_Output auto mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) -> VoidPtr {
+ if (Detail::mm_check_heap_address(ptr_heap) == No) return nullptr;
- /// @brief Is this value writable?
- UInt8 fWriteRead : 1;
+ if (!ptr_heap || new_sz < 1) return nullptr;
- /// @brief Is this value owned by the user?
- UInt8 fUser : 1;
+ kout << "This function is not implemented by the kernel yet.\r";
- /// @brief Is this a page pointer?
- UInt8 fPage : 1;
+ ke_panic(RUNTIME_CHECK_INVALID);
- /// @brief 32-bit CRC checksum.
- UInt32 fCRC32;
+ return nullptr;
+}
- /// @brief 64-bit Allocation flags.
- UInt16 fFlags;
+/// @brief Allocate chunk of memory.
+/// @param sz Size of pointer
+/// @param wr Read Write bit.
+/// @param user User enable bit.
+/// @return The newly allocated pointer.
+_Output VoidPtr mm_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount) {
+ auto sz_fix = sz;
- /// @brief 64-bit pointer size.
- SizeT fSize;
+ if (sz_fix == 0) return nullptr;
- /// @brief 64-bit target offset pointer.
- UIntPtr fOffset;
+ sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK);
- /// @brief Padding.
- UInt32 fPad;
+ PageMgr page_mgr;
+ auto wrapper = page_mgr.Request(wr, user, No, sz_fix, pad_amount);
- /// @brief Padding bytes for header.
- UInt8 fPadding[kMemoryMgrAlignSz];
- };
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>(wrapper.VirtualAddress() +
+ sizeof(Detail::MM_INFORMATION_BLOCK));
- /// @brief Check for heap address validity.
- /// @param heap_ptr The address_ptr to check.
- /// @return Bool if the pointer is valid or not.
- _Output auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool
- {
- if (!heap_ptr)
- return false;
+ heap_info_ptr->fSize = sz_fix;
+ heap_info_ptr->fMagic = kMemoryMgrMagic;
+ heap_info_ptr->fCRC32 = 0; // 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;
- IntPtr base_heap = ((IntPtr)heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK);
+ rt_set_memory(heap_info_ptr->fPadding, 0, kMemoryMgrAlignSz);
- /// Add that check in case we're having an integer underflow. ///
+ auto result = reinterpret_cast<VoidPtr>(heap_info_ptr->fOffset);
- if (base_heap < 0)
- {
- return false;
- }
+ (Void)(kout << "Registered heap address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr))
+ << kendl);
- return true;
- }
+ return result;
+}
- typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR;
- } // namespace Detail
+/// @brief Makes a page heap.
+/// @param heap_ptr the pointer to make a page heap.
+/// @return kErrorSuccess if successful, otherwise an error code.
+_Output Int32 mm_make_page(VoidPtr heap_ptr) {
+ if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent;
- /// @brief Declare a new size for ptr_heap.
- /// @param ptr_heap the pointer.
- /// @return Newly allocated heap header.
- _Output auto mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) -> VoidPtr
- {
- if (Detail::mm_check_heap_address(ptr_heap) == No)
- return nullptr;
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
- if (!ptr_heap || new_sz < 1)
- return nullptr;
+ if (!heap_info_ptr) return kErrorHeapNotPresent;
- kout << "This function is not implemented by the kernel itself.\r";
+ heap_info_ptr->fPage = true;
- ke_panic(RUNTIME_CHECK_INVALID);
+ (Void)(kout << "Registered page address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr))
+ << kendl);
- return nullptr;
- }
+ return kErrorSuccess;
+}
- /// @brief Allocate chunk of memory.
- /// @param sz Size of pointer
- /// @param wr Read Write bit.
- /// @param user User enable bit.
- /// @return The newly allocated pointer.
- _Output VoidPtr mm_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount)
- {
- auto sz_fix = sz;
+/// @brief Overwrites and set the flags of a heap header.
+/// @param heap_ptr the pointer to update.
+/// @param flags the flags to set.
+_Output Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags) {
+ if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent;
- if (sz_fix == 0)
- return nullptr;
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
- sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK);
-
- PageMgr heap_mgr;
- auto wrapper = heap_mgr.Request(wr, user, No, sz_fix, pad_amount);
+ if (!heap_info_ptr) return kErrorHeapNotPresent;
- 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 = kMemoryMgrMagic;
- heap_info_ptr->fCRC32 = 0; // 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;
+ heap_info_ptr->fFlags = flags;
- rt_set_memory(heap_info_ptr->fPadding, 0, kMemoryMgrAlignSz);
+ return kErrorSuccess;
+}
- auto result = reinterpret_cast<VoidPtr>(heap_info_ptr->fOffset);
+/// @brief Gets the flags of a heap header.
+/// @param heap_ptr the pointer to get.
+_Output UInt64 mm_get_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));
- (void)(kout << "Registered heap address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl);
+ if (!heap_info_ptr) return kErrorHeapNotPresent;
+
+ return heap_info_ptr->fFlags;
+}
- return result;
- }
+/// @brief Declare pointer as free.
+/// @param heap_ptr the pointer.
+/// @return
+_Output Int32 mm_delete_heap(VoidPtr heap_ptr) {
+ if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent;
+
+ Detail::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 == kMemoryMgrMagic) {
+ 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 << "Address has been successfully freed: " << hex_number((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};
+
+ PageMgr page_mgr;
+ page_mgr.Free(pte_address);
+
+ return kErrorSuccess;
+ }
+
+ return kErrorInternal;
+}
- /// @brief Makes a page heap.
- /// @param heap_ptr the pointer to make a page heap.
- /// @return kErrorSuccess if successful, otherwise an error code.
- _Output Int32 mm_make_page(VoidPtr heap_ptr)
- {
- if (Detail::mm_check_heap_address(heap_ptr) == No)
- return kErrorHeapNotPresent;
-
- Detail::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 << "Registered page 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_make_flags(VoidPtr heap_ptr, UInt64 flags)
- {
- if (Detail::mm_check_heap_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_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_delete_heap(VoidPtr heap_ptr)
- {
- if (Detail::mm_check_heap_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 == kMemoryMgrMagic)
- {
- 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 << "Address has been successfully freed: " << hex_number((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};
-
- PageMgr heap_mgr;
- heap_mgr.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_heap(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 == kMemoryMgrMagic);
- }
-
- return No;
- }
-
- /// @brief Protect the heap with a CRC value.
- /// @param heap_ptr HIB pointer.
- /// @return if it valid: point has crc now., otherwise fail.
- _Output Boolean mm_protect_heap(VoidPtr heap_ptr)
- {
- if (heap_ptr)
- {
- Detail::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 && kMemoryMgrMagic == 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
+/// @brief Check if pointer is a valid Kernel pointer.
+/// @param heap_ptr the pointer
+/// @return if it exists.
+_Output Boolean mm_is_valid_heap(VoidPtr heap_ptr) {
+ if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) {
+ Detail::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 == kMemoryMgrMagic);
+ }
+
+ return No;
+}
+
+/// @brief Protect the heap with a CRC value.
+/// @param heap_ptr HIB pointer.
+/// @return if it valid: point has crc now., otherwise fail.
+_Output Boolean mm_protect_heap(VoidPtr heap_ptr) {
+ if (heap_ptr) {
+ Detail::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 && kMemoryMgrMagic == 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/MutableArray.cc b/dev/kernel/src/MutableArray.cc
index aa18ac39..4b07f9ae 100644
--- a/dev/kernel/src/MutableArray.cc
+++ b/dev/kernel/src/MutableArray.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/Network/IPAddr.cc b/dev/kernel/src/Network/IPAddr.cc
index 02e2c258..4437df22 100644
--- a/dev/kernel/src/Network/IPAddr.cc
+++ b/dev/kernel/src/Network/IPAddr.cc
@@ -1,129 +1,100 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <NetworkKit/IP.h>
#include <NewKit/Utils.h>
-namespace Kernel
-{
- Char* RawIPAddress::Address()
- {
- return fAddr;
- }
-
- RawIPAddress::RawIPAddress(char bytes[4])
- {
- rt_copy_memory(bytes, fAddr, 4);
- }
-
- BOOL RawIPAddress::operator==(const RawIPAddress& ipv4)
- {
- for (Size index = 0; index < 4; ++index)
- {
- if (ipv4.fAddr[index] != fAddr[index])
- return false;
- }
-
- return true;
- }
-
- BOOL RawIPAddress::operator!=(const RawIPAddress& ipv4)
- {
- for (Size index = 0; index < 4; ++index)
- {
- if (ipv4.fAddr[index] == fAddr[index])
- return false;
- }
-
- return true;
- }
-
- Char& RawIPAddress::operator[](const Size& index)
- {
- kout << "[RawIPAddress::operator[]] Fetching Index...\r";
-
- static char IP_PLACEHOLDER = '0';
- if (index > 4)
- return IP_PLACEHOLDER;
-
- return fAddr[index];
- }
-
- RawIPAddress6::RawIPAddress6(char bytes[8])
- {
- rt_copy_memory(bytes, fAddr, 8);
- }
-
- char& RawIPAddress6::operator[](const Size& index)
- {
- kout << "[RawIPAddress6::operator[]] Fetching Index...\r";
-
- static char IP_PLACEHOLDER = '0';
- if (index > 8)
- return IP_PLACEHOLDER;
-
- return fAddr[index];
- }
-
- bool RawIPAddress6::operator==(const RawIPAddress6& ipv6)
- {
- for (SizeT index = 0; index < 8; ++index)
- {
- if (ipv6.fAddr[index] != fAddr[index])
- return false;
- }
-
- return true;
- }
-
- bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6)
- {
- for (SizeT index = 0; index < 8; ++index)
- {
- if (ipv6.fAddr[index] == fAddr[index])
- return false;
- }
-
- return true;
- }
-
- ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress6>& ipv6)
- {
- auto str = KStringBuilder::Construct(ipv6.Leak().Address());
- return str;
- }
-
- ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4)
- {
- auto str = KStringBuilder::Construct(ipv4.Leak().Address());
- return str;
- }
-
- bool IPFactory::IpCheckVersion4(const Char* ip)
- {
- if (!ip)
- return NO;
-
- Int32 cnter = 0;
-
- for (SizeT base = 0; base < rt_string_len(ip); ++base)
- {
- if (ip[base] == '.')
- {
- cnter = 0;
- }
- else
- {
- if (cnter == 3)
- return false;
-
- ++cnter;
- }
- }
-
- return true;
- }
-} // namespace Kernel
+namespace Kernel {
+Char* RawIPAddress::Address() {
+ return fAddr;
+}
+
+RawIPAddress::RawIPAddress(char bytes[4]) {
+ rt_copy_memory(bytes, fAddr, 4);
+}
+
+BOOL RawIPAddress::operator==(const RawIPAddress& ipv4) {
+ for (Size index = 0; index < 4; ++index) {
+ if (ipv4.fAddr[index] != fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+BOOL RawIPAddress::operator!=(const RawIPAddress& ipv4) {
+ for (Size index = 0; index < 4; ++index) {
+ if (ipv4.fAddr[index] == fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+Char& RawIPAddress::operator[](const Size& index) {
+ kout << "[RawIPAddress::operator[]] Fetching Index...\r";
+
+ static char IP_PLACEHOLDER = '0';
+ if (index > 4) return IP_PLACEHOLDER;
+
+ return fAddr[index];
+}
+
+RawIPAddress6::RawIPAddress6(char bytes[8]) {
+ rt_copy_memory(bytes, fAddr, 8);
+}
+
+char& RawIPAddress6::operator[](const Size& index) {
+ kout << "[RawIPAddress6::operator[]] Fetching Index...\r";
+
+ static char IP_PLACEHOLDER = '0';
+ if (index > 8) return IP_PLACEHOLDER;
+
+ return fAddr[index];
+}
+
+bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) {
+ for (SizeT index = 0; index < 8; ++index) {
+ if (ipv6.fAddr[index] != fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) {
+ for (SizeT index = 0; index < 8; ++index) {
+ if (ipv6.fAddr[index] == fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress6>& ipv6) {
+ auto str = KStringBuilder::Construct(ipv6.Leak().Address());
+ return str;
+}
+
+ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4) {
+ auto str = KStringBuilder::Construct(ipv4.Leak().Address());
+ return str;
+}
+
+bool IPFactory::IpCheckVersion4(const Char* ip) {
+ if (!ip) return NO;
+
+ Int32 cnter = 0;
+
+ for (SizeT base = 0; base < rt_string_len(ip); ++base) {
+ if (ip[base] == '.') {
+ cnter = 0;
+ } else {
+ if (cnter == 3) return false;
+
+ ++cnter;
+ }
+ }
+
+ return true;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/Network/IPCAddr.cc b/dev/kernel/src/Network/IPCAddr.cc
index a56aec14..4c1dd500 100644
--- a/dev/kernel/src/Network/IPCAddr.cc
+++ b/dev/kernel/src/Network/IPCAddr.cc
@@ -4,29 +4,24 @@
------------------------------------------- */
-#include <NetworkKit/IPC.h>
#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.ProcessTeam == this->ProcessTeam;
- }
+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.ProcessTeam == this->ProcessTeam;
- }
+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.ProcessTeam != this->ProcessTeam;
- }
+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.ProcessTeam != this->ProcessTeam;
- }
-} // namespace Kernel
+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/IPCMsg.cc b/dev/kernel/src/Network/IPCMsg.cc
index ceb0ae98..b3c9d9fd 100644
--- a/dev/kernel/src/Network/IPCMsg.cc
+++ b/dev/kernel/src/Network/IPCMsg.cc
@@ -1,125 +1,106 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#include <NetworkKit/IPC.h>
#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;
+
+ 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;
+
+ rt_copy_memory(src->IpcData, target->IpcData, src->IpcMsgSz);
+
+ return Yes;
+ }
-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.ProcessTeam = 0;
-
- (*pckt_in)->IpcFrom.UserProcessID = 0;
- (*pckt_in)->IpcFrom.ProcessTeam = 0;
-
- 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;
-
- rt_copy_memory(src->IpcData, target->IpcData, src->IpcMsgSz);
-
- return Yes;
- }
-
- return No;
- }
-} // namespace Kernel
+ return No;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/Network/MACAddressGetter.cc b/dev/kernel/src/Network/MACAddressGetter.cc
index 192dbc70..736e1e27 100644
--- a/dev/kernel/src/Network/MACAddressGetter.cc
+++ b/dev/kernel/src/Network/MACAddressGetter.cc
@@ -1,15 +1,13 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <NetworkKit/MAC.h>
-namespace Kernel
-{
- Array<UInt8, kMACAddrLen>& MacAddressGetter::AsBytes()
- {
- return this->fMacAddress;
- }
-} // namespace Kernel
+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
index d7d78c28..6f77a244 100644
--- a/dev/kernel/src/Network/NetworkDevice.cc
+++ b/dev/kernel/src/Network/NetworkDevice.cc
@@ -1,36 +1,29 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <NetworkKit/NetworkDevice.h>
#include <NewKit/Utils.h>
-namespace Kernel
-{
- /// \brief Getter for fNetworkName.
- /// \return Network device name.
- const Char* NetworkDevice::Name() const
- {
- return this->fNetworkName;
- }
-
- /// \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) > cNetworkNameLen)
- return NO;
-
- rt_copy_memory((VoidPtr)name,
- (VoidPtr)this->fNetworkName, rt_string_len(name));
-
- return YES;
- }
-} // namespace Kernel
+namespace Kernel {
+/// \brief Getter for fNetworkName.
+/// \return Network device name.
+const Char* NetworkDevice::Name() const {
+ return this->fNetworkName;
+}
+
+/// \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) > cNetworkNameLen) return NO;
+
+ rt_copy_memory((VoidPtr) name, (VoidPtr) this->fNetworkName, rt_string_len(name));
+
+ return YES;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/New+Delete.cc b/dev/kernel/src/New+Delete.cc
index d0abb20d..96e7ab64 100644
--- a/dev/kernel/src/New+Delete.cc
+++ b/dev/kernel/src/New+Delete.cc
@@ -1,60 +1,48 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <KernelKit/MemoryMgr.h>
#include <NewKit/New.h>
-void* operator new[](size_t sz)
-{
- if (sz == 0)
- ++sz;
+void* operator new[](size_t sz) {
+ if (sz == 0) ++sz;
- return Kernel::mm_new_heap(sz, true, false);
+ return Kernel::mm_new_heap(sz, true, false);
}
-void* operator new(size_t sz)
-{
- if (sz == 0)
- ++sz;
+void* operator new(size_t sz) {
+ if (sz == 0) ++sz;
- return Kernel::mm_new_heap(sz, true, false);
+ return Kernel::mm_new_heap(sz, true, false);
}
-void operator delete[](void* ptr)
-{
- if (ptr == nullptr)
- return;
+void operator delete[](void* ptr) {
+ if (ptr == nullptr) return;
- Kernel::mm_delete_heap(ptr);
+ Kernel::mm_delete_heap(ptr);
}
-void operator delete(void* ptr)
-{
- if (ptr == nullptr)
- return;
+void operator delete(void* ptr) {
+ if (ptr == nullptr) return;
- Kernel::mm_delete_heap(ptr);
+ Kernel::mm_delete_heap(ptr);
}
-void operator delete(void* ptr, size_t sz)
-{
- if (ptr == nullptr)
- return;
+void operator delete(void* ptr, size_t sz) {
+ if (ptr == nullptr) return;
- NE_UNUSED(sz);
+ NE_UNUSED(sz);
- Kernel::mm_delete_heap(ptr);
+ Kernel::mm_delete_heap(ptr);
}
-void operator delete[](void* ptr, size_t sz)
-{
- if (ptr == nullptr)
- return;
+void operator delete[](void* ptr, size_t sz) {
+ if (ptr == nullptr) return;
- NE_UNUSED(sz);
+ NE_UNUSED(sz);
- Kernel::mm_delete_heap(ptr);
+ Kernel::mm_delete_heap(ptr);
}
diff --git a/dev/kernel/src/OwnPtr.cc b/dev/kernel/src/OwnPtr.cc
index 9623d4a4..8fd2b985 100644
--- a/dev/kernel/src/OwnPtr.cc
+++ b/dev/kernel/src/OwnPtr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc
index 668dd916..09a262d4 100644
--- a/dev/kernel/src/PEFCodeMgr.cc
+++ b/dev/kernel/src/PEFCodeMgr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -9,260 +9,254 @@
#include <KernelKit/PEFCodeMgr.h>
#include <KernelKit/ProcessScheduler.h>
#include <NewKit/Defines.h>
+#include <NewKit/KString.h>
#include <NewKit/KernelPanic.h>
#include <NewKit/OwnPtr.h>
-#include <NewKit/KString.h>
/// @brief PEF stack size symbol.
#define kPefStackSizeSymbol "__PEFSizeOfReserveStack"
-#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap"
-#define kPefNameSymbol "__PEFProgramName"
-
-namespace Kernel
-{
- namespace Detail
- {
- /***********************************************************************************/
- /// @brief Get the PEF platform signature according to the compiled architecture.
- /***********************************************************************************/
- UInt32 ldr_get_platform(void) noexcept
- {
+#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap"
+#define kPefNameSymbol "__PEFProgramName"
+
+namespace Kernel {
+namespace Detail {
+ /***********************************************************************************/
+ /// @brief Get the PEF platform signature according to the compiled architecture.
+ /***********************************************************************************/
+ UInt32 ldr_get_platform(void) noexcept {
#if defined(__NE_32X0__)
- return kPefArch32x0;
+ return kPefArch32x0;
#elif defined(__NE_64X0__)
- return kPefArch64x0;
+ return kPefArch64x0;
#elif defined(__NE_AMD64__)
- return kPefArchAMD64;
+ return kPefArchAMD64;
#elif defined(__NE_PPC64__)
- return kPefArchPowerPC;
+ return kPefArchPowerPC;
#elif defined(__NE_ARM64__)
- return kPefArchARM64;
+ return kPefArchARM64;
#else
- return kPefArchInvalid;
-#endif // __32x0__ || __64x0__ || __x86_64__
- }
- } // namespace Detail
-
- /***********************************************************************************/
- /// @brief PEF loader constructor w/ blob.
- /// @param blob file blob.
- /***********************************************************************************/
- PEFLoader::PEFLoader(const VoidPtr blob)
- : fCachedBlob(blob)
- {
- MUST_PASS(fCachedBlob);
- fBad = false;
- }
-
- /***********************************************************************************/
- /// @brief PEF loader constructor.
- /// @param path the filesystem path.
- /***********************************************************************************/
- PEFLoader::PEFLoader(const Char* path)
- : fCachedBlob(nullptr), fFatBinary(false), fBad(false)
- {
- fFile.New(const_cast<Char*>(path), kRestrictRB);
- fPath = KStringBuilder::Construct(path).Leak();
-
- auto kPefHeader = "PEF_CONTAINER";
-
- fCachedBlob = fFile->Read(kPefHeader, mib_cast(16));
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- if (container->Cpu == Detail::ldr_get_platform() &&
- container->Magic[0] == kPefMagic[0] &&
- container->Magic[1] == kPefMagic[1] &&
- container->Magic[2] == kPefMagic[2] &&
- container->Magic[3] == kPefMagic[3] &&
- container->Magic[4] == kPefMagic[4] && container->Abi == kPefAbi)
- {
- return;
- }
- else if (container->Magic[4] == kPefMagic[0] &&
- container->Magic[3] == kPefMagic[1] &&
- container->Magic[2] == kPefMagic[2] &&
- container->Magic[1] == kPefMagic[3] &&
- container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi)
- {
- /// This is a fat binary.
- this->fFatBinary = true;
- return;
- }
-
- fBad = true;
-
- if (fCachedBlob)
- mm_delete_heap(fCachedBlob);
-
- kout << "PEFLoader: warn: Executable format error!\r";
-
- fCachedBlob = nullptr;
- }
-
- /***********************************************************************************/
- /// @brief PEF destructor.
- /***********************************************************************************/
- PEFLoader::~PEFLoader()
- {
- if (fCachedBlob)
- mm_delete_heap(fCachedBlob);
-
- fFile.Delete();
- }
-
- /***********************************************************************************/
- /// @brief Finds the symbol according to it's name.
- /// @param name name of symbol.
- /// @param kind kind of symbol we want.
- /***********************************************************************************/
- VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind)
- {
- if (!fCachedBlob || fBad || !name)
- return nullptr;
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- auto blob = fFile->Read(name, mib_cast(16));
-
- PEFCommandHeader* container_header = reinterpret_cast<PEFCommandHeader*>(blob);
-
- constexpr auto cMangleCharacter = '$';
- const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr};
-
- ErrorOr<KString> error_or_symbol;
-
- switch (kind)
- {
- case kPefCode: {
- error_or_symbol = KStringBuilder::Construct(cContainerKinds[0]); // code symbol.
- break;
- }
- case kPefData: {
- error_or_symbol = KStringBuilder::Construct(cContainerKinds[1]); // data symbol.
- break;
- }
- case kPefZero: {
- error_or_symbol = KStringBuilder::Construct(cContainerKinds[2]); // block starting symbol.
- break;
- }
- default:
- return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were
- // a user process.
- }
-
- Char* unconst_symbol = const_cast<Char*>(name);
-
- for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i)
- {
- if (unconst_symbol[i] == ' ')
- {
- unconst_symbol[i] = cMangleCharacter;
- }
- }
-
- error_or_symbol.Leak().Leak() += name;
-
- for (SizeT index = 0; index < container->Count; ++index)
- {
- if (KStringBuilder::Equals(container_header->Name,
- error_or_symbol.Leak().Leak().CData()))
- {
- if (container_header->Kind == kind)
- {
- if (container_header->Cpu != Detail::ldr_get_platform())
- {
- if (!this->fFatBinary)
- {
- mm_delete_heap(blob);
- return nullptr;
- }
- }
-
- Char* container_blob_value = new Char[container_header->Size];
-
- rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size);
- mm_delete_heap(blob);
-
- kout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r";
-
- return container_blob_value;
- }
- }
- }
-
- mm_delete_heap(blob);
- return nullptr;
- }
-
- /// @brief Finds the executable entrypoint.
- /// @return
- ErrorOr<VoidPtr> PEFLoader::FindStart()
- {
- if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym)
- return ErrorOr<VoidPtr>(sym);
-
- return ErrorOr<VoidPtr>(kErrorExecutable);
- }
-
- /// @brief Tells if the executable is loaded or not.
- /// @return
- bool PEFLoader::IsLoaded() noexcept
- {
- return !fBad && fCachedBlob;
- }
-
- const Char* PEFLoader::Path()
- {
- return fPath.Leak().CData();
- }
-
- const Char* PEFLoader::AsString()
- {
+ return kPefArchInvalid;
+#endif // __32x0__ || __64x0__ || __x86_64__
+ }
+} // namespace Detail
+
+/***********************************************************************************/
+/// @brief PEF loader constructor w/ blob.
+/// @param blob file blob.
+/***********************************************************************************/
+PEFLoader::PEFLoader(const VoidPtr blob) : fCachedBlob(blob) {
+ MUST_PASS(fCachedBlob);
+ fBad = false;
+}
+
+/***********************************************************************************/
+/// @brief PEF loader constructor.
+/// @param path the filesystem path.
+/***********************************************************************************/
+PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false), fBad(false) {
+ fFile.New(const_cast<Char*>(path), kRestrictRB);
+ fPath = KStringBuilder::Construct(path).Leak();
+
+ auto kPefHeader = "PEF_CONTAINER";
+
+ fCachedBlob = fFile->Read(kPefHeader, mib_cast(16));
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] &&
+ container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] &&
+ container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4] &&
+ container->Abi == kPefAbi) {
+ return;
+ } else if (container->Magic[4] == kPefMagic[0] && container->Magic[3] == kPefMagic[1] &&
+ container->Magic[2] == kPefMagic[2] && container->Magic[1] == kPefMagic[3] &&
+ container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) {
+ /// This is a fat binary.
+ this->fFatBinary = true;
+ return;
+ }
+
+ fBad = true;
+
+ if (fCachedBlob) mm_delete_heap(fCachedBlob);
+
+ kout << "PEFLoader: Warning: Executable format error!\r";
+
+ fCachedBlob = nullptr;
+}
+
+/***********************************************************************************/
+/// @brief PEF destructor.
+/***********************************************************************************/
+PEFLoader::~PEFLoader() {
+ if (fCachedBlob) mm_delete_heap(fCachedBlob);
+
+ fFile.Delete();
+}
+
+/***********************************************************************************/
+/// @brief Finds the symbol according to it's name.
+/// @param name name of symbol.
+/// @param kind kind of symbol we want.
+/***********************************************************************************/
+ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) {
+ if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ auto blob = fFile->Read(name, sizeof(PEFCommandHeader));
+
+ PEFCommandHeader* container_header = reinterpret_cast<PEFCommandHeader*>(blob);
+
+ constexpr 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 (unconst_symbol[i] == ' ') {
+ unconst_symbol[i] = kMangleCharacter;
+ }
+ }
+
+ error_or_symbol.Leak().Leak() += name;
+
+ for (SizeT index = 0; index < container->Count; ++index) {
+ if (KStringBuilder::Equals(container_header->Name, error_or_symbol.Leak().Leak().CData())) {
+ if (container_header->Kind == kind) {
+ if (container_header->Cpu != Detail::ldr_get_platform()) {
+ if (!this->fFatBinary) {
+ mm_delete_heap(blob);
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+ }
+
+ Char* container_blob_value = new Char[container_header->Size];
+
+ rt_copy_memory((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value,
+ container_header->Size);
+ mm_delete_heap(blob);
+
+ kout << "PEFLoader: Information: Loaded stub: " << container_header->Name << "!\r";
+
+ auto ret = HAL::mm_map_page((VoidPtr) container_header->VMAddress,
+ (VoidPtr) HAL::mm_get_phys_address(container_blob_value),
+ HAL::kMMFlagsPresent | HAL::kMMFlagsUser);
+
+ if (ret != kErrorSuccess) {
+ mm_delete_heap(container_blob_value);
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+
+ return ErrorOr<VoidPtr>{container_blob_value};
+ }
+ }
+ }
+
+ mm_delete_heap(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 executable.";
+ return "32x0 PEF.";
#elif defined(__64x0__)
- return "64x0 PEF executable.";
+ return "64x0 PEF.";
#elif defined(__x86_64__)
- return "x86_64 PEF executable.";
+ return "x86_64 PEF.";
#elif defined(__aarch64__)
- return "AARCH64 PEF executable.";
+ return "AARCH64 PEF.";
#elif defined(__powerpc64__)
- return "POWER64 PEF executable.";
+ return "POWER64 PEF.";
#else
- return "???? PEF executable.";
-#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__
- }
-
- const Char* PEFLoader::MIME()
- {
- return kPefApplicationMime;
- }
-
- ErrorOr<VoidPtr> PEFLoader::GetBlob()
- {
- return ErrorOr<VoidPtr>{this->fCachedBlob};
- }
-
- namespace Utils
- {
- ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& process_kind) noexcept
- {
- auto errOrStart = exec.FindStart();
-
- if (errOrStart.Error() != kErrorSuccess)
- return kSchedInvalidPID;
-
- auto id = UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(exec.FindSymbol(kPefNameSymbol, kPefData)), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
-
- if (id != kSchedInvalidPID)
- {
- UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind;
- UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData);
- UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData);
- }
-
- return id;
- }
- } // namespace Utils
-} // namespace Kernel
+ 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")};
+ }
+
+ auto id =
+ UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()),
+ errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
+
+ mm_delete_heap(symname.Leak().Leak());
+
+ if (id != kSchedInvalidPID) {
+ auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData);
+
+ if (!symname) {
+ stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)};
+ }
+
+ if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) {
+ *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz;
+ }
+
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind;
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize =
+ *(UIntPtr*) stacksym.Leak().Leak();
+
+ mm_delete_heap(stacksym.Leak().Leak());
+ }
+
+ return id;
+ }
+} // namespace Utils
+} // namespace Kernel
diff --git a/dev/kernel/src/PRDT.cc b/dev/kernel/src/PRDT.cc
index ed8edb8d..f7380d2d 100644
--- a/dev/kernel/src/PRDT.cc
+++ b/dev/kernel/src/PRDT.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -8,17 +8,15 @@
#include <NewKit/KString.h>
#include <StorageKit/PRDT.h>
-namespace Kernel
-{
- /***********************************************************************************/
- /// @brief constructs a new PRD.
- /// @param prd PRD reference.
- /// @note This doesnt construct a valid, please fill it by yourself.
- /***********************************************************************************/
- void construct_prdt(Ref<PRDT>& prd)
- {
- prd.Leak().fPhysAddress = 0x0;
- prd.Leak().fSectorCount = 0x0;
- prd.Leak().fEndBit = 0x0;
- }
-} // namespace Kernel
+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
index 8778a855..f60fa57a 100644
--- a/dev/kernel/src/PageMgr.cc
+++ b/dev/kernel/src/PageMgr.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -11,100 +11,85 @@
#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()
- {
-#ifndef __NE_MINIMAL_OS__
- hal_flush_tlb();
-#endif // !__NE_MINIMAL_OS__
- }
-
- /// @brief Reclaim freed page.
- /// @return
- Bool PTEWrapper::Reclaim()
- {
- if (!this->fPresent)
- {
- this->fPresent = true;
- return true;
- }
-
- return false;
- }
-
- /// @brief Request a PTE.
- /// @param Rw r/w?
- /// @param User user mode?
- /// @param ExecDisable disable execution on page?
- /// @return
- PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, 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
+#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 r/w?
+/// @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
index 325e19af..35ea4195 100644
--- a/dev/kernel/src/Pmm.cc
+++ b/dev/kernel/src/Pmm.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -9,90 +9,75 @@
#if defined(__NE_ARM64__)
#include <HALKit/ARM64/Processor.h>
-#endif // defined(__NE_ARM64__)
+#endif // defined(__NE_ARM64__)
#if defined(__NE_AMD64__)
#include <HALKit/AMD64/Processor.h>
-#endif // defined(__NE_AMD64__)
+#endif // defined(__NE_AMD64__)
-namespace Kernel
-{
- /***********************************************************************************/
- /// @brief Pmm constructor.
- /***********************************************************************************/
- Pmm::Pmm()
- : fPageMgr()
- {
- kout << "[PMM] Allocate PageMemoryMgr.\r";
- }
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Pmm constructor.
+/***********************************************************************************/
+Pmm::Pmm() : fPageMgr() {
+ kout << "[PMM] Allocate PageMemoryMgr.\r";
+}
- Pmm::~Pmm() = default;
+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);
+/***********************************************************************************/
+/// @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 {};
- }
+ if (pt.fPresent) {
+ kout << "[PMM]: Allocation failed.\r";
+ return {};
+ }
- return Ref<PTEWrapper>(pt);
- }
+ return Ref<PTEWrapper>(pt);
+}
- Boolean Pmm::FreePage(Ref<PTEWrapper> PageRef)
- {
- if (!PageRef)
- return false;
+Boolean Pmm::FreePage(Ref<PTEWrapper> PageRef) {
+ if (!PageRef) return false;
- PageRef.Leak().fPresent = false;
+ PageRef.Leak().fPresent = false;
- return true;
- }
+ return true;
+}
- Boolean Pmm::TogglePresent(Ref<PTEWrapper> PageRef, Boolean Enable)
- {
- if (!PageRef)
- return false;
+Boolean Pmm::TogglePresent(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
- PageRef.Leak().fPresent = Enable;
+ PageRef.Leak().fPresent = Enable;
- return true;
- }
+ return true;
+}
- Boolean Pmm::ToggleUser(Ref<PTEWrapper> PageRef, Boolean Enable)
- {
- if (!PageRef)
- return false;
+Boolean Pmm::ToggleUser(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
- PageRef.Leak().fRw = Enable;
+ PageRef.Leak().fRw = Enable;
- return true;
- }
+ return true;
+}
- Boolean Pmm::ToggleRw(Ref<PTEWrapper> PageRef, Boolean Enable)
- {
- if (!PageRef)
- return false;
+Boolean Pmm::ToggleRw(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
- PageRef.Leak().fRw = Enable;
+ PageRef.Leak().fRw = Enable;
- return true;
- }
+ return true;
+}
- Boolean Pmm::ToggleShare(Ref<PTEWrapper> PageRef, Boolean Enable)
- {
- if (!PageRef)
- return false;
+Boolean Pmm::ToggleShare(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
- PageRef.Leak().fShareable = Enable;
+ PageRef.Leak().fShareable = Enable;
- return true;
- }
-} // namespace Kernel
+ return true;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/ProcessTeam.cc b/dev/kernel/src/ProcessTeam.cc
deleted file mode 100644
index 87d21d67..00000000
--- a/dev/kernel/src/ProcessTeam.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -------------------------------------------
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
-
-------------------------------------------- */
-
-/***********************************************************************************/
-/// @file ProcessTeam.cc
-/// @brief Process teams implementation.
-/***********************************************************************************/
-
-#include <KernelKit/ProcessScheduler.h>
-
-namespace Kernel
-{
- ProcessTeam::ProcessTeam()
- {
- for (SizeT i = 0U; i < this->mProcessList.Count(); ++i)
- {
- this->mProcessList[i] = Process();
- this->mProcessList[i].PTime = 0;
- this->mProcessList[i].Status = ProcessStatusKind::kKilled;
- }
-
- this->mProcessCount = 0UL;
- }
-
- /***********************************************************************************/
- /// @brief Process list array getter.
- /// @return The list of process to schedule.
- /***********************************************************************************/
-
- Array<Process, kSchedProcessLimitPerTeam>& ProcessTeam::AsArray()
- {
- return this->mProcessList;
- }
-
- /***********************************************************************************/
- /// @brief Get team ID.
- /// @return The team's ID.
- /***********************************************************************************/
-
- ProcessID& ProcessTeam::Id() noexcept
- {
- return this->mTeamId;
- }
-
- /***********************************************************************************/
- /// @brief Get current process getter as Ref.
- /// @return The current process header.
- /***********************************************************************************/
-
- Ref<Process>& ProcessTeam::AsRef()
- {
- return this->mCurrentProcess;
- }
-} // namespace Kernel
-
-// last rev 05-03-24
diff --git a/dev/kernel/src/Property.cc b/dev/kernel/src/Property.cc
index 8aee4618..62aa6ef2 100644
--- a/dev/kernel/src/Property.cc
+++ b/dev/kernel/src/Property.cc
@@ -1,45 +1,41 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <CFKit/Property.h>
-namespace 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(KString& name)
- {
- return this->fName && this->fName == name;
- }
-
- /***********************************************************************************/
- /// @brief Gets the key (name) of property.
- /***********************************************************************************/
- KString& Property::GetKey()
- {
- return this->fName;
- }
-
- /***********************************************************************************/
- /// @brief Gets the value of the property.
- /***********************************************************************************/
- PropertyId& Property::GetValue()
- {
- return fValue;
- }
-} // namespace CF
+namespace 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(KString& name) {
+ return this->fName && this->fName == name;
+}
+
+/***********************************************************************************/
+/// @brief Gets the key (name) of property.
+/***********************************************************************************/
+KString& Property::GetKey() {
+ return this->fName;
+}
+
+/***********************************************************************************/
+/// @brief Gets the value of the property.
+/***********************************************************************************/
+PropertyId& Property::GetValue() {
+ return fValue;
+}
+} // namespace CF
diff --git a/dev/kernel/src/Ref.cc b/dev/kernel/src/Ref.cc
index 7c01ea18..c185952b 100644
--- a/dev/kernel/src/Ref.cc
+++ b/dev/kernel/src/Ref.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
diff --git a/dev/kernel/src/SoftwareTimer.cc b/dev/kernel/src/SoftwareTimer.cc
index 35d9c6f1..535bec9e 100644
--- a/dev/kernel/src/SoftwareTimer.cc
+++ b/dev/kernel/src/SoftwareTimer.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -10,30 +10,24 @@
using namespace Kernel;
-SoftwareTimer::SoftwareTimer(Int64 seconds)
- : fWaitFor(seconds)
-{
- fDigitalTimer = new UIntPtr();
- MUST_PASS(fDigitalTimer);
+SoftwareTimer::SoftwareTimer(Int64 seconds) : fWaitFor(seconds) {
+ fDigitalTimer = new UIntPtr();
+ MUST_PASS(fDigitalTimer);
}
-SoftwareTimer::~SoftwareTimer()
-{
- delete fDigitalTimer;
- fDigitalTimer = nullptr;
+SoftwareTimer::~SoftwareTimer() {
+ delete fDigitalTimer;
+ fDigitalTimer = nullptr;
- fWaitFor = 0;
+ fWaitFor = 0;
}
-BOOL SoftwareTimer::Wait() noexcept
-{
- if (fWaitFor < 1)
- return NO;
+BOOL SoftwareTimer::Wait() noexcept {
+ if (fWaitFor < 1) return NO;
- while (*fDigitalTimer < (*fDigitalTimer + fWaitFor))
- {
- ++(*fDigitalTimer);
- }
+ while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) {
+ ++(*fDigitalTimer);
+ }
- return YES;
+ return YES;
}
diff --git a/dev/kernel/src/Storage/AHCIDeviceInterface.cc b/dev/kernel/src/Storage/AHCIDeviceInterface.cc
index c5f43bf6..2d97eee7 100644
--- a/dev/kernel/src/Storage/AHCIDeviceInterface.cc
+++ b/dev/kernel/src/Storage/AHCIDeviceInterface.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -12,95 +12,78 @@ using namespace Kernel;
/// @param Out Drive output
/// @param In Drive input
/// @param Cleanup Drive cleanup.
-AHCIDeviceInterface::AHCIDeviceInterface(void (*out)(IDeviceObject* self, MountpointInterface* outpacket),
- void (*in)(IDeviceObject* self, MountpointInterface* inpacket))
- : IDeviceObject(out, in)
-{
-}
+AHCIDeviceInterface::AHCIDeviceInterface(void (*out)(IDeviceObject* self,
+ MountpointInterface* outpacket),
+ void (*in)(IDeviceObject* self,
+ MountpointInterface* inpacket))
+ : IDeviceObject(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 "/dev/sda{}";
+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<<(MountpointInterface* 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&)IDeviceObject<MountpointInterface*>::operator<<(
- mnt);
+AHCIDeviceInterface& AHCIDeviceInterface::operator<<(MountpointInterface* 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&) IDeviceObject<MountpointInterface*>::operator<<(mnt);
}
/// @brief Input operator.
/// @param mnt the disk mountpoint.
/// @return the class itself after operation.
-AHCIDeviceInterface& AHCIDeviceInterface::operator>>(MountpointInterface* 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&)IDeviceObject<MountpointInterface*>::operator>>(
- mnt);
+AHCIDeviceInterface& AHCIDeviceInterface::operator>>(MountpointInterface* 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&) IDeviceObject<MountpointInterface*>::operator>>(mnt);
}
-const UInt16& AHCIDeviceInterface::GetPortsImplemented()
-{
- return this->fPortsImplemented;
+const UInt16& AHCIDeviceInterface::GetPortsImplemented() {
+ return this->fPortsImplemented;
}
-Void AHCIDeviceInterface::SetPortsImplemented(const UInt16& pi)
-{
- MUST_PASS(pi > 0);
- this->fPortsImplemented = pi;
+Void AHCIDeviceInterface::SetPortsImplemented(const UInt16& pi) {
+ MUST_PASS(pi > 0);
+ this->fPortsImplemented = pi;
}
-const UInt32& AHCIDeviceInterface::GetIndex()
-{
- return this->fDriveIndex;
+const UInt32& AHCIDeviceInterface::GetIndex() {
+ return this->fDriveIndex;
}
-Void AHCIDeviceInterface::SetIndex(const UInt32& drv)
-{
- MUST_PASS(MountpointInterface::kDriveIndexInvalid != drv);
- this->fDriveIndex = drv;
+Void AHCIDeviceInterface::SetIndex(const UInt32& drv) {
+ MUST_PASS(MountpointInterface::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
index 3fe331dd..a66d812b 100644
--- a/dev/kernel/src/Storage/ATADeviceInterface.cc
+++ b/dev/kernel/src/Storage/ATADeviceInterface.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -12,107 +12,85 @@ using namespace Kernel;
/// @param Out Drive output
/// @param In Drive input
/// @param Cleanup Drive cleanup.
-ATADeviceInterface::ATADeviceInterface(
- void (*Out)(IDeviceObject*, MountpointInterface* outpacket),
- void (*In)(IDeviceObject*, MountpointInterface* inpacket))
- : IDeviceObject(Out, In)
-{
-}
+ATADeviceInterface::ATADeviceInterface(void (*Out)(IDeviceObject*, MountpointInterface* outpacket),
+ void (*In)(IDeviceObject*, MountpointInterface* inpacket))
+ : IDeviceObject(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 "/dev/hda{}";
+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<<(MountpointInterface* 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&)IDeviceObject<MountpointInterface*>::operator<<(
- Data);
+ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* Data) {
+ if (!Data) return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
+ auto interface = Data->GetAddressOf(driveCount);
+
+ if ((interface) &&
+ rt_string_cmp((interface)->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&) IDeviceObject<MountpointInterface*>::operator<<(Data);
}
/// @brief Input operator.
/// @param Data the disk mountpoint.
/// @return the class itself after operation.
-ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* 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&)IDeviceObject<MountpointInterface*>::operator>>(
- Data);
+ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* 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&) IDeviceObject<MountpointInterface*>::operator>>(Data);
}
-const UInt32& ATADeviceInterface::GetIndex()
-{
- return this->fDriveIndex;
+const UInt32& ATADeviceInterface::GetIndex() {
+ return this->fDriveIndex;
}
-Void ATADeviceInterface::SetIndex(const UInt32& drv)
-{
- MUST_PASS(MountpointInterface::kDriveIndexInvalid != drv);
- this->fDriveIndex = drv;
+Void ATADeviceInterface::SetIndex(const UInt32& drv) {
+ MUST_PASS(MountpointInterface::kDriveIndexInvalid != drv);
+ this->fDriveIndex = drv;
}
-const UInt16& ATADeviceInterface::GetIO()
-{
- return this->fIO;
+const UInt16& ATADeviceInterface::GetIO() {
+ return this->fIO;
}
-Void ATADeviceInterface::SetIO(const UInt16& drv)
-{
- MUST_PASS(0xFFFF != drv);
- this->fIO = drv;
+Void ATADeviceInterface::SetIO(const UInt16& drv) {
+ MUST_PASS(0xFFFF != drv);
+ this->fIO = drv;
}
-const UInt16& ATADeviceInterface::GetMaster()
-{
- return this->fIO;
+const UInt16& ATADeviceInterface::GetMaster() {
+ return this->fIO;
}
-Void ATADeviceInterface::SetMaster(const UInt16& drv)
-{
- MUST_PASS(0xFFFF != drv);
- this->fMaster = drv;
+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
index 14c9722f..cff776c9 100644
--- a/dev/kernel/src/Storage/NVMEDeviceInterface.cc
+++ b/dev/kernel/src/Storage/NVMEDeviceInterface.cc
@@ -1,28 +1,23 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <StorageKit/NVME.h>
-namespace Kernel
-{
- NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(IDeviceObject*, MountpointInterface* outpacket),
- void (*in)(IDeviceObject*, MountpointInterface* inpacket),
- void (*cleanup)(void))
- : IDeviceObject(out, in), fCleanup(cleanup)
- {
- }
+namespace Kernel {
+NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(IDeviceObject*,
+ MountpointInterface* outpacket),
+ void (*in)(IDeviceObject*, MountpointInterface* inpacket),
+ void (*cleanup)(void))
+ : IDeviceObject(out, in), fCleanup(cleanup) {}
- NVMEDeviceInterface::~NVMEDeviceInterface()
- {
- if (fCleanup)
- fCleanup();
- }
+NVMEDeviceInterface::~NVMEDeviceInterface() {
+ if (fCleanup) fCleanup();
+}
- const Char* NVMEDeviceInterface::Name() const
- {
- return ("/dev/nvme{}");
- }
-} // namespace Kernel
+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
index 1b924227..6f26f486 100644
--- a/dev/kernel/src/Storage/SCSIDeviceInterface.cc
+++ b/dev/kernel/src/Storage/SCSIDeviceInterface.cc
@@ -1,11 +1,9 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <StorageKit/SCSI.h>
-///! @brief ATAPI SCSI packet.
-const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0,
- 0, 12, 0x40, 0, 0};
+using namespace Kernel;
diff --git a/dev/kernel/src/Stream.cc b/dev/kernel/src/Stream.cc
index 0be3e844..8fd4dab3 100644
--- a/dev/kernel/src/Stream.cc
+++ b/dev/kernel/src/Stream.cc
@@ -1,11 +1,11 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
- File: Stream.cc
- Purpose: Stream object
+ File: Stream.cc
+ Purpose: Stream object
- Revision History:
+ Revision History:
------------------------------------------- */
diff --git a/dev/kernel/src/Swap/DiskSwap.cc b/dev/kernel/src/Swap/DiskSwap.cc
index 1650a5af..118be0f6 100644
--- a/dev/kernel/src/Swap/DiskSwap.cc
+++ b/dev/kernel/src/Swap/DiskSwap.cc
@@ -1,67 +1,57 @@
/* -------------------------------------------
- Copyright (C) 2024-2025 Amlal El Mahrouss Labs, all rights reserved.
+ Copyright (C) 2024-2025 Amlal El Mahrouss Labs, all rights reserved.
------------------------------------------- */
-#include <SwapKit/DiskSwap.h>
#include <KernelKit/FileMgr.h>
+#include <SwapKit/DiskSwap.h>
-namespace Kernel
-{
- /***********************************************************************************/
- /// @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 SwapDiskInterface::Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data)
- {
- if (!fork_name || !fork_name_len)
- return NO;
+namespace Kernel {
+/***********************************************************************************/
+/// @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 (*fork_name == 0) return NO;
- if (!data)
- return NO;
+ if (!data) return NO;
- FileStream file(kSwapPageFile, "wb");
+ FileStream file(kSwapPageFilePath, kRestrictWRB);
- auto ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz);
+ ErrorOr<Int64> ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz);
- if (ret.Error())
- return NO;
+ if (ret.Error()) return NO;
- return YES;
- }
+ 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* SwapDiskInterface::Read(const Char* fork_name, SizeT fork_name_len, SizeT data_len)
- {
- if (!fork_name || !fork_name_len)
- return nullptr;
+/***********************************************************************************/
+/// @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 (*fork_name == 0) return nullptr;
- if (data_len > kSwapBlockMaxSize)
- return nullptr;
+ if (data_len > kSwapBlockMaxSize) return nullptr;
- if (data_len == 0)
- return nullptr;
+ if (data_len == 0) return nullptr;
- FileStream file(kSwapPageFile, "rb");
+ FileStream file(kSwapPageFilePath, kRestrictRB);
- VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len);
+ VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len);
- return reinterpret_cast<SWAP_DISK_HEADER*>(blob);
- }
-} // namespace Kernel
+ return reinterpret_cast<SWAP_DISK_HEADER*>(blob);
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/ThreadLocalStorage.cc b/dev/kernel/src/ThreadLocalStorage.cc
index a6c12142..e248e67c 100644
--- a/dev/kernel/src/ThreadLocalStorage.cc
+++ b/dev/kernel/src/ThreadLocalStorage.cc
@@ -1,16 +1,16 @@
/*
* ========================================================
*
-* NeKernel
+ * NeKernel
* Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
*
* ========================================================
*/
-#include <NewKit/KString.h>
#include <CFKit/Property.h>
#include <KernelKit/ProcessScheduler.h>
#include <KernelKit/ThreadLocalStorage.h>
+#include <NewKit/KString.h>
/***********************************************************************************/
/// @bugs: 0
@@ -26,19 +26,16 @@ using namespace Kernel;
* @return if the cookie is enabled, true; false otherwise
*/
-Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr)
-{
- if (!tib_ptr ||
- !tib_ptr->Record)
- return false;
+Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) {
+ if (!tib_ptr || !tib_ptr->Record) return false;
- ICodec encoder;
- const Char* tib_as_bytes = encoder.AsBytes<THREAD_INFORMATION_BLOCK*>(tib_ptr);
+ ICodec encoder;
+ const Char* tib_as_bytes = encoder.AsBytes<THREAD_INFORMATION_BLOCK*>(tib_ptr);
- kout << "TLS: Validating the TIB...\r";
+ kout << "TLS: Validating the TIB...\r";
- return tib_as_bytes[kCookieMag0Idx] == kCookieMag0 && tib_as_bytes[kCookieMag1Idx] == kCookieMag1 &&
- tib_as_bytes[kCookieMag2Idx] == kCookieMag2;
+ return tib_as_bytes[kCookieMag0Idx] == kCookieMag0 &&
+ tib_as_bytes[kCookieMag1Idx] == kCookieMag1 && tib_as_bytes[kCookieMag2Idx] == kCookieMag2;
}
/**
@@ -46,22 +43,19 @@ Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr)
* @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;
- }
+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);
+ THREAD_INFORMATION_BLOCK* tib = reinterpret_cast<THREAD_INFORMATION_BLOCK*>(tib_ptr);
- if (!tls_check_tib(tib))
- {
- kout << "TLS: Failed because of an invalid TIB...\r";
- return No;
- }
+ if (!tls_check_tib(tib)) {
+ kout << "TLS: Failed because of an invalid TIB...\r";
+ return No;
+ }
- kout << "TLS Pass.\r";
- return Yes;
+ kout << "TLS Pass.\r";
+ return Yes;
}
diff --git a/dev/kernel/src/Timer.cc b/dev/kernel/src/Timer.cc
index c2202373..826be99a 100644
--- a/dev/kernel/src/Timer.cc
+++ b/dev/kernel/src/Timer.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
@@ -13,7 +13,6 @@
using namespace Kernel;
/// @brief Unimplemented as it is an interface.
-BOOL TimerInterface::Wait() noexcept
-{
- return NO;
+BOOL TimerInterface::Wait() noexcept {
+ return NO;
}
diff --git a/dev/kernel/src/User.cc b/dev/kernel/src/User.cc
index d29ed112..3e6aeeba 100644
--- a/dev/kernel/src/User.cc
+++ b/dev/kernel/src/User.cc
@@ -2,194 +2,169 @@
* ========================================================
*
* NeKernel
- * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
*
- * File: User.cc
- * Purpose: User class, used to provide authentication and security.
+ * File: User.cc
+ * Purpose: User class, used to provide authentication and security.
*
* ========================================================
*/
-#include <KernelKit/User.h>
-#include <KernelKit/KPC.h>
-#include <NewKit/KernelPanic.h>
#include <KernelKit/FileMgr.h>
+#include <KernelKit/KPC.h>
#include <KernelKit/MemoryMgr.h>
+#include <KernelKit/User.h>
+#include <NewKit/KernelPanic.h>
-#define kStdUserType (0xEE)
+#define kStdUserType (0xEE)
#define kSuperUserType (0xEF)
/// @file User.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
- ////////////////////////////////////////////////////////////
- Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length)
- {
- if (!password || !user)
- return 1;
+namespace Kernel {
+namespace Detail {
+ ////////////////////////////////////////////////////////////
+ /// \brief Constructs a password by hashing the password.
+ /// \param password password to hash.
+ /// \return the hashed password
+ ////////////////////////////////////////////////////////////
+ Int32 user_standard_token_generator(Char* password, const Char* in_password, User* user,
+ SizeT length) {
+ if (!password || !user) return 1;
+ if (*password == 0) return 1;
+
+ kout << "user_standard_token_generator: Hashing user password...\r";
+
+ for (SizeT i_pass = 0UL; i_pass < length; ++i_pass) {
+ Char cur_chr = in_password[i_pass];
+
+ password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType);
+ }
+
+ kout << "user_standard_token_generator: Hashed user password.\r";
+
+ return 0;
+ }
+} // 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((VoidPtr) user_name, this->mUserName, rt_string_len(user_name));
+}
+
+////////////////////////////////////////////////////////////
+/// @brief User ring constructor.
+////////////////////////////////////////////////////////////
+User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) {
+ rt_copy_memory((VoidPtr) user_name, this->mUserName, rt_string_len(user_name));
+}
+
+////////////////////////////////////////////////////////////
+/// @brief User destructor class.
+////////////////////////////////////////////////////////////
+User::~User() = default;
+
+Bool User::Save(const UserPublicKey password_to_fill) noexcept {
+ if (!password_to_fill || *password_to_fill == 0) return No;
+
+ SizeT len = rt_string_len(password_to_fill);
- kout << "cred_construct_token: Hashing user password...\r";
+ UserPublicKey password = new UserPublicKeyType[len];
- for (SizeT i_pass = 0UL; i_pass < length; ++i_pass)
- {
- Char cur_chr = in_password[i_pass];
+ MUST_PASS(password);
- if (cur_chr == 0)
- break;
+ rt_set_memory(password, 0, len);
- password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType);
- }
+ // fill data first, generate hash.
+ // return false on error.
- kout << "cred_construct_token: Hashed user password.\r";
+ rt_copy_memory((VoidPtr) password_to_fill, password, len);
- return 0;
- }
- } // namespace Detail
+ if (!Detail::user_standard_token_generator(password, password_to_fill, this, len)) {
+ delete[] password;
+ password = nullptr;
- ////////////////////////////////////////////////////////////
- /// @brief User ring constructor.
- ////////////////////////////////////////////////////////////
- User::User(const Int32& sel, const Char* user_name)
- : mUserRing((UserRingKind)sel)
- {
- MUST_PASS(sel >= 0);
- rt_copy_memory((VoidPtr)user_name, this->mUserName, rt_string_len(user_name));
- }
+ return No;
+ }
- ////////////////////////////////////////////////////////////
- /// @brief User ring constructor.
- ////////////////////////////////////////////////////////////
- User::User(const UserRingKind& ring_kind, const Char* user_name)
- : mUserRing(ring_kind)
- {
- rt_copy_memory((VoidPtr)user_name, this->mUserName, rt_string_len(user_name));
- }
+ // then store password.
- ////////////////////////////////////////////////////////////
- /// @brief User destructor class.
- ////////////////////////////////////////////////////////////
- User::~User() = default;
+ rt_copy_memory(password, this->mUserKey, rt_string_len(password_to_fill));
- Bool User::Save(const UserPublicKey password_to_fill) noexcept
- {
- if (!password_to_fill ||
- *password_to_fill == 0)
- return No;
+ delete[] password;
+ password = nullptr;
- SizeT len = rt_string_len(password_to_fill);
+ kout << "User::Save: Saved password successfully...\r";
- UserPublicKey password = new UserPublicKeyType[len];
+ return Yes;
+}
- MUST_PASS(password);
+Bool User::Matches(const UserPublicKey password_to_fill) noexcept {
+ if (!password_to_fill || *password_to_fill) return No;
- rt_set_memory(password, 0, len);
+ SizeT len = rt_string_len(password_to_fill);
- // fill data first, generate hash.
- // return false on error.
-
- rt_copy_memory((VoidPtr)password_to_fill, password, len);
-
- if (!Detail::cred_construct_token(password, password_to_fill, this, len))
- {
- delete[] password;
- password = nullptr;
-
- return No;
- }
-
- // then store password.
-
- rt_copy_memory(password, this->mUserKey, rt_string_len(password_to_fill));
-
- delete[] password;
- password = nullptr;
-
- kout << "User::Save: Saved password successfully...\r";
-
- return Yes;
- }
-
- Bool User::Matches(const UserPublicKey password_to_fill) noexcept
- {
- if (!password_to_fill ||
- *password_to_fill)
- return No;
-
- SizeT len = rt_string_len(password_to_fill);
-
- Char* password = new Char[len];
- MUST_PASS(password);
+ Char* password = new Char[len];
+ MUST_PASS(password);
- // fill data first, generate hash.
- // return false on error.
+ // fill data first, generate hash.
+ // return false on error.
- rt_copy_memory((VoidPtr)password_to_fill, password, len);
+ rt_copy_memory((VoidPtr) password_to_fill, password, len);
- if (!Detail::cred_construct_token(password, password_to_fill, this, len))
- {
- delete[] password;
- password = nullptr;
+ if (!Detail::user_standard_token_generator(password, password_to_fill, this, len)) {
+ delete[] password;
+ password = nullptr;
- return No;
- }
+ return No;
+ }
- kout << "User::Matches: Validating hashed passwords...\r";
+ kout << "User::Matches: Validating hashed passwords...\r";
- // now check if the password matches.
- if (rt_string_cmp(password, this->mUserKey, rt_string_len(this->mUserKey)) == 0)
- {
- kout << "User::Matches: Password matches.\r";
- return Yes;
- }
+ // now check if the password matches.
+ if (rt_string_cmp(password, this->mUserKey, rt_string_len(this->mUserKey)) == 0) {
+ kout << "User::Matches: Password matches.\r";
+ return Yes;
+ }
- kout << "User::Matches: Password doesn't match.\r";
- return No;
- }
+ kout << "User::Matches: Password doesn't match.\r";
+ return No;
+}
- Bool User::operator==(const User& lhs)
- {
- return lhs.mUserRing == this->mUserRing;
- }
+Bool User::operator==(const User& lhs) {
+ return lhs.mUserRing == this->mUserRing;
+}
- 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.
- ////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+/// @brief Returns the user's name.
+////////////////////////////////////////////////////////////
- Char* User::Name() noexcept
- {
- return this->mUserName;
- }
+Char* User::Name() noexcept {
+ return this->mUserName;
+}
- ////////////////////////////////////////////////////////////
- /// @brief Returns the user's ring.
- /// @return The king of ring the user is attached to.
- ////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+/// @brief Returns the user's ring.
+/// @return The king of ring the user is attached to.
+////////////////////////////////////////////////////////////
- const UserRingKind& User::Ring() noexcept
- {
- return this->mUserRing;
- }
+const UserRingKind& User::Ring() noexcept {
+ return this->mUserRing;
+}
- Bool User::IsStdUser() noexcept
- {
- return this->Ring() == UserRingKind::kRingStdUser;
- }
+Bool User::IsStdUser() noexcept {
+ return this->Ring() == UserRingKind::kRingStdUser;
+}
- Bool User::IsSuperUser() noexcept
- {
- return this->Ring() == UserRingKind::kRingSuperUser;
- }
-} // namespace Kernel
+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
index 5e8cc89e..45a95b5b 100644
--- a/dev/kernel/src/UserProcessScheduler.cc
+++ b/dev/kernel/src/UserProcessScheduler.cc
@@ -1,9 +1,9 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
- FILE: UserProcessScheduler.cc
- PURPOSE: Low level/Ring-3 Process scheduler.
+ FILE: UserProcessScheduler.cc
+ PURPOSE: Low level/Ring-3 process scheduler.
------------------------------------------- */
@@ -13,609 +13,695 @@
/// @author Amlal El Mahrouss (amlal@nekernel.org)
/***********************************************************************************/
-#include <KernelKit/ProcessScheduler.h>
+#include <ArchKit/ArchKit.h>
#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/IPEFDylibObject.h>
-#include <ArchKit/ArchKit.h>
+#include <KernelKit/KPC.h>
#include <KernelKit/MemoryMgr.h>
+#include <KernelKit/ProcessScheduler.h>
#include <NewKit/KString.h>
-#include <KernelKit/KPC.h>
///! BUGS: 0
-namespace Kernel
-{
- /***********************************************************************************/
- /// @brief Exit Code global variable.
- /***********************************************************************************/
-
- STATIC UInt32 kLastExitCode = 0U;
-
- /***********************************************************************************/
- /// @brief External reference of the thread scheduler.
- /***********************************************************************************/
-
- STATIC UserProcessScheduler kProcessScheduler;
-
- Process::Process() = default;
- Process::~Process() = default;
-
- /// @brief Gets the last exit code.
- /// @note Not thread-safe.
- /// @return Int32 the last exit code.
-
- const UInt32& sched_get_exit_code(void) noexcept
- {
- return kLastExitCode;
- }
-
- /***********************************************************************************/
- /// @brief Crashes the current process.
- /***********************************************************************************/
-
- Void Process::Crash()
- {
- if (this->Status != ProcessStatusKind::kRunning)
- return;
-
- (void)(kout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << kendl);
- this->Exit(kErrorProcessFault);
- }
-
- /***********************************************************************************/
- /// @brief boolean operator, check status.
- /***********************************************************************************/
-
- 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.
- /***********************************************************************************/
-
- const UInt32& Process::GetExitCode() noexcept
- {
- return this->fLastExitCode;
- }
-
- /***********************************************************************************/
- /// @brief Error code variable getter.
- /***********************************************************************************/
-
- Int32& Process::GetLocalCode() noexcept
- {
- return this->fLocalCode;
- }
-
- /***********************************************************************************/
- /// @brief Wakes process header.
- /// @param should_wakeup if the program shall wakeup or not.
- /***********************************************************************************/
-
- Void Process::Wake(Bool should_wakeup)
- {
- this->Status =
- should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen;
- }
-
- /***********************************************************************************/
- /** @brief Allocate pointer to track list. */
- /***********************************************************************************/
-
- ErrorOr<VoidPtr> Process::New(SizeT sz, SizeT pad_amount)
- {
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Exit Code global variable.
+/***********************************************************************************/
+
+STATIC UInt32 kLastExitCode = 0U;
+
+STATIC BOOL kCurrentlySwitching = No;
+
+/***********************************************************************************/
+/// @brief Scheduler itself.
+/***********************************************************************************/
+
+STATIC UserProcessScheduler kScheduler;
+
+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.
+
+const UInt32& sched_get_exit_code(void) noexcept {
+ return kLastExitCode;
+}
+
+/***********************************************************************************/
+/// @brief Crashes the current process.
+/***********************************************************************************/
+
+Void USER_PROCESS::Crash() {
+ if (this->Status != ProcessStatusKind::kRunning) return;
+
+ (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl);
+ this->Exit(-kErrorProcessFault);
+}
+
+/***********************************************************************************/
+/// @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.
+/***********************************************************************************/
+
+const UInt32& USER_PROCESS::GetExitCode() noexcept {
+ return this->fLastExitCode;
+}
+
+/***********************************************************************************/
+/// @brief Error code variable getter.
+/***********************************************************************************/
+
+Int32& USER_PROCESS::GetLocalCode() noexcept {
+ return this->fLocalCode;
+}
+
+/***********************************************************************************/
+/// @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. */
+/***********************************************************************************/
+
+STATIC USER_PROCESS::USER_HEAP_TREE* sched_try_go_upper_heap_tree(
+ USER_PROCESS::USER_HEAP_TREE* tree) {
+ if (!tree) {
+ return nullptr;
+ }
+
+ tree = tree->MemoryParent;
+
+ if (tree) {
+ auto tree_tmp = tree->MemoryNext;
+
+ if (!tree_tmp) {
+ return tree;
+ }
+
+ return tree_tmp;
+ }
+
+ return tree;
+}
+
+/***********************************************************************************/
+/** @brief Allocate pointer to heap 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 = hal_read_cr3();
- hal_write_cr3(this->VMRegister);
+ auto vm_register = kKernelCR3;
+ hal_write_cr3(this->VMRegister);
- auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount);
+ auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount);
- hal_write_cr3(vm_register);
+ hal_write_cr3(vm_register);
#else
- auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount);
+ auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount);
#endif
- if (!this->ProcessMemoryHeap)
- {
- this->ProcessMemoryHeap = new ProcessMemoryHeapList();
+ if (!this->HeapTree) {
+ this->HeapTree = new USER_HEAP_TREE();
+
+ this->HeapTree->MemoryColor = USER_HEAP_TREE::kBlackMemory;
+
+ this->HeapTree->MemoryEntryPad = pad_amount;
+ this->HeapTree->MemoryEntrySize = sz;
+
+ this->HeapTree->MemoryEntry = ptr;
+
+ this->HeapTree->MemoryPrev = nullptr;
+ this->HeapTree->MemoryNext = nullptr;
+ this->HeapTree->MemoryParent = nullptr;
+ this->HeapTree->MemoryChild = nullptr;
+ } else {
+ USER_HEAP_TREE* entry = this->HeapTree;
+ USER_HEAP_TREE* prev_entry = entry;
- this->ProcessMemoryHeap->MemoryEntryPad = pad_amount;
- this->ProcessMemoryHeap->MemoryEntrySize = sz;
+ BOOL is_parent = NO;
- this->ProcessMemoryHeap->MemoryEntry = ptr;
+ while (entry) {
+ if (entry->MemoryEntrySize < 1) break;
- this->ProcessMemoryHeap->MemoryPrev = nullptr;
- this->ProcessMemoryHeap->MemoryNext = nullptr;
- }
- else
- {
- ProcessMemoryHeapList* entry = this->ProcessMemoryHeap;
+ prev_entry = entry;
- while (entry)
- {
- if (entry->MemoryEntry == nullptr)
- break; // chose to break here, when we get an already allocated memory entry for our needs.
+ if (entry->MemoryNext) {
+ is_parent = NO;
+ entry = entry->MemoryNext;
+ } else if (entry->MemoryChild) {
+ entry = entry->MemoryChild;
+ is_parent = YES;
+ } else {
+ entry = sched_try_go_upper_heap_tree(entry);
+ }
+ }
- entry = entry->MemoryNext;
- }
+ if (!entry) entry = new USER_HEAP_TREE();
- entry->MemoryNext = new ProcessMemoryHeapList();
- entry->MemoryNext->MemoryEntry = ptr;
+ entry->MemoryEntry = ptr;
+ entry->MemoryEntrySize = sz;
+ entry->MemoryEntryPad = pad_amount;
- entry->MemoryNext->MemoryPrev = entry;
- entry->MemoryNext->MemoryNext = nullptr;
- }
+ if (is_parent) {
+ entry->MemoryParent = prev_entry;
+ prev_entry->MemoryChild = entry;
- this->UsedMemory += sz;
+ prev_entry->MemoryColor = USER_HEAP_TREE::kBlackMemory;
+ entry->MemoryColor = USER_HEAP_TREE::kRedMemory;
+ } else {
+ prev_entry->MemoryNext = entry;
+ entry->MemoryPrev = prev_entry;
+ }
+ }
- return ErrorOr<VoidPtr>(ptr);
- }
+ 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.
+*/
+/***********************************************************************************/
- /***********************************************************************************/
- /// @brief Gets the name of the current process.
- /***********************************************************************************/
+const AffinityKind& USER_PROCESS::GetAffinity() noexcept {
+ return this->Affinity;
+}
- const Char* Process::GetName() noexcept
- {
- return this->Name;
- }
+/***********************************************************************************/
+/** @brief Free heap tree. */
+/***********************************************************************************/
- /***********************************************************************************/
- /// @brief Gets the owner of the process.
- /***********************************************************************************/
+STATIC Void sched_free_heap_tree(USER_PROCESS::USER_HEAP_TREE* memory_heap_list) {
+ // Deleting memory lists. Make sure to free all of them.
+ while (memory_heap_list) {
+ if (memory_heap_list->MemoryEntry) {
+ MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry));
+ }
- const User* Process::GetOwner() noexcept
- {
- return this->Owner;
- }
+ auto next = memory_heap_list->MemoryNext;
- /// @brief Process status getter.
- const ProcessStatusKind& Process::GetStatus() noexcept
- {
- return this->Status;
- }
+ mm_delete_heap(memory_heap_list);
- /***********************************************************************************/
- /**
- @brief Affinity is the time slot allowed for the process.
- */
- /***********************************************************************************/
+ if (memory_heap_list->MemoryChild) sched_free_heap_tree(memory_heap_list->MemoryChild);
- const AffinityKind& Process::GetAffinity() noexcept
- {
- return this->Affinity;
- }
+ memory_heap_list = next;
+ }
+}
- /***********************************************************************************/
- /**
- @brief Exit process method.
- @param exit_code The process's exit code.
- */
- /***********************************************************************************/
+/***********************************************************************************/
+/**
+@brief Exit process method.
+@param exit_code The process's exit code.
+*/
+/***********************************************************************************/
- Void Process::Exit(const Int32& exit_code)
- {
- this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen;
- this->fLastExitCode = exit_code;
+Void USER_PROCESS::Exit(const Int32& exit_code) {
+ this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen;
+ this->fLastExitCode = exit_code;
- kLastExitCode = exit_code;
+ kLastExitCode = exit_code;
- auto memory_heap_list = this->ProcessMemoryHeap;
+ auto memory_heap_list = this->HeapTree;
#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- auto pd = hal_read_cr3();
- hal_write_cr3(this->VMRegister);
+ auto pd = kKernelCR3;
+ hal_write_cr3(this->VMRegister);
#endif
- // Deleting memory lists. Make sure to free all of them.
- while (memory_heap_list)
- {
- if (memory_heap_list->MemoryEntry)
- {
- MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry));
- }
+ sched_free_heap_tree(memory_heap_list);
#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- hal_write_cr3(pd);
+ hal_write_cr3(pd);
#endif
- auto next = memory_heap_list->MemoryNext;
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ //! Free the memory's page directory.
+ if (this->VMRegister) HAL::mm_free_bitmap(this->VMRegister);
+#endif
- mm_delete_heap(memory_heap_list);
+ //! Delete image if not done already.
+ if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode)) mm_delete_heap(this->Image.fCode);
- memory_heap_list = next;
- }
+ //! Delete blob too.
+ if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob)) mm_delete_heap(this->Image.fBlob);
- //! Free the memory's page directory.
- HAL::mm_free_bitmap(this->VMRegister);
+ //! Delete stack frame.
+ if (this->StackFrame && mm_is_valid_heap(this->StackFrame))
+ mm_delete_heap((VoidPtr) this->StackFrame);
- //! Delete image if not done already.
- if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode))
- mm_delete_heap(this->Image.fCode);
+ //! Delete stack reserve.
+ if (this->StackReserve && mm_is_valid_heap(this->StackReserve))
+ mm_delete_heap(reinterpret_cast<VoidPtr>(this->StackReserve));
- //! Delete blob too.
- if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob))
- mm_delete_heap(this->Image.fBlob);
+ //! Avoid use after free.
+ this->Image.fBlob = nullptr;
+ this->Image.fCode = nullptr;
+ this->StackFrame = nullptr;
+ this->StackReserve = nullptr;
- //! Delete stack frame.
- if (this->StackFrame && mm_is_valid_heap(this->StackFrame))
- mm_delete_heap((VoidPtr)this->StackFrame);
+ if (this->Kind == kExecutableDylibKind) {
+ Bool success = false;
- //! Delete stack reserve.
- if (this->StackReserve && mm_is_valid_heap(this->StackReserve))
- mm_delete_heap(reinterpret_cast<VoidPtr>(this->StackReserve));
+ rtl_fini_dylib_pef(*this, reinterpret_cast<IPEFDylibObject*>(this->DylibDelegate), &success);
- //! Avoid use after free.
- this->Image.fBlob = nullptr;
- this->Image.fCode = nullptr;
- this->StackFrame = nullptr;
- this->StackReserve = nullptr;
+ if (!success) {
+ ke_panic(RUNTIME_CHECK_PROCESS);
+ }
- if (this->Kind == kExecutableDylibKind)
- {
- Bool success = false;
+ this->DylibDelegate = nullptr;
+ }
- rtl_fini_dylib(*this, reinterpret_cast<IPEFDylibObject*>(this->DylibDelegate), &success);
+ this->ProcessId = 0UL;
+ this->Status = ProcessStatusKind::kFinished;
- if (!success)
- {
- ke_panic(RUNTIME_CHECK_PROCESS);
- }
+ --this->ParentTeam->mProcessCount;
+}
- this->DylibDelegate = nullptr;
- }
+/***********************************************************************************/
+/// @brief Add process to team.
+/// @param process the process *Ref* class.
+/// @return the process index inside the team.
+/***********************************************************************************/
- this->ProcessId = 0UL;
- this->Status = ProcessStatusKind::kFinished;
+ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image) {
+ if (!name || !code) {
+ return -kErrorProcessFault;
+ }
- --this->ProcessParentTeam->mProcessCount;
+ if (*name == 0) {
+ return -kErrorProcessFault;
+ }
- delete this;
- }
+ ProcessID pid = this->mTeam.mProcessCount;
- /***********************************************************************************/
- /// @brief Add process to team.
- /// @param process the process *Ref* class.
- /// @return the process index inside the team.
- /***********************************************************************************/
+ if (pid > kSchedProcessLimitPerTeam) {
+ return -kErrorProcessFault;
+ }
- ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image)
- {
- ProcessID pid = this->mTeam.mProcessCount;
+ ++this->mTeam.mProcessCount;
- if (pid > kSchedProcessLimitPerTeam)
- {
- return kErrorProcessFault;
- }
+ USER_PROCESS& process = this->mTeam.mProcessList[pid];
- ++this->mTeam.mProcessCount;
+ process.Image.fCode = code;
+ process.Image.fBlob = image;
- Process& process = this->mTeam.mProcessList[pid];
+ SizeT len = rt_string_len(name);
- process.Image.fCode = code;
- process.Image.fBlob = image;
+ if (len > kSchedNameLen) {
+ return -kErrorProcessFault;
+ }
- rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, rt_string_len(name));
+ rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, len);
#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- process.VMRegister = new PDE();
+ process.VMRegister = new PDE();
- if (!process.VMRegister)
- {
- process.Crash();
- return kErrorProcessFault;
- }
+ if (!process.VMRegister) {
+ process.Crash();
+ return -kErrorProcessFault;
+ }
- UInt32 flags = HAL::kMMFlagsPresent;
- flags |= HAL::kMMFlagsWr;
- flags |= HAL::kMMFlagsUser;
+ UInt32 flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
- HAL::mm_map_page((VoidPtr)process.VMRegister, process.VMRegister, flags);
-#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ HAL::mm_map_page((VoidPtr) process.VMRegister, process.VMRegister, flags);
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- process.StackFrame = new HAL::StackFrame();
+ process.StackFrame = new HAL::StackFrame();
- if (!process.StackFrame)
- {
- process.Crash();
- return kErrorProcessFault;
- }
+ if (!process.StackFrame) {
+ process.Crash();
+ return -kErrorProcessFault;
+ }
- rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame));
+ rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame));
#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- flags = HAL::kMMFlagsPresent;
- flags |= HAL::kMMFlagsWr;
- flags |= HAL::kMMFlagsUser;
-
- HAL::mm_map_page((VoidPtr)process.StackFrame, process.StackFrame, flags);
-#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
-
- // React according to process kind.
- switch (process.Kind)
- {
- case Process::kExecutableDylibKind: {
- process.DylibDelegate = rtl_init_dylib(process);
- MUST_PASS(process.DylibDelegate);
- break;
- }
- case Process::kExecutableKind: {
- break;
- }
- default: {
- (void)(kout << "Unknown process kind: " << hex_number(process.Kind) << kendl);
- break;
- }
- }
-
- process.StackReserve = new UInt8[process.StackSize];
-
- if (!process.StackReserve)
- {
- process.Crash();
- return kErrorProcessFault;
- }
-
- rt_set_memory(process.StackReserve, 0, process.StackSize);
+ flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr) process.StackFrame, process.StackFrame, flags);
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+
+ // React according to process kind.
+ switch (process.Kind) {
+ case USER_PROCESS::kExecutableDylibKind: {
+ process.DylibDelegate = rtl_init_dylib_pef(process);
+ MUST_PASS(process.DylibDelegate);
+ break;
+ }
+ case USER_PROCESS::kExecutableKind: {
+ break;
+ }
+ default: {
+ (Void)(kout << "Unknown process kind: " << hex_number(process.Kind) << kendl);
+ break;
+ }
+ }
+
+ process.StackReserve = new UInt8[process.StackSize];
+
+ if (!process.StackReserve) {
+ process.Crash();
+ return -kErrorProcessFault;
+ }
+
+ rt_set_memory(process.StackReserve, 0, process.StackSize);
#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
- flags = HAL::kMMFlagsPresent;
- flags |= HAL::kMMFlagsWr;
- flags |= HAL::kMMFlagsUser;
+ flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr) process.StackReserve, process.StackReserve, flags);
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+
+ process.ParentTeam = &mTeam;
+
+ process.ProcessId = pid;
+ process.Status = ProcessStatusKind::kStarting;
+ process.PTime = (UIntPtr) AffinityKind::kStandard;
+ process.RTime = 0;
+
+ (Void)(kout << "PID: " << number(process.ProcessId) << kendl);
+ (Void)(kout << "Name: " << process.Name << kendl);
+
+ return pid;
+}
+
+/***********************************************************************************/
+/// @brief Retrieves the singleton of the process scheduler.
+/***********************************************************************************/
+
+UserProcessScheduler& UserProcessScheduler::The() {
+ 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(0);
+}
+
+/// @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.mProcessCount < 1) {
+ return 0UL;
+ }
+
+ if (kCurrentlySwitching) return 0UL;
+
+ kCurrentlySwitching = Yes;
+
+ 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)) {
+ if (process.StackSize > kSchedMaxStackSz) {
+ kout << "The process: " << process.Name << ", has not a valid stack size! Crashing it...\r";
+ process.Crash();
+ continue;
+ }
+
+ // Set current process header.
+ this->CurrentProcess() = process;
+
+ process.PTime = static_cast<Int32>(process.Affinity);
+
+ // tell helper to find a core to schedule on.
+ BOOL ret = UserProcessHelper::Switch(process.Image.Leak().Leak().Leak(),
+ &process.StackReserve[process.StackSize - 1],
+ process.StackFrame, process.ProcessId);
+
+ if (!ret) {
+ kout << "The process: " << process.Name << ", is not valid! Crashing it...\r";
+ process.Crash();
+ }
+ } else {
+ if (process.ProcessId == this->CurrentProcess().Leak().ProcessId) {
+ if (process.PTime < process.RTime) {
+ if (process.RTime < (Int32) AffinityKind::kRealTime)
+ process.PTime = (Int32) AffinityKind::kVeryLowUsage;
+ else if (process.RTime < (Int32) AffinityKind::kVeryHigh)
+ process.PTime = (Int32) AffinityKind::kLowUsage;
+ else if (process.RTime < (Int32) AffinityKind::kHigh)
+ process.PTime = (Int32) AffinityKind::kStandard;
+ else if (process.RTime < (Int32) AffinityKind::kStandard)
+ process.PTime = (Int32) AffinityKind::kHigh;
+
+ process.RTime = static_cast<Int32>(process.Affinity);
+
+ BOOL ret = UserProcessHelper::Switch(process.Image.Leak().Leak().Leak(),
+ &process.StackReserve[process.StackSize - 1],
+ process.StackFrame, process.ProcessId);
+
+ if (!ret) {
+ kout << "The process: " << process.Name << ", is not valid! Crashing it...\r";
+ process.Crash();
+ }
+ } else {
+ ++process.RTime;
+ }
+ }
+
+ --process.PTime;
+ }
+ }
+
+ kCurrentlySwitching = No;
+
+ return process_index;
+}
+
+/// @brief Gets the current scheduled team.
+/// @return
+UserProcessTeam& UserProcessScheduler::CurrentTeam() {
+ 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;
+
+ if (kCurrentlySwitching) return No;
+
+ kScheduler.mTeam = team;
+
+ return Yes;
+}
+
+/// @brief Gets current running process.
+/// @return
+Ref<USER_PROCESS>& UserProcessScheduler::CurrentProcess() {
+ return mTeam.AsRef();
+}
+
+/// @brief Current proccess id getter.
+/// @return USER_PROCESS ID integer.
+ErrorOr<PID> UserProcessHelper::TheCurrentPID() {
+ if (!kScheduler.CurrentProcess()) return ErrorOr<PID>{-kErrorProcessFault};
+
+ kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r";
+ return ErrorOr<PID>{kScheduler.CurrentProcess().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.Status == ProcessStatusKind::kKilled ||
+ process.Status == ProcessStatusKind::kFinished ||
+ process.Status == ProcessStatusKind::kStarting ||
+ process.Status == ProcessStatusKind::kFrozen)
+ return No;
+
+ if (process.Status == ProcessStatusKind::kInvalid) return No;
+
+ if (!process.Image.HasCode()) return No;
+
+ if (!process.Name[0]) return No;
+
+ // real time processes shouldn't wait that much.
+ if (process.Affinity == AffinityKind::kRealTime) return Yes;
+
+ return process.PTime < 1;
+}
+
+/***********************************************************************************/
+/**
+ * @brief Start scheduling current AP.
+ */
+/***********************************************************************************/
+
+SizeT UserProcessHelper::StartScheduling() {
+ return kScheduler.Run();
+}
+
+/***********************************************************************************/
+/**
+ * \brief Does a context switch in a CPU.
+ * \param the_stack the stackframe of the running app.
+ * \param new_pid the process's PID.
+ */
+/***********************************************************************************/
+
+Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr frame_ptr,
+ PID new_pid) {
+ for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) {
+ if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid ||
+ HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot)
+ continue;
+
+ // A fallback is a special core for real-time tasks which needs immediate execution.
+ if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPRealTime) {
+ if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity !=
+ AffinityKind::kRealTime)
+ continue;
+
+ if (HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid)) {
+ HardwareThreadScheduler::The()[index].Leak()->fPTime =
+ UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime;
+
+ UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID();
+
+ return YES;
+ }
+
+ continue;
+ }
+
+ if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity ==
+ AffinityKind::kRealTime)
+ continue;
+
+ ////////////////////////////////////////////////////////////
+ /// Prepare task switch. ///
+ ////////////////////////////////////////////////////////////
+
+ Bool ret =
+ HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid);
- HAL::mm_map_page((VoidPtr)process.StackReserve, process.StackReserve, flags);
-#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ ////////////////////////////////////////////////////////////
+ /// Rollback on fail. ///
+ ////////////////////////////////////////////////////////////
- process.ProcessParentTeam = &mTeam;
+ if (!ret) continue;
- process.ProcessId = pid;
- process.Status = ProcessStatusKind::kStarting;
- process.PTime = (UIntPtr)AffinityKind::kStandard;
+ UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid;
- (void)(kout << "PID: " << number(process.ProcessId) << kendl);
- (void)(kout << "Name: " << process.Name << kendl);
+ HardwareThreadScheduler::The()[index].Leak()->fPTime =
+ UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime;
+ HardwareThreadScheduler::The()[index].Leak()->Wake(YES);
- return pid;
- }
+ return Yes;
+ }
- /***********************************************************************************/
- /// @brief Retrieves the singleton of the process scheduler.
- /***********************************************************************************/
+ return No;
+}
- UserProcessScheduler& UserProcessScheduler::The()
- {
- return kProcessScheduler;
- }
-
- /***********************************************************************************/
+////////////////////////////////////////////////////////////
+/// @brief this checks if any process is on the team.
+////////////////////////////////////////////////////////////
+UserProcessScheduler::operator bool() {
+ return mTeam.AsArray().Count() > 0;
+}
- /// @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)
- {
- mTeam.mProcessList[process_id].Exit(0);
- }
-
- /// @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()
- {
- return Yes;
- }
-
- /***********************************************************************************/
- /// @brief Run User scheduler object.
- /// @return Process count executed within a team.
- /***********************************************************************************/
-
- SizeT UserProcessScheduler::Run() noexcept
- {
- SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many
- //! things we have scheduled.
-
- if (mTeam.mProcessCount < 1)
- {
- return 0UL;
- }
-
- for (; process_index < mTeam.AsArray().Capacity(); ++process_index)
- {
- auto& process = mTeam.AsArray()[process_index];
-
- //! check if the process needs to be run.
- if (UserProcessHelper::CanBeScheduled(process))
- {
- // Set current process header.
- this->CurrentProcess() = process;
-
- process.PTime = static_cast<Int32>(process.Affinity);
-
- // tell helper to find a core to schedule on.
- BOOL ret = UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame,
- process.ProcessId);
-
- if (!ret)
- {
- if (process.Affinity == AffinityKind::kRealTime)
- continue;
-
- kout << "The process: " << process.Name << ", is not valid! Crashing it...\r";
-
- process.Crash();
- }
- }
- else
- {
- --process.PTime;
- }
- }
-
- return process_index;
- }
-
- /// @brief Gets the current scheduled team.
- /// @return
- ProcessTeam& UserProcessScheduler::CurrentTeam()
- {
- return mTeam;
- }
-
- /// @internal
-
- /// @brief Gets current running process.
- /// @return
- Ref<Process>& UserProcessScheduler::CurrentProcess()
- {
- return mTeam.AsRef();
- }
-
- /// @brief Current proccess id getter.
- /// @return Process ID integer.
- ErrorOr<PID> UserProcessHelper::TheCurrentPID()
- {
- if (!kProcessScheduler.CurrentProcess())
- return ErrorOr<PID>{kErrorProcessFault};
-
- kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r";
- return ErrorOr<PID>{kProcessScheduler.CurrentProcess().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 Process& process)
- {
- if (process.Status == ProcessStatusKind::kKilled ||
- process.Status == ProcessStatusKind::kFinished ||
- process.Status == ProcessStatusKind::kStarting ||
- process.Status == ProcessStatusKind::kFrozen)
- return No;
-
- if (process.Status == ProcessStatusKind::kInvalid)
- return No;
-
- if (!process.Image.fCode)
- return No;
-
- if (!process.Name[0])
- return No;
-
- // real time processes shouldn't wait that much.
- if (process.Affinity == AffinityKind::kRealTime)
- return Yes;
-
- return process.PTime < 1;
- }
-
- /***********************************************************************************/
- /**
- * @brief Start scheduling current AP.
- */
- /***********************************************************************************/
-
- SizeT UserProcessHelper::StartScheduling()
- {
- return kProcessScheduler.Run();
- }
-
- /***********************************************************************************/
- /**
- * \brief Does a context switch in a CPU.
- * \param the_stack the stackframe of the running app.
- * \param new_pid the process's PID.
- */
- /***********************************************************************************/
-
- Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr frame_ptr, PID new_pid)
- {
- for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index)
- {
- if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid ||
- HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot)
- continue;
-
- // A fallback is a special core for real-time tasks which needs immediate execution.
- if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPRealTime)
- {
- if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity != AffinityKind::kRealTime)
- continue;
-
- if (HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid))
- {
- HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime;
-
- UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID();
-
- return YES;
- }
-
- continue;
- }
-
- if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity == AffinityKind::kRealTime)
- continue;
-
- ////////////////////////////////////////////////////////////
- /// Prepare task switch. ///
- ////////////////////////////////////////////////////////////
-
- Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid);
-
- ////////////////////////////////////////////////////////////
- /// Rollback on fail. ///
- ////////////////////////////////////////////////////////////
-
- if (!ret)
- continue;
-
- UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid;
-
- HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime;
- HardwareThreadScheduler::The()[index].Leak()->Wake(YES);
-
- return Yes;
- }
-
- return No;
- }
-
- ////////////////////////////////////////////////////////////
- /// @brief this checks if any process is on the team.
- ////////////////////////////////////////////////////////////
- UserProcessScheduler::operator bool()
- {
- return mTeam.AsArray().Count() > 0;
- }
-
- ////////////////////////////////////////////////////////////
- /// @brief this checks if no process is on the team.
- ////////////////////////////////////////////////////////////
- Bool UserProcessScheduler::operator!()
- {
- return mTeam.AsArray().Count() == 0;
- }
-} // namespace Kernel
+////////////////////////////////////////////////////////////
+/// @brief this checks if no process is on the team.
+////////////////////////////////////////////////////////////
+Bool UserProcessScheduler::operator!() {
+ return mTeam.AsArray().Count() == 0;
+}
+} // namespace Kernel
diff --git a/dev/kernel/src/UserProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc
new file mode 100644
index 00000000..7acbcf8d
--- /dev/null
+++ b/dev/kernel/src/UserProcessTeam.cc
@@ -0,0 +1,53 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/***********************************************************************************/
+/// @file UserProcessTeam.cc
+/// @brief Process teams implementation.
+/***********************************************************************************/
+
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel {
+UserProcessTeam::UserProcessTeam() {
+ for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) {
+ this->mProcessList[i] = USER_PROCESS();
+ this->mProcessList[i].PTime = 0;
+ this->mProcessList[i].Status = ProcessStatusKind::kKilled;
+ }
+
+ this->mProcessCount = 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
new file mode 100644
index 00000000..8486f59d
--- /dev/null
+++ b/dev/kernel/src/UtfUtils.cc
@@ -0,0 +1,31 @@
+/* -------------------------------------------
+
+ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Utils.h>
+
+namespace Kernel {
+Size urt_string_len(const Utf8Char* str) {
+ SizeT len{0};
+
+ while (str[len] != u'\0') ++len;
+
+ return len;
+}
+
+Int urt_copy_memory(const voidPtr src, voidPtr dst, Size len) {
+ 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 \ No newline at end of file
diff --git a/dev/kernel/src/Utils.cc b/dev/kernel/src/Utils.cc
index f5e61ddf..4f47849b 100644
--- a/dev/kernel/src/Utils.cc
+++ b/dev/kernel/src/Utils.cc
@@ -1,224 +1,195 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <NewKit/Utils.h>
-namespace Kernel
-{
- Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size)
- {
- Int32 counter = 0;
+namespace Kernel {
+Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) {
+ Int32 counter = 0;
- for (Size index = 0; index < size; ++index)
- {
- if (src[index] != cmp[index])
- ++counter;
- }
+ for (Size index = 0; index < size; ++index) {
+ if (src[index] != cmp[index]) ++counter;
+ }
- return counter;
- }
+ return counter;
+}
+
+Void rt_zero_memory(voidPtr pointer, Size len) {
+ rt_set_memory(pointer, 0, len);
+}
+
+SizeT rt_string_len(const Char* str, SizeT _len) {
+ SizeT len{0};
+
+ do {
+ if (len > _len) {
+ return _len;
+ }
+
+ ++len;
+ } while (str[len] != '\0');
+
+ return len;
+}
+
+Size rt_string_len(const Char* ptr) {
+ SizeT cnt{0};
+
+ while (ptr[cnt] != 0) ++cnt;
+
+ return cnt;
+}
+
+voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) {
+ UInt32* start = reinterpret_cast<UInt32*>(src);
+
+ while (len) {
+ *start = value;
+ ++start;
+ --len;
+ }
+
+ return (voidPtr) start;
+}
+
+Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) {
+ Char* srcChr = reinterpret_cast<Char*>(src);
+ Char* dstChar = reinterpret_cast<Char*>(dst);
+ SizeT index = 0;
+
+ while (index < len) {
+ dstChar[index] = srcChr[index];
+ srcChr[index] = 0;
+
+ ++index;
+ }
+
+ return 0;
+}
+
+Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len) {
+ char* srcChr = reinterpret_cast<char*>(src);
+ char* dstChar = reinterpret_cast<char*>(dst);
+ Size index = 0;
+
+ while (index < len) {
+ dstChar[index] = srcChr[index];
+ ++index;
+ }
- Void rt_zero_memory(voidPtr pointer, Size len)
- {
- rt_set_memory(pointer, 0, len);
- }
+ dstChar[index] = 0;
- SizeT rt_string_len(const Char* str, SizeT _len)
- {
- SizeT len{0};
+ return index;
+}
+
+const Char* rt_alloc_string(const Char* src) {
+ const Char* string = new Char[rt_string_len(src) + 1];
+
+ if (!string) return nullptr;
+
+ voidPtr v_src = reinterpret_cast<voidPtr>(const_cast<char*>(src));
+ voidPtr v_dst = reinterpret_cast<voidPtr>(const_cast<char*>(string));
+
+ rt_copy_memory(v_src, v_dst, rt_string_len(src) + 1);
+
+ return string;
+}
- do
- {
- if (len > _len)
- {
- return _len;
- }
+Int32 rt_to_uppercase(Int32 character) {
+ if (character >= 'a' && character <= 'z') return character - 0x20;
- ++len;
- } while (str[len] != '\0');
+ return character;
+}
- return len;
- }
+Int32 rt_is_alnum(Int32 character) {
+ return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') ||
+ (character >= '0' && character <= '9');
+}
- Size rt_string_len(const Char* ptr)
- {
- SizeT cnt{0};
+Int32 rt_to_lower(Int32 character) {
+ if (character >= 'A' && character <= 'Z') return character + 0x20;
- while (ptr[cnt] != 0)
- ++cnt;
-
- return cnt;
- }
-
- voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len)
- {
- UInt32* start = reinterpret_cast<UInt32*>(src);
-
- while (len)
- {
- *start = value;
- ++start;
- --len;
- }
-
- return (voidPtr)start;
- }
-
- Int rt_move_memory(const voidPtr src, voidPtr dst, Size len)
- {
- Char* srcChr = reinterpret_cast<Char*>(src);
- Char* dstChar = reinterpret_cast<Char*>(dst);
- SizeT index = 0;
-
- while (index < len)
- {
- dstChar[index] = srcChr[index];
- srcChr[index] = 0;
-
- ++index;
- }
-
- return 0;
- }
-
- Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len)
- {
- char* srcChr = reinterpret_cast<char*>(src);
- char* dstChar = reinterpret_cast<char*>(dst);
- Size index = 0;
-
- while (index < len)
- {
- dstChar[index] = srcChr[index];
- ++index;
- }
-
- dstChar[index] = 0;
-
- return index;
- }
-
- const Char* rt_alloc_string(const Char* src)
- {
- const Char* string = new Char[rt_string_len(src) + 1];
-
- if (!string)
- return nullptr;
-
- voidPtr v_src = reinterpret_cast<voidPtr>(const_cast<char*>(src));
- voidPtr v_dst = reinterpret_cast<voidPtr>(const_cast<char*>(string));
-
- rt_copy_memory(v_src, v_dst, rt_string_len(src) + 1);
-
- return string;
- }
-
- Int32 rt_to_uppercase(Int32 character)
- {
- if (character >= 'a' && character <= 'z')
- return character - 0x20;
-
- return character;
- }
-
- Int32 rt_is_alnum(Int32 character)
- {
- return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9');
- }
-
- Int32 rt_to_lower(Int32 character)
- {
- if (character >= 'A' && character <= 'Z')
- return character + 0x20;
-
- return character;
- }
+ return character;
+}
- Boolean rt_is_space(Char chr)
- {
- return chr == ' ';
- }
-
- Boolean rt_is_newln(Char chr)
- {
- return chr == '\n';
- }
-
- VoidPtr rt_string_in_string(const Char* in, const Char* needle)
- {
- for (SizeT i = 0; i < rt_string_len(in); ++i)
- {
- if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0)
- return reinterpret_cast<voidPtr>(const_cast<char*>(in + i));
- }
-
- return nullptr;
- }
-
- Char rt_to_char(UInt64 base, Int32 limit)
- {
- Char kNumbers[17] = "0123456789ABCDEF";
- return kNumbers[base % limit];
- }
+Boolean rt_is_space(Char chr) {
+ return chr == ' ';
+}
- Bool rt_to_string(Char* str, UInt64 base, Int32 limit)
- {
+Boolean rt_is_newln(Char chr) {
+ return chr == '\n';
+}
+
+VoidPtr rt_string_in_string(const Char* in, const Char* needle) {
+ for (SizeT i = 0; i < rt_string_len(in); ++i) {
+ if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0)
+ return reinterpret_cast<voidPtr>(const_cast<char*>(in + i));
+ }
+
+ return nullptr;
+}
+
+Char rt_to_char(UInt64 base, Int32 limit) {
+ Char kNumbers[17] = "0123456789ABCDEF";
+ return kNumbers[base % limit];
+}
+
+Bool rt_to_string(Char* str, UInt64 base, Int32 limit) {
#ifdef __NE_AMD64__
- auto i = 0;
+ auto i = 0;
- auto final_number = base;
+ auto final_number = base;
- auto mult = 1;
- auto elems = 0L;
+ auto mult = 1;
+ auto elems = 0L;
- base /= 10;
+ base /= 10;
- while (base > 0)
- {
- elems++;
- mult *= 10;
- base /= 10;
- }
+ while (base > 0) {
+ elems++;
+ mult *= 10;
+ base /= 10;
+ }
- while (elems > -1)
- {
- final_number = (final_number % mult) * 10 + final_number / mult;
- str[i] = rt_to_char(final_number, limit);
+ while (elems > -1) {
+ final_number = (final_number % mult) * 10 + final_number / mult;
+ str[i] = rt_to_char(final_number, limit);
- --elems;
- ++i;
- }
+ --elems;
+ ++i;
+ }
#endif
- return YES;
- }
+ return YES;
+}
+
+/// @brief Checks for a string start at the character.
- /// @brief Checks for a string start at the character.
+Char* rt_string_has_char(Char* str, Char chr) {
+ while (*str != chr) {
+ ++str;
- Char* rt_string_has_char(Char* str, Char chr)
- {
- while (*str != chr)
- {
- ++str;
+ if (*str == 0) return nullptr;
+ }
- if (*str == 0)
- return nullptr;
- }
+ return str;
+}
+} // namespace Kernel
- return str;
- }
-} // namespace Kernel
+////// @note These symbols were written to satisfy gcc, clang and other compiler complaints.
+
+EXTERN_C void* memset(void* dst, int c, long long unsigned int len) {
+ return Kernel::rt_set_memory(dst, c, len);
+}
-EXTERN_C void* memset(void* dst, int c, long long unsigned int len)
-{
- return Kernel::rt_set_memory(dst, c, len);
+EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) {
+ Kernel::rt_copy_memory(const_cast<void*>(src), dst, len);
+ return dst;
}
-EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len)
-{
- Kernel::rt_copy_memory(const_cast<void*>(src), dst, len);
- return dst;
+EXTERN_C Kernel::Int32 strcmp(const char* dst, const char* src) {
+ return Kernel::rt_string_cmp(dst, src, Kernel::rt_string_len(dst));
}
diff --git a/dev/kernel/src/Variant.cc b/dev/kernel/src/Variant.cc
index 239b73fa..5dd39926 100644
--- a/dev/kernel/src/Variant.cc
+++ b/dev/kernel/src/Variant.cc
@@ -1,43 +1,38 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
#include <NewKit/Variant.h>
-namespace Kernel
-{
- const Char* Variant::ToString()
- {
- switch (fKind)
- {
- case VariantKind::kXML:
- return ("Class:{XML}");
- case VariantKind::kJson:
- return ("Class:{Json}");
- case VariantKind::kString:
- return ("Class:{String}");
- case VariantKind::kBlob:
- return ("Class:{Blob}");
- case VariantKind::kNull:
- return ("Class:{Null}");
- case VariantKind::kSwap:
- return ("Class:{Swap}");
- default:
- return ("Class:{Unknown}");
- }
- }
+namespace Kernel {
+const Char* Variant::ToString() {
+ switch (fKind) {
+ case VariantKind::kXML:
+ return ("Class:{XML}");
+ case VariantKind::kJson:
+ return ("Class:{Json}");
+ case VariantKind::kString:
+ return ("Class:{String}");
+ case VariantKind::kBlob:
+ return ("Class:{Blob}");
+ 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 Return variant's kind.
+Variant::VariantKind& Variant::Kind() {
+ return this->fKind;
+}
- /// @brief Leak variant's instance.
- VoidPtr Variant::Leak()
- {
- return this->fPtr;
- }
-} // namespace Kernel
+/// @brief Leak variant's instance.
+VoidPtr Variant::Leak() {
+ return this->fPtr;
+}
+} // namespace Kernel