summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-04-17 23:55:24 +0200
committerGitHub <noreply@github.com>2025-04-17 23:55:24 +0200
commit8ccccad87b171890cbf5040e63b613307cdc5a30 (patch)
tree4dfb464d36a409ab4686ff4e2cfbf0ed8310f6a8 /dev/kernel
parent496f814adf3b9cbcaab2e73188a6730d0a780912 (diff)
parent2363e0ef10e1c34b4a6224199304cc6fda4526bb (diff)
Merge pull request #21 from amlel-el-mahrouss/dev
kernel, boot: recovering lost changes because of some git issue.
Diffstat (limited to 'dev/kernel')
-rw-r--r--dev/kernel/FSKit/Ext2.h129
-rw-r--r--dev/kernel/FSKit/HeFS.h29
-rw-r--r--dev/kernel/FSKit/NeFS.h3
-rw-r--r--dev/kernel/FirmwareKit/GPT.h7
-rw-r--r--dev/kernel/FirmwareKit/Handover.h2
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc28
-rw-r--r--dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc2
-rw-r--r--dev/kernel/HALKit/AMD64/Processor.h2
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc2
-rw-r--r--dev/kernel/HALKit/ARM64/Processor.h2
-rw-r--r--dev/kernel/KernelKit/KernelProcessScheduler.h7
-rw-r--r--dev/kernel/KernelKit/ProcessScheduler.h381
-rw-r--r--dev/kernel/KernelKit/UserProcessScheduler.h383
-rw-r--r--dev/kernel/src/BitMapMgr.cc2
-rw-r--r--dev/kernel/src/UserProcessScheduler.cc12
15 files changed, 568 insertions, 423 deletions
diff --git a/dev/kernel/FSKit/Ext2.h b/dev/kernel/FSKit/Ext2.h
new file mode 100644
index 00000000..81b6853e
--- /dev/null
+++ b/dev/kernel/FSKit/Ext2.h
@@ -0,0 +1,129 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+/// @file Ext2.h
+/// @brief EXT2 filesystem structures and constants.
+
+#define kExt2FSMagic (0xEF53)
+#define kExt2FSMaxFileNameLen (255U)
+#define kExt2FSSuperblockOffset (1024)
+#define kExt2FSRootInodeNumber (2)
+
+#define kExt2FSInodeSize (128U)
+#define kExt2FSBlockSizeBase (1024U)
+
+#define kExt2FSRev0 (0)
+#define kExt2FSRev1 (1)
+
+enum
+{
+ kExt2FileTypeUnknown = 0,
+ kExt2FileTypeRegular = 1,
+ kExt2FileTypeDirectory = 2,
+ kExt2FileTypeCharDevice = 3,
+ kExt2FileTypeBlockDevice = 4,
+ kExt2FileTypeFIFO = 5,
+ kExt2FileTypeSocket = 6,
+ kExt2FileTypeSymbolicLink = 7
+};
+
+struct PACKED EXT2_SUPER_BLOCK final
+{
+ Kernel::UInt32 fInodeCount;
+ Kernel::UInt32 fBlockCount;
+ Kernel::UInt32 fReservedBlockCount;
+ Kernel::UInt32 fFreeBlockCount;
+ Kernel::UInt32 fFreeInodeCount;
+ Kernel::UInt32 fFirstDataBlock;
+ Kernel::UInt32 fLogBlockSize;
+ Kernel::UInt32 fLogFragmentSize;
+ Kernel::UInt32 fBlocksPerGroup;
+ Kernel::UInt32 fFragmentsPerGroup;
+ Kernel::UInt32 fInodesPerGroup;
+ Kernel::UInt32 fMountTime;
+ Kernel::UInt32 fWriteTime;
+ Kernel::UInt16 fMountCount;
+ Kernel::UInt16 fMaxMountCount;
+ Kernel::UInt16 fMagic; // should be 0xEF53
+ Kernel::UInt16 fState;
+ Kernel::UInt16 fErrors;
+ Kernel::UInt16 fMinorRevision;
+ Kernel::UInt32 fLastCheck;
+ Kernel::UInt32 fCheckInterval;
+ Kernel::UInt32 fCreatorOS;
+ Kernel::UInt32 fRevisionLevel;
+ Kernel::UInt16 fDefaultUID;
+ Kernel::UInt16 fDefaultGID;
+
+ // EXT2_DYNAMIC_REV fields
+ Kernel::UInt32 fFirstInode;
+ Kernel::UInt16 fInodeSize;
+ Kernel::UInt16 fBlockGroupNumber;
+ Kernel::UInt32 fFeatureCompat;
+ Kernel::UInt32 fFeatureIncompat;
+ Kernel::UInt32 fFeatureROCompat;
+ Kernel::UInt8 fUUID[16];
+ Kernel::Char fVolumeName[16];
+ Kernel::Char fLastMounted[64];
+ Kernel::UInt32 fAlgoBitmap;
+
+ // Optional journal fields and padding
+ Kernel::UInt8 fPreallocBlocks;
+ Kernel::UInt8 fPreallocDirBlocks;
+ Kernel::UInt16 fReservedGDTBlocks;
+
+ Kernel::UInt8 fJournalUUID[16];
+ Kernel::UInt32 fJournalInode;
+ Kernel::UInt32 fJournalDevice;
+ Kernel::UInt32 fLastOrphan;
+
+ Kernel::UInt32 fHashSeed[4];
+ Kernel::UInt8 fDefHashVersion;
+ Kernel::UInt8 fReservedCharPad;
+ Kernel::UInt16 fReservedWordPad;
+ Kernel::UInt32 fDefaultMountOpts;
+ Kernel::UInt32 fFirstMetaBlockGroup;
+
+ Kernel::UInt8 fReserved[760]; // Padding to make 1024 bytes
+};
+
+struct PACKED EXT2_INODE final
+{
+ Kernel::UInt16 fMode;
+ Kernel::UInt16 fUID;
+ Kernel::UInt32 fSize;
+ Kernel::UInt32 fAccessTime;
+ Kernel::UInt32 fCreateTime;
+ Kernel::UInt32 fModifyTime;
+ Kernel::UInt32 fDeleteTime;
+ Kernel::UInt16 fGID;
+ Kernel::UInt16 fLinksCount;
+ Kernel::UInt32 fBlocks;
+ Kernel::UInt32 fFlags;
+ Kernel::UInt32 fOSD1;
+
+ Kernel::UInt32 fBlock[15]; // 0-11: direct, 12: indirect, 13: double indirect, 14: triple indirect
+
+ Kernel::UInt32 fGeneration;
+ Kernel::UInt32 fFileACL;
+ Kernel::UInt32 fDirACL; // Only for revision 1+
+ Kernel::UInt32 fFragmentAddr;
+
+ Kernel::UInt8 fOSD2[12];
+};
+
+struct PACKED EXT2_DIR_ENTRY final
+{
+ Kernel::UInt32 fInode;
+ Kernel::UInt16 fRecordLength;
+ Kernel::UInt8 fNameLength;
+ Kernel::UInt8 fFileType;
+ Kernel::Char fName[kExt2FSMaxFileNameLen]; // null-terminated, not fixed-length in actual on-disk layout
+}; \ No newline at end of file
diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h
index 6c294ec6..cf1bebfc 100644
--- a/dev/kernel/FSKit/HeFS.h
+++ b/dev/kernel/FSKit/HeFS.h
@@ -20,19 +20,30 @@
#define kHeFSMinimumDiskSize (mib_cast(256))
+struct HeFS_BOOT_NODE;
+
enum
{
- kHeFSInvalidDrive,
- kHeFSHDDDrive,
- kHeFSSSDDrive,
- kHeFSMassStorageDrive,
- kHeFSSCSIDrive,
- kHeFSDriveCount,
+ kHeFSHardDrive = 0xC0, // Hard Drive
+ kHeFSSolidStateDrive = 0xC1, // Solid State Drive
+ kHeFSOpticalDrive = 0x0C, // Blu-Ray/DVD
+ kHeFSMassStorageDevice = 0xCC, // USB
+ kHeFSScsiDrive = 0xC4, // SCSI Hard Drive
+ kHeFSFlashDrive = 0xC6,
+ kHeFSUnknown = 0xFF, // Unknown device.
+ kHeFSDriveCount = 7,
};
-struct HeFS_BOOT_NODE;
+enum
+{
+ kHeFSStatusUnlocked = 0x18,
+ kHeFSStatusLocked,
+ kHeFSStatusError,
+ kHeFSStatusInvalid,
+ kHeFSStatusCount,
+};
-struct HeFS_BOOT_NODE final
+struct PACKED HeFS_BOOT_NODE final
{
Kernel::Char fMagic[kHeFSMagicLen];
Kernel::Char fPartName[kHeFSPartNameLen];
@@ -47,7 +58,7 @@ struct HeFS_BOOT_NODE final
Kernel::UInt64 fRecoveryINode;
};
-struct HeFS_INDEX_NODE
+struct PACKED HeFS_INDEX_NODE
{
Kernel::Char fName[kHeFSFileNameLen];
Kernel::UInt32 fFlags;
diff --git a/dev/kernel/FSKit/NeFS.h b/dev/kernel/FSKit/NeFS.h
index 3c11fdb4..747af16b 100644
--- a/dev/kernel/FSKit/NeFS.h
+++ b/dev/kernel/FSKit/NeFS.h
@@ -135,9 +135,10 @@ enum
kNeFSStatusLocked,
kNeFSStatusError,
kNeFSStatusInvalid,
+ kNeFSStatusCount,
};
-/// @brief Catalog type.
+/// @brief Catalog record type.
struct PACKED NEFS_CATALOG_STRUCT final
{
BOOL ForkOrCatalog : 1 {0};
diff --git a/dev/kernel/FirmwareKit/GPT.h b/dev/kernel/FirmwareKit/GPT.h
index a8b53ead..9a6cffc6 100644
--- a/dev/kernel/FirmwareKit/GPT.h
+++ b/dev/kernel/FirmwareKit/GPT.h
@@ -9,7 +9,8 @@
#include <NewKit/Defines.h>
#include <FirmwareKit/EFI/EFI.h>
-#define kSectorSizeGPT (512U)
+#define kSectorAlignGPT_Part (420U)
+#define kSectorAlignGPT_PartEntry (72U)
#define kPartNameGPT (8U)
namespace Kernel
@@ -43,7 +44,7 @@ namespace Kernel
UInt32 NumPartitionEntries;
UInt32 SizeOfEntries;
UInt32 CRC32PartEntry;
- UInt8 Reserved2[kSectorSizeGPT];
+ UInt8 Reserved2[kSectorAlignGPT_Part];
};
struct PACKED GPT_PARTITION_ENTRY
@@ -53,6 +54,6 @@ namespace Kernel
UInt64 StartLBA;
UInt64 EndLBA;
UInt64 Attributes;
- UInt8 Name[72];
+ UInt8 Name[kSectorAlignGPT_PartEntry];
};
} // namespace Kernel
diff --git a/dev/kernel/FirmwareKit/Handover.h b/dev/kernel/FirmwareKit/Handover.h
index ecdaca64..dd529a9e 100644
--- a/dev/kernel/FirmwareKit/Handover.h
+++ b/dev/kernel/FirmwareKit/Handover.h
@@ -17,7 +17,7 @@
#pragma once
-#include "FirmwareKit/EFI/EFI.h"
+#include <FirmwareKit/EFI/EFI.h>
#include <NewKit/Defines.h>
#define kHandoverMagic 0xBADCC
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index 43888f3b..938907f4 100644
--- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -210,24 +210,15 @@ namespace Kernel::HAL
if (kMADTBlock)
{
- SizeT index = 1;
+ SizeT index = 1UL;
kSMPInterrupt = 0;
kSMPCount = 0;
- kout << "SMP: Starting APs...\r";
+ kout << "SMP: Registering APIC IDs...\r";
kApicBaseAddress = kMADTBlock->Address;
- constexpr auto kMemoryAPStart = 0x7C000;
- Char* ptr_ap_code = reinterpret_cast<Char*>(kMemoryAPStart);
-
- mm_map_page(ptr_ap_code, ptr_ap_code, kMMFlagsWr);
-
- SizeT hal_ap_blob_len = hal_ap_blob_end - hal_ap_blob_start;
-
- rt_copy_memory((Char*)hal_ap_blob_start, ptr_ap_code, hal_ap_blob_len);
-
while (Yes)
{
if (kMADTBlock->List[index].Type > 9 ||
@@ -241,18 +232,7 @@ namespace Kernel::HAL
break;
kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].LAPIC.ProcessorID;
- (void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
-
- // I'll just make the AP start from scratch here.
-
- hal_send_start_ipi(kApicBaseAddress, kAPICLocales[kSMPCount]);
-
- HardwareTimer timer(Kernel::rtl_ms(10));
- timer.Wait();
-
- /// TODO: HAL helper to create an address.
-
- hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)ptr_ap_code) >> 12));
+ (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
++kSMPCount;
break;
@@ -264,7 +244,7 @@ namespace Kernel::HAL
++index;
}
- (void)(kout << "SMP: number of APs: " << number(kSMPCount) << kendl);
+ (Void)(kout << "SMP: Number of IDs: " << number(kSMPCount) << kendl);
// Kernel is now SMP aware.
// That means that the scheduler is now available (on MP Kernels)
diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
index 4b50a3f4..16fe843a 100644
--- a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
+++ b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
@@ -143,7 +143,7 @@ namespace Kernel::HAL
pte->Wr = !!(flags & kMMFlagsWr);
pte->User = !!(flags & kMMFlagsUser);
pte->Nx = !!(flags & kMMFlagsNX);
- pte->Pcd = !(flags & kMMFlagsUncached);
+ pte->Pcd = !(flags & kMMFlagsPCD);
pte->PhysicalAddress = (UIntPtr)(physical_address);
mmi_page_status(pte);
diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h
index e375a935..a5bc82c7 100644
--- a/dev/kernel/HALKit/AMD64/Processor.h
+++ b/dev/kernel/HALKit/AMD64/Processor.h
@@ -73,7 +73,7 @@ namespace Kernel::HAL
kMMFlagsWr = 1 << 2,
kMMFlagsUser = 1 << 3,
kMMFlagsNX = 1 << 4,
- kMMFlagsUncached = 1 << 5,
+ kMMFlagsPCD = 1 << 5,
kMMFlagsCount = 4,
};
diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
index 2dfd89a1..9c8f95bc 100644
--- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
@@ -283,7 +283,7 @@ STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi)
kSATADev.EnableMmio();
kSATADev.BecomeBusMaster();
- HAL::mm_map_page((VoidPtr)mem_ahci, (VoidPtr)mem_ahci, HAL::kMMFlagsPresent | HAL::kMMFlagsWr | HAL::kMMFlagsUncached);
+ HAL::mm_map_page((VoidPtr)mem_ahci, (VoidPtr)mem_ahci, HAL::kMMFlagsPresent | HAL::kMMFlagsWr | HAL::kMMFlagsPCD);
UInt32 ports_implemented = mem_ahci->Pi;
UInt16 ahci_index = 0;
diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h
index b108fc82..4cead7ea 100644
--- a/dev/kernel/HALKit/ARM64/Processor.h
+++ b/dev/kernel/HALKit/ARM64/Processor.h
@@ -28,7 +28,7 @@ namespace Kernel::HAL
kMMFlagsWr = 1 << 1,
kMMFlagsUser = 1 << 2,
kMMFlagsNX = 1 << 3,
- kMMFlagsUncached = 1 << 4,
+ kMMFlagsPCD = 1 << 4,
kMMFlagsCount = 4,
};
diff --git a/dev/kernel/KernelKit/KernelProcessScheduler.h b/dev/kernel/KernelKit/KernelProcessScheduler.h
new file mode 100644
index 00000000..47d61ff7
--- /dev/null
+++ b/dev/kernel/KernelKit/KernelProcessScheduler.h
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once \ No newline at end of file
diff --git a/dev/kernel/KernelKit/ProcessScheduler.h b/dev/kernel/KernelKit/ProcessScheduler.h
index cff2ce6b..038f46db 100644
--- a/dev/kernel/KernelKit/ProcessScheduler.h
+++ b/dev/kernel/KernelKit/ProcessScheduler.h
@@ -1,383 +1,10 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#ifndef INC_PROCESS_SCHEDULER_H
-#define INC_PROCESS_SCHEDULER_H
+#pragma once
-/// @file ProcessScheduler.h
-/// @brief Process scheduler code and definitions.
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-
-#include <ArchKit/ArchKit.h>
-#include <KernelKit/LockDelegate.h>
-#include <KernelKit/User.h>
-#include <NewKit/MutableArray.h>
-
-#define kSchedMinMicroTime (AffinityKind::kStandard)
-#define kSchedInvalidPID (-1)
-#define kSchedProcessLimitPerTeam (32U)
-
-#define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */
-#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */
-
-#define kSchedNameLen (128U)
-
-////////////////////////////////////////////////////
-// Last revision date is: Fri Mar 28 2025 //
-////////////////////////////////////////////////////
-
-namespace Kernel
-{
- //! @brief Forward declarations.
-
- class IDylibObject;
- class Process;
- class ProcessTeam;
- class UserProcessScheduler;
- class UserProcessHelper;
-
- typedef UInt64 PTime;
-
- /***********************************************************************************/
- //! @brief Local Process identifier.
- /***********************************************************************************/
- typedef Int64 ProcessID;
-
- /***********************************************************************************/
- //! @brief Local Process status enum.
- /***********************************************************************************/
- enum class ProcessStatusKind : Int32
- {
- kInvalid,
- kStarting,
- kRunning,
- kKilled,
- kFrozen,
- kFinished,
- kCount,
- };
-
- /***********************************************************************************/
- //! @brief Affinity is the amount of nano-seconds this process is going to run.
- /***********************************************************************************/
- enum class AffinityKind : Int32
- {
- kRealTime = 500,
- kVeryHigh = 250,
- kHigh = 200,
- kStandard = 1000,
- kLowUsage = 1500,
- kVeryLowUsage = 2000,
- };
-
- /***********************************************************************************/
- //! Operators for AffinityKind
- /***********************************************************************************/
-
- inline bool operator<(AffinityKind lhs, AffinityKind rhs)
- {
- Int32 lhs_int = static_cast<Int>(lhs);
- Int32 rhs_int = static_cast<Int>(rhs);
-
- return lhs_int < rhs_int;
- }
-
- inline bool operator>(AffinityKind lhs, AffinityKind rhs)
- {
- Int32 lhs_int = static_cast<Int>(lhs);
- Int32 rhs_int = static_cast<Int>(rhs);
-
- return lhs_int > rhs_int;
- }
-
- inline bool operator<=(AffinityKind lhs, AffinityKind rhs)
- {
- Int32 lhs_int = static_cast<Int>(lhs);
- Int32 rhs_int = static_cast<Int>(rhs);
-
- return lhs_int <= rhs_int;
- }
-
- inline bool operator>=(AffinityKind lhs, AffinityKind rhs)
- {
- Int32 lhs_int = static_cast<Int>(lhs);
- Int32 rhs_int = static_cast<Int>(rhs);
-
- return lhs_int >= rhs_int;
- }
-
- /***********************************************************************************/
- /// @brief Subsystem enum type.
- /***********************************************************************************/
-
- enum class ProcessSubsystem : Int32
- {
- kProcessSubsystemSecurity = 100,
- kProcessSubsystemApplication,
- kProcessSubsystemService,
- kProcessSubsystemDriver,
- kProcessSubsystemInvalid = 256U,
- kProcessSubsystemCount = 4,
- };
-
- using ProcessTime = UInt64;
- using PID = Int64;
-
- /***********************************************************************************/
- /// @note For User manager, tells where we run the code.
- /***********************************************************************************/
- enum class ProcessLevelRing : Int32
- {
- kRingStdUser = 1,
- kRingSuperUser = 2,
- kRingGuestUser = 5,
- kRingCount = 5,
- };
-
- /***********************************************************************************/
- /// @brief Helper type to describe a code image.
- /***********************************************************************************/
- using ImagePtr = VoidPtr;
-
- struct ProcessImage final
- {
- explicit ProcessImage() = default;
-
- ImagePtr fCode;
- ImagePtr fBlob;
-
- Bool HasCode()
- {
- return this->fCode != nullptr;
- }
-
- Bool HasImage()
- {
- return this->fBlob != nullptr;
- }
- };
-
- /***********************************************************************************/
- /// @name Process
- /// @brief Process class, holds information about the running process/thread.
- /***********************************************************************************/
- class Process final
- {
- public:
- explicit Process();
- ~Process();
-
- public:
- NE_COPY_DEFAULT(Process)
-
- public:
- Char Name[kSchedNameLen] = {"Process"};
- ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid};
- User* Owner{nullptr};
- HAL::StackFramePtr StackFrame{nullptr};
- AffinityKind Affinity{AffinityKind::kStandard};
- ProcessStatusKind Status{ProcessStatusKind::kFinished};
- UInt8* StackReserve{nullptr};
- ProcessImage Image{};
- SizeT StackSize{kSchedMaxStackSz};
- IDylibObject* DylibDelegate{nullptr};
- SizeT MemoryCursor{0UL};
- SizeT MemoryLimit{kSchedMaxMemoryLimit};
- SizeT UsedMemory{0UL};
-
- struct ProcessMemoryHeapList final
- {
- VoidPtr MemoryEntry{nullptr};
- SizeT MemoryEntrySize{0UL};
- SizeT MemoryEntryPad{0UL};
-
- struct ProcessMemoryHeapList* MemoryPrev{nullptr};
- struct ProcessMemoryHeapList* MemoryNext{nullptr};
- };
-
- struct ProcessSignal final
- {
- UIntPtr SignalArg;
- ProcessStatusKind PreviousStatus;
- UIntPtr SignalID;
- };
-
- ProcessSignal ProcessSignal;
- ProcessMemoryHeapList* ProcessMemoryHeap{nullptr};
- ProcessTeam* ProcessParentTeam;
-
- VoidPtr VMRegister{0UL};
-
- enum
- {
- kInvalidExecutableKind,
- kExectuableKind,
- kExectuableDylibKind,
- kExectuableKindCount,
- };
-
- ProcessTime PTime{0}; //! @brief Process allocated tine.
-
- PID ProcessId{kSchedInvalidPID};
- Int32 Kind{kExectuableKind};
-
- public:
- /***********************************************************************************/
- //! @brief boolean operator, check status.
- /***********************************************************************************/
- operator bool();
-
- /***********************************************************************************/
- ///! @brief Crashes the app, exits with code ~0.
- /***********************************************************************************/
- Void Crash();
-
- /***********************************************************************************/
- ///! @brief Exits the app.
- /***********************************************************************************/
- Void Exit(const Int32& exit_code = 0);
-
- /***********************************************************************************/
- ///! @brief TLS allocate.
- ///! @param sz size of data structure.
- ///! @param pad_amount amount to add after pointer.
- ///! @return A wrapped pointer, or error code.
- /***********************************************************************************/
- ErrorOr<VoidPtr> New(SizeT sz, SizeT pad_amount = 0);
-
- /***********************************************************************************/
- ///! @brief TLS free.
- ///! @param ptr the pointer to free.
- ///! @param sz the size of it.
- /***********************************************************************************/
- template <typename T>
- Boolean Delete(ErrorOr<T*> ptr);
-
- /***********************************************************************************/
- ///! @brief Wakes up thread.
- /***********************************************************************************/
- Void Wake(Bool wakeup = false);
-
- public:
- /***********************************************************************************/
- //! @brief Gets the local exit code.
- /***********************************************************************************/
- const UInt32& GetExitCode() noexcept;
-
- /***********************************************************************************/
- ///! @brief Get the process's name
- ///! @example 'C Runtime Library'
- /***********************************************************************************/
- const Char* GetName() noexcept;
-
- /***********************************************************************************/
- //! @brief return local error code of process.
- //! @return Int32 local error code.
- /***********************************************************************************/
- Int32& GetLocalCode() noexcept;
-
- const User* GetOwner() noexcept;
- const ProcessStatusKind& GetStatus() noexcept;
- const AffinityKind& GetAffinity() noexcept;
-
- private:
- UInt32 fLastExitCode{0};
- Int32 fLocalCode{0};
-
- friend UserProcessScheduler;
- friend UserProcessHelper;
- };
-
- /// \brief Processs Team (contains multiple processes inside it.)
- /// Equivalent to a process batch
- class ProcessTeam final
- {
- public:
- explicit ProcessTeam();
- ~ProcessTeam() = default;
-
- NE_COPY_DEFAULT(ProcessTeam)
-
- Array<Process, kSchedProcessLimitPerTeam>& AsArray();
- Ref<Process>& AsRef();
- ProcessID& Id() noexcept;
-
- public:
- Array<Process, kSchedProcessLimitPerTeam> mProcessList;
- Ref<Process> mCurrentProcess;
- ProcessID mTeamId{0};
- ProcessID mProcessCount{0};
- };
-
- typedef Array<Process, kSchedProcessLimitPerTeam> UserThreadArray;
-
- using UserProcessRef = Process&;
-
- /***********************************************************************************/
- /// @brief Process scheduler class.
- /// The main class which you call to schedule user processes.
- /***********************************************************************************/
- class UserProcessScheduler final : public ISchedulable
- {
- friend class UserProcessHelper;
-
- public:
- explicit UserProcessScheduler() = default;
- ~UserProcessScheduler() override = default;
-
- NE_COPY_DEFAULT(UserProcessScheduler)
-
- operator bool();
- bool operator!();
-
- public:
- ProcessTeam& CurrentTeam();
-
- public:
- ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image);
- Void Remove(ProcessID process_id);
-
- Bool IsUser() override;
- Bool IsKernel() override;
- Bool HasMP() override;
-
- public:
- Ref<Process>& CurrentProcess();
- SizeT Run() noexcept;
-
- public:
- STATIC UserProcessScheduler& The();
-
- private:
- ProcessTeam mTeam{};
- };
-
- /***********************************************************************************/
- /**
- * \brief Process helper class, which contains needed utilities for the scheduler.
- */
- /***********************************************************************************/
-
- class UserProcessHelper final
- {
- public:
- STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, PID new_pid);
- STATIC Bool CanBeScheduled(const Process& process);
- STATIC ErrorOr<PID> TheCurrentPID();
- STATIC SizeT StartScheduling();
- };
-
- const UInt32& sched_get_exit_code(void) noexcept;
-} // namespace Kernel
-
-#include <KernelKit/ThreadLocalStorage.h>
-#include <KernelKit/UserProcessScheduler.inl>
-
-////////////////////////////////////////////////////
-// END
-////////////////////////////////////////////////////
-
-#endif /* ifndef INC_PROCESS_SCHEDULER_H */
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/KernelProcessScheduler.h> \ No newline at end of file
diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h
new file mode 100644
index 00000000..a99fc45b
--- /dev/null
+++ b/dev/kernel/KernelKit/UserProcessScheduler.h
@@ -0,0 +1,383 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#define INC_PROCESS_SCHEDULER_H
+
+/// @file ProcessScheduler.h
+/// @brief Process scheduler code and definitions.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/LockDelegate.h>
+#include <KernelKit/User.h>
+#include <NewKit/MutableArray.h>
+
+#define kSchedMinMicroTime (AffinityKind::kStandard)
+#define kSchedInvalidPID (-1)
+#define kSchedProcessLimitPerTeam (32U)
+
+#define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */
+#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */
+
+#define kSchedNameLen (128U)
+
+////////////////////////////////////////////////////
+// Last revision date is: Fri Mar 28 2025 //
+////////////////////////////////////////////////////
+
+namespace Kernel
+{
+ //! @brief Forward declarations.
+
+ class IDylibObject;
+ class Process;
+ class ProcessTeam;
+ class UserProcessScheduler;
+ class UserProcessHelper;
+
+ typedef UInt64 PTime;
+
+ /***********************************************************************************/
+ //! @brief Local Process identifier.
+ /***********************************************************************************/
+ typedef Int64 ProcessID;
+
+ /***********************************************************************************/
+ //! @brief Local Process status enum.
+ /***********************************************************************************/
+ enum class ProcessStatusKind : Int32
+ {
+ kInvalid,
+ kStarting,
+ kRunning,
+ kKilled,
+ kFrozen,
+ kFinished,
+ kCount,
+ };
+
+ /***********************************************************************************/
+ //! @brief Affinity is the amount of nano-seconds this process is going to run.
+ /***********************************************************************************/
+ enum class AffinityKind : Int32
+ {
+ kRealTime = 500,
+ kVeryHigh = 250,
+ kHigh = 200,
+ kStandard = 1000,
+ kLowUsage = 1500,
+ kVeryLowUsage = 2000,
+ };
+
+ /***********************************************************************************/
+ //! Operators for AffinityKind
+ /***********************************************************************************/
+
+ inline bool operator<(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int < rhs_int;
+ }
+
+ inline bool operator>(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int > rhs_int;
+ }
+
+ inline bool operator<=(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int <= rhs_int;
+ }
+
+ inline bool operator>=(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int >= rhs_int;
+ }
+
+ /***********************************************************************************/
+ /// @brief Subsystem enum type.
+ /***********************************************************************************/
+
+ enum class ProcessSubsystem : Int32
+ {
+ kProcessSubsystemSecurity = 100,
+ kProcessSubsystemApplication,
+ kProcessSubsystemService,
+ kProcessSubsystemDriver,
+ kProcessSubsystemInvalid = 256U,
+ kProcessSubsystemCount = 4,
+ };
+
+ using ProcessTime = UInt64;
+ using PID = Int64;
+
+ /***********************************************************************************/
+ /// @note For User manager, tells where we run the code.
+ /***********************************************************************************/
+ enum class ProcessLevelRing : Int32
+ {
+ kRingStdUser = 1,
+ kRingSuperUser = 2,
+ kRingGuestUser = 5,
+ kRingCount = 5,
+ };
+
+ /***********************************************************************************/
+ /// @brief Helper type to describe a code image.
+ /***********************************************************************************/
+ using ImagePtr = VoidPtr;
+
+ struct ProcessImage final
+ {
+ explicit ProcessImage() = default;
+
+ ImagePtr fCode;
+ ImagePtr fBlob;
+
+ Bool HasCode()
+ {
+ return this->fCode != nullptr;
+ }
+
+ Bool HasImage()
+ {
+ return this->fBlob != nullptr;
+ }
+ };
+
+ /***********************************************************************************/
+ /// @name Process
+ /// @brief Process class, holds information about the running process/thread.
+ /***********************************************************************************/
+ class Process final
+ {
+ public:
+ explicit Process();
+ ~Process();
+
+ public:
+ NE_COPY_DEFAULT(Process)
+
+ public:
+ Char Name[kSchedNameLen] = {"Process"};
+ ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid};
+ User* Owner{nullptr};
+ HAL::StackFramePtr StackFrame{nullptr};
+ AffinityKind Affinity{AffinityKind::kStandard};
+ ProcessStatusKind Status{ProcessStatusKind::kFinished};
+ UInt8* StackReserve{nullptr};
+ ProcessImage Image{};
+ SizeT StackSize{kSchedMaxStackSz};
+ IDylibObject* DylibDelegate{nullptr};
+ SizeT MemoryCursor{0UL};
+ SizeT MemoryLimit{kSchedMaxMemoryLimit};
+ SizeT UsedMemory{0UL};
+
+ struct ProcessMemoryHeapList final
+ {
+ VoidPtr MemoryEntry{nullptr};
+ SizeT MemoryEntrySize{0UL};
+ SizeT MemoryEntryPad{0UL};
+
+ struct ProcessMemoryHeapList* MemoryPrev{nullptr};
+ struct ProcessMemoryHeapList* MemoryNext{nullptr};
+ };
+
+ struct ProcessSignal final
+ {
+ UIntPtr SignalArg;
+ ProcessStatusKind PreviousStatus;
+ UIntPtr SignalID;
+ };
+
+ ProcessSignal ProcessSignal;
+ ProcessMemoryHeapList* ProcessMemoryHeap{nullptr};
+ ProcessTeam* ProcessParentTeam;
+
+ VoidPtr VMRegister{0UL};
+
+ enum
+ {
+ kInvalidExecutableKind,
+ kExecutableKind,
+ kExecutableDylibKind,
+ kExecutableKindCount,
+ };
+
+ ProcessTime PTime{0}; //! @brief Process allocated tine.
+
+ PID ProcessId{kSchedInvalidPID};
+ Int32 Kind{kExecutableKind};
+
+ public:
+ /***********************************************************************************/
+ //! @brief boolean operator, check status.
+ /***********************************************************************************/
+ operator bool();
+
+ /***********************************************************************************/
+ ///! @brief Crashes the app, exits with code ~0.
+ /***********************************************************************************/
+ Void Crash();
+
+ /***********************************************************************************/
+ ///! @brief Exits the app.
+ /***********************************************************************************/
+ Void Exit(const Int32& exit_code = 0);
+
+ /***********************************************************************************/
+ ///! @brief TLS allocate.
+ ///! @param sz size of data structure.
+ ///! @param pad_amount amount to add after pointer.
+ ///! @return A wrapped pointer, or error code.
+ /***********************************************************************************/
+ ErrorOr<VoidPtr> New(SizeT sz, SizeT pad_amount = 0);
+
+ /***********************************************************************************/
+ ///! @brief TLS free.
+ ///! @param ptr the pointer to free.
+ ///! @param sz the size of it.
+ /***********************************************************************************/
+ template <typename T>
+ Boolean Delete(ErrorOr<T*> ptr);
+
+ /***********************************************************************************/
+ ///! @brief Wakes up thread.
+ /***********************************************************************************/
+ Void Wake(Bool wakeup = false);
+
+ public:
+ /***********************************************************************************/
+ //! @brief Gets the local exit code.
+ /***********************************************************************************/
+ const UInt32& GetExitCode() noexcept;
+
+ /***********************************************************************************/
+ ///! @brief Get the process's name
+ ///! @example 'C Runtime Library'
+ /***********************************************************************************/
+ const Char* GetName() noexcept;
+
+ /***********************************************************************************/
+ //! @brief return local error code of process.
+ //! @return Int32 local error code.
+ /***********************************************************************************/
+ Int32& GetLocalCode() noexcept;
+
+ const User* GetOwner() noexcept;
+ const ProcessStatusKind& GetStatus() noexcept;
+ const AffinityKind& GetAffinity() noexcept;
+
+ private:
+ UInt32 fLastExitCode{0};
+ Int32 fLocalCode{0};
+
+ friend UserProcessScheduler;
+ friend UserProcessHelper;
+ };
+
+ /// \brief Processs Team (contains multiple processes inside it.)
+ /// Equivalent to a process batch
+ class ProcessTeam final
+ {
+ public:
+ explicit ProcessTeam();
+ ~ProcessTeam() = default;
+
+ NE_COPY_DEFAULT(ProcessTeam)
+
+ Array<Process, kSchedProcessLimitPerTeam>& AsArray();
+ Ref<Process>& AsRef();
+ ProcessID& Id() noexcept;
+
+ public:
+ Array<Process, kSchedProcessLimitPerTeam> mProcessList;
+ Ref<Process> mCurrentProcess;
+ ProcessID mTeamId{0};
+ ProcessID mProcessCount{0};
+ };
+
+ typedef Array<Process, kSchedProcessLimitPerTeam> UserThreadArray;
+
+ using UserProcessRef = Process&;
+
+ /***********************************************************************************/
+ /// @brief Process scheduler class.
+ /// The main class which you call to schedule user processes.
+ /***********************************************************************************/
+ class UserProcessScheduler final : public ISchedulable
+ {
+ friend class UserProcessHelper;
+
+ public:
+ explicit UserProcessScheduler() = default;
+ ~UserProcessScheduler() override = default;
+
+ NE_COPY_DEFAULT(UserProcessScheduler)
+
+ operator bool();
+ bool operator!();
+
+ public:
+ ProcessTeam& CurrentTeam();
+
+ public:
+ ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image);
+ Void Remove(ProcessID process_id);
+
+ Bool IsUser() override;
+ Bool IsKernel() override;
+ Bool HasMP() override;
+
+ public:
+ Ref<Process>& CurrentProcess();
+ SizeT Run() noexcept;
+
+ public:
+ STATIC UserProcessScheduler& The();
+
+ private:
+ ProcessTeam mTeam{};
+ };
+
+ /***********************************************************************************/
+ /**
+ * \brief Process helper class, which contains needed utilities for the scheduler.
+ */
+ /***********************************************************************************/
+
+ class UserProcessHelper final
+ {
+ public:
+ STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, PID new_pid);
+ STATIC Bool CanBeScheduled(const Process& process);
+ STATIC ErrorOr<PID> TheCurrentPID();
+ STATIC SizeT StartScheduling();
+ };
+
+ const UInt32& sched_get_exit_code(void) noexcept;
+} // namespace Kernel
+
+#include <KernelKit/ThreadLocalStorage.h>
+#include <KernelKit/UserProcessScheduler.inl>
+
+////////////////////////////////////////////////////
+// END
+////////////////////////////////////////////////////
+
+#endif /* ifndef INC_PROCESS_SCHEDULER_H */
diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc
index fe4b9625..96cbb803 100644
--- a/dev/kernel/src/BitMapMgr.cc
+++ b/dev/kernel/src/BitMapMgr.cc
@@ -78,7 +78,7 @@ namespace Kernel
if (user)
flags |= kMMFlagsUser;
- flags |= HAL::kMMFlagsUncached;
+ flags |= HAL::kMMFlagsPCD;
return flags;
}
diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc
index b2052723..5e8cc89e 100644
--- a/dev/kernel/src/UserProcessScheduler.cc
+++ b/dev/kernel/src/UserProcessScheduler.cc
@@ -255,7 +255,7 @@ namespace Kernel
this->StackFrame = nullptr;
this->StackReserve = nullptr;
- if (this->Kind == kExectuableDylibKind)
+ if (this->Kind == kExecutableDylibKind)
{
Bool success = false;
@@ -325,6 +325,8 @@ namespace Kernel
return kErrorProcessFault;
}
+ rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame));
+
#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
flags = HAL::kMMFlagsPresent;
flags |= HAL::kMMFlagsWr;
@@ -336,11 +338,14 @@ namespace Kernel
// React according to process kind.
switch (process.Kind)
{
- case Process::kExectuableDylibKind: {
+ 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;
@@ -348,7 +353,6 @@ namespace Kernel
}
process.StackReserve = new UInt8[process.StackSize];
- rt_set_memory(process.StackReserve, 0, process.StackSize);
if (!process.StackReserve)
{
@@ -356,6 +360,8 @@ namespace Kernel
return kErrorProcessFault;
}
+ rt_set_memory(process.StackReserve, 0, process.StackSize);
+
#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
flags = HAL::kMMFlagsPresent;
flags |= HAL::kMMFlagsWr;