diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-04-17 23:55:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-17 23:55:24 +0200 |
| commit | 8ccccad87b171890cbf5040e63b613307cdc5a30 (patch) | |
| tree | 4dfb464d36a409ab4686ff4e2cfbf0ed8310f6a8 /dev | |
| parent | 496f814adf3b9cbcaab2e73188a6730d0a780912 (diff) | |
| parent | 2363e0ef10e1c34b4a6224199304cc6fda4526bb (diff) | |
Merge pull request #21 from amlel-el-mahrouss/dev
kernel, boot: recovering lost changes because of some git issue.
Diffstat (limited to 'dev')
| -rw-r--r-- | dev/boot/modules/SysChk/amd64-pio.json | 1 | ||||
| -rw-r--r-- | dev/boot/src/HEL/AMD64/BootEFI.cc | 3 | ||||
| -rw-r--r-- | dev/kernel/FSKit/Ext2.h | 129 | ||||
| -rw-r--r-- | dev/kernel/FSKit/HeFS.h | 29 | ||||
| -rw-r--r-- | dev/kernel/FSKit/NeFS.h | 3 | ||||
| -rw-r--r-- | dev/kernel/FirmwareKit/GPT.h | 7 | ||||
| -rw-r--r-- | dev/kernel/FirmwareKit/Handover.h | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 28 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Processor.h | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/Processor.h | 2 | ||||
| -rw-r--r-- | dev/kernel/KernelKit/KernelProcessScheduler.h | 7 | ||||
| -rw-r--r-- | dev/kernel/KernelKit/ProcessScheduler.h | 381 | ||||
| -rw-r--r-- | dev/kernel/KernelKit/UserProcessScheduler.h | 383 | ||||
| -rw-r--r-- | dev/kernel/src/BitMapMgr.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/src/UserProcessScheduler.cc | 12 |
17 files changed, 572 insertions, 423 deletions
diff --git a/dev/boot/modules/SysChk/amd64-pio.json b/dev/boot/modules/SysChk/amd64-pio.json index f15a8efd..3848a611 100644 --- a/dev/boot/modules/SysChk/amd64-pio.json +++ b/dev/boot/modules/SysChk/amd64-pio.json @@ -17,6 +17,7 @@ "__BOOTZ_STANDALONE__", "__NE_AMD64__", "__ATA_PIO__", + "BOOTZ_EPM_SUPPORT", "kChkVersionHighest=0x0100", "kChkVersionLowest=0x0100", "kChkVersion=0x0100" diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index fa0cb74b..2ee662f3 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -226,6 +226,9 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, handover_hdr->f_Magic = kHandoverMagic; handover_hdr->f_Version = kHandoverVersion; + handover_hdr->f_EFIImageKey = map_key; + handover_hdr->f_EFIImage = image_handle; + // Provide fimware vendor name. Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, sys_table->FirmwareVendor, 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; |
