summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-11-24 03:02:43 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-11-24 03:02:43 +0100
commit83d870e58457a1d335a1d9b9966a6a1887cc297b (patch)
tree72888f88c7728c82f3f6df1f4f70591de15eab36 /src
parentab37adbacf0f33845804c788b39680cd754752a8 (diff)
feat! breaking changes on kernel sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'src')
-rw-r--r--src/boot/BootKit/BitManip.h20
-rw-r--r--src/boot/BootKit/BootKit.h335
-rw-r--r--src/boot/BootKit/BootThread.h41
-rw-r--r--src/boot/BootKit/Device.h35
-rw-r--r--src/boot/BootKit/EPM.h9
-rw-r--r--src/boot/BootKit/HW/ATA.h47
-rw-r--r--src/boot/BootKit/HW/SATA.h42
-rw-r--r--src/boot/BootKit/Platform.h32
-rw-r--r--src/boot/BootKit/Protocol.h10
-rw-r--r--src/boot/BootKit/Qr.h797
-rw-r--r--src/boot/BootKit/QrPrelude.h1
-rw-r--r--src/boot/BootKit/Shared/base.h24
-rw-r--r--src/boot/BootKit/Shared/bit.h228
-rw-r--r--src/boot/BootKit/Support.h145
-rw-r--r--src/boot/amd64-ci.make148
-rw-r--r--src/boot/amd64-desktop.make159
-rw-r--r--src/boot/arm64-desktop.make112
-rw-r--r--src/boot/download-ovmf.ps14
-rw-r--r--src/boot/gdbinit3
-rw-r--r--src/boot/modules/.keep0
-rw-r--r--src/boot/modules/BootNet/.hgkeep0
-rw-r--r--src/boot/modules/BootNet/BootNet.cc121
-rw-r--r--src/boot/modules/BootNet/BootNet.h12
-rw-r--r--src/boot/modules/BootNet/BootNetStartup.S24
-rw-r--r--src/boot/modules/BootNet/amd64.json23
-rw-r--r--src/boot/modules/SysChk/.hgkeep0
-rw-r--r--src/boot/modules/SysChk/SysChk.cc41
-rw-r--r--src/boot/modules/SysChk/SysChkStartup.S24
-rw-r--r--src/boot/modules/SysChk/amd64-ahci-epm.json42
-rw-r--r--src/boot/modules/SysChk/amd64-ahci-gpt.json40
-rw-r--r--src/boot/modules/SysChk/amd64-pio-epm.json41
-rw-r--r--src/boot/modules/SysChk/amd64-pio-gpt.json41
-rw-r--r--src/boot/modules/SysChk/arm64.json26
-rw-r--r--src/boot/obj/.gitkeep0
-rw-r--r--src/boot/src/.gitkeep0
-rw-r--r--src/boot/src/BootFileReader.cc177
-rw-r--r--src/boot/src/BootString.cc81
-rw-r--r--src/boot/src/BootSupport.cc128
-rw-r--r--src/boot/src/BootTextWriter.cc157
-rw-r--r--src/boot/src/BootThread.cc216
-rw-r--r--src/boot/src/HEL/64X000/.gitkeep0
-rw-r--r--src/boot/src/HEL/64X000/BootCB.S35
-rw-r--r--src/boot/src/HEL/AMD64/BootAPI.S122
-rw-r--r--src/boot/src/HEL/AMD64/BootATA.cc269
-rw-r--r--src/boot/src/HEL/AMD64/BootEFI.cc257
-rw-r--r--src/boot/src/HEL/AMD64/BootPlatform.cc36
-rw-r--r--src/boot/src/HEL/AMD64/BootSATA.cc76
-rw-r--r--src/boot/src/HEL/ARM64/.gitkeep0
-rw-r--r--src/boot/src/HEL/ARM64/BootAPI.S12
-rw-r--r--src/boot/src/HEL/ARM64/BootEFI.cc196
-rw-r--r--src/boot/src/HEL/ARM64/BootNB.S40
-rw-r--r--src/boot/src/HEL/ARM64/BootPlatform.cc28
-rw-r--r--src/boot/src/HEL/POWER/.gitkeep0
-rw-r--r--src/boot/src/HEL/POWER/BootNB.S34
-rw-r--r--src/boot/src/New+Delete.cc74
-rw-r--r--src/boot/src/boot_rsrc.rsrc25
-rw-r--r--src/boot/src/docs/KERN_VER.md18
-rw-r--r--src/boot/src/docs/MKFS_HEFS.md106
-rw-r--r--src/boot/src/root/ifs.json10
-rw-r--r--src/hint/CompilerHint.h25
-rw-r--r--src/kernel/ArchKit/ArchKit.h108
-rw-r--r--src/kernel/CFKit/GUIDWizard.h21
-rw-r--r--src/kernel/CFKit/GUIDWrapper.h48
-rw-r--r--src/kernel/CFKit/Property.h51
-rw-r--r--src/kernel/CFKit/Utils.h48
-rw-r--r--src/kernel/CompilerKit/CompilerKit.h13
-rw-r--r--src/kernel/CompilerKit/Detail.h27
-rw-r--r--src/kernel/CompilerKit/Version.h9
-rw-r--r--src/kernel/DmaKit/DmaPool.h101
-rw-r--r--src/kernel/FSKit/Defines.h12
-rw-r--r--src/kernel/FSKit/Ext2+IFS.h273
-rw-r--r--src/kernel/FSKit/Ext2.h148
-rw-r--r--src/kernel/FSKit/IndexableProperty.h58
-rw-r--r--src/kernel/FSKit/NeFS.h413
-rw-r--r--src/kernel/FSKit/OpenHeFS.h434
-rw-r--r--src/kernel/FirmwareKit/.gitkeep1
-rw-r--r--src/kernel/FirmwareKit/EFI.h12
-rw-r--r--src/kernel/FirmwareKit/EFI/API.h88
-rw-r--r--src/kernel/FirmwareKit/EFI/EFI.h916
-rw-r--r--src/kernel/FirmwareKit/EFI/NS.h18
-rw-r--r--src/kernel/FirmwareKit/EPM.h112
-rw-r--r--src/kernel/FirmwareKit/GPT.h48
-rw-r--r--src/kernel/FirmwareKit/Handover.h108
-rw-r--r--src/kernel/FirmwareKit/NeBoot/BootNet.h41
-rw-r--r--src/kernel/FirmwareKit/NeBoot/NS.h10
-rw-r--r--src/kernel/FirmwareKit/NeBoot/NeBoot.h34
-rw-r--r--src/kernel/FirmwareKit/VEPM.h47
-rw-r--r--src/kernel/GfxKit/FB.h52
-rw-r--r--src/kernel/HALKit/.gitkeep0
-rw-r--r--src/kernel/HALKit/AMD64/CPUID.h89
-rw-r--r--src/kernel/HALKit/AMD64/CxxAbi.cc79
-rw-r--r--src/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc113
-rw-r--r--src/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc39
-rw-r--r--src/kernel/HALKit/AMD64/HalApplicationProcessor.cc221
-rw-r--r--src/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s23
-rw-r--r--src/kernel/HALKit/AMD64/HalCommonAPI.asm137
-rw-r--r--src/kernel/HALKit/AMD64/HalControlRegisterAPI.s45
-rw-r--r--src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc168
-rw-r--r--src/kernel/HALKit/AMD64/HalCoreSystemCalls.cc9
-rw-r--r--src/kernel/HALKit/AMD64/HalDebugOutput.cc227
-rw-r--r--src/kernel/HALKit/AMD64/HalDebugProtocol.cc16
-rw-r--r--src/kernel/HALKit/AMD64/HalDescriptorLoader.cc71
-rw-r--r--src/kernel/HALKit/AMD64/HalHandoverStub.asm30
-rw-r--r--src/kernel/HALKit/AMD64/HalInterruptAPI.asm370
-rw-r--r--src/kernel/HALKit/AMD64/HalKernelMain.cc160
-rw-r--r--src/kernel/HALKit/AMD64/HalKernelPanic.cc58
-rw-r--r--src/kernel/HALKit/AMD64/HalPagingMgr.cc167
-rw-r--r--src/kernel/HALKit/AMD64/HalProcessor.cc89
-rw-r--r--src/kernel/HALKit/AMD64/HalRoutineWait.s11
-rw-r--r--src/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.cc51
-rw-r--r--src/kernel/HALKit/AMD64/HalTimer.cc101
-rw-r--r--src/kernel/HALKit/AMD64/HalUtilsAPI.asm24
-rw-r--r--src/kernel/HALKit/AMD64/Hypervisor.h24
-rw-r--r--src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc129
-rw-r--r--src/kernel/HALKit/AMD64/PCI/DMA.cc72
-rw-r--r--src/kernel/HALKit/AMD64/PCI/Database.cc9
-rw-r--r--src/kernel/HALKit/AMD64/PCI/Device.cc142
-rw-r--r--src/kernel/HALKit/AMD64/PCI/Express.cc9
-rw-r--r--src/kernel/HALKit/AMD64/PCI/IO.cc7
-rw-r--r--src/kernel/HALKit/AMD64/PCI/Iterator.cc30
-rw-r--r--src/kernel/HALKit/AMD64/PCI/PCI.cc7
-rw-r--r--src/kernel/HALKit/AMD64/Paging.h91
-rw-r--r--src/kernel/HALKit/AMD64/Processor.h283
-rw-r--r--src/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc600
-rw-r--r--src/kernel/HALKit/AMD64/Storage/DMA+Generic.cc199
-rw-r--r--src/kernel/HALKit/AMD64/Storage/NVME+Generic.cc9
-rw-r--r--src/kernel/HALKit/AMD64/Storage/PIO+Generic.cc278
-rw-r--r--src/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc13
-rw-r--r--src/kernel/HALKit/ARM64/APM/APM+IO.cc35
-rw-r--r--src/kernel/HALKit/ARM64/ApplicationProcessor.h19
-rw-r--r--src/kernel/HALKit/ARM64/CxxAbi.cc87
-rw-r--r--src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc26
-rw-r--r--src/kernel/HALKit/ARM64/HalApplicationProcessor.cc140
-rw-r--r--src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s12
-rw-r--r--src/kernel/HALKit/ARM64/HalCommonAPI.s9
-rw-r--r--src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc159
-rw-r--r--src/kernel/HALKit/ARM64/HalDebugOutput.cc71
-rw-r--r--src/kernel/HALKit/ARM64/HalHandoverStub.s19
-rw-r--r--src/kernel/HALKit/ARM64/HalInterruptAPI.s3
-rw-r--r--src/kernel/HALKit/ARM64/HalKernelMain.cc63
-rw-r--r--src/kernel/HALKit/ARM64/HalKernelPanic.cc54
-rw-r--r--src/kernel/HALKit/ARM64/HalPagingMgr.cc86
-rw-r--r--src/kernel/HALKit/ARM64/HalSchedulerCore.cc21
-rw-r--r--src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc30
-rw-r--r--src/kernel/HALKit/ARM64/HalTimer.cc15
-rw-r--r--src/kernel/HALKit/ARM64/Paging.h107
-rw-r--r--src/kernel/HALKit/ARM64/Processor.h78
-rw-r--r--src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc13
-rw-r--r--src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc8
-rw-r--r--src/kernel/HALKit/POWER/.gitkeep0
-rw-r--r--src/kernel/HALKit/POWER/AP.h39
-rw-r--r--src/kernel/HALKit/POWER/APM/.gitkeep0
-rw-r--r--src/kernel/HALKit/POWER/HalApplicationProcessor.cc43
-rw-r--r--src/kernel/HALKit/POWER/HalDebugOutput.cc24
-rw-r--r--src/kernel/HALKit/POWER/HalHardwareThread.cc8
-rw-r--r--src/kernel/HALKit/POWER/HalStartSequence.s14
-rw-r--r--src/kernel/HALKit/POWER/HalVirtualMemory.cc46
-rw-r--r--src/kernel/HALKit/POWER/Processor.h60
-rw-r--r--src/kernel/HALKit/RISCV/.keep0
-rw-r--r--src/kernel/HALKit/RISCV/AP.h35
-rw-r--r--src/kernel/HALKit/RISCV/APM/.gitkeep0
-rw-r--r--src/kernel/HALKit/RISCV/HalApplicationProcessor.cc40
-rw-r--r--src/kernel/HALKit/RISCV/Storage/.gitkeep0
-rw-r--r--src/kernel/HALKit/X86S/.gitkeep0
-rw-r--r--src/kernel/HALKit/X86S/ACPI/.gitkeep0
-rw-r--r--src/kernel/HALKit/X86S/Storage/.gitkeep0
-rw-r--r--src/kernel/KernelKit/BinaryMutex.h39
-rw-r--r--src/kernel/KernelKit/CodeMgr.h49
-rw-r--r--src/kernel/KernelKit/CoreProcessScheduler.h273
-rw-r--r--src/kernel/KernelKit/DebugOutput.h207
-rw-r--r--src/kernel/KernelKit/Defines.h19
-rw-r--r--src/kernel/KernelKit/DeviceMgr.h129
-rw-r--r--src/kernel/KernelKit/DriveMgr.h175
-rw-r--r--src/kernel/KernelKit/FileMgr.h445
-rw-r--r--src/kernel/KernelKit/HardwareThreadScheduler.h135
-rw-r--r--src/kernel/KernelKit/HeapMgr.h58
-rw-r--r--src/kernel/KernelKit/HeapMgr.inl35
-rw-r--r--src/kernel/KernelKit/IDylibObject.h45
-rw-r--r--src/kernel/KernelKit/IFS.h25
-rw-r--r--src/kernel/KernelKit/ILoader.h32
-rw-r--r--src/kernel/KernelKit/IPEFDylibObject.h86
-rw-r--r--src/kernel/KernelKit/KPC.h78
-rw-r--r--src/kernel/KernelKit/KernelTaskScheduler.h47
-rw-r--r--src/kernel/KernelKit/LockDelegate.h58
-rw-r--r--src/kernel/KernelKit/MSDOS.h51
-rw-r--r--src/kernel/KernelKit/PCI/DMA.h75
-rw-r--r--src/kernel/KernelKit/PCI/DMA.inl17
-rw-r--r--src/kernel/KernelKit/PCI/Database.h51
-rw-r--r--src/kernel/KernelKit/PCI/Device.h73
-rw-r--r--src/kernel/KernelKit/PCI/Express.h12
-rw-r--r--src/kernel/KernelKit/PCI/IO.h63
-rw-r--r--src/kernel/KernelKit/PCI/IOArray+AMD64.inl49
-rw-r--r--src/kernel/KernelKit/PCI/Iterator.h41
-rw-r--r--src/kernel/KernelKit/PCI/PCI.h54
-rw-r--r--src/kernel/KernelKit/PE.h130
-rw-r--r--src/kernel/KernelKit/PE32CodeMgr.h91
-rw-r--r--src/kernel/KernelKit/PEF.h117
-rw-r--r--src/kernel/KernelKit/PEFCodeMgr.h75
-rw-r--r--src/kernel/KernelKit/ProcessScheduler.h18
-rw-r--r--src/kernel/KernelKit/Semaphore.h110
-rw-r--r--src/kernel/KernelKit/ThreadLocalStorage.h68
-rw-r--r--src/kernel/KernelKit/ThreadLocalStorage.inl89
-rw-r--r--src/kernel/KernelKit/Timer.h75
-rw-r--r--src/kernel/KernelKit/TraceSrv.h22
-rw-r--r--src/kernel/KernelKit/UserMgr.h95
-rw-r--r--src/kernel/KernelKit/UserProcessScheduler.h243
-rw-r--r--src/kernel/KernelKit/UserProcessScheduler.inl64
-rw-r--r--src/kernel/KernelKit/XCOFF.h51
-rw-r--r--src/kernel/KernelKit/ZXD.h53
-rw-r--r--src/kernel/NeKit/Array.h46
-rw-r--r--src/kernel/NeKit/ArrayList.h44
-rw-r--r--src/kernel/NeKit/Atom.h33
-rw-r--r--src/kernel/NeKit/Crc32.h20
-rw-r--r--src/kernel/NeKit/CxxAbi.h26
-rw-r--r--src/kernel/NeKit/Defines.h179
-rw-r--r--src/kernel/NeKit/ErrorOr.h62
-rw-r--r--src/kernel/NeKit/Function.h51
-rw-r--r--src/kernel/NeKit/Json.h146
-rw-r--r--src/kernel/NeKit/KString.h92
-rw-r--r--src/kernel/NeKit/KString.inl174
-rw-r--r--src/kernel/NeKit/KernelPanic.h69
-rw-r--r--src/kernel/NeKit/Macros.h151
-rw-r--r--src/kernel/NeKit/MutableArray.h203
-rw-r--r--src/kernel/NeKit/NeKit.h20
-rw-r--r--src/kernel/NeKit/New.h20
-rw-r--r--src/kernel/NeKit/OwnPtr.h67
-rw-r--r--src/kernel/NeKit/PageMgr.h76
-rw-r--r--src/kernel/NeKit/Pair.h51
-rw-r--r--src/kernel/NeKit/Pmm.h39
-rw-r--r--src/kernel/NeKit/Ref.h77
-rw-r--r--src/kernel/NeKit/Stream.h45
-rw-r--r--src/kernel/NeKit/TOML.h15
-rw-r--r--src/kernel/NeKit/Utils.h62
-rw-r--r--src/kernel/NeKit/Variant.h71
-rw-r--r--src/kernel/NetworkKit/IP.h76
-rw-r--r--src/kernel/NetworkKit/IPC.h90
-rw-r--r--src/kernel/NetworkKit/LTE.h16
-rw-r--r--src/kernel/NetworkKit/MAC.h34
-rw-r--r--src/kernel/NetworkKit/NetworkDevice.h83
-rw-r--r--src/kernel/NetworkKit/NetworkDevice.inl32
-rw-r--r--src/kernel/SignalKit/Signals.h51
-rw-r--r--src/kernel/StorageKit/AHCI.h49
-rw-r--r--src/kernel/StorageKit/ATA.h56
-rw-r--r--src/kernel/StorageKit/NVME.h32
-rw-r--r--src/kernel/StorageKit/PRDT.h33
-rw-r--r--src/kernel/StorageKit/SCSI.h11
-rw-r--r--src/kernel/StorageKit/StorageKit.h21
-rw-r--r--src/kernel/SwapKit/DiskSwap.h72
-rw-r--r--src/kernel/amd64-ci.make77
-rw-r--r--src/kernel/amd64-desktop.make79
-rw-r--r--src/kernel/arm64-desktop.make64
-rw-r--r--src/kernel/kernel_rsrc.rsrc25
-rwxr-xr-xsrc/kernel/move-all-aarch64.sh7
-rwxr-xr-xsrc/kernel/move-all-x64.sh7
-rw-r--r--src/kernel/obj/.gitkeep0
-rw-r--r--src/kernel/power64-cb.make4
-rw-r--r--src/kernel/riscv64-cb.make0
-rw-r--r--src/kernel/src/ACPIFactoryInterface.cc88
-rw-r--r--src/kernel/src/Array.cc7
-rw-r--r--src/kernel/src/ArrayList.cc7
-rw-r--r--src/kernel/src/AsciiUtils.cc161
-rw-r--r--src/kernel/src/Atom.cc10
-rw-r--r--src/kernel/src/BinaryMutex.cc70
-rw-r--r--src/kernel/src/BitMapMgr.cc206
-rw-r--r--src/kernel/src/CRuntimeOverrides.cc27
-rw-r--r--src/kernel/src/CodeMgr.cc35
-rw-r--r--src/kernel/src/Crc32.cc65
-rw-r--r--src/kernel/src/Defines.cc7
-rw-r--r--src/kernel/src/DeviceMgr.cc9
-rw-r--r--src/kernel/src/DriveMgr.cc254
-rw-r--r--src/kernel/src/ErrorOr.cc12
-rw-r--r--src/kernel/src/FS/Ext2+IFS.cc1555
-rw-r--r--src/kernel/src/FS/NeFS+FileMgr.cc276
-rw-r--r--src/kernel/src/FS/NeFS+FileSystemParser.cc870
-rw-r--r--src/kernel/src/FS/OpenHeFS+FileMgr.cc191
-rw-r--r--src/kernel/src/FS/OpenHeFS+FileSystemParser.cc1160
-rw-r--r--src/kernel/src/FileMgr.cc49
-rw-r--r--src/kernel/src/GUIDWizard.cc67
-rw-r--r--src/kernel/src/GUIDWrapper.cc9
-rw-r--r--src/kernel/src/Gfx/FBDeviceInterface.cc50
-rw-r--r--src/kernel/src/HardwareThreadScheduler.cc184
-rw-r--r--src/kernel/src/HeapMgr.cc260
-rw-r--r--src/kernel/src/IDylibObject.cc13
-rw-r--r--src/kernel/src/IFS.cc89
-rw-r--r--src/kernel/src/IPEFDylibObject.cc109
-rw-r--r--src/kernel/src/IndexableProperty.cc45
-rw-r--r--src/kernel/src/Json.cc9
-rw-r--r--src/kernel/src/KPC.cc39
-rw-r--r--src/kernel/src/KernelTaskScheduler.cc37
-rw-r--r--src/kernel/src/LockDelegate.cc11
-rw-r--r--src/kernel/src/MutableArray.cc7
-rw-r--r--src/kernel/src/Network/IPAddress.cc113
-rw-r--r--src/kernel/src/Network/IPCAddress.cc27
-rw-r--r--src/kernel/src/Network/IPCMessage.cc129
-rw-r--r--src/kernel/src/Network/MACAddressGetter.cc13
-rw-r--r--src/kernel/src/Network/NetworkDevice.cc29
-rw-r--r--src/kernel/src/New+Delete.cc48
-rw-r--r--src/kernel/src/OwnPtr.cc7
-rw-r--r--src/kernel/src/PE32CodeMgr.cc258
-rw-r--r--src/kernel/src/PEFCodeMgr.cc335
-rw-r--r--src/kernel/src/PRDT.cc22
-rw-r--r--src/kernel/src/PageMgr.cc95
-rw-r--r--src/kernel/src/Pmm.cc83
-rw-r--r--src/kernel/src/Property.cc41
-rw-r--r--src/kernel/src/Ref.cc7
-rw-r--r--src/kernel/src/Semaphore.cc7
-rw-r--r--src/kernel/src/SoftwareTimer.cc36
-rw-r--r--src/kernel/src/Storage/AHCIDeviceInterface.cc87
-rw-r--r--src/kernel/src/Storage/ATADeviceInterface.cc96
-rw-r--r--src/kernel/src/Storage/NVMEDeviceInterface.cc22
-rw-r--r--src/kernel/src/Storage/SCSIDeviceInterface.cc9
-rw-r--r--src/kernel/src/Stream.cc12
-rw-r--r--src/kernel/src/Swap/DiskSwap.cc64
-rw-r--r--src/kernel/src/ThreadLocalStorage.cc52
-rw-r--r--src/kernel/src/Timer.cc19
-rw-r--r--src/kernel/src/UserMgr.cc131
-rw-r--r--src/kernel/src/UserProcessScheduler.cc690
-rw-r--r--src/kernel/src/UserProcessTeam.cc57
-rw-r--r--src/kernel/src/UtfUtils.cc62
-rw-r--r--src/kernel/src/Variant.cc38
-rw-r--r--src/kernel/src/ZXD.cc7
-rw-r--r--src/launch/.keep0
-rw-r--r--src/launch/LaunchKit/Foundation.h21
-rw-r--r--src/launch/launch.json20
-rw-r--r--src/launch/obj/.keep0
-rw-r--r--src/launch/src/.keep0
-rw-r--r--src/launch/src/AppMain.cc28
-rw-r--r--src/launch/src/CRuntimeZero.S23
-rw-r--r--src/libDDK/DriverKit/ddk.h76
-rw-r--r--src/libDDK/DriverKit/dev.h36
-rw-r--r--src/libDDK/DriverKit/dki/contract.h34
-rw-r--r--src/libDDK/DriverKit/io.h18
-rw-r--r--src/libDDK/DriverKit/macros.h48
-rw-r--r--src/libDDK/DriverKit/net.h16
-rw-r--r--src/libDDK/DriverKit/str.h17
-rw-r--r--src/libDDK/docs/SPECIFICATION_DDK.md18
-rw-r--r--src/libDDK/libDDK.json23
-rw-r--r--src/libDDK/obj/.gitkeep0
-rw-r--r--src/libDDK/src/ddk_abi_cxx.cc27
-rw-r--r--src/libDDK/src/ddk_alloc.c32
-rw-r--r--src/libDDK/src/ddk_dev.c27
-rw-r--r--src/libDDK/src/ddk_io.c36
-rw-r--r--src/libDDK/src/ddk_kernel_call.c77
-rw-r--r--src/libDDK/src/ddk_kernel_call_dispatch.S47
-rw-r--r--src/libDDK/src/ddk_str.c36
-rw-r--r--src/libDDK/src/ddk_ver.c25
-rw-r--r--src/libMsg/.keep0
-rw-r--r--src/libMsg/MsgKit/Network.h9
-rw-r--r--src/libMsg/MsgKit/Server.h41
-rw-r--r--src/libMsg/obj/.keep0
-rw-r--r--src/libMsg/script/window_client.json7
-rw-r--r--src/libMsg/src/.keep0
-rw-r--r--src/libSystem/SystemKit/Err.h58
-rw-r--r--src/libSystem/SystemKit/Jail.h36
-rw-r--r--src/libSystem/SystemKit/Macros.h126
-rw-r--r--src/libSystem/SystemKit/Syscall.h21
-rw-r--r--src/libSystem/SystemKit/System.h389
-rw-r--r--src/libSystem/SystemKit/Verify.h40
-rw-r--r--src/libSystem/docs/SPECIFICATION_SYSCALLS.md25
-rw-r--r--src/libSystem/libSystem.json20
-rw-r--r--src/libSystem/obj/.keep0
-rw-r--r--src/libSystem/src/JailCalls.cc17
-rw-r--r--src/libSystem/src/Makefile16
-rw-r--r--src/libSystem/src/SystemCalls.cc169
-rw-r--r--src/libSystem/src/SystemCallsABI+AMD64.asm81
-rw-r--r--src/libSystem/src/Utils.cc29
-rw-r--r--src/libSystem/src/VerifyCalls.cc18
-rw-r--r--src/misc/.keep0
-rw-r--r--src/misc/BenchKit/Chronometer.h40
-rw-r--r--src/misc/BenchKit/HWChronometer.h66
-rw-r--r--src/modules/ACPI/ACPI.h83
-rw-r--r--src/modules/ACPI/ACPIFactoryInterface.h57
-rw-r--r--src/modules/AHCI/AHCI.h360
-rw-r--r--src/modules/APM/APM.h29
-rw-r--r--src/modules/ATA/ATA.h157
-rw-r--r--src/modules/CoreGfx/CoreAccess.h33
-rw-r--r--src/modules/CoreGfx/CoreGfx.h118
-rw-r--r--src/modules/CoreGfx/MathGfx.h27
-rw-r--r--src/modules/CoreGfx/TextGfx.h183
-rw-r--r--src/modules/GPRS/.keep0
-rw-r--r--src/modules/HPET/Defines.h39
-rw-r--r--src/modules/IEEE802/.gitkeep0
-rw-r--r--src/modules/LTE/LTE.h34
-rw-r--r--src/modules/MBCI/MBCI.h126
-rw-r--r--src/modules/NVME/NVME.h104
-rw-r--r--src/modules/OHCI/.gitkeep0
-rw-r--r--src/modules/Power/PowerFactory.h30
-rw-r--r--src/modules/SCSI/.gitkeep0
-rw-r--r--src/modules/SCSI/SCSI.h21
-rw-r--r--src/modules/WiFi/.gitkeep0
-rw-r--r--src/modules/XHCI/XHCI.h66
391 files changed, 31988 insertions, 0 deletions
diff --git a/src/boot/BootKit/BitManip.h b/src/boot/BootKit/BitManip.h
new file mode 100644
index 00000000..32795328
--- /dev/null
+++ b/src/boot/BootKit/BitManip.h
@@ -0,0 +1,20 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __BITMANIP_H__
+#define __BITMANIP_H__
+
+/// File: BitManip.h
+/// Purpose: Bit manipulation helpers, based on neboot-dev.
+
+#define bk_set_bit(X, O) X = (1 << O) | X
+#define bk_clear_bit(X, O) X = ~(1 << O) & X
+#define bk_toogle(X, O) X = (1 << O) ^ X
+#define bk_lsb(X) X = X & -X
+#define bk_msb(X) X = -(mp_lsb(X)) & X
+#define bk_look_for_bit(X, O) (1 << O) | X
+
+#endif // ifndef __BITMANIP_H__
diff --git a/src/boot/BootKit/BootKit.h b/src/boot/BootKit/BootKit.h
new file mode 100644
index 00000000..e1a2b628
--- /dev/null
+++ b/src/boot/BootKit/BootKit.h
@@ -0,0 +1,335 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/***********************************************************************************/
+/// @file BootKit.h
+/// @brief Bootloader Application Programming Interface.
+/***********************************************************************************/
+
+#pragma once
+
+#include <BootKit/HW/ATA.h>
+#include <CompilerKit/Version.h>
+#include <modules/CoreGfx/CoreGfx.h>
+
+/// include NeFS header and Support header as well.
+
+#include <BootKit/Support.h>
+#include <FSKit/NeFS.h>
+
+/***********************************************************************************/
+/// Include other APIs.
+/***********************************************************************************/
+
+#include <NeKit/Defines.h>
+#include <modules/ATA/ATA.h>
+
+#include <FirmwareKit/EFI.h>
+#include <FirmwareKit/EPM.h>
+#include <FirmwareKit/GPT.h>
+#include <FirmwareKit/VEPM.h>
+
+#define kBKBootFileMime "boot-x/file"
+#define kBKBootDirMime "boot-x/dir"
+
+/***********************************************************************************/
+/// Framebuffer helpers.
+/***********************************************************************************/
+
+namespace Boot {
+void ThrowError(const WideChar* errorCode, const WideChar* reason) noexcept;
+
+class BootTextWriter;
+class BootFileReader;
+class BootThread;
+class BVersionString;
+
+typedef Char* PEFImagePtr;
+typedef Char* PEImagePtr;
+
+typedef WideChar CharacterTypeUTF16;
+typedef Char CharacterTypeASCII;
+typedef char8_t CharacterTypeUTF8;
+
+using namespace Kernel;
+
+/**
+ * @brief BootKit Text Writer class
+ * Writes to UEFI StdOut.
+ */
+class BootTextWriter final {
+ BootTextWriter& _Write(const UInt64& num);
+
+ public:
+ BootTextWriter& Write(const UInt64& num);
+ BootTextWriter& Write(const Char* str);
+ BootTextWriter& Write(const CharacterTypeUTF16* str);
+ BootTextWriter& WriteCharacter(CharacterTypeUTF16 c);
+ BootTextWriter& Write(const UChar* str);
+
+ template <typename T>
+ BootTextWriter& operator<<(T elem) {
+ this->Write(elem);
+ return *this;
+ }
+
+ public:
+ explicit BootTextWriter() = default;
+ ~BootTextWriter() = default;
+
+ public:
+ BootTextWriter& operator=(const BootTextWriter&) = default;
+ BootTextWriter(const BootTextWriter&) = default;
+};
+
+Kernel::SizeT BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len);
+
+Kernel::SizeT BSetMem(CharacterTypeASCII* src, const CharacterTypeASCII byte,
+ const Kernel::SizeT len);
+
+/// String length functions.
+
+/// @brief get string length.
+Kernel::SizeT BStrLen(const CharacterTypeUTF16* ptr);
+
+/// @brief set memory with custom value.
+Kernel::SizeT BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte,
+ const Kernel::SizeT len);
+
+/**
+ * @brief BootKit File Reader class
+ * Reads the Firmware Boot partition and filesystem.
+ */
+class BootFileReader final {
+ public:
+ explicit BootFileReader(const CharacterTypeUTF16* path, EfiHandlePtr ImageHandle);
+ ~BootFileReader();
+
+ public:
+ Void ReadAll(SizeT until, SizeT chunk = kib_cast(4), UIntPtr out_address = 0UL);
+
+ enum {
+ kOperationOkay,
+ kNotSupported,
+ kEmptyDirectory,
+ kNoSuchEntry,
+ kIsDirectory,
+ kTooSmall,
+ kCount,
+ };
+
+ /// @brief error code getter.
+ /// @return the error code.
+ Int32& Error();
+
+ /// @brief blob getter.
+ /// @return the blob.
+ VoidPtr Blob();
+
+ /// @breif Size getter.
+ /// @return the size of the file.
+ UInt64& Size();
+
+ public:
+ BootFileReader& operator=(const BootFileReader&) = default;
+ BootFileReader(const BootFileReader&) = default;
+
+ private:
+ Int32 mErrorCode{kOperationOkay};
+ VoidPtr mBlob{nullptr};
+ CharacterTypeUTF16 mPath[kPathLen];
+ BootTextWriter mWriter;
+ EfiFileProtocol* mFile{nullptr};
+ UInt64 mSizeFile{0};
+ EfiFileProtocol* mRootFs;
+};
+
+typedef UInt8* BlobType;
+
+/// @brief Bootloader Version String.
+class BVersionString final {
+ public:
+ static const CharacterTypeASCII* The() { return BOOTLOADER_VERSION; }
+};
+
+/***********************************************************************************/
+/// Provide some useful processor features.
+/***********************************************************************************/
+
+#ifdef __EFI_x86_64__
+
+/***
+ * Common processor instructions.
+ */
+
+EXTERN_C void rt_out8(UInt16 port, UInt8 value);
+EXTERN_C void rt_out16(UInt16 port, UInt16 value);
+EXTERN_C void rt_out32(UInt16 port, UInt32 value);
+EXTERN_C UInt8 rt_in8(UInt16 port);
+EXTERN_C UInt16 rt_in16(UInt16 port);
+EXTERN_C UInt32 rt_in32(UInt16 port);
+
+EXTERN_C void rt_halt();
+EXTERN_C void rt_cli();
+EXTERN_C void rt_sti();
+EXTERN_C void rt_cld();
+EXTERN_C void rt_std();
+
+#endif // __EFI_x86_64__
+
+/// @brief BootKit Drive Formatter.
+template <typename BootDev>
+class BDiskFormatFactory final {
+ public:
+ /// @brief File entry for **BDiskFormatFactory**.
+ struct BFileDescriptor final {
+ Char fFileName[kNeFSCatalogNameLen];
+ Int32 fKind;
+ };
+
+ public:
+ explicit BDiskFormatFactory() = default;
+ ~BDiskFormatFactory() = default;
+
+ NE_COPY_DELETE(BDiskFormatFactory)
+
+ /// @brief Format disk using partition name and blob.
+ /// @param Partition part_name the target partition name.
+ /// @param blob blobs array.
+ /// @param blob_sz blobs array count.
+ /// @retval True disk has been formatted.
+ /// @retval False failed to format.
+ Boolean Format(const Char* part_name);
+
+ /// @brief check if partition is good.
+ Bool IsPartitionValid() noexcept {
+#if defined(BOOTZ_EPM_SUPPORT)
+ fDiskDev.Leak().mBase = (kEPMBootBlockLba);
+ fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK);
+
+ EPM_PART_BLOCK buf_epm = {};
+
+ fDiskDev.Read((Char*) &buf_epm, sizeof(EPM_PART_BLOCK));
+
+ if (StrCmp(buf_epm.Magic, kEPMMagic) > 0) {
+ return false;
+ }
+
+ if (buf_epm.Version != kEPMRevisionBcd) {
+ return false;
+ }
+
+ BootTextWriter writer;
+ writer.Write("BootZ: EPM Partition found.\r");
+
+ return true;
+#else
+ GPT_PARTITION_TABLE* gpt_part = (GPT_PARTITION_TABLE*) RTL_ALLOCA(sizeof(GPT_PARTITION_TABLE));
+
+ fDiskDev.Leak().mBase = (kGPTPartitionTableLBA);
+ fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_TABLE);
+
+ fDiskDev.Read((Char*) gpt_part, sizeof(GPT_PARTITION_TABLE));
+
+ BootTextWriter writer;
+
+ if (StrCmp(gpt_part->Signature, kMagicGPT) == 0) {
+ writer.Write("BootZ: GPT Partition found.\r");
+ return true;
+ }
+
+ writer.Write("BootZ: No Partition found.\r");
+
+ return false;
+#endif
+ }
+
+ private:
+ BootDev fDiskDev;
+};
+
+/// @brief Format disk with a specific partition scheme.
+/// @param part_name partition Name
+/// @retval True disk has been formatted.
+/// @retval False failed to format.
+template <typename BootDev>
+inline Boolean BDiskFormatFactory<BootDev>::Format(const Char* part_name) {
+#if defined(BOOTZ_EPM_SUPPORT)
+ EPM_PART_BLOCK* epm_boot = (EPM_PART_BLOCK*) RTL_ALLOCA(sizeof(EPM_PART_BLOCK));
+
+ const auto kFsName = "NeKernel";
+ const auto kBlockName = " NeKernelOS";
+
+ epm_boot->FsVersion = 0;
+ epm_boot->LbaStart = sizeof(EPM_PART_BLOCK);
+ epm_boot->LbaEnd = fDiskDev.GetDiskSize() - 1;
+ epm_boot->SectorSz = BootDev::kSectorSize;
+ epm_boot->Kind = kEPMNeKernel;
+ epm_boot->NumBlocks = 1;
+
+ epm_boot->Guid = kEPMNilGuid;
+
+ CopyMem(epm_boot->Fs, reinterpret_cast<VoidPtr>(const_cast<Char*>(kFsName)), StrLen(kFsName));
+ CopyMem(epm_boot->Name, reinterpret_cast<VoidPtr>(const_cast<Char*>(kBlockName)),
+ StrLen(kBlockName));
+ CopyMem(epm_boot->Magic, reinterpret_cast<VoidPtr>(const_cast<Char*>(kEPMMagic)),
+ StrLen(kEPMMagic));
+
+ fDiskDev.Leak().mBase = kEPMBootBlockLba; // always always resies at zero block.
+ fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK);
+
+ fDiskDev.Write((Char*) epm_boot, sizeof(EPM_PART_BLOCK));
+
+ BootTextWriter writer;
+ writer.Write(L"BootZ: Drive is EPM formatted.\r");
+#elif defined(BOOTZ_GPT_SUPPORT)
+ NE_UNUSED(part_name);
+
+ GPT_PARTITION_TABLE* gpt_part = (GPT_PARTITION_TABLE*) RTL_ALLOCA(sizeof(GPT_PARTITION_TABLE));
+
+ CopyMem(gpt_part->Signature, reinterpret_cast<VoidPtr>(const_cast<Char*>(kMagicGPT)),
+ StrLen(kMagicGPT));
+
+ gpt_part->Revision = 0x00010000;
+ gpt_part->HeaderSize = sizeof(GPT_PARTITION_TABLE);
+
+ gpt_part->CRC32 = 0x00000000;
+
+ gpt_part->Reserved1 = 0x00000000;
+ gpt_part->LBAHeader = 0x00000000;
+ gpt_part->LBAAltHeader = 0x00000000;
+ gpt_part->FirstGPTEntry = 0x00000000;
+ gpt_part->LastGPTEntry = 0x00000000;
+
+ gpt_part->Guid.Data1 = 0x00000000;
+ gpt_part->Guid.Data2 = 0x0000;
+ gpt_part->Guid.Data3 = 0x0000;
+
+ SetMem(gpt_part->Guid.Data4, 0, 8);
+
+ gpt_part->Revision = 0x00010000;
+
+ gpt_part->StartingLBA = 0x00000000;
+ gpt_part->NumPartitionEntries = 0x00000000;
+ gpt_part->SizeOfEntries = 0x00000000;
+ gpt_part->CRC32PartEntry = 0x00000000;
+
+ SetMem(gpt_part->Reserved2, 0, kSectorAlignGPT_PartTbl);
+
+ fDiskDev.Leak().mBase = kGPTPartitionTableLBA; // always always resies at zero block.
+ fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_TABLE);
+
+ fDiskDev.Write((Char*) gpt_part, sizeof(GPT_PARTITION_TABLE));
+
+ BootTextWriter writer;
+ writer.Write(L"BootZ: Drive is GPT formatted.\r");
+#else
+ NE_UNUSED(part_name);
+#endif
+
+ return YES;
+}
+} // namespace Boot
diff --git a/src/boot/BootKit/BootThread.h b/src/boot/BootKit/BootThread.h
new file mode 100644
index 00000000..abe4d653
--- /dev/null
+++ b/src/boot/BootKit/BootThread.h
@@ -0,0 +1,41 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+
+namespace Boot {
+using namespace Kernel;
+
+class BootThread;
+
+/// @brief Bootloader Thread class.
+class BootThread final {
+ public:
+ explicit BootThread() = delete;
+ ~BootThread() = default;
+
+ explicit BootThread(Kernel::VoidPtr blob);
+
+ BootThread& operator=(const BootThread&) = default;
+ BootThread(const BootThread&) = default;
+
+ Int32 Start(HEL::BootInfoHeader* handover, BOOL is_own_stack);
+ void SetName(const char* name);
+ const char* GetName();
+ bool IsValid();
+
+ private:
+ Char fBlobName[256U] = {"BootThread"};
+ VoidPtr fStartAddress{nullptr};
+ VoidPtr fBlob{nullptr};
+ UInt8* fStack{nullptr};
+ HEL::BootInfoHeader* fHandover{nullptr};
+};
+} // namespace Boot
diff --git a/src/boot/BootKit/Device.h b/src/boot/BootKit/Device.h
new file mode 100644
index 00000000..36e2b3d4
--- /dev/null
+++ b/src/boot/BootKit/Device.h
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <modules/AHCI/AHCI.h>
+#include <modules/ATA/ATA.h>
+
+namespace Kernel {
+/// @brief Device type.
+class Device {
+ public:
+ explicit Device() = default;
+ virtual ~Device() = default;
+
+ NE_MOVE_DEFAULT(Device)
+
+ struct Trait {
+ SizeT mBase{0};
+ SizeT mSize{0};
+ };
+
+ virtual Trait& Leak() = 0;
+
+ virtual Device& Read(Char* Buf, SizeT SecCount) = 0;
+ virtual Device& Write(Char* Buf, SizeT SecCount) = 0;
+};
+
+typedef Device BootDevice;
+typedef Device NetworkDevice;
+typedef Device DiskDevice;
+} // namespace Kernel \ No newline at end of file
diff --git a/src/boot/BootKit/EPM.h b/src/boot/BootKit/EPM.h
new file mode 100644
index 00000000..cc82dd41
--- /dev/null
+++ b/src/boot/BootKit/EPM.h
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <FirmwareKit/EPM.h>
diff --git a/src/boot/BootKit/HW/ATA.h b/src/boot/BootKit/HW/ATA.h
new file mode 100644
index 00000000..25629869
--- /dev/null
+++ b/src/boot/BootKit/HW/ATA.h
@@ -0,0 +1,47 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <BootKit/Device.h>
+#include <modules/ATA/ATA.h>
+
+using namespace Kernel;
+
+class BootDeviceATA final : public Device {
+ public:
+ enum {
+ kPrimary = ATA_PRIMARY_IO,
+ kSecondary = ATA_SECONDARY_IO,
+ };
+
+ explicit BootDeviceATA() noexcept;
+ ~BootDeviceATA() = default;
+
+ enum { kSectorSize = kATASectorSize };
+
+ struct ATATrait final : public Device::Trait {
+ UInt16 mBus{kPrimary};
+ UInt8 mMaster{0};
+ Boolean mErr{false};
+
+ operator bool() { return !mErr; }
+ };
+
+ public:
+ operator bool();
+
+ SizeT GetSectorsCount() noexcept;
+ SizeT GetDiskSize() noexcept;
+
+ BootDeviceATA& Read(Char* Buf, SizeT SecCount) override;
+ BootDeviceATA& Write(Char* Buf, SizeT SecCount) override;
+
+ ATATrait& Leak() override;
+
+ private:
+ ATATrait mTrait;
+};
diff --git a/src/boot/BootKit/HW/SATA.h b/src/boot/BootKit/HW/SATA.h
new file mode 100644
index 00000000..07ce7611
--- /dev/null
+++ b/src/boot/BootKit/HW/SATA.h
@@ -0,0 +1,42 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <BootKit/BootKit.h>
+#include <CompilerKit/CompilerKit.h>
+#include <modules/AHCI/AHCI.h>
+
+#define kAHCISectorSz (512)
+
+class BootDeviceSATA final {
+ public:
+ explicit BootDeviceSATA() noexcept;
+ ~BootDeviceSATA() = default;
+
+ NE_COPY_DEFAULT(BootDeviceSATA)
+
+ struct SATATrait final : public Device::Trait {
+ Kernel::Boolean mErr{false};
+ Kernel::Boolean mDetected{false};
+
+ operator bool() { return !this->mErr; }
+ };
+
+ operator bool() { return this->Leak().mDetected; }
+
+ SizeT GetDiskSize() { return drv_std_get_size(); }
+
+ constexpr static auto kSectorSize = kAHCISectorSize;
+
+ BootDeviceSATA& Read(Boot::CharacterTypeASCII* Buf, const Kernel::SizeT SecCount);
+ BootDeviceSATA& Write(Boot::CharacterTypeASCII* Buf, const Kernel::SizeT SecCount);
+
+ SATATrait& Leak();
+
+ private:
+ SATATrait mTrait;
+};
diff --git a/src/boot/BootKit/Platform.h b/src/boot/BootKit/Platform.h
new file mode 100644
index 00000000..bfc738fc
--- /dev/null
+++ b/src/boot/BootKit/Platform.h
@@ -0,0 +1,32 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/**
+ @file Platform.h
+ @brief Platform specific code.
+*/
+
+#ifdef __x86_64__
+
+#ifdef __cplusplus
+#ifndef EXTERN_C
+#define EXTERN_C extern "C"
+#endif
+#else
+#ifndef EXTERN_C
+#define EXTERN_C extern
+#endif
+#endif // __cplusplus
+
+EXTERN_C void rt_halt();
+EXTERN_C void rt_cli();
+EXTERN_C void rt_sti();
+EXTERN_C void rt_cld();
+EXTERN_C void rt_std();
+
+#endif /* ifdef __x86_64__ */
diff --git a/src/boot/BootKit/Protocol.h b/src/boot/BootKit/Protocol.h
new file mode 100644
index 00000000..0a049b77
--- /dev/null
+++ b/src/boot/BootKit/Protocol.h
@@ -0,0 +1,10 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <FirmwareKit/EFI.h>
+#include <FirmwareKit/Handover.h>
diff --git a/src/boot/BootKit/Qr.h b/src/boot/BootKit/Qr.h
new file mode 100644
index 00000000..f537aa5e
--- /dev/null
+++ b/src/boot/BootKit/Qr.h
@@ -0,0 +1,797 @@
+#ifndef QR_H
+#define QR_H
+
+#include <BootKit/Shared/base.h>
+#include <BootKit/Shared/bit.h>
+
+#include <BootKit/QrPrelude.h>
+#include <BootKit/Support.h>
+#include <CompilerKit/Detail.h>
+#include <modules/CoreGfx/CoreGfx.h>
+
+/// @note the QR code is still code 128, it utilizes the same concept of having it's own character
+/// set.
+
+namespace qr {
+inline uint8_t min_poly = 0b11101, /* Minimal polynomial x^8 + x^4 + x^3 + x^2 + 1 */
+ generator = 0b10; /* Generator of Galois field */
+
+/// @brief galois finite field multiplication.
+inline uint8_t gf_mul(uint8_t a, uint8_t b) {
+ uint8_t res = 0;
+
+ for (; b; b >>= 1) {
+ if (b & 1) res ^= a;
+ if (a & 0x80)
+ a = (a << 1) ^ min_poly;
+ else
+ a <<= 1;
+ }
+
+ return res;
+}
+
+// Size of Ecc block with respect to level and version. 0 version is for
+// padding.
+constexpr int ECC_CODEWORDS_PER_BLOCK[4][41] = {
+ {0, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28,
+ 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
+ {0, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26,
+ 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28},
+ {0, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30,
+ 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
+ {0, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28,
+ 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
+};
+
+// Number of Ecc blocks with respect to level and version. 0 version is for
+// padding.
+constexpr int N_ECC_BLOCKS[4][41] = {
+ {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8,
+ 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25},
+ {0, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16,
+ 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49},
+ {0, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20,
+ 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68},
+ {0, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25,
+ 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81},
+};
+
+// Positions of central modules of alignment patterns according to version. 0
+// version is for padding.
+constexpr int ALIGN_POS[41][7] = {
+ {},
+ {0},
+ {6, 18},
+ {6, 22},
+ {6, 26},
+ {6, 30},
+ {6, 34},
+ {6, 22, 38},
+ {6, 24, 42},
+ {6, 26, 46},
+ {6, 28, 50},
+ {6, 30, 54},
+ {6, 32, 58},
+ {6, 34, 62},
+ {6, 26, 46, 66},
+ {6, 26, 48, 70},
+ {6, 26, 50, 74},
+ {6, 30, 54, 78},
+ {6, 30, 56, 82},
+ {6, 30, 58, 86},
+ {6, 34, 62, 90},
+ {6, 28, 50, 72, 94},
+ {6, 26, 50, 74, 98},
+ {6, 30, 54, 78, 102},
+ {6, 28, 54, 80, 106},
+ {6, 32, 58, 84, 110},
+ {6, 30, 58, 86, 114},
+ {6, 34, 62, 90, 118},
+ {6, 26, 50, 74, 98, 122},
+ {6, 30, 54, 78, 102, 126},
+ {6, 26, 52, 78, 104, 130},
+ {6, 30, 56, 82, 108, 134},
+ {6, 34, 60, 86, 112, 138},
+ {6, 30, 58, 86, 114, 142},
+ {6, 34, 62, 90, 118, 146},
+ {6, 30, 54, 78, 102, 126, 150},
+ {6, 24, 50, 76, 102, 128, 154},
+ {6, 28, 54, 80, 106, 132, 158},
+ {6, 32, 58, 84, 110, 136, 162},
+ {6, 26, 54, 82, 110, 138, 166},
+ {6, 30, 58, 86, 114, 142, 170},
+};
+
+// Return n-th bit of arr starting from MSB.
+constexpr uint8_t get_bit_r(uint8_t* arr, int n) {
+ return (arr[n >> 3] >> (7 - (n & 7))) & 1;
+}
+
+// Add up to 16 bits to arr. Data starts from MSB as well as each byte of an
+// array.
+constexpr void add_bits(uint16_t data, int n, uint8_t* arr, size_t& pos) {
+ while (n--) {
+ arr[pos >> 3] |= ((data >> n) & 1) << (7 - (pos & 7));
+ ++pos;
+ }
+}
+
+// Translate char to alphanumeric encoding value,
+constexpr int alphanumeric(char c) {
+ if (c >= '0' && c <= '9') return c - '0';
+
+ if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
+
+ switch (c) {
+ case ' ':
+ return 36;
+ case '$':
+ return 37;
+ case '%':
+ return 38;
+ case '*':
+ return 39;
+ case '+':
+ return 40;
+ case '-':
+ return 41;
+ case '.':
+ return 42;
+ case '/':
+ return 43;
+ case ':':
+ return 44;
+ }
+ return -1;
+}
+
+// Check if string can be encoded in alphanumeric mode.
+constexpr bool is_alphanumeric(const char* str, size_t len) {
+ for (size_t i = 0; i < len; ++i)
+ if (alphanumeric(str[i]) == -1) return false;
+ return true;
+}
+
+// Check if string can be encoded in numeric mode.
+constexpr bool is_numeric(const char* str, size_t len) {
+ for (size_t i = 0; i < len; ++i)
+ if (str[i] < '0' || str[i] > '9') return false;
+ return true;
+}
+
+// Check if string can be encoded in kanji mode.
+constexpr bool is_kanji(const char* str, size_t len) {
+ for (size_t i = 0; i < len; i += 2) {
+ uint16_t val = uint16_t(str[i]) | (uint16_t(str[i + 1]) << 8);
+ if (val < 0x8140 || val > 0xebbf || (val > 0x9ffc && val < 0xe040)) return false;
+ }
+ return true;
+}
+
+// Reed-Solomon Ecc generator polynomial for the given degree.
+constexpr void gf_gen_poly(int degree, uint8_t* poly) {
+ SetMem(poly, 0, degree);
+
+ uint8_t root = poly[degree - 1] = 1;
+
+ for (int i = 0; i < degree; ++i) {
+ for (int j = 0; j < degree - 1; ++j) poly[j] = gf_mul(poly[j], root) ^ poly[j + 1];
+ poly[degree - 1] = gf_mul(poly[degree - 1], root);
+ root = (root << 1) ^ ((root >> 7) * 0x11d);
+ }
+}
+
+// Polynomial division if Galois Field.
+constexpr void gf_poly_div(uint8_t* dividend, size_t len, uint8_t* divisor, int degree,
+ uint8_t* result) {
+ SetMem(result, 0, degree);
+
+ for (size_t i = 0; i < len; ++i) {
+ uint8_t factor = dividend[i] ^ result[0];
+ MoveMem(&result[0], &result[1], degree - 1);
+ result[degree - 1] = 0;
+ for (int j = 0; j < degree; ++j) result[j] ^= gf_mul(divisor[j], factor);
+ }
+}
+
+enum Ecc {
+ L,
+ M,
+ Q,
+ H,
+};
+
+enum Mode {
+ M_NUMERIC,
+ M_ALPHANUMERIC,
+ M_BYTE,
+ M_KANJI,
+};
+
+// Select appropriate encoding mode for string.
+constexpr Mode select_mode(const char* str, size_t len) {
+ if (is_numeric(str, len)) return M_NUMERIC;
+ if (is_alphanumeric(str, len)) return M_ALPHANUMERIC;
+ if (is_kanji(str, len)) return M_KANJI;
+ return M_BYTE;
+}
+
+// Return size of Character Control Indicator in bits for given version and
+// mode.
+constexpr int cci(int ver, Mode mode) {
+ constexpr int cnt[4][3] = {
+ {10, 12, 14},
+ {9, 11, 13},
+ {8, 16, 16},
+ {8, 10, 12},
+ };
+ if (ver < 10) return cnt[mode][0];
+ if (ver < 27) return cnt[mode][1];
+ return cnt[mode][2];
+}
+
+template <int V>
+struct Qr {
+ private:
+ friend class QrDelegate;
+ bool draw(int x, int y) noexcept;
+
+ public:
+ constexpr auto side_size() const { return SIDE; }
+
+ bool module(int x, int y);
+ bool encode(const char* str, size_t len, Ecc ecc, int mask = -1);
+
+ private:
+ bool encode_data(const char* data, size_t len, Ecc ecc, uint8_t* out);
+ void encode_ecc(uint8_t* data, Ecc ecc, uint8_t* out);
+
+ void add_data(uint8_t* data, uint8_t* patterns);
+ void add_patterns();
+ void add_version();
+ void add_format(Ecc ecc, int mask);
+ void reserve_patterns(uint8_t* out);
+
+ template <bool Black>
+ void draw_rect(int y, int x, int height, int width, uint8_t* out);
+ template <bool Black>
+ void draw_bound(int y, int x, int height, int width, uint8_t* out);
+
+ template <bool Horizontal>
+ int rule_1_3_score();
+ int penalty_score();
+ int select_mask(Ecc ecc, uint8_t* patterns);
+ void apply_mask(int mask, uint8_t* patterns);
+
+ private:
+ static_assert(V >= 1 && V <= 40, "invalid version");
+ static constexpr int SIDE = 17 + V * 4;
+ static constexpr int N_BITS = SIDE * SIDE;
+ static constexpr int N_ALIGN = V == 1 ? 0 : V / 7 + 2;
+ static constexpr int N_ALIGN_BITS = V > 1 ? (N_ALIGN* N_ALIGN - 3) * 25 : 0;
+ static constexpr int N_TIMING_BITS = (SIDE - 16) * 2 - (10 * (V > 1 ? N_ALIGN - 2 : 0));
+ static constexpr int N_VER_BITS = V > 6 ? 36 : 0;
+ static constexpr int N_DAT_BITS = N_BITS - (192 + N_ALIGN_BITS + N_TIMING_BITS + 31 + N_VER_BITS);
+ static constexpr int N_BYTES = utl::bytes_in_bits(N_BITS); // Actual number of bytes_in_bits
+ // required to store whole Qr code
+ static constexpr int N_DAT_BYTES =
+ utl::bytes_in_bits(N_DAT_BITS); // Actual number of bytes_in_bits required to store
+ // [data + ecc]
+ static constexpr int N_DAT_CAPACITY =
+ N_DAT_BITS >> 3; // Capacity of [data + ecc] without remainder bits
+ private:
+ /// @brief internal function to retrieve bit from a bitset.
+ uint8_t get_arr_bit(uint8_t* arr, unsigned bit) const { return utl::get_arr_bit(arr, bit); }
+
+ /// @brief internal function to set bit from a bitset.
+ void set_arr_bit(uint8_t* arr, unsigned bit) { utl::set_arr_bit(arr, bit); }
+
+ /// @brief internal function to clear bit from a bitset.
+ void clr_arr_bit(uint8_t* arr, unsigned bit) { utl::clr_arr_bit(arr, bit); }
+
+ uint8_t code[N_BYTES] = {};
+
+ bool status = false;
+};
+
+// Get color of a module from left-to-right and top-to-bottom. Black is true.
+template <int V>
+bool Qr<V>::module(int x, int y) {
+ return get_arr_bit(code, y * SIDE + x);
+}
+
+/// @brief draw a new QR code.
+template <int V>
+bool Qr<V>::draw(int whereX, int whereY) noexcept {
+ if (!this->status) return false; // it may be invalid.
+
+ cg_init();
+
+ for (int y = 0; y < (this->side_size()); ++y) {
+ for (int x = 0; x < (this->side_size()); ++x) {
+ FBDrawInRegion((this->module(x, y) ? RGB(00, 00, 00) : RGB(0xFF, 0xFF, 0xFF)), 1, 1,
+ x + whereX, y + whereY);
+ }
+ }
+
+ cg_clear();
+
+ return false;
+}
+
+// Create Qr code with given error correction level. If mask == -1,
+// then best mask selected automatically. NOTE: Automatic mask is the
+// most expensive operation. Takes about 95 % of all computation time.
+template <int V>
+bool Qr<V>::encode(const char* str, size_t len, Ecc ecc, int mask) {
+ uint8_t data[N_DAT_BYTES] = {};
+ uint8_t data_with_ecc[N_DAT_BYTES] = {};
+ uint8_t patterns[N_BYTES] = {};
+
+ if (!encode_data(str, len, ecc, data)) {
+ return status = false;
+ }
+
+ encode_ecc(data, ecc, data_with_ecc);
+
+ reserve_patterns(patterns);
+ CopyMem(code, patterns, N_BYTES);
+
+ add_data(data_with_ecc, patterns);
+ add_patterns();
+ add_version();
+
+ mask = mask != -1 ? mask & 7 : select_mask(ecc, patterns);
+
+ add_format(ecc, mask);
+ apply_mask(mask, patterns);
+
+ return status = true;
+}
+
+template <int V>
+bool Qr<V>::encode_data(const char* data, size_t len, Ecc ecc, uint8_t* out) {
+ Mode mode = select_mode(data, len);
+
+ size_t n_bits = (N_DAT_CAPACITY - ECC_CODEWORDS_PER_BLOCK[ecc][V] * N_ECC_BLOCKS[ecc][V]) << 3;
+ size_t pos = 0;
+
+ add_bits(1 << mode, 4, out, pos);
+ add_bits(len, cci(V, mode), out, pos);
+
+ if (mode == M_NUMERIC) {
+ const size_t triplets = len / 3;
+ const size_t triplets_size = triplets * 3;
+ const size_t rem = len % 3;
+ const size_t rem_bits = rem == 2 ? 7 : rem == 1 ? 4 : 0;
+ const size_t total_size = 10 * triplets + rem_bits;
+
+ if (pos + total_size > n_bits) return false;
+
+ char buf[4] = {};
+
+ for (size_t i = 0; i < triplets_size; i += 3) {
+ buf[0] = data[i];
+ buf[1] = data[i + 1];
+ buf[2] = data[i + 2];
+
+ uint16_t num = StringToLong(buf, NULL, 10);
+ add_bits(num, 10, out, pos);
+ }
+
+ if (rem) {
+ buf[0] = data[triplets_size];
+ buf[1] = data[triplets_size + 1];
+ buf[rem] = 0;
+
+ uint16_t num = StringToLong(buf, NULL, 10);
+ add_bits(num, rem_bits, out, pos);
+ }
+ } else if (mode == M_ALPHANUMERIC) {
+ if (pos + 11 * (int(len & ~1ul) / 2) > n_bits) return false;
+
+ for (int i = 0; i < int(len & ~1ul); i += 2) {
+ uint16_t num = alphanumeric(data[i]) * 45 + alphanumeric(data[i + 1]);
+ add_bits(num, 11, out, pos);
+ }
+ if (len & 1) {
+ if (pos + 6 > n_bits) return false;
+
+ add_bits(alphanumeric(data[len - 1]), 6, out, pos);
+ }
+ } else if (mode == M_BYTE) {
+ if (pos + len * 8 > n_bits) return false;
+
+ for (size_t i = 0; i < len; ++i) add_bits(data[i], 8, out, pos);
+ } else {
+ if (pos + 13 * (len / 2) > n_bits) return false;
+
+ for (size_t i = 0; i < len; i += 2) {
+ uint16_t val = ((uint8_t) data[i]) | (((uint8_t) data[i + 1]) << 8);
+ uint16_t res = 0;
+ val -= val < 0x9FFC ? 0x8140 : 0xC140;
+ res += val & 0xff;
+ res += (val >> 8) * 0xc0;
+ add_bits(res, 13, out, pos);
+ }
+ }
+
+ size_t padding = n_bits - pos;
+ size_t i = 0;
+
+ add_bits(0, padding > 4 ? 4 : padding, out, pos);
+
+ if (pos & 7) add_bits(0, (8 - pos) & 7, out, pos);
+
+ while (pos < n_bits) add_bits(++i & 1 ? 0xec : 0x11, 8, out, pos);
+
+ return true;
+}
+
+template <int V>
+void Qr<V>::encode_ecc(uint8_t* data, Ecc ecc, uint8_t* out) {
+ int n_blocks = N_ECC_BLOCKS[ecc][V];
+ int ecc_len = ECC_CODEWORDS_PER_BLOCK[ecc][V];
+
+ int n_data_bytes = N_DAT_CAPACITY - ecc_len * n_blocks;
+
+ int n_short_blocks = n_blocks - N_DAT_CAPACITY % n_blocks;
+ int short_len = N_DAT_CAPACITY / n_blocks - ecc_len;
+
+ uint8_t gen_poly[30];
+ uint8_t ecc_buf[30];
+
+ gf_gen_poly(ecc_len, gen_poly);
+
+ uint8_t* data_ptr = data;
+
+ for (int i = 0; i < n_blocks; ++i) {
+ int data_len = short_len;
+
+ if (i >= n_short_blocks) ++data_len;
+
+ gf_poly_div(data_ptr, data_len, gen_poly, ecc_len, ecc_buf);
+
+ for (int j = 0, k = i; j < data_len; ++j, k += n_blocks) {
+ if (j == short_len) k -= n_short_blocks;
+ out[k] = data_ptr[j];
+ }
+ for (int j = 0, k = n_data_bytes + i; j < ecc_len; ++j, k += n_blocks) out[k] = ecc_buf[j];
+
+ data_ptr += data_len;
+ }
+}
+
+template <int V>
+void Qr<V>::add_data(uint8_t* data, uint8_t* patterns) {
+ int data_pos = 0;
+
+ for (int x = SIDE - 1; x >= 1; x -= 2) {
+ if (x == 6) x = 5;
+
+ for (int i = 0; i < SIDE; ++i) {
+ int y = !((x + 1) & 2) ? SIDE - 1 - i : i;
+ int coord = y * SIDE + x;
+
+ if (!get_arr_bit(patterns, coord)) {
+ if (get_bit_r(data, data_pos)) set_arr_bit(code, coord);
+
+ ++data_pos;
+ }
+
+ if (!get_arr_bit(patterns, coord - 1)) {
+ if (get_bit_r(data, data_pos)) set_arr_bit(code, coord - 1);
+
+ ++data_pos;
+ }
+ }
+ }
+}
+
+template <int V>
+void Qr<V>::add_patterns() {
+ // White bounds inside finders
+ draw_bound<false>(1, 1, 5, 5, code);
+ draw_bound<false>(1, SIDE - 6, 5, 5, code);
+ draw_bound<false>(SIDE - 6, 1, 5, 5, code);
+
+ // Finish alignment patterns
+ for (int i = 0; i < N_ALIGN; ++i) {
+ for (int j = 0; j < N_ALIGN; ++j) {
+ if ((!i && !j) || (!i && j == N_ALIGN - 1) || (!j && i == N_ALIGN - 1)) continue;
+ draw_bound<false>(ALIGN_POS[V][i] - 1, ALIGN_POS[V][j] - 1, 3, 3, code);
+ }
+ }
+
+ // Draw white separators
+ draw_rect<false>(7, 0, 1, 8, code);
+ draw_rect<false>(0, 7, 8, 1, code);
+ draw_rect<false>(SIDE - 8, 0, 1, 8, code);
+ draw_rect<false>(SIDE - 8, 7, 8, 1, code);
+ draw_rect<false>(7, SIDE - 8, 1, 8, code);
+ draw_rect<false>(0, SIDE - 8, 8, 1, code);
+
+ // Perforate timing patterns
+ for (int i = 7; i < SIDE - 7; i += 2) {
+ clr_arr_bit(code, 6 * SIDE + i);
+ clr_arr_bit(code, i * SIDE + 6);
+ }
+}
+
+template <int V>
+void Qr<V>::add_version() {
+ if (V < 7) return;
+
+ uint32_t rem = V;
+
+ for (uint8_t i = 0; i < 12; ++i) rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
+
+ uint32_t data = V << 12 | rem;
+
+ for (int x = 0; x < 6; ++x) {
+ for (int j = 0; j < 3; ++j) {
+ int y = SIDE - 11 + j;
+
+ bool black = (data >> (x * 3 + j)) & 1;
+
+ if (!black) {
+ clr_arr_bit(code, y * SIDE + x);
+ clr_arr_bit(code, y + SIDE * x);
+ }
+ }
+ }
+}
+
+template <int V>
+void Qr<V>::add_format(Ecc ecc, int mask) {
+ int data = (ecc ^ 1) << 3 | mask;
+ int rem = data;
+
+ for (int i = 0; i < 10; i++) rem = (rem << 1) ^ ((rem >> 9) * 0b10100110111);
+
+ int res = (data << 10 | rem) ^ 0b101010000010010;
+
+ for (int i = 0; i < 6; ++i) {
+ if ((res >> i) & 1) {
+ set_arr_bit(code, SIDE * 8 + SIDE - 1 - i);
+ set_arr_bit(code, SIDE * i + 8);
+ } else {
+ clr_arr_bit(code, SIDE * 8 + SIDE - 1 - i);
+ clr_arr_bit(code, SIDE * i + 8);
+ }
+ }
+
+ for (int i = 6; i < 8; ++i) {
+ if ((res >> i) & 1) {
+ set_arr_bit(code, SIDE * 8 + SIDE - 1 - i);
+ set_arr_bit(code, SIDE * (i + 1) + 8);
+ } else {
+ clr_arr_bit(code, SIDE * 8 + SIDE - 1 - i);
+ clr_arr_bit(code, SIDE * (i + 1) + 8);
+ }
+ }
+
+ if ((res >> 8) & 1) {
+ set_arr_bit(code, SIDE * 8 + 7);
+ set_arr_bit(code, SIDE * (SIDE - 7) + 8);
+ } else {
+ clr_arr_bit(code, SIDE * 8 + 7);
+ clr_arr_bit(code, SIDE * (SIDE - 7) + 8);
+ }
+
+ for (int i = 9, j = 5; i < 15; ++i, --j) {
+ if ((res >> i) & 1) {
+ set_arr_bit(code, SIDE * 8 + j);
+ set_arr_bit(code, SIDE * (SIDE - 1 - j) + 8);
+ } else {
+ clr_arr_bit(code, SIDE * 8 + j);
+ clr_arr_bit(code, SIDE * (SIDE - 1 - j) + 8);
+ }
+ }
+}
+
+template <int V>
+template <bool B>
+void Qr<V>::draw_rect(int y, int x, int height, int width, uint8_t* out) {
+ if (B) {
+ for (int dy = y * SIDE; dy < (y + height) * SIDE; dy += SIDE)
+ for (int dx = x; dx < x + width; ++dx) set_arr_bit(out, dy + dx);
+ } else {
+ for (int dy = y * SIDE; dy < (y + height) * SIDE; dy += SIDE)
+ for (int dx = x; dx < x + width; ++dx) clr_arr_bit(out, dy + dx);
+ }
+}
+
+template <int V>
+template <bool B>
+void Qr<V>::draw_bound(int y, int x, int height, int width, uint8_t* out) {
+ if (B) {
+ for (int i = y * SIDE + x; i < y * SIDE + x + width; ++i) set_arr_bit(out, i);
+ for (int i = (y + height - 1) * SIDE + x; i < (y + height - 1) * SIDE + x + width; ++i)
+ set_arr_bit(out, i);
+ for (int i = (y + 1) * SIDE + x; i < (y + height - 1) * SIDE + x; i += SIDE)
+ set_arr_bit(out, i);
+ for (int i = (y + 1) * SIDE + x + width - 1; i < (y + height - 1) * SIDE + x + width - 1;
+ i += SIDE)
+ set_arr_bit(out, i);
+ } else {
+ for (int i = y * SIDE + x; i < y * SIDE + x + width; ++i) clr_arr_bit(out, i);
+ for (int i = (y + height - 1) * SIDE + x; i < (y + height - 1) * SIDE + x + width; ++i)
+ clr_arr_bit(out, i);
+ for (int i = (y + 1) * SIDE + x; i < (y + height - 1) * SIDE + x; i += SIDE)
+ clr_arr_bit(out, i);
+ for (int i = (y + 1) * SIDE + x + width - 1; i < (y + height - 1) * SIDE + x + width - 1;
+ i += SIDE)
+ clr_arr_bit(out, i);
+ }
+}
+
+template <int V>
+void Qr<V>::reserve_patterns(uint8_t* out) {
+ draw_rect<true>(0, 6, SIDE, 1, out);
+ draw_rect<true>(6, 0, 1, SIDE, out);
+
+ draw_rect<true>(0, 0, 9, 9, out);
+ draw_rect<true>(SIDE - 8, 0, 8, 9, out);
+ draw_rect<true>(0, SIDE - 8, 9, 8, out);
+
+ for (int i = 0; i < N_ALIGN; ++i) {
+ for (int j = 0; j < N_ALIGN; ++j) {
+ if ((!i && !j) || (!i && j == N_ALIGN - 1) || (!j && i == N_ALIGN - 1)) continue;
+ draw_rect<true>(ALIGN_POS[V][i] - 2, ALIGN_POS[V][j] - 2, 5, 5, out);
+ }
+ }
+
+ if (V >= 7) {
+ draw_rect<true>(SIDE - 11, 0, 3, 6, out);
+ draw_rect<true>(0, SIDE - 11, 6, 3, out);
+ }
+}
+
+template <int V>
+template <bool H>
+int Qr<V>::rule_1_3_score() {
+ constexpr int y_max = H ? N_BITS : SIDE;
+ constexpr int x_max = H ? SIDE : N_BITS;
+ constexpr int y_step = H ? SIDE : 1;
+ constexpr int x_step = H ? 1 : SIDE;
+
+ int res = 0;
+
+ for (int y = 0; y < y_max; y += y_step) {
+ bool color = get_arr_bit(code, y);
+ int finder = color;
+ int cnt = 1;
+ for (int x = 1; x < x_max; x += x_step) {
+ if (get_arr_bit(code, y + x) == color) {
+ ++cnt;
+ if (cnt == 5) res += 3;
+ if (cnt > 5) ++res;
+ } else {
+ color = !color;
+ cnt = 1;
+ }
+ // Finder-like
+ finder = ((finder << 1) & 0x7ff) | color;
+ if (x >= x_step * 10) {
+ if (finder == 0x05d || finder == 0x5d0) res += 40;
+ }
+ }
+ }
+ return res;
+}
+
+template <int V>
+int Qr<V>::penalty_score() {
+ int res = 0;
+
+ res += rule_1_3_score<true>();
+ res += rule_1_3_score<false>();
+
+ for (int y = 0; y < N_BITS - SIDE; y += SIDE) {
+ for (int x = 0; x < SIDE - 1; ++x) {
+ bool c = get_arr_bit(code, y + x);
+
+ if (c == get_arr_bit(code, y + x + 1) && c == get_arr_bit(code, y + x + SIDE) &&
+ c == get_arr_bit(code, y + x + SIDE + 1))
+ res += 3;
+ }
+ }
+
+ int black = 0;
+ for (int y = 0; y < N_BITS; y += SIDE) {
+ for (int x = 0; x < SIDE; ++x) black += get_arr_bit(code, y + x);
+ }
+ res += abs((black * 100) / N_BITS - 50) / 5 * 10;
+
+ return res;
+}
+
+template <int V>
+int Qr<V>::select_mask(Ecc ecc, uint8_t* patterns) {
+ unsigned min_score = -1;
+ unsigned score = 0;
+ uint8_t mask = 0;
+
+ for (int i = 0; i < 8; ++i) {
+ add_format(ecc, i);
+ apply_mask(i, patterns);
+ score = penalty_score();
+ if (score < min_score) {
+ mask = i;
+ min_score = score;
+ }
+ apply_mask(i, patterns);
+ }
+ return mask;
+}
+
+template <int V>
+void Qr<V>::apply_mask(int mask, uint8_t* patterns) {
+ for (int y = 0, dy = 0; y < SIDE; ++y, dy += SIDE) {
+ for (int x = 0; x < SIDE; ++x) {
+ int coord = dy + x;
+
+ if (get_arr_bit(patterns, coord)) continue;
+
+ bool keep = true;
+
+ switch (mask) {
+ case 0:
+ keep = (x + y) & 1;
+ break;
+ case 1:
+ keep = y & 1;
+ break;
+ case 2:
+ keep = x % 3;
+ break;
+ case 3:
+ keep = (x + y) % 3;
+ break;
+ case 4:
+ keep = (y / 2 + x / 3) & 1;
+ break;
+ case 5:
+ keep = x * y % 2 + x * y % 3;
+ break;
+ case 6:
+ keep = (x * y % 2 + x * y % 3) & 1;
+ break;
+ case 7:
+ keep = ((x + y) % 2 + x * y % 3) & 1;
+ break;
+ }
+
+ if (!keep) {
+ if (get_arr_bit(code, coord))
+ clr_arr_bit(code, coord);
+ else
+ set_arr_bit(code, coord);
+ }
+ }
+ }
+}
+
+/// @brief QR code encoder class.
+class QrDelegate final {
+ public:
+ explicit QrDelegate() = default;
+ ~QrDelegate() = default;
+
+ NE_COPY_DEFAULT(QrDelegate)
+
+ /// @brief Draw method delegate.
+ template <Int32 V>
+ bool draw(Qr<V>& subject, Int32 x, Int32 y) noexcept {
+ return subject.draw(x, y);
+ }
+};
+} // namespace qr
+
+namespace Kernel::Qr {
+using namespace qr;
+} // namespace Kernel::Qr
+
+#endif // QR_H \ No newline at end of file
diff --git a/src/boot/BootKit/QrPrelude.h b/src/boot/BootKit/QrPrelude.h
new file mode 100644
index 00000000..e89fad7a
--- /dev/null
+++ b/src/boot/BootKit/QrPrelude.h
@@ -0,0 +1 @@
+#include <BootKit/BitManip.h> \ No newline at end of file
diff --git a/src/boot/BootKit/Shared/base.h b/src/boot/BootKit/Shared/base.h
new file mode 100644
index 00000000..c95db0cc
--- /dev/null
+++ b/src/boot/BootKit/Shared/base.h
@@ -0,0 +1,24 @@
+#ifndef UTL_BASE_H
+#define UTL_BASE_H
+
+#include <math.h>
+#include <stddef.h>
+#include <stdint.h>
+
+namespace utl {
+
+/**
+ * @brief Helper to get number of elements in array.
+ *
+ * @tparam T Auto-deduced element type
+ * @tparam N Auto-deduced number of elements
+ * @return Array size
+ */
+template <class T, size_t N>
+constexpr size_t countof(T (&)[N]) {
+ return N;
+}
+
+} // namespace utl
+
+#endif \ No newline at end of file
diff --git a/src/boot/BootKit/Shared/bit.h b/src/boot/BootKit/Shared/bit.h
new file mode 100644
index 00000000..1ac29c89
--- /dev/null
+++ b/src/boot/BootKit/Shared/bit.h
@@ -0,0 +1,228 @@
+#ifndef UTL_BIT_H
+#define UTL_BIT_H
+
+#include <bit>
+
+namespace utl {
+
+/**
+ * @brief Size of object in terms of bits.
+ *
+ * @tparam T Object type
+ * @return Number of bits
+ */
+template <class T>
+constexpr auto bit_size() {
+ return sizeof(T) * 8;
+}
+
+/**
+ * @brief Integer with all bits set to 1.
+ *
+ * @tparam T Integer type
+ * @return All set integer
+ */
+template <class T>
+constexpr T bit_full() {
+ return T(-1);
+}
+
+/**
+ * @brief Wrap around mask for power of two number of bits
+ * within given integer type. For example:
+ * [ bit_wrap<uint8_t> = 8 - 1 = 0b111 ]
+ * [ bit_wrap<uint16_t> = 16 - 1 = 0b1111 ]
+ * [ bit_wrap<uint32_t> = 32 - 1 = 0b11111 ]
+ *
+ * @tparam T Integer type
+ * @return Wrap around mask for number of bits
+ */
+template <class T>
+constexpr T bit_wrap() {
+ return bit_size<T>() - 1;
+}
+
+/**
+ * @brief Number of bits to fit bit_wrap<T> result, in other words
+ * bit width of (sizeof(T) * 8 - 1). For example:
+ * [ bit_shft<uint8_t> = bit_width(0b111) = 3 ]
+ * [ bit_shft<uint16_t> = bit_width(0b1111) = 4 ]
+ * [ bit_shft<uint32_t> = bit_width(0b11111) = 5 ]
+ *
+ * @tparam T Integer type
+ * @return Number of bits to shift to divide by sizeof(T) * 8
+ */
+template <class T>
+constexpr auto bit_shft() {
+ return std::bit_width(bit_wrap<T>());
+}
+
+/**
+ * @brief Round up division by number of bits within given integer type,
+ * which sizeof(T) * 8 is power of two.
+ *
+ * @tparam T Inetegr type
+ * @param x Dividend
+ * @return Quotient
+ */
+template <class T>
+constexpr auto bit_ceil(auto x) {
+ return (x + bit_wrap<T>()) >> bit_shft<T>();
+}
+
+/**
+ * @brief Count leading zeros.
+ *
+ * @param x Unsigned integer argument
+ * @return Number of leading zeros
+ */
+constexpr unsigned cntlz(auto x) {
+ if constexpr (std::is_same_v<decltype(x), int>)
+ return std::countl_zero(unsigned(x));
+ else
+ return std::countl_zero(x);
+}
+
+/**
+ * @brief Count trailing zeros.
+ *
+ * @param x Unsigned integer argument
+ * @return Number of trailing zeros
+ */
+constexpr unsigned cnttz(auto x) {
+ if constexpr (std::is_same_v<decltype(x), int>)
+ return std::countr_zero(unsigned(x));
+ else
+ return std::countr_zero(x);
+}
+
+/**
+ * @brief Get number of words (integers) required to store N bits.
+ *
+ * @tparam T Word integer type
+ * @param n Number of bits to store
+ * @return Number of words
+ */
+template <class T>
+constexpr size_t words_in_bits(size_t n) {
+ return (n >> bit_shft<T>()) + !!(n & bit_wrap<T>());
+}
+
+/**
+ * @brief Get number of bytes required to store N bits.
+ *
+ * @param n Number of bits to store
+ * @return Number of bytes
+ */
+constexpr size_t bytes_in_bits(size_t n) {
+ return words_in_bits<uint8_t>(n);
+}
+
+/**
+ * @brief Make integer with bit at given position.
+ *
+ * @tparam T Inetegr type
+ * @param n Bit position
+ * @return Integer with set bit
+ */
+template <class T = unsigned>
+constexpr T bit(int n) {
+ return T(1) << n;
+}
+
+/**
+ * @brief Get n-th bit of an integer.
+ *
+ * @tparam T Integer type
+ * @param x Integer
+ * @param n Bit position from LSB
+ * @return true if set
+ */
+template <class T>
+constexpr bool get_bit(T x, int n) {
+ return (x >> n) & 1;
+}
+
+/**
+ * @brief Set n-th bit of an integer.
+ *
+ * @tparam T Integer type
+ * @param x Integer
+ * @param n Bit position from LSB
+ */
+template <class T>
+constexpr void set_bit(T& x, int n) {
+ x |= 1 << n;
+}
+
+/**
+ * @brief Clear n-th bit of an integer.
+ *
+ * @tparam T Integer type
+ * @param x Integer
+ * @param n Bit position from LSB
+ */
+template <class T>
+constexpr void clr_bit(T& x, int n) {
+ x &= ~(1 << n);
+}
+
+/**
+ * @brief Get n-th bit in array of words (starting from LSB).
+ *
+ * @tparam T Word type
+ * @param p Array of words
+ * @param n Index of bit to get
+ * @return true if set
+ */
+template <class T>
+constexpr bool get_arr_bit(const T* p, unsigned n) {
+ return get_bit(p[n >> bit_shft<T>()], n & bit_wrap<T>());
+}
+
+/**
+ * @brief Set n-th bit in array of words (starting from LSB).
+ *
+ * @tparam T Word type
+ * @param p Array of words
+ * @param n Index of bit to set
+ */
+template <class T>
+constexpr void set_arr_bit(T* p, unsigned n) {
+ set_bit(p[n >> bit_shft<T>()], n & bit_wrap<T>());
+}
+
+/**
+ * @brief Clear n-th bit in array of words (starting from LSB).
+ *
+ * @tparam T Word type
+ * @param p Array of words
+ * @param n Index of bit to clear
+ */
+template <class T>
+constexpr void clr_arr_bit(T* p, unsigned n) {
+ clr_bit(p[n >> bit_shft<T>()], n & bit_wrap<T>());
+}
+
+/**
+ * @brief Shift bits left in array of integer elements from least significant bit
+ * and considering 0-th byte as the right most.
+ * uint16_t example: 0b10000000'11100001 ==> 0b00000001'11000010.
+ *
+ * @tparam T Integer type
+ * @tparam L Length of array
+ * @param x Array of integers, nullptr not acceptable!
+ * @param len Number of elements
+ */
+template <class T, size_t L>
+constexpr void shift_left(T (&x)[L]) {
+ for (int i = L - 1; i > 0; --i) {
+ x[i] <<= 1;
+ x[i] |= x[i - 1] >> bit_wrap<T>();
+ }
+ x[0] <<= 1;
+}
+
+} // namespace utl
+
+#endif \ No newline at end of file
diff --git a/src/boot/BootKit/Support.h b/src/boot/BootKit/Support.h
new file mode 100644
index 00000000..110b220c
--- /dev/null
+++ b/src/boot/BootKit/Support.h
@@ -0,0 +1,145 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/// @file Support.h
+/// @brief Purpose of this file is to help port libs into the bootloader.
+
+#ifndef __NE_ARM64__
+#include <string.h>
+#endif
+
+#define kLongMax ((long) (~0UL >> 1))
+#define kLongMin (~kLongMax)
+
+#ifdef __BOOTZ__
+
+/// @brief memset definition in C++.
+/// @param dst destination pointer.
+/// @param byte value to fill in.
+/// @param len length of of src.
+EXTERN_C void* memset(void* dst, int byte, long long unsigned int len);
+
+/// @brief memcpy definition in C++.
+/// @param dst destination pointer.
+/// @param src source pointer.
+/// @param len length of of src.
+EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len);
+
+/// @brief strlen definition in C++.
+EXTERN_C size_t strlen(const char* whatToCheck);
+
+/// @brief strcmp definition in C++.
+EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight);
+
+#else
+
+#ifndef __NE_ARM64__
+#include <string.h>
+#endif
+
+#endif // __BOOTZ__
+
+#define SetMem(dst, c, sz) memset(dst, c, sz)
+#define MoveMem(dst, src, sz) memcpy(dst, src, sz)
+#define CopyMem(dst, src, sz) memcpy(dst, src, sz)
+#define StrLen(src) strlen(src)
+#define StrCmp(dst, src) strcmp(dst, src)
+
+inline int IsSpace(int c) {
+ return c == ' ';
+}
+
+inline int StringNCompare(const char* destination, const char* source, long length) {
+ long err = 0;
+
+ for (long i = 0UL; i < length; ++i) {
+ if (source[i] != destination[i]) ++err;
+ }
+
+ return err;
+}
+
+inline long StringToLong(const char* nptr, char** endptr, int base) {
+ const char *p = nptr, *endp;
+ bool is_neg = 0, overflow = 0;
+
+ /* Need unsigned so (-kLongMin) can fit in these: */
+ unsigned long n = 0UL, cutoff;
+ int cutlim;
+
+ if (base < 0 || base == 1 || base > 36) {
+ return 0L;
+ }
+
+ endp = nptr;
+
+ while (IsSpace(*p)) p++;
+
+ if (*p == '+') {
+ p++;
+ } else if (*p == '-') {
+ is_neg = 1, p++;
+ }
+ if (*p == '0') {
+ p++;
+ /* For strtol(" 0xZ", &endptr, 16), endptr should point to 'x';
+ * pointing to ' ' or '0' is non-compliant.
+ * (Many implementations do this wrong.) */
+ endp = p;
+ if (base == 16 && (*p == 'X' || *p == 'x')) {
+ p++;
+ } else if (base == 2 && (*p == 'B' || *p == 'b')) {
+ /* C23 standard supports "0B" and "0b" prefixes. */
+ p++;
+ } else if (base == 0) {
+ if (*p == 'X' || *p == 'x') {
+ base = 16, p++;
+ } else if (*p == 'B' || *p == 'b') {
+ base = 2, p++;
+ } else {
+ base = 8;
+ }
+ }
+ } else if (base == 0) {
+ base = 10;
+ }
+
+ cutoff = (is_neg) ? -(kLongMin / base) : kLongMax / base;
+ cutlim = (is_neg) ? -(kLongMin % base) : kLongMax % base;
+
+ while (1) {
+ int c;
+ if (*p >= 'A')
+ c = ((*p - 'A') & (~('a' ^ 'A'))) + 10;
+ else if (*p <= '9')
+ c = *p - '0';
+ else
+ break;
+ if (c < 0 || c >= base) break;
+ endp = ++p;
+ if (overflow) {
+ /* endptr should go forward and point to the non-digit character
+ * (of the given base); required by ANSI standard. */
+ if (endptr) continue;
+ break;
+ }
+ if (n > cutoff || (n == cutoff && c > cutlim)) {
+ overflow = 1;
+ continue;
+ }
+ n = n * base + c;
+ }
+
+ if (endptr) *endptr = (char*) endp;
+
+ if (overflow) {
+ return ((is_neg) ? kLongMin : kLongMax);
+ }
+
+ return (long) ((is_neg) ? -n : n);
+}
diff --git a/src/boot/amd64-ci.make b/src/boot/amd64-ci.make
new file mode 100644
index 00000000..eee7b3cb
--- /dev/null
+++ b/src/boot/amd64-ci.make
@@ -0,0 +1,148 @@
+##################################################
+# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license.
+# This is the bootloader makefile.
+##################################################
+
+CC_GNU=x86_64-w64-mingw32-g++
+LD_GNU=x86_64-w64-mingw32-ld
+
+WINDRES=x86_64-w64-mingw32-windres
+
+ADD_FILE=touch
+COPY=cp
+HTTP_GET=wget
+
+# Select this for Windows.
+ifneq ($(findstring CYGWIN_NT-10.0,$(shell uname)), )
+EMU=qemu-system-x86_64w.exe
+else
+# this for NT distributions
+EMU=qemu-system-x86_64
+endif
+
+ifeq ($(NEOS_MODEL), )
+NE_MODEL=-DkMachineModel="\"Kernel\""
+endif
+
+BIOS=OVMF.fd
+IMG=epm-master-1.img
+IMG_2=epm-master-2.img
+
+BOOT=./src/nekernel-esp.img
+
+DISK_DRV =
+
+ifneq ($(ATA_PIO_SUPPORT), )
+DISK_DRV = -D__ATA_PIO__
+endif
+
+ifneq ($(ATA_DMA_SUPPORT), )
+DISK_DRV = -D__ATA_DMA__
+endif
+
+ifneq ($(AHCI_SUPPORT), )
+DISK_DRV = -D__AHCI__
+endif
+
+DEBUG_MACRO = -D__DEBUG__
+
+ifeq ($(shell uname), Darwin)
+EMU_FLAGS=-M q35 -smp 4 -m 8G \
+ -bios $(BIOS) -cdrom $(BOOT) -boot d
+endif
+
+ifneq ($(shell uname), Darwin)
+EMU_FLAGS= -smp 4 -m 8G \
+ -bios $(BIOS) -M q35 -cdrom $(BOOT) -boot d -accel kvm
+endif
+
+LD_FLAGS=-e BootloaderMain --subsystem=10
+
+STANDALONE_MACRO=-D__BOOTZ_STANDALONE__
+OBJ=obj/*.o
+
+REM=rm
+REM_FLAG=-f
+
+FLAG_ASM=-f win64
+FLAG_GNU=-fshort-wchar -Wall -Wpedantic -Wextra -Werror -D__EFI_x86_64__ -mno-red-zone -D__NEKERNEL__ -D__BOOTZ__ \
+ -DEFI_FUNCTION_WRAPPER -I./ -I../kernel $(DEBUG_MACRO) $(DISK_DRV) -I../ -c -nostdlib -fno-rtti -fno-exceptions \
+ -std=c++20 -DBOOTZ_GPT_SUPPORT -DBOOTZ_EPM_SUPPORT -D__HAVE_NE_APIS__ -DZBA_USE_FB -D__NE_AMD64__ -D__NE__ -DNE_AUTO_FORMAT
+
+BOOTLOADER=ne_bootz
+KERNEL=ne_kernel
+SYSCHK=chk.efi
+BOOTNET=net.efi
+SCIKIT=libSystem.dll
+
+.PHONY: invalid-recipe
+invalid-recipe:
+ @echo "=== ERROR ==="
+ @echo "=> Use make compile-<arch> instead."
+
+# CI doesn't do anything than build.
+.PHONY: all
+all: compile-amd64
+ mkdir -p src/root/EFI/BOOT
+ $(LD_GNU) $(OBJ) $(LD_FLAGS) -o src/$(BOOTLOADER)
+
+.PHONY: disk
+disk:
+ dd if=/dev/zero of=$(BOOT) bs=7M count=100
+ mformat -i $(BOOT) -F -v "NeKernel"
+
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG = -D__DEBUG__
+endif
+
+.PHONY: compile-amd64
+compile-amd64:
+ $(WINDRES) src/boot_rsrc.rsrc -O coff -o boot_rsrc.o
+ $(CC_GNU) $(NE_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \
+ $(wildcard src/HEL/AMD64/*.cc) \
+ $(wildcard src/HEL/AMD64/*.S) \
+ $(wildcard src/*.cc)
+ mv *.o obj/
+
+.PHONY: run-efi-amd64-ahci
+run-efi-amd64-ahci:
+ $(EMU) $(EMU_FLAGS) -d int -hda $(IMG) -s -S -trace ahci_* -boot menu=on
+
+.PHONY: run-efi-amd64-ata-pio
+run-efi-amd64-ata-pio:
+ $(EMU) $(EMU_FLAGS) -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -s -S
+
+.PHONY: run-efi-amd64-ata-dma
+run-efi-amd64-ata-dma:
+ $(EMU) $(EMU_FLAGS) -device piix4-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -s -S
+
+.PHONY: run-efi-amd64-ata
+run-efi-amd64-ata: run-efi-amd64-ata-dma
+
+# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta specs.
+.PHONY: epm-img
+epm-img:
+ qemu-img create -f raw $(IMG) 4G
+
+.PHONY: efi
+efi:
+ $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd -O OVMF.fd
+
+BINS=*.bin
+EXECUTABLES=ne_bootz ne_kernel OVMF.fd
+
+TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES)
+
+.PHONY: clean
+clean:
+ $(REM) $(TARGETS)
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "epm-img: Format a disk using the Explicit Partition Map."
+ @echo "gpt-img: Format a disk using the Explicit Partition Map."
+ @echo "clean: remove bootloader and files."
+ @echo "bootloader-amd64: Build bootloader. (PC AMD64)"
+ @echo "run-efi-amd64-<ahci, ata>: Run bootloader. (PC AMD64)"
diff --git a/src/boot/amd64-desktop.make b/src/boot/amd64-desktop.make
new file mode 100644
index 00000000..2ddc4659
--- /dev/null
+++ b/src/boot/amd64-desktop.make
@@ -0,0 +1,159 @@
+##################################################
+# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license.
+# This is the bootloader makefile.
+##################################################
+
+CC_GNU=x86_64-w64-mingw32-g++
+LD_GNU=x86_64-w64-mingw32-ld
+
+WINDRES=x86_64-w64-mingw32-windres
+
+ADD_FILE=touch
+COPY=cp
+HTTP_GET=wget
+
+# Select this for Windows.
+ifneq ($(findstring CYGWIN_NT-10.0,$(shell uname)), )
+EMU=qemu-system-x86_64w.exe
+else
+# this for NT distributions
+EMU=qemu-system-x86_64
+endif
+
+ifeq ($(NEOS_MODEL), )
+NE_MODEL=-DkMachineModel="\"Kernel\""
+endif
+
+BIOS=OVMF.fd
+IMG=epm-master-1.img
+IMG_2=epm-master-2.img
+
+BOOT=./src/nekernel-esp.img
+
+DISK_DRV =
+
+ifneq ($(ATA_PIO_SUPPORT), )
+DISK_DRV = -D__ATA_PIO__
+endif
+
+ifneq ($(ATA_DMA_SUPPORT), )
+DISK_DRV = -D__ATA_DMA__
+endif
+
+ifneq ($(AHCI_SUPPORT), )
+DISK_DRV = -D__AHCI__
+endif
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG_MACRO = -D__DEBUG__
+endif
+
+ifeq ($(shell uname), Darwin)
+EMU_FLAGS=-M q35 -smp 4 -m 8G \
+ -bios $(BIOS) -cdrom $(BOOT) -boot d
+endif
+
+ifneq ($(shell uname), Darwin)
+EMU_FLAGS= -smp 4 -m 8G \
+ -bios $(BIOS) -M q35 -cdrom $(BOOT) -boot d -accel kvm
+endif
+
+LD_FLAGS=-e BootloaderMain --subsystem=10
+
+STANDALONE_MACRO=-D__BOOTZ_STANDALONE__
+OBJ=obj/*.o
+
+REM=rm
+REM_FLAG=-f
+
+FLAG_ASM=-f win64
+FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -Wall -Wpedantic -Wextra -mno-red-zone -D__NEKERNEL__ -D__BOOTZ__ -DBOOTZ_VEPM_SUPPORT \
+ -DEFI_FUNCTION_WRAPPER -I./ -I../kernel $(DISK_DRV) -I../ -c -nostdlib -fno-rtti -fno-exceptions \
+ -std=c++20 -DBOOTZ_GPT_SUPPORT -D__HAVE_NE_APIS__ -DZBA_USE_FB -D__NE_AMD64__ -D__NE__ -DNE_AUTO_FORMAT -Wl,--disable-reloc-section
+
+BOOTLOADER=ne_bootz
+KERNEL=ne_kernel
+SYSCHK=chk.efi
+BOOTNET=net.efi
+SCIKIT=libSystem.dll
+DDK=libDDK.dll
+
+.PHONY: invalid-recipe
+invalid-recipe:
+ @echo "=== ERROR ==="
+ @echo "=> Use make compile-<arch> instead."
+
+.PHONY: all
+all: compile-amd64
+ mkdir -p src/root/EFI/BOOT
+ $(LD_GNU) $(OBJ) $(LD_FLAGS) -o src/$(BOOTLOADER)
+ $(COPY) src/$(BOOTLOADER) src/root/EFI/BOOT/BOOTX64.EFI
+ $(COPY) src/$(BOOTLOADER) src/root/EFI/BOOT/BOOTZ.EFI
+ $(COPY) ../kernel/$(KERNEL) src/root/$(KERNEL)
+ $(COPY) ./modules/SysChk/$(SYSCHK) src/root/$(SYSCHK)
+ $(COPY) ./modules/BootNet/$(BOOTNET) src/root/$(BOOTNET)
+ $(COPY) ../libSystem/$(SCIKIT) src/root/$(SCIKIT)
+ $(COPY) src/$(BOOTLOADER) src/root/$(BOOTLOADER)
+ $(COPY) ../libDDK/$(DDK) src/root/$(DDK)
+
+.PHONY: disk
+disk:
+ dd if=/dev/zero of=$(BOOT) bs=7M count=100
+ mformat -i $(BOOT) -F -v "ESP"
+
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG = -D__DEBUG__
+endif
+
+.PHONY: compile-amd64
+compile-amd64:
+ $(WINDRES) src/boot_rsrc.rsrc -O coff -o boot_rsrc.o
+ $(CC_GNU) $(NE_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \
+ $(wildcard src/HEL/AMD64/*.cc) \
+ $(wildcard src/HEL/AMD64/*.S) \
+ $(wildcard src/*.cc)
+ mv *.o obj/
+
+.PHONY: run-efi-amd64-ahci
+run-efi-amd64-ahci:
+ $(EMU) $(EMU_FLAGS) -monitor stdio -hda $(IMG) -s -boot menu=on
+
+.PHONY: run-efi-amd64-ata-pio
+run-efi-amd64-ata-pio:
+ $(EMU) $(EMU_FLAGS) -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -s -d int -boot menu=on
+
+.PHONY: run-efi-amd64-ata-dma
+run-efi-amd64-ata-dma:
+ $(EMU) $(EMU_FLAGS) -device piix4-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -s -boot menu=on
+
+.PHONY: run-efi-amd64-ata
+run-efi-amd64-ata: run-efi-amd64-ata-pio
+
+# img_2 is the rescue disk. img is the bootable disk, as provided by the NeKernel specs.
+.PHONY: epm-img
+epm-img:
+ qemu-img create -f raw $(IMG) 2G
+
+.PHONY: efi
+efi:
+ $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd -O OVMF.fd
+
+BINS=*.bin
+EXECUTABLES=ne_bootz ne_kernel OVMF.fd
+
+TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES)
+
+.PHONY: clean
+clean:
+ $(REM) $(TARGETS)
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "epm-img: Format a disk using the Explicit Partition Map."
+ @echo "gpt-img: Format a disk using the Explicit Partition Map."
+ @echo "disk: Format a FAT32 ESP disk."
+ @echo "clean: remove bootloader and files."
+ @echo "bootloader-amd64: Build bootloader. (PC AMD64)"
+ @echo "run-efi-amd64-<ahci, ata>: Run bootloader. (PC AMD64)"
diff --git a/src/boot/arm64-desktop.make b/src/boot/arm64-desktop.make
new file mode 100644
index 00000000..44299cc3
--- /dev/null
+++ b/src/boot/arm64-desktop.make
@@ -0,0 +1,112 @@
+##################################################
+# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license.
+# This is the bootloader makefile.
+##################################################
+
+CC_GNU = clang++
+LD_GNU = lld-link
+
+ADD_FILE=touch
+COPY=cp
+HTTP_GET=wget
+
+# Select this for Windows.
+ifneq ($(findstring CYGWIN_NT-10.0,$(shell uname)), )
+EMU=qemu-system-aarch64w.exe
+else
+# this for NT distributions
+EMU=qemu-system-aarch64
+endif
+
+ifeq ($(NEOS_MODEL), )
+NE_MODEL=-DkMachineModel="\"NeKernel\""
+endif
+
+BIOS=OVMF.fd
+IMG=epm-master-1.img
+IMG_2=epm-slave.img
+IMG_3=epm-master-2.img
+
+EMU_FLAGS= -smp 4 -m 8G -cpu max -M virt \
+ -bios $(BIOS) \
+ -drive id=disk,file=$(IMG),format=raw,if=none \
+ -drive \
+ file=fat:rw:src/root/,index=2,format=raw \
+ -no-shutdown -no-reboot -cpu cortex-a72 -device virtio-gpu-pci
+
+LD_FLAGS=-subsystem:efi_application -entry:BootloaderMain /nodefaultlib
+
+STANDALONE_MACRO=-D__BOOTZ_STANDALONE__
+OBJ=*.o
+
+REM=rm
+REM_FLAG=-f
+
+FLAG_ASM=-f win64
+FLAG_GNU=-fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__NE_ARM64__ -fno-rtti -fno-exceptions -I./ \
+ -target aarch64-unknown-windows \
+ -std=c++20 -DBOOTZ_EPM_SUPPORT -DZBA_USE_FB -D__FSKIT_USE_NEFS__ -D__BOOTZ_STANDALONE__ -D__NEKERNEL__ -D__BOOTZ__ -D__HAVE_NE_APIS__ -D__NE__ -I../ -I../kernel
+
+BOOT_LOADER=ne_bootz
+KERNEL=ne_kernel
+SYSCHK=chk.efi
+STARTUP=startup.efi
+
+.PHONY: invalid-recipe
+invalid-recipe:
+ @echo "invalid-recipe: Use make compile-<arch> instead."
+
+.PHONY: all
+all: compile
+ mkdir -p src/root/EFI/BOOT
+ $(LD_GNU) $(OBJ) $(LD_FLAGS) /out:src/$(BOOT_LOADER)
+ $(COPY) src/$(BOOT_LOADER) src/root/EFI/BOOT/BOOTAA64.EFI
+ $(COPY) src/$(BOOT_LOADER) src/root/EFI/BOOT/BootZ.EFI
+ $(COPY) ../kernel/$(KERNEL) src/root/$(KERNEL)
+ $(COPY) ./modules/SysChk/$(SYSCHK) src/root/$(SYSCHK)
+ $(COPY) src/$(BOOT_LOADER) src/root/$(BOOT_LOADER)
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG = -D__DEBUG__
+endif
+
+.PHONY: compile
+compile:
+ $(RESCMD)
+ $(CC_GNU) $(NE_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \
+ $(wildcard src/HEL/ARM64/*.cc) \
+ $(wildcard src/HEL/ARM64/*.S) \
+ $(wildcard src/*.cc)
+
+.PHONY: run
+run:
+ $(EMU) $(EMU_FLAGS)
+
+# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta.
+.PHONY: epm-img
+epm-img:
+ qemu-img create -f raw $(IMG) 10G
+ qemu-img create -f raw $(IMG_2) 4G
+ qemu-img create -f raw $(IMG_3) 4G
+
+.PHONY: efi
+efi:
+ $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGAARCH64_QEMU_EFI.fd -O OVMF.fd
+
+BINS=*.bin
+EXECUTABLES=ne_bootz ne_kernel OVMF.fd
+
+TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES)
+
+.PHONY: clean
+clean:
+ $(REM) $(TARGETS)
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "epm-img: Format a disk using the Explicit Partition Map."
+ @echo "gpt-img: Format a disk using the Explicit Partition Map."
+ @echo "clean: clean bootloader."
+ @echo "bootloader-amd64: Build bootloader. (PC AMD64)"
+ @echo "run: Run bootloader. (PC AMD64)"
diff --git a/src/boot/download-ovmf.ps1 b/src/boot/download-ovmf.ps1
new file mode 100644
index 00000000..5a2c5f0e
--- /dev/null
+++ b/src/boot/download-ovmf.ps1
@@ -0,0 +1,4 @@
+$client = new-object System.Net.WebClient
+$output = "$PSScriptRoot\OVMF.fd"
+
+$client.DownloadFile("https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd", $output)
diff --git a/src/boot/gdbinit b/src/boot/gdbinit
new file mode 100644
index 00000000..b55fa645
--- /dev/null
+++ b/src/boot/gdbinit
@@ -0,0 +1,3 @@
+set disassemble-next-line on
+b BootloaderMain
+target remote localhost:1234
diff --git a/src/boot/modules/.keep b/src/boot/modules/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/modules/.keep
diff --git a/src/boot/modules/BootNet/.hgkeep b/src/boot/modules/BootNet/.hgkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/modules/BootNet/.hgkeep
diff --git a/src/boot/modules/BootNet/BootNet.cc b/src/boot/modules/BootNet/BootNet.cc
new file mode 100644
index 00000000..20d1a6c9
--- /dev/null
+++ b/src/boot/modules/BootNet/BootNet.cc
@@ -0,0 +1,121 @@
+/*
+ * ========================================================
+ *
+ * BootNet
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/BootThread.h>
+#include <FirmwareKit/EFI/API.h>
+#include <modules/BootNet/BootNet.h>
+
+STATIC EFI_GUID kEfiSimpleProtoGUID = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
+STATIC EFI_SIMPLE_NETWORK_PROTOCOL* kEfiProtocol = nullptr;
+
+STATIC Void bootnet_read_ip_packet(BOOTNET_INTERNET_HEADER inet,
+ BOOTNET_INTERNET_HEADER** inet_out);
+
+EXTERN_C Int32 BootNetModuleMain(Kernel::HEL::BootInfoHeader* handover) {
+ fw_init_efi((EfiSystemTable*) handover->f_FirmwareCustomTables[Kernel::HEL::kHandoverTableST]);
+
+ Boot::BootTextWriter writer;
+
+ writer.Write("BootNet: Init BootNet...\r");
+
+ if (BS->LocateProtocol(&kEfiSimpleProtoGUID, nullptr, (VoidPtr*) &kEfiProtocol) != kEfiOk) {
+ writer.Write("BootNet: Not supported by firmware.\r");
+ return kEfiFail;
+ }
+
+ BOOTNET_INTERNET_HEADER inet{};
+ BOOTNET_INTERNET_HEADER* inet_out = nullptr;
+
+ SetMem(&inet, 0, sizeof(BOOTNET_INTERNET_HEADER));
+
+ writer.Write("BootNet: Downloading kernel...\r");
+
+ bootnet_read_ip_packet(inet, &inet_out);
+
+ if (inet_out->Length < 1) {
+ writer.Write("BootNet: No executable attached to the packet, aborting.\r");
+ return kEfiFail;
+ }
+
+ if (inet_out->Version != kBootNetVersion) {
+ writer.Write("BootNet: The version clashes, not good.\r");
+ return kEfiFail;
+ }
+
+ if (!inet_out->ImpliesProgram) {
+ Boot::BootThread thread(inet_out->Data);
+
+ if (thread.IsValid()) {
+ writer.Write("BootNet: Running NeKernel...\r");
+ return thread.Start(handover, YES);
+ }
+
+ return kEfiFail;
+ } else {
+ constexpr auto kROMSize = 0x200;
+
+ if (inet_out->Length > kROMSize) {
+ writer.Write("BootNet: Not within 512K, won't flash EEPROM.\r");
+ return kEfiFail;
+ }
+
+ writer.Write("BootNet: Programming the flash...\r");
+
+ /// TODO: Program new firmware to EEPROM (if crc and size matches)
+
+ const ATTRIBUTE(unused) UIntPtr kEEPROMStartAddress = 0;
+ const ATTRIBUTE(unused) UInt16 kEEPROMSize = inet_out->Length;
+
+ return kEfiFail;
+ }
+
+ return kEfiFail;
+}
+
+STATIC Void bootnet_read_ip_packet(BOOTNET_INTERNET_HEADER inet,
+ BOOTNET_INTERNET_HEADER** inet_out) {
+ NE_UNUSED(inet);
+
+ kEfiProtocol->Start(kEfiProtocol);
+
+ UInt32 size_inet = sizeof(inet);
+
+ /// Connect to the local BootNet server.
+
+ /// And receive the handshake packet.
+ if (kEfiProtocol->Receive(kEfiProtocol, &size_inet, (UInt32*) &inet.Length, (VoidPtr) &inet,
+ nullptr, nullptr, nullptr) == kEfiOk) {
+ BOOTNET_INTERNET_HEADER* out = nullptr;
+
+ BS->AllocatePool(EfiLoaderData, sizeof(BOOTNET_INTERNET_HEADER) + inet.Length, (VoidPtr*) &out);
+
+ if (out == nullptr) {
+ kEfiProtocol->Stop(kEfiProtocol);
+ kEfiProtocol->Shutdown(kEfiProtocol);
+ return;
+ }
+
+ SetMem(out, 0, sizeof(BOOTNET_INTERNET_HEADER));
+ SetMem(out->Data, 0, inet.Length);
+
+ size_inet = sizeof(BOOTNET_INTERNET_HEADER);
+
+ auto full_size = size_inet + inet.Length;
+
+ /// Ask for it again since we know the full_size variable now.
+ kEfiProtocol->Receive(kEfiProtocol, &size_inet, (UInt32*) &full_size, (VoidPtr) out, nullptr,
+ nullptr, nullptr);
+
+ *inet_out = out;
+ }
+
+ kEfiProtocol->Stop(kEfiProtocol);
+ kEfiProtocol->Shutdown(kEfiProtocol);
+} \ No newline at end of file
diff --git a/src/boot/modules/BootNet/BootNet.h b/src/boot/modules/BootNet/BootNet.h
new file mode 100644
index 00000000..9fe1a186
--- /dev/null
+++ b/src/boot/modules/BootNet/BootNet.h
@@ -0,0 +1,12 @@
+/*
+ * ========================================================
+ *
+ * BootNet
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <FirmwareKit/NeBoot/BootNet.h>
diff --git a/src/boot/modules/BootNet/BootNetStartup.S b/src/boot/modules/BootNet/BootNetStartup.S
new file mode 100644
index 00000000..a5832ee6
--- /dev/null
+++ b/src/boot/modules/BootNet/BootNetStartup.S
@@ -0,0 +1,24 @@
+;; /*
+;; * ========================================================
+;; *
+;; * BootZ
+;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+#ifdef __NE_AMD64__
+.code64
+.intel_syntax noprefix
+#endif
+
+#define kTypeDriver 101
+#define kArchAmd64 122
+#define kHandoverMagic 0xBADCC
+
+.section .ldr
+
+.quad kHandoverMagic
+.word kTypeDriver
+.word 0
+.word kArchAmd64 \ No newline at end of file
diff --git a/src/boot/modules/BootNet/amd64.json b/src/boot/modules/BootNet/amd64.json
new file mode 100644
index 00000000..3d58cbc1
--- /dev/null
+++ b/src/boot/modules/BootNet/amd64.json
@@ -0,0 +1,23 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "../../", "../../../kernel", "../../../", "./"],
+ "sources_path": ["*.cc", "*.S", "../../src/HEL/AMD64/*.cc", "../../src/HEL/AMD64/*.S", "../../src/*.cc"],
+ "output_name": "net.efi",
+ "compiler_flags": [
+ "-nostdlib",
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17,--image-base,0x10000000,-e,BootNetModuleMain"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__BOOTZ__",
+ "__BOOTZ_STANDALONE__",
+ "__NE_AMD64__",
+ "kBootNetVersionHighest=0x0100",
+ "kBootNetVersionLowest=0x0100",
+ "kBootNetEFIVersion=0x0100"
+ ]
+}
diff --git a/src/boot/modules/SysChk/.hgkeep b/src/boot/modules/SysChk/.hgkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/modules/SysChk/.hgkeep
diff --git a/src/boot/modules/SysChk/SysChk.cc b/src/boot/modules/SysChk/SysChk.cc
new file mode 100644
index 00000000..0706d457
--- /dev/null
+++ b/src/boot/modules/SysChk/SysChk.cc
@@ -0,0 +1,41 @@
+/*
+ * ========================================================
+ *
+ * SysChk
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/BootThread.h>
+#include <BootKit/HW/SATA.h>
+#include <FirmwareKit/EFI.h>
+#include <FirmwareKit/EFI/API.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+#include <KernelKit/PEF.h>
+#include <NeKit/Macros.h>
+#include <NeKit/Ref.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+// Makes the compiler shut up.
+#ifndef kMachineModel
+#define kMachineModel "OS"
+#endif // !kMachineModel
+
+EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) {
+ fw_init_efi((EfiSystemTable*) handover->f_FirmwareCustomTables[Kernel::HEL::kHandoverTableST]);
+
+#if defined(__ATA_PIO__)
+ Boot::BDiskFormatFactory<BootDeviceATA> partition_factory;
+#elif defined(__AHCI__)
+ Boot::BDiskFormatFactory<BootDeviceSATA> partition_factory;
+#endif
+
+ if (partition_factory.IsPartitionValid()) return kEfiOk;
+
+ return partition_factory.Format(kMachineModel);
+}
diff --git a/src/boot/modules/SysChk/SysChkStartup.S b/src/boot/modules/SysChk/SysChkStartup.S
new file mode 100644
index 00000000..a5832ee6
--- /dev/null
+++ b/src/boot/modules/SysChk/SysChkStartup.S
@@ -0,0 +1,24 @@
+;; /*
+;; * ========================================================
+;; *
+;; * BootZ
+;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+#ifdef __NE_AMD64__
+.code64
+.intel_syntax noprefix
+#endif
+
+#define kTypeDriver 101
+#define kArchAmd64 122
+#define kHandoverMagic 0xBADCC
+
+.section .ldr
+
+.quad kHandoverMagic
+.word kTypeDriver
+.word 0
+.word kArchAmd64 \ No newline at end of file
diff --git a/src/boot/modules/SysChk/amd64-ahci-epm.json b/src/boot/modules/SysChk/amd64-ahci-epm.json
new file mode 100644
index 00000000..8ce9bfd8
--- /dev/null
+++ b/src/boot/modules/SysChk/amd64-ahci-epm.json
@@ -0,0 +1,42 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "../../", "../../../kernel", "../../../", "./"],
+ "sources_path": [
+ "*.cc",
+ "*.S",
+ "../../src/HEL/AMD64/BootSATA.cc",
+ "../../src/HEL/AMD64/BootPlatform.cc",
+ "../../src/HEL/AMD64/BootAPI.S",
+ "../../src/BootTextWriter.cc",
+ "../../src/BootSupport.cc",
+ "../../src/New+Delete.cc",
+ "../../../kernel/HALKit/AMD64/PCI/*.cc",
+ "../../../kernel/HALKit/AMD64/Storage/*.cc",
+ "../../../kernel/src/Storage/*.cc",
+ "../../../kernel/src/Network/*.cc",
+ "../../../kernel/HALKit/AMD64/*.cc",
+ "../../../kernel/HALKit/AMD64/*.s",
+ "../../../kernel/src/*.cc"
+ ],
+ "output_name": "chk.efi",
+ "compiler_flags": [
+ "-nostdlib",
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17,--image-base,0x10000000,-e,SysChkModuleMain"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__NE_AMD64__",
+ "__AHCI__",
+ "__SYSCHK__",
+ "BOOTZ_EPM_SUPPORT",
+ "__NE_VEPM__",
+ "__NE_MODULAR_KERNEL_COMPONENTS__",
+ "kChkVersionHighest=0x0100",
+ "kChkVersionLowest=0x0100",
+ "kChkVersion=0x0100"
+ ]
+}
diff --git a/src/boot/modules/SysChk/amd64-ahci-gpt.json b/src/boot/modules/SysChk/amd64-ahci-gpt.json
new file mode 100644
index 00000000..80bb433e
--- /dev/null
+++ b/src/boot/modules/SysChk/amd64-ahci-gpt.json
@@ -0,0 +1,40 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "../../", "../../../kernel", "../../../", "./"],
+ "sources_path": [
+ "*.cc",
+ "*.S",
+ "../../src/HEL/AMD64/BootSATA.cc",
+ "../../src/HEL/AMD64/BootPlatform.cc",
+ "../../src/HEL/AMD64/BootAPI.S",
+ "../../src/BootTextWriter.cc",
+ "../../src/BootSupport.cc",
+ "../../src/New+Delete.cc",
+ "../../../kernel/HALKit/AMD64/PCI/*.cc",
+ "../../../kernel/HALKit/AMD64/Storage/*.cc",
+ "../../../kernel/src/Storage/*.cc",
+ "../../../kernel/HALKit/AMD64/*.cc",
+ "../../../kernel/HALKit/AMD64/*.s",
+ "../../../kernel/src/*.cc"
+ ],
+ "output_name": "chk.efi",
+ "compiler_flags": [
+ "-nostdlib",
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17,--image-base,0x10000000,-e,SysChkModuleMain"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__NE_AMD64__",
+ "__AHCI__",
+ "__SYSCHK__",
+ "BOOTZ_GPT_SUPPORT",
+ "__NE_MODULAR_KERNEL_COMPONENTS__",
+ "kChkVersionHighest=0x0100",
+ "kChkVersionLowest=0x0100",
+ "kChkVersion=0x0100"
+ ]
+}
diff --git a/src/boot/modules/SysChk/amd64-pio-epm.json b/src/boot/modules/SysChk/amd64-pio-epm.json
new file mode 100644
index 00000000..b1b95d8d
--- /dev/null
+++ b/src/boot/modules/SysChk/amd64-pio-epm.json
@@ -0,0 +1,41 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": [
+ "../",
+ "../../",
+ "../../../kernel",
+ "../../../",
+ "./"
+ ],
+ "sources_path": [
+ "*.cc",
+ "*.S",
+ "../../src/HEL/AMD64/BootATA.cc",
+ "../../src/HEL/AMD64/BootPlatform.cc",
+ "../../src/HEL/AMD64/BootAPI.S",
+ "../../src/BootTextWriter.cc",
+ "../../src/BootSupport.cc",
+ "../../src/New+Delete.cc"
+ ],
+ "output_name": "chk.efi",
+ "compiler_flags": [
+ "-nostdlib",
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17,--image-base,0x10000000,-e,SysChkModuleMain"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__BOOTZ__",
+ "__BOOTZ_STANDALONE__",
+ "__NE_AMD64__",
+ "__ATA_PIO__",
+ "BOOTZ_EPM_SUPPORT",
+ "__NE_VEPM__",
+ "kChkVersionHighest=0x0100",
+ "kChkVersionLowest=0x0100",
+ "kChkVersion=0x0100"
+ ]
+} \ No newline at end of file
diff --git a/src/boot/modules/SysChk/amd64-pio-gpt.json b/src/boot/modules/SysChk/amd64-pio-gpt.json
new file mode 100644
index 00000000..b1a4d38b
--- /dev/null
+++ b/src/boot/modules/SysChk/amd64-pio-gpt.json
@@ -0,0 +1,41 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": [
+ "../",
+ "../../",
+ "../../../kernel",
+ "../../../",
+ "./"
+ ],
+ "sources_path": [
+ "*.cc",
+ "*.S",
+ "../../src/HEL/AMD64/BootATA.cc",
+ "../../src/HEL/AMD64/BootPlatform.cc",
+ "../../src/HEL/AMD64/BootAPI.S",
+ "../../src/BootTextWriter.cc",
+ "../../src/BootSupport.cc",
+ "../../src/New+Delete.cc"
+ ],
+ "output_name": "chk.efi",
+ "compiler_flags": [
+ "-nostdlib",
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17,--image-base,0x10000000,-e,SysChkModuleMain"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__BOOTZ__",
+ "__BOOTZ_STANDALONE__",
+ "__NE_AMD64__",
+ "__ATA_PIO__",
+ "__NE_VEPM__",
+ "BOOTZ_GPT_SUPPORT",
+ "kChkVersionHighest=0x0100",
+ "kChkVersionLowest=0x0100",
+ "kChkVersion=0x0100"
+ ]
+} \ No newline at end of file
diff --git a/src/boot/modules/SysChk/arm64.json b/src/boot/modules/SysChk/arm64.json
new file mode 100644
index 00000000..ad5fde6e
--- /dev/null
+++ b/src/boot/modules/SysChk/arm64.json
@@ -0,0 +1,26 @@
+{
+ "compiler_path": "clang++",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "../../", "../../../kernel", "../../../", "./"],
+ "sources_path": ["*.cc", "*.S", "../../src/HEL/ARM64/*.cc", "../../src/HEL/ARM64/*.S", "../../src/*.cc"],
+ "output_name": "chk.efi",
+ "compiler_flags": [
+ "-ffreestanding",
+ "-nostdlib",
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-fuse-ld=lld",
+ "-Wl,-subsystem:efi_application,-entry:BootloaderMain",
+ "-target aarch64-unknown-windows"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__BOOTZ__",
+ "__BOOTZ_STANDALONE__",
+ "__NE_ARM64__",
+ "kChkVersionHighest=0x0100",
+ "kChkVersionLowest=0x0100",
+ "kChkVersion=0x0100"
+ ]
+}
diff --git a/src/boot/obj/.gitkeep b/src/boot/obj/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/obj/.gitkeep
diff --git a/src/boot/src/.gitkeep b/src/boot/src/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/src/.gitkeep
diff --git a/src/boot/src/BootFileReader.cc b/src/boot/src/BootFileReader.cc
new file mode 100644
index 00000000..a929bb93
--- /dev/null
+++ b/src/boot/src/BootFileReader.cc
@@ -0,0 +1,177 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: FileReader.cc
+ Purpose: New Boot FileReader,
+ Read complete file and store it in a buffer.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/Platform.h>
+#include <BootKit/Protocol.h>
+#include <FirmwareKit/EFI/API.h>
+#include <FirmwareKit/Handover.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+/// @file BootFileReader
+/// @brief Bootloader File reader.
+/// BUGS: 0
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+///
+///
+/// @name BootFileReader class
+/// @brief Reads the file as a blob.
+///
+///
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/***
+ @brief File Reader constructor.
+*/
+Boot::BootFileReader::BootFileReader(const CharacterTypeUTF16* path, EfiHandlePtr ImageHandle) {
+ if (path != nullptr) {
+ SizeT index = 0UL;
+ for (; path[index] != L'\0'; ++index) {
+ mPath[index] = path[index];
+ }
+
+ mPath[index] = 0;
+ }
+
+ /// Load protocols with their GUIDs.
+
+ EFI_GUID guidEfp = EFI_GUID(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID);
+
+ EfiSimpleFilesystemProtocol* efp = nullptr;
+
+ EfiLoadImageProtocol* img = nullptr;
+ EFI_GUID guidImg = EFI_GUID(EFI_LOADED_IMAGE_PROTOCOL_GUID);
+
+ if (BS->HandleProtocol(ImageHandle, &guidImg, (void**) &img) != kEfiOk) {
+ mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r");
+ this->mErrorCode = kNotSupported;
+ }
+
+ if (BS->HandleProtocol(img->DeviceHandle, &guidEfp, (void**) &efp) != kEfiOk) {
+ mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r");
+ this->mErrorCode = kNotSupported;
+ return;
+ }
+
+ /// Start doing disk I/O
+
+ if (efp->OpenVolume(efp, &mRootFs) != kEfiOk) {
+ mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Volume").Write(L"\r");
+ this->mErrorCode = kNotSupported;
+ return;
+ }
+
+ EfiFileProtocol* fileFs = nullptr;
+
+ if (mRootFs->Open(mRootFs, &fileFs, mPath, kEFIFileRead, kEFIReadOnly) != kEfiOk) {
+ mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Path: ").Write(mPath).Write(L"\r");
+ this->mErrorCode = kNotSupported;
+
+ cg_render_string("BootZ: PLEASE RECOVER YOUR NEKERNEL INSTALL.", 40, 10, RGB(0xFF, 0xFF, 0xFF));
+
+ mRootFs->Close(mRootFs);
+
+ return;
+ }
+
+ mSizeFile = 0;
+ mFile = fileFs;
+ mErrorCode = kOperationOkay;
+}
+
+Boot::BootFileReader::~BootFileReader() {
+ if (this->mFile) {
+ this->mFile->Close(this->mFile);
+ this->mFile = nullptr;
+ }
+
+ if (this->mRootFs) {
+ this->mRootFs->Close(this->mRootFs);
+ this->mRootFs = nullptr;
+ }
+
+ if (this->mBlob) {
+ BS->FreePool(this->mBlob);
+ this->mBlob = nullptr;
+ }
+
+ BSetMem(this->mPath, 0, kPathLen);
+}
+
+/**
+ @brief Reads all of the file into a buffer.
+ @param **readUntil** size of file
+ @param **chunkToRead** chunk to read each time.
+*/
+Void Boot::BootFileReader::ReadAll(SizeT readUntil, SizeT chunkToRead, UIntPtr out_address) {
+ UInt32 szInfo = sizeof(EfiFileInfo);
+
+ EfiFileInfo newPtrInfo{};
+
+ EFI_GUID kFileInfoGUID = EFI_FILE_INFO_GUID;
+
+ if (mFile->GetInfo(mFile, &kFileInfoGUID, &szInfo, &newPtrInfo) == kEfiOk) {
+ readUntil = newPtrInfo.FileSize;
+ mWriter.Write(L"BootZ: File size: ").Write(readUntil).Write("\r");
+ }
+
+ if (readUntil == 0) {
+ mErrorCode = kNotSupported;
+ return;
+ }
+
+ if (mBlob == nullptr) {
+ if (!out_address) {
+ if (auto err = BS->AllocatePool(EfiLoaderCode, readUntil, (VoidPtr*) &mBlob) != kEfiOk) {
+ mWriter.Write(L"*** error: ").Write(err).Write(L" ***\r");
+ Boot::ThrowError(L"OutOfMemory", L"Out of memory.");
+ }
+ } else {
+ mBlob = (VoidPtr) out_address;
+ }
+ }
+
+ mWriter.Write(L"*** Bytes to read: ").Write(readUntil).Write(L" ***\r");
+
+ UInt64 bufSize = chunkToRead;
+ UInt64 szCnt = 0UL;
+
+ while (szCnt < readUntil) {
+ auto res = mFile->Read(mFile, &bufSize, (VoidPtr) (&((Char*) mBlob)[szCnt]));
+
+ szCnt += bufSize;
+
+ if (res == kBufferTooSmall) {
+ bufSize = chunkToRead;
+ }
+ }
+
+ mSizeFile = szCnt;
+ mErrorCode = kOperationOkay;
+}
+
+/// @brief error code getter.
+/// @return the error code.
+Int32& Boot::BootFileReader::Error() {
+ return mErrorCode;
+}
+
+/// @brief blob getter.
+/// @return the blob.
+VoidPtr Boot::BootFileReader::Blob() {
+ return mBlob;
+}
+
+/// @breif Size getter.
+/// @return the size of the file.
+UInt64& Boot::BootFileReader::Size() {
+ return mSizeFile;
+}
diff --git a/src/boot/src/BootString.cc b/src/boot/src/BootString.cc
new file mode 100644
index 00000000..6dadda3f
--- /dev/null
+++ b/src/boot/src/BootString.cc
@@ -0,0 +1,81 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: BootString.cc
+ Purpose: BootZ string library
+
+ Revision History:
+
+
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/Platform.h>
+#include <BootKit/Protocol.h>
+
+/// BUGS: 0
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Kernel::SizeT Boot::BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src,
+ const Kernel::SizeT len) {
+ if (!dest || !src) return 0;
+
+ SizeT index = 0UL;
+ for (; index < len; ++index) {
+ dest[index] = src[index];
+ }
+
+ return index;
+}
+
+Kernel::SizeT Boot::BStrLen(const CharacterTypeUTF16* ptr) {
+ if (!ptr) return 0;
+
+ Kernel::SizeT cnt = 0;
+
+ while (*ptr != (CharacterTypeUTF16) 0) {
+ ++ptr;
+ ++cnt;
+ }
+
+ return cnt;
+}
+
+Kernel::SizeT Boot::BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte,
+ const Kernel::SizeT len) {
+ if (!src) return 0;
+
+ Kernel::SizeT cnt = 0UL;
+
+ while (*src != 0) {
+ if (cnt > len) break;
+
+ *src = byte;
+ ++src;
+
+ ++cnt;
+ }
+
+ return cnt;
+}
+
+Kernel::SizeT Boot::BSetMem(CharacterTypeASCII* src, const CharacterTypeASCII byte,
+ const Kernel::SizeT len) {
+ if (!src) return 0;
+
+ Kernel::SizeT cnt = 0UL;
+
+ while (*src != 0) {
+ if (cnt > len) break;
+
+ *src = byte;
+ ++src;
+
+ ++cnt;
+ }
+
+ return cnt;
+}
diff --git a/src/boot/src/BootSupport.cc b/src/boot/src/BootSupport.cc
new file mode 100644
index 00000000..24e09094
--- /dev/null
+++ b/src/boot/src/BootSupport.cc
@@ -0,0 +1,128 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/Support.h>
+#include <FirmwareKit/EFI/API.h>
+#include <FirmwareKit/EFI/EFI.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+
+#ifdef __BOOTZ_STANDALONE__
+
+/// @brief memset definition in C++.
+/// @param dst destination pointer.
+/// @param byte value to fill in.
+/// @param len length of of src.
+EXTERN_C VoidPtr memnset(void* dst, int byte, long long unsigned int len,
+ long long unsigned int dst_size) {
+ if (!dst || len > dst_size) {
+ // For now, we return nullptr or an error status.
+ return nullptr;
+ }
+ unsigned char* p = (unsigned char*) dst;
+ unsigned char val = (unsigned char) byte;
+ for (size_t i = 0UL; i < len; ++i) {
+ p[i] = val;
+ }
+ return dst;
+}
+
+/// @brief memcpy definition in C++.
+/// @param dst destination pointer.
+/// @param src source pointer.
+/// @param len length of of src.
+EXTERN_C VoidPtr memncpy(void* dst, const void* src, long long unsigned int len,
+ long long unsigned int dst_size) {
+ if (!dst || !src || len > dst_size) {
+ // Similar to memset, this is a critical failure.
+ return nullptr;
+ }
+ unsigned char* d = (unsigned char*) dst;
+ const unsigned char* s = (const unsigned char*) src;
+ for (size_t i = 0UL; i < len; ++i) {
+ d[i] = s[i];
+ }
+ return dst;
+}
+
+/// @brief strlen definition in C++.
+EXTERN_C size_t strnlen(const char* whatToCheck, size_t max_len) {
+ size_t len = 0;
+ while (len < max_len && whatToCheck[len] != '\0') {
+ ++len;
+ }
+ return len;
+}
+
+/// @brief strcmp definition in C++.
+EXTERN_C int strncmp(const char* whatToCheck, const char* whatToCheckRight, size_t max_len) {
+ size_t i = 0;
+ while (i < max_len && whatToCheck[i] == whatToCheckRight[i]) {
+ if (whatToCheck[i] == '\0') return 0;
+ ++i;
+ }
+ if (i == max_len) {
+ return 0;
+ }
+ return (unsigned char) whatToCheck[i] - (unsigned char) whatToCheckRight[i];
+}
+
+/// @brief something specific to the Microsoft's ABI, When the stack grows too big.
+EXTERN_C void ___chkstk_ms(void) {}
+
+/// @note GCC expects them to be here.
+
+/// @brief memset definition in C++.
+/// @param dst destination pointer.
+/// @param byte value to fill in.
+/// @param len length of of src.
+EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) {
+ for (size_t i = 0UL; i < len; ++i) {
+ ((int*) dst)[i] = byte;
+ }
+
+ return dst;
+}
+
+/// @brief memcpy definition in C++.
+/// @param dst destination pointer.
+/// @param src source pointer.
+/// @param len length of of src.
+EXTERN_C VoidPtr memcpy(void* dst, const void* src, long long unsigned int len) {
+ for (size_t i = 0UL; i < len; ++i) {
+ ((int*) dst)[i] = ((int*) src)[i];
+ }
+
+ return dst;
+}
+
+/// @brief strlen definition in C++.
+EXTERN_C size_t strlen(const char* whatToCheck) {
+ SizeT len = 0;
+
+ while (whatToCheck[len] != 0) {
+ ++len;
+ }
+
+ return len;
+}
+
+/// @brief strcmp definition in C++.
+EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) {
+ SizeT len = 0;
+
+ while (whatToCheck[len] == whatToCheckRight[len]) {
+ if (whatToCheck[len] == 0) return 0;
+
+ ++len;
+ }
+
+ return len;
+}
+
+#endif
diff --git a/src/boot/src/BootTextWriter.cc b/src/boot/src/BootTextWriter.cc
new file mode 100644
index 00000000..0b53e845
--- /dev/null
+++ b/src/boot/src/BootTextWriter.cc
@@ -0,0 +1,157 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: BootTextWriter.cc
+ Purpose: BootZ string library
+
+ Revision History:
+
+
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/Platform.h>
+#include <BootKit/Protocol.h>
+#include <FirmwareKit/EFI/API.h>
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// BUGS: 0 ///
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+@brief puts wrapper over EFI ConOut.
+*/
+Boot::BootTextWriter& Boot::BootTextWriter::Write(const CharacterTypeUTF16* str) {
+ NE_UNUSED(str);
+
+#ifdef __DEBUG__
+ if (!str || *str == 0) return *this;
+
+ CharacterTypeUTF16 strTmp[2];
+ strTmp[1] = 0;
+
+ for (size_t i = 0; str[i] != 0; i++) {
+ if (str[i] == '\r') {
+ strTmp[0] = str[i];
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+
+ strTmp[0] = '\n';
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+ } else {
+ strTmp[0] = str[i];
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+ }
+ }
+#endif // ifdef __DEBUG__
+
+ return *this;
+}
+
+/// @brief UTF-8 equivalent of Write (UTF-16).
+/// @param str the input string.
+Boot::BootTextWriter& Boot::BootTextWriter::Write(const Char* str) {
+ NE_UNUSED(str);
+
+#ifdef __DEBUG__
+ if (!str || *str == 0) return *this;
+
+ CharacterTypeUTF16 strTmp[2];
+ strTmp[1] = 0;
+
+ for (size_t i = 0; str[i] != 0; i++) {
+ if (str[i] == '\r') {
+ strTmp[0] = str[i];
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+
+ strTmp[0] = '\n';
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+ } else {
+ strTmp[0] = str[i];
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+ }
+ }
+#endif // ifdef __DEBUG__
+
+ return *this;
+}
+
+Boot::BootTextWriter& Boot::BootTextWriter::Write(const UChar* str) {
+ NE_UNUSED(str);
+
+#ifdef __DEBUG__
+ if (!str || *str == 0) return *this;
+
+ CharacterTypeUTF16 strTmp[2];
+ strTmp[1] = 0;
+
+ for (size_t i = 0; str[i] != 0; i++) {
+ if (str[i] == '\r') {
+ strTmp[0] = str[i];
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+
+ strTmp[0] = '\n';
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+ } else {
+ strTmp[0] = str[i];
+ ST->ConOut->OutputString(ST->ConOut, strTmp);
+ }
+ }
+#endif // ifdef __DEBUG__
+
+ return *this;
+}
+
+/**
+@brief putc wrapper over EFI ConOut.
+*/
+Boot::BootTextWriter& Boot::BootTextWriter::WriteCharacter(CharacterTypeUTF16 c) {
+ NE_UNUSED(c);
+
+#ifdef __DEBUG__
+ EfiCharType str[2];
+
+ str[0] = c;
+ str[1] = 0;
+ ST->ConOut->OutputString(ST->ConOut, str);
+#endif // ifdef __DEBUG__
+
+ return *this;
+}
+
+Boot::BootTextWriter& Boot::BootTextWriter::Write(const UInt64& x) {
+ NE_UNUSED(x);
+
+#ifdef __DEBUG__
+ this->_Write(x);
+ this->Write("h");
+#endif // ifdef __DEBUG__
+
+ return *this;
+}
+
+Boot::BootTextWriter& Boot::BootTextWriter::_Write(const UInt64& x) {
+ NE_UNUSED(x);
+
+#ifdef __DEBUG__
+ UInt64 y = (x > 0 ? x : -x) / 16;
+ UInt64 h = (x > 0 ? x : -x) % 16;
+
+ if (y) this->_Write(y);
+
+ /* fail if the hex number is not base-16 */
+ if (h > 16) {
+ this->WriteCharacter('?');
+ return *this;
+ }
+
+ if (y == ~0UL) y = -y;
+
+ const char kNumberList[] = "0123456789ABCDEF";
+
+ this->WriteCharacter(kNumberList[h]);
+#endif // ifdef __DEBUG__
+
+ return *this;
+}
diff --git a/src/boot/src/BootThread.cc b/src/boot/src/BootThread.cc
new file mode 100644
index 00000000..e3ca9221
--- /dev/null
+++ b/src/boot/src/BootThread.cc
@@ -0,0 +1,216 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/BootThread.h>
+#include <BootKit/Support.h>
+#include <FirmwareKit/EFI/API.h>
+
+#include <CFKit/Utils.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+#include <KernelKit/PEF.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+#define kBootThreadSz mib_cast(16)
+
+/// @brief External boot services symbol.
+EXTERN EfiBootServices* BS;
+
+/// @note BootThread doesn't parse the symbols so doesn't nullify them, .bss is though.
+
+namespace Boot {
+EXTERN_C Int32 rt_jump_to_address(VoidPtr code, HEL::BootInfoHeader* handover, UInt8* stack);
+
+BootThread::BootThread(VoidPtr blob) : fStartAddress(nullptr), fBlob(blob) {
+ // detect the format.
+ const Char* blob_bytes = reinterpret_cast<char*>(fBlob);
+
+ BootTextWriter writer;
+
+ if (!blob_bytes) {
+ // failed to provide a valid pointer.
+ return;
+ }
+
+ if (blob_bytes[0] == kMagMz0 && blob_bytes[1] == kMagMz1) {
+ LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header(blob_bytes);
+ LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header(blob_bytes);
+
+ if (!header_ptr || !opt_header_ptr) return;
+
+#ifdef __NE_AMD64__
+ if (header_ptr->Machine != kPeMachineAMD64 || header_ptr->Signature != kPeSignature) {
+ writer.Write("BootZ: Not a PE32+ executable.\r");
+ return;
+ }
+#elif defined(__NE_ARM64__)
+ if (header_ptr->Machine != kPeMachineARM64 || header_ptr->Signature != kPeSignature) {
+ writer.Write("BootZ: Not a PE32+ executable.\r");
+ return;
+ }
+#endif // __NE_AMD64__ || __NE_ARM64__
+
+ writer.Write("BootZ: PE32+ executable detected (NeKernel Subsystem).\r");
+
+ auto numSecs = header_ptr->NumberOfSections;
+
+ writer.Write("BootZ: Major Linker Ver: ").Write(opt_header_ptr->MajorLinkerVersion).Write("\r");
+ writer.Write("BootZ: Minor Linker Ver: ").Write(opt_header_ptr->MinorLinkerVersion).Write("\r");
+ writer.Write("BootZ: Major Subsystem Ver: ")
+ .Write(opt_header_ptr->MajorSubsystemVersion)
+ .Write("\r");
+ writer.Write("BootZ: Minor Subsystem Ver: ")
+ .Write(opt_header_ptr->MinorSubsystemVersion)
+ .Write("\r");
+ writer.Write("BootZ: Magic: ").Write(header_ptr->Signature).Write("\r");
+
+ EfiPhysicalAddress loadStartAddress = opt_header_ptr->ImageBase;
+
+ writer.Write("BootZ: Image-Base: ").Write(loadStartAddress).Write("\r");
+
+ fStack = new UInt8[kBootThreadSz];
+
+ if (!fStack) {
+ writer.Write("BootZ: Unable to allocate stack.\r");
+ return;
+ }
+
+ LDR_SECTION_HEADER_PTR sectPtr =
+ (LDR_SECTION_HEADER_PTR) (((Char*) opt_header_ptr) + header_ptr->SizeOfOptionalHeader);
+
+ constexpr auto sectionForCode = ".text";
+ constexpr auto sectionForBootZ = ".ldr";
+
+ for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) {
+ LDR_SECTION_HEADER_PTR sect = &sectPtr[sectIndex];
+
+ auto sz = sect->VirtualSize;
+
+ if (sect->SizeOfRawData > 0) sz = sect->SizeOfRawData;
+
+ SetMem((VoidPtr) (loadStartAddress + sect->VirtualAddress), 0, sz);
+
+ if (sect->SizeOfRawData > 0) {
+ CopyMem((VoidPtr) (loadStartAddress + sect->VirtualAddress),
+ (VoidPtr) ((UIntPtr) fBlob + sect->PointerToRawData), sect->SizeOfRawData);
+ }
+
+ if (StrCmp(sectionForCode, sect->Name) == 0) {
+ fStartAddress =
+ (VoidPtr) ((UIntPtr) loadStartAddress + opt_header_ptr->AddressOfEntryPoint);
+ writer.Write("BootZ: Executable entry address: ")
+ .Write((UIntPtr) fStartAddress)
+ .Write("\r");
+
+ /// @note .text region shall be marked as executable on ARM.
+
+#ifdef __NE_ARM64__
+
+#endif
+ } else if (StrCmp(sectionForBootZ, sect->Name) == 0) {
+ struct HANDOVER_INFORMATION_STUB {
+ UInt64 HandoverMagic;
+ UInt32 HandoverType;
+ UInt32 HandoverPad;
+ UInt32 HandoverArch;
+ }* handover_struc =
+ (struct HANDOVER_INFORMATION_STUB*) ((UIntPtr) fBlob + sect->PointerToRawData);
+
+ if (handover_struc->HandoverMagic != kHandoverMagic) {
+#ifdef __NE_AMD64__
+ if (handover_struc->HandoverArch != HEL::kArchAMD64) {
+ writer.Write("BootZ: Not an handover header, bad CPU...\r");
+ }
+#elif defined(__NE_ARM64__)
+ if (handover_struc->HandoverArch != HEL::kArchARM64) {
+ writer.Write("BootZ: Not an handover header, bad CPU...\r");
+ }
+#endif
+
+ writer.Write("BootZ: Not an handover header...\r");
+ ::Boot::Stop();
+ }
+ }
+
+ writer.Write("BootZ: Raw offset: ")
+ .Write(sect->PointerToRawData)
+ .Write(" of ")
+ .Write(sect->Name)
+ .Write("\r");
+
+ CopyMem((VoidPtr) (loadStartAddress + sect->VirtualAddress),
+ (VoidPtr) ((UIntPtr) fBlob + sect->PointerToRawData), sect->SizeOfRawData);
+ }
+ } else if (blob_bytes[0] == kPefMagic[0] && blob_bytes[1] == kPefMagic[1] &&
+ blob_bytes[2] == kPefMagic[2] && blob_bytes[3] == kPefMagic[3]) {
+ // ========================================= //
+ // PEF executable has been detected.
+ // ========================================= //
+
+ fStartAddress = nullptr;
+
+ writer.Write("BootZ: PEF executable detected, won't load it.\r");
+ writer.Write("BootZ: note: PEF executables aren't supported for now.\r");
+ } else {
+ writer.Write("BootZ: Invalid Executable.\r");
+ }
+}
+
+/// @note handover header has to be valid!
+Int32 BootThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) {
+ if (!fStartAddress) {
+ return kEfiFail;
+ }
+
+ if (!handover) {
+ return kEfiFail;
+ }
+
+ fHandover = handover;
+
+ BootTextWriter writer;
+
+ writer.Write("BootZ: Starting: ").Write(fBlobName).Write("\r");
+ writer.Write("BootZ: Handover address: ").Write((UIntPtr) fHandover).Write("\r");
+
+ if (own_stack) {
+ writer.Write("BootZ: Using it's own stack.\r");
+ writer.Write("BootZ: Stack address: ").Write((UIntPtr) &fStack[kBootThreadSz - 1]).Write("\r");
+ writer.Write("BootZ: Stack size: ").Write(kBootThreadSz).Write("\r");
+
+ fHandover->f_StackTop = &fStack[kBootThreadSz - 1];
+ fHandover->f_StackSz = kBootThreadSz;
+
+ auto ret = rt_jump_to_address(fStartAddress, fHandover, &fStack[kBootThreadSz - 1]);
+
+ // we don't need the stack anymore.
+
+ delete[] fStack;
+ fStack = nullptr;
+
+ return ret;
+ } else {
+ writer.Write("BootZ: Using the bootloader's stack.\r");
+
+ return reinterpret_cast<HEL::HandoverProc>(fStartAddress)(fHandover);
+ }
+
+ return kEfiFail;
+}
+
+const Char* BootThread::GetName() {
+ return fBlobName;
+}
+
+Void BootThread::SetName(const Char* name) {
+ CopyMem(fBlobName, name, StrLen(name));
+}
+
+bool BootThread::IsValid() {
+ return fStartAddress != nullptr;
+}
+} // namespace Boot \ No newline at end of file
diff --git a/src/boot/src/HEL/64X000/.gitkeep b/src/boot/src/HEL/64X000/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/src/HEL/64X000/.gitkeep
diff --git a/src/boot/src/HEL/64X000/BootCB.S b/src/boot/src/HEL/64X000/BootCB.S
new file mode 100644
index 00000000..223a697e
--- /dev/null
+++ b/src/boot/src/HEL/64X000/BootCB.S
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+.section .boot_hdr
+.align 4
+
+/* BootZ boot header begin for a 64x000 Kernel. */
+
+boot_hdr_mag:
+ .ascii "CB"
+boot_hdr_name:
+ // it has to match ten bytes.
+ .asciz "bootz\0\0\0"
+boot_hdr_ver:
+ .word 0x104
+boot_hdr_proc:
+ .long bootloader_start
+
+/* BootZ boot header end */
+
+.extern bootloader_main
+.extern bootloader_stack
+
+.globl bootloader_start
+bootloader_start:
+ psh 4 /* real address of .Laddr */
+ ldi 0,(bootloader_stack-bootloader_start)(4) /* stack address location */
+ mv 19,0 /* use user defined stack */
+ jrl
+
+ bl bootloader_main
+ blr
diff --git a/src/boot/src/HEL/AMD64/BootAPI.S b/src/boot/src/HEL/AMD64/BootAPI.S
new file mode 100644
index 00000000..33c1f5d3
--- /dev/null
+++ b/src/boot/src/HEL/AMD64/BootAPI.S
@@ -0,0 +1,122 @@
+.global rt_jump_to_address
+.global rt_reset_hardware
+
+.data
+
+.global kApicBaseAddress
+
+kApicBaseAddress:
+ .long 0
+
+.text
+
+.intel_syntax noprefix
+
+.global hal_load_idt
+
+hal_load_idt:
+ ret
+
+.global sched_jump_to_task
+
+sched_jump_to_task:
+ ret
+
+/**
+ @brief this function setups a stack and then jumps to
+ a function */
+rt_jump_to_address:
+ mov rbx, rcx
+ mov rcx, rdx
+ push rbx
+ push rdx
+ mov rsp, r8
+ push rax
+ jmp rbx
+
+ pop rdx
+ pop rbx
+ pop rax
+
+ ret
+
+rt_reset_hardware:
+ /* dont raise any interrupts. (except ofc NMIs.) */
+ cli
+ /* remap PIC */
+wait_gate1:
+ in al,0x64
+ and al,2
+ jnz wait_gate1
+ mov al,0x0D1
+ out 0x64,al
+wait_gate2:
+ in al,0x64
+ and al,2
+ jnz wait_gate2
+ mov al,0x0FE
+ out 0x60,al
+
+ /* trigger triple fault, by writing to cr4 */
+
+ mov rax, 0
+ lidt [rax]
+
+reset_wait:
+ jmp reset_wait
+
+.global boot_write_cr3
+.global boot_read_cr3
+
+boot_read_cr3:
+ mov rax, cr3
+ ret
+
+boot_write_cr3:
+ mov cr3, rcx
+ ret
+
+.section .text
+
+.extern rt_wait_400ns
+
+.global rt_out8
+.global rt_out16
+.global rt_out32
+
+.global rt_in8
+.global rt_in16
+.global rt_in32
+
+rt_out8:
+ mov al, dl
+ mov dx, cx
+ out dx, al
+ ret
+
+rt_out16:
+ mov ax, dx
+ mov dx, cx
+ out dx, ax
+ ret
+
+rt_out32:
+ mov eax, edx
+ mov edx, ecx
+ out dx, eax
+ ret
+
+rt_in8:
+ mov dx, cx
+ in al, dx
+ ret
+
+rt_in16:
+ mov edx, ecx
+ in ax, dx
+ ret
+
+rt_in32:
+ mov rdx, rcx
+ in eax, dx
+ ret \ No newline at end of file
diff --git a/src/boot/src/HEL/AMD64/BootATA.cc b/src/boot/src/HEL/AMD64/BootATA.cc
new file mode 100644
index 00000000..02051471
--- /dev/null
+++ b/src/boot/src/HEL/AMD64/BootATA.cc
@@ -0,0 +1,269 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss/Symphony Corp, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/**
+ * @file BootATA.cc
+ * @author Amlal El Mahrouss (amlal@nekernel.org)
+ * @brief ATA driver.
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) Amlal El Mahrouss
+ *
+ */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/HW/ATA.h>
+#include <FirmwareKit/EFI.h>
+
+#define kATADataLen (256)
+
+/// bugs: 0
+
+using namespace Boot;
+
+static Boolean kATADetected = false;
+static UInt16 kATAData[kATADataLen] = {0};
+
+Boolean boot_ata_detected(Void);
+
+STATIC Boolean boot_ata_wait_io(UInt16 IO) {
+ for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS);
+
+ATAWaitForIO_Retry:
+ auto status_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry;
+
+ATAWaitForIO_Retry2:
+ status_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if (status_rdy & ATA_SR_ERR) return false;
+
+ if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2;
+
+ return true;
+}
+
+Void boot_ata_select(UInt16 Bus) {
+ if (Bus == ATA_PRIMARY_IO)
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL);
+ else
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL);
+}
+
+Boolean boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) {
+ NE_UNUSED(Drive);
+
+ if (boot_ata_detected()) return true;
+
+ BootTextWriter writer;
+
+ UInt16 IO = Bus;
+
+ boot_ata_select(IO);
+
+ // Bus init, NEIN bit.
+ rt_out8(IO + ATA_REG_NEIN, 1);
+
+ // identify until it's good.
+ATAInit_Retry:
+ auto status_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if (status_rdy & ATA_SR_ERR) {
+ writer.Write(L"VMBoot: ATA: Not an IDE based drive.\r");
+
+ return false;
+ }
+
+ if ((status_rdy & ATA_SR_BSY)) goto ATAInit_Retry;
+
+ boot_ata_select(IO);
+
+ rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
+
+ /// fetch serial info
+ /// model, speed, number of sectors...
+
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
+ ;
+
+ for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) {
+ kATAData[indexData] = rt_in16(IO + ATA_REG_DATA);
+ }
+
+ OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary;
+
+ OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE;
+
+ return true;
+}
+
+Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz,
+ SizeT Size) {
+ Lba /= SectorSz;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ boot_ata_wait_io(IO);
+ boot_ata_select(IO);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
+
+ rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
+
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
+ ;
+
+ for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) {
+ boot_ata_wait_io(IO);
+
+ auto in = rt_in16(IO + ATA_REG_DATA);
+
+ Buf[IndexOff] = in & 0xFF;
+ Buf[IndexOff + 1] = (in >> 8) & 0xFF;
+ boot_ata_wait_io(IO);
+ }
+}
+
+Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz,
+ SizeT Size) {
+ Lba /= SectorSz;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ boot_ata_wait_io(IO);
+ boot_ata_select(IO);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz));
+
+ rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
+
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
+ ;
+
+ for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) {
+ boot_ata_wait_io(IO);
+
+ UInt8 low = (UInt8) Buf[IndexOff];
+ UInt8 high = (IndexOff + 1 < Size) ? (UInt8) Buf[IndexOff + 1] : 0;
+ UInt16 packed = (high << 8) | low;
+
+ rt_out16(IO + ATA_REG_DATA, packed);
+
+ boot_ata_wait_io(IO);
+ }
+
+ boot_ata_wait_io(IO);
+}
+
+/// @check is ATA detected?
+Boolean boot_ata_detected(Void) {
+ return kATADetected;
+}
+
+/***
+ *
+ *
+ * @brief ATA Device class.
+ *
+ *
+ */
+
+/**
+ * @brief ATA Device constructor.
+ * @param void none.
+ */
+BootDeviceATA::BootDeviceATA() noexcept {
+ if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, this->Leak().mMaster) ||
+ boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, this->Leak().mMaster)) {
+ kATADetected = true;
+ }
+}
+/**
+ * @brief Is ATA detected?
+ */
+BootDeviceATA::operator bool() {
+ return boot_ata_detected();
+}
+
+/**
+ @brief Read Buf from disk
+ @param Sz Sector size
+ @param Buf buffer
+*/
+BootDeviceATA& BootDeviceATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) {
+ if (!boot_ata_detected()) {
+ Leak().mErr = true;
+ return *this;
+ }
+
+ this->Leak().mErr = false;
+
+ if (!Buf || SectorSz < 1) return *this;
+
+ boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz,
+ this->Leak().mSize);
+
+ return *this;
+}
+
+/**
+ @brief Write Buf into disk
+ @param Sz Sector size
+ @param Buf buffer
+*/
+BootDeviceATA& BootDeviceATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) {
+ if (!boot_ata_detected()) {
+ Leak().mErr = true;
+ return *this;
+ }
+
+ Leak().mErr = false;
+
+ if (!Buf || SectorSz < 1 || this->Leak().mSize < 1) {
+ Leak().mErr = true;
+ return *this;
+ }
+
+ boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz,
+ this->Leak().mSize);
+
+ return *this;
+}
+
+/**
+ * @brief ATA trait getter.
+ * @return BootDeviceATA::ATATrait& the drive config.
+ */
+BootDeviceATA::ATATrait& BootDeviceATA::Leak() {
+ return mTrait;
+}
+
+/***
+ @brief Getter, gets the number of sectors inside the drive.
+*/
+SizeT BootDeviceATA::GetSectorsCount() noexcept {
+ return (kATAData[61] << 16) | kATAData[60];
+}
+
+SizeT BootDeviceATA::GetDiskSize() noexcept {
+ return this->GetSectorsCount() * BootDeviceATA::kSectorSize;
+}
diff --git a/src/boot/src/HEL/AMD64/BootEFI.cc b/src/boot/src/HEL/AMD64/BootEFI.cc
new file mode 100644
index 00000000..331ded5f
--- /dev/null
+++ b/src/boot/src/HEL/AMD64/BootEFI.cc
@@ -0,0 +1,257 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/BootThread.h>
+#include <FirmwareKit/EFI.h>
+#include <FirmwareKit/EFI/API.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+#include <KernelKit/PEF.h>
+#include <NeKit/Macros.h>
+#include <NeKit/Ref.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+/** Graphics related. */
+
+STATIC EfiGraphicsOutputProtocol* kGop = nullptr;
+STATIC UInt16 kGopStride = 0U;
+STATIC EFI_GUID kGopGuid;
+
+/** Related to jumping to the reset vector. */
+
+EXTERN_C Void rt_reset_hardware();
+
+EXTERN_C Kernel::VoidPtr boot_read_cr3(); // @brief Page directory inside cr3 register.
+
+/**
+ @brief Finds and stores the GOP object.
+*/
+STATIC Bool boot_init_fb() noexcept {
+ kGopGuid = EFI_GUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID);
+ kGop = nullptr;
+
+ if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*) &kGop) != kEfiOk) return No;
+
+ kGopStride = 4;
+
+ return Yes;
+}
+
+EFI_GUID kEfiGlobalNamespaceVarGUID = {
+ 0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C}};
+
+/// @brief BootloaderMain EFI entrypoint.
+/// @param image_handle Handle of this image.
+/// @param sys_table The system table of it.
+/// @return nothing, never returns.
+EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTable* sys_table) {
+ fw_init_efi(sys_table); ///! Init the EFI library.
+
+ ST->ConOut->ClearScreen(sys_table->ConOut);
+ ST->ConOut->SetAttribute(sys_table->ConOut, kEFIYellow);
+
+ ST->BootServices->SetWatchdogTimer(0, 0, 0, nullptr);
+ ST->ConOut->EnableCursor(ST->ConOut, false);
+
+ HEL::BootInfoHeader* handover_hdr = new HEL::BootInfoHeader();
+
+ UInt32 map_key = 0;
+ UInt32 size_struct_ptr = sizeof(EfiMemoryDescriptor);
+ EfiMemoryDescriptor* struct_ptr = nullptr;
+ UInt32 sz_desc = sizeof(EfiMemoryDescriptor);
+ UInt32 rev_desc = 0;
+
+ Boot::BootTextWriter writer;
+
+ if (!boot_init_fb()) {
+ writer.Write("BootZ: Invalid Framebuffer, can't boot to NeKernel.\r");
+ Boot::Stop();
+ }
+
+ for (SizeT index_vt = 0; index_vt < sys_table->NumberOfTableEntries; ++index_vt) {
+ Char* vendor_table =
+ reinterpret_cast<Char*>(sys_table->ConfigurationTable[index_vt].VendorTable);
+
+ // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...)
+ if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && vendor_table[2] == 'D' &&
+ vendor_table[3] == ' ' && vendor_table[4] == 'P' && vendor_table[5] == 'T' &&
+ vendor_table[6] == 'R' && vendor_table[7] == ' ') {
+ handover_hdr->f_HardwareTables.f_VendorPtr = (VoidPtr) vendor_table;
+ break;
+ }
+ }
+
+ // ------------------------------------------ //
+ // draw background color.
+ // ------------------------------------------ //
+
+ handover_hdr->f_GOP.f_The = kGop->Mode->FrameBufferBase;
+ handover_hdr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution;
+ handover_hdr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution;
+ handover_hdr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine;
+ handover_hdr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat;
+ handover_hdr->f_GOP.f_Size = kGop->Mode->FrameBufferSize;
+
+ // ------------------------------------------- //
+ // Grab MP services, extended to runtime. //
+ // ------------------------------------------- //
+
+ EFI_GUID guid_mp = EFI_GUID(EFI_MP_SERVICES_PROTOCOL_GUID);
+ EfiMpServicesProtocol* mp = nullptr;
+
+ BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast<VoidPtr*>(&mp));
+
+ handover_hdr->f_HardwareTables.f_MpPtr = reinterpret_cast<VoidPtr>(mp);
+
+ kHandoverHeader = handover_hdr;
+
+ FB::cg_clear_video();
+
+ UInt32 cnt_enabled = 0;
+ UInt32 cnt_disabled = 0;
+
+ if (mp) {
+ mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled);
+ handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1;
+ } else {
+ handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = NO;
+ }
+
+ // Fill handover header now.
+
+ handover_hdr->f_BitMapStart = nullptr; /* Start of bitmap. */
+ handover_hdr->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap in bytes. */
+
+ kHandoverHeader->f_BitMapStart = nullptr; /* Start of bitmap. */
+ kHandoverHeader->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap in bytes. */
+
+ UInt16 trials = 5;
+
+ while (BS->AllocatePool(EfiLoaderData, kHandoverHeader->f_BitMapSize,
+ &kHandoverHeader->f_BitMapStart) != kEfiOk) {
+ --trials;
+
+ if (!trials) {
+ writer.Write("BootZ: Unable to allocate sufficient memory, trying again with 2GB...\r");
+
+ trials = 3;
+
+ kHandoverHeader->f_BitMapSize = kHandoverBitMapSz / 2; /* Size of bitmap in bytes. */
+
+ while (BS->AllocatePool(EfiLoaderData, kHandoverHeader->f_BitMapSize,
+ &kHandoverHeader->f_BitMapStart) != kEfiOk) {
+ --trials;
+
+ if (!trials) {
+ writer.Write("BootZ: Unable to allocate sufficient memory, aborting...\r");
+ Boot::Stop();
+ }
+ }
+ }
+ }
+
+ handover_hdr->f_FirmwareCustomTables[Kernel::HEL::kHandoverTableBS] = (VoidPtr) BS;
+ handover_hdr->f_FirmwareCustomTables[Kernel::HEL::kHandoverTableST] = (VoidPtr) ST;
+
+ // ------------------------------------------ //
+ // If we succeed in reading the blob, then execute it.
+ // ------------------------------------------ //
+
+ Boot::BootFileReader reader_syschk(L"chk.efi", image_handle);
+ reader_syschk.ReadAll(0);
+
+ Boot::BootThread* syschk_thread = nullptr;
+
+ if (reader_syschk.Blob()) {
+ syschk_thread = new Boot::BootThread(reader_syschk.Blob());
+ syschk_thread->SetName("SysChk");
+
+ syschk_thread->Start(handover_hdr, NO);
+ }
+
+ BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc);
+
+ handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor);
+
+ handover_hdr->f_Magic = kHandoverMagic;
+ handover_hdr->f_Version = kHandoverVersion;
+
+ handover_hdr->f_HardwareTables.f_ImageKey = map_key;
+ handover_hdr->f_HardwareTables.f_ImageHandle = image_handle;
+
+ // Provide fimware vendor name.
+
+ Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, sys_table->FirmwareVendor,
+ handover_hdr->f_FirmwareVendorLen);
+
+ handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor);
+ // Assign to global 'kHandoverHeader'.
+
+ WideChar kernel_path[256U] = L"ne_kernel";
+ UInt32 kernel_path_sz = StrLen("ne_kernel");
+
+ UInt32 sz_ver = sizeof(UInt64);
+ UInt64 ver = KERNEL_VERSION_BCD;
+
+ ST->RuntimeServices->GetVariable(L"/props/kern_ver", kEfiGlobalNamespaceVarGUID, nullptr, &sz_ver,
+ &ver);
+
+ if (ver < KERNEL_VERSION_BCD) {
+ ver = KERNEL_VERSION_BCD;
+
+ ST->RuntimeServices->SetVariable(L"/props/kern_ver", kEfiGlobalNamespaceVarGUID, nullptr,
+ &sz_ver, &ver);
+
+ writer.Write("BootZ: Version has been updated: ").Write(ver).Write("\r");
+
+ if (ST->RuntimeServices->GetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, nullptr,
+ &kernel_path_sz, kernel_path) != kEfiOk) {
+ /// access attributes (in order)
+ /// EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
+ UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004;
+
+ ST->RuntimeServices->SetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, &attr,
+ &kernel_path_sz, kernel_path);
+ }
+ } else {
+ writer.Write("BootZ: Version: ").Write(ver).Write("\r");
+ }
+
+ // boot to kernel, if not bootnet this.
+
+ Boot::BootFileReader reader_kernel(kernel_path, image_handle);
+ reader_kernel.ReadAll(0);
+
+ // ------------------------------------------ //
+ // If we succeed in reading the blob, then execute it.
+ // ------------------------------------------ //
+
+ if (reader_kernel.Blob()) {
+ handover_hdr->f_PageStart = boot_read_cr3();
+
+ auto kernel_thread = Boot::BootThread(reader_kernel.Blob());
+
+ kernel_thread.SetName("NeKernel");
+
+ handover_hdr->f_KernelImage = reader_kernel.Blob();
+ handover_hdr->f_KernelSz = reader_kernel.Size();
+
+ kernel_thread.Start(handover_hdr, YES);
+ }
+
+ Boot::BootFileReader reader_netboot(L"net.efi", image_handle);
+ reader_netboot.ReadAll(0);
+
+ if (!reader_netboot.Blob()) return kEfiFail;
+
+ auto netboot_thread = Boot::BootThread(reader_netboot.Blob());
+ netboot_thread.SetName("BootNet");
+
+ return netboot_thread.Start(handover_hdr, NO);
+}
diff --git a/src/boot/src/HEL/AMD64/BootPlatform.cc b/src/boot/src/HEL/AMD64/BootPlatform.cc
new file mode 100644
index 00000000..7d88b883
--- /dev/null
+++ b/src/boot/src/HEL/AMD64/BootPlatform.cc
@@ -0,0 +1,36 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/Platform.h>
+#include <BootKit/Protocol.h>
+
+#ifdef __BOOTZ_STANDALONE__
+
+using namespace Boot;
+
+EXTERN_C void rt_halt() {
+ asm volatile("hlt");
+}
+
+EXTERN_C void rt_cli() {
+ asm volatile("cli");
+}
+
+EXTERN_C void rt_sti() {
+ asm volatile("sti");
+}
+
+EXTERN_C void rt_cld() {
+ asm volatile("cld");
+}
+
+EXTERN_C void rt_std() {
+ asm volatile("std");
+}
+
+#endif // __BOOTZ_STANDALONE__
diff --git a/src/boot/src/HEL/AMD64/BootSATA.cc b/src/boot/src/HEL/AMD64/BootSATA.cc
new file mode 100644
index 00000000..1364c58b
--- /dev/null
+++ b/src/boot/src/HEL/AMD64/BootSATA.cc
@@ -0,0 +1,76 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/**
+ * @file BootAHCI.cc
+ * @author Amlal El Mahrouss (amlal@nekernel.org)
+ * @brief SATA support for BootZ.
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) Amlal El Mahrouss
+ *
+ */
+
+#include <BootKit/HW/SATA.h>
+#include <BootKit/Platform.h>
+#include <BootKit/Protocol.h>
+
+#include <BootKit/BootKit.h>
+#include <FirmwareKit/EFI.h>
+
+#if defined(__AHCI__) && defined(__SYSCHK__)
+
+using namespace Boot;
+
+/***
+ *
+ *
+ * @brief SATA Device class.
+ *
+ *
+ */
+
+/**
+ * @brief ATA Device constructor.
+ * @param void none.
+ */
+BootDeviceSATA::BootDeviceSATA() noexcept {
+ UInt16 pi = 0u;
+ drv_std_init(pi);
+}
+
+/**
+ @brief Read Buf from disk
+ @param Sz Sector size
+ @param Buf buffer
+*/
+BootDeviceSATA& BootDeviceSATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) {
+ drv_std_read(mTrait.mBase / SectorSz, Buf, SectorSz, mTrait.mSize);
+
+ return *this;
+}
+
+/**
+ @brief Write Buf into disk
+ @param Sz Sector size
+ @param Buf buffer
+*/
+BootDeviceSATA& BootDeviceSATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) {
+ drv_std_write(mTrait.mBase / SectorSz, Buf, SectorSz, mTrait.mSize);
+
+ return *this;
+}
+
+/**
+ * @brief ATA trait getter.
+ * @return BootDeviceSATA::ATATrait& the drive config.
+ */
+BootDeviceSATA::SATATrait& BootDeviceSATA::Leak() {
+ return mTrait;
+}
+
+#endif \ No newline at end of file
diff --git a/src/boot/src/HEL/ARM64/.gitkeep b/src/boot/src/HEL/ARM64/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/src/HEL/ARM64/.gitkeep
diff --git a/src/boot/src/HEL/ARM64/BootAPI.S b/src/boot/src/HEL/ARM64/BootAPI.S
new file mode 100644
index 00000000..55183abf
--- /dev/null
+++ b/src/boot/src/HEL/ARM64/BootAPI.S
@@ -0,0 +1,12 @@
+.global rt_jump_to_address
+
+.text
+
+/**
+ @brief this function setups a stack and then jumps to
+ a function */
+rt_jump_to_address:
+ mov sp, x1
+ br x0
+ ret
+
diff --git a/src/boot/src/HEL/ARM64/BootEFI.cc b/src/boot/src/HEL/ARM64/BootEFI.cc
new file mode 100644
index 00000000..ac5eb030
--- /dev/null
+++ b/src/boot/src/HEL/ARM64/BootEFI.cc
@@ -0,0 +1,196 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/BootThread.h>
+#include <FirmwareKit/EFI.h>
+#include <FirmwareKit/EFI/API.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+#include <KernelKit/PEF.h>
+#include <NeKit/Macros.h>
+#include <NeKit/Ref.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+#ifndef kExpectedWidth
+#define kExpectedWidth (800)
+#endif
+
+#ifndef kExpectedHeight
+#define kExpectedHeight (600)
+#endif
+
+/** Graphics related. */
+
+STATIC EfiGraphicsOutputProtocol* kGop = nullptr;
+STATIC UInt16 kGopStride = 0U;
+STATIC EFI_GUID kGopGuid;
+
+EXTERN_C Void rt_reset_hardware();
+
+EXTERN EfiBootServices* BS;
+
+/**
+ @brief Finds and stores the GOP object.
+*/
+STATIC Bool boot_init_fb() noexcept {
+ kGopGuid = EFI_GUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID);
+ kGop = nullptr;
+
+ if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*) &kGop) != kEfiOk) return No;
+
+ kGopStride = 4;
+
+ for (SizeT i = 0; i < kGop->Mode->MaxMode; ++i) {
+ EfiGraphicsOutputProtocolModeInformation* infoPtr = nullptr;
+ UInt32 sz = 0U;
+
+ kGop->QueryMode(kGop, i, &sz, &infoPtr);
+
+ if (infoPtr->HorizontalResolution == kExpectedWidth &&
+ infoPtr->VerticalResolution == kExpectedHeight) {
+ kGop->SetMode(kGop, i);
+ return Yes;
+ }
+ }
+
+ return No;
+}
+
+EXTERN EfiBootServices* BS;
+
+/// @brief BootloaderMain EFI entrypoint.
+/// @param image_handle Handle of this image.
+/// @param sys_table The system table of it.
+/// @return nothing, never returns.
+EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTable* sys_table) {
+ fw_init_efi(sys_table); ///! Init the EFI library.
+
+ kHandoverHeader = new HEL::BootInfoHeader();
+
+#ifdef ZBA_USE_FB
+ if (!boot_init_fb()) return kEfiFail; ///! Init the GOP.
+
+ for (SizeT index_vt = 0; index_vt < sys_table->NumberOfTableEntries; ++index_vt) {
+ Char* vendor_table =
+ reinterpret_cast<Char*>(sys_table->ConfigurationTable[index_vt].VendorTable);
+
+ // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...)
+ if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && vendor_table[2] == 'D' &&
+ vendor_table[3] == ' ' && vendor_table[4] == 'P' && vendor_table[5] == 'T' &&
+ vendor_table[6] == 'R' && vendor_table[7] == ' ') {
+ kHandoverHeader->f_HardwareTables.f_VendorPtr = (VoidPtr) vendor_table;
+ break;
+ }
+ }
+
+ // ------------------------------------------ //
+ // draw background color.
+ // ------------------------------------------ //
+
+ kHandoverHeader->f_GOP.f_The = kGop->Mode->FrameBufferBase;
+ kHandoverHeader->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution;
+ kHandoverHeader->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution;
+ kHandoverHeader->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine;
+ kHandoverHeader->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat;
+ kHandoverHeader->f_GOP.f_Size = kGop->Mode->FrameBufferSize;
+#endif // ZBA_USE_FB
+
+ // ------------------------------------------- //
+ // Grab MP services, extended to runtime. //
+ // ------------------------------------------- //
+
+ EFI_GUID guid_mp = EFI_GUID(EFI_MP_SERVICES_PROTOCOL_GUID);
+ EfiMpServicesProtocol* mp = nullptr;
+
+ BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast<VoidPtr*>(&mp));
+ kHandoverHeader->f_HardwareTables.f_MpPtr = reinterpret_cast<VoidPtr>(mp);
+
+ UInt32 cnt_enabled = 0;
+ UInt32 cnt_disabled = 0;
+
+ if (mp) {
+ mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled);
+ kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1;
+ } else {
+ kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled = NO;
+ }
+
+ //-------------------------------------------------------------//
+ // Allocate heap.
+ //-------------------------------------------------------------//
+
+ Boot::BootTextWriter writer;
+
+ kHandoverHeader->f_BitMapStart = nullptr; /* Start of bitmap. */
+ kHandoverHeader->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap in bytes. */
+
+ UInt16 trials = 5;
+
+ while (BS->AllocatePool(EfiLoaderData, kHandoverHeader->f_BitMapSize,
+ &kHandoverHeader->f_BitMapStart) != kEfiOk) {
+ --trials;
+
+ if (!trials) {
+ writer.Write("BootZ: Unable to allocate sufficient memory, trying again with 2GB...\r");
+
+ trials = 3;
+
+ kHandoverHeader->f_BitMapSize = kHandoverBitMapSz / 2; /* Size of bitmap in bytes. */
+
+ while (BS->AllocatePool(EfiLoaderData, kHandoverHeader->f_BitMapSize,
+ &kHandoverHeader->f_BitMapStart) != kEfiOk) {
+ --trials;
+
+ if (!trials) {
+ writer.Write("BootZ: Unable to allocate sufficient memory, aborting...\r");
+ Boot::Stop();
+ }
+ }
+ }
+ }
+
+ // ------------------------------------------ //
+ // null these fields, to avoid being reused later.
+ // ------------------------------------------ //
+
+ kHandoverHeader->f_FirmwareCustomTables[0] = nullptr;
+ kHandoverHeader->f_FirmwareCustomTables[1] = nullptr;
+
+ kHandoverHeader->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor);
+
+ kHandoverHeader->f_Magic = kHandoverMagic;
+ kHandoverHeader->f_Version = kHandoverVersion;
+
+ // Provide fimware vendor name.
+
+ Boot::BCopyMem(kHandoverHeader->f_FirmwareVendorName, sys_table->FirmwareVendor,
+ kHandoverHeader->f_FirmwareVendorLen);
+
+ kHandoverHeader->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor);
+
+ Boot::BootFileReader reader_kernel(L"ne_kernel", image_handle);
+
+ reader_kernel.ReadAll(0);
+
+ // ------------------------------------------ //
+ // If we succeed in reading the blob, then execute it.
+ // ------------------------------------------ //
+
+ if (reader_kernel.Blob()) {
+ auto kernel_thread = Boot::BootThread(reader_kernel.Blob());
+ kernel_thread.SetName("NeKernel");
+
+ kHandoverHeader->f_KernelImage = reader_kernel.Blob();
+ kHandoverHeader->f_KernelSz = reader_kernel.Size();
+
+ kernel_thread.Start(kHandoverHeader, YES);
+ }
+
+ CANT_REACH();
+}
diff --git a/src/boot/src/HEL/ARM64/BootNB.S b/src/boot/src/HEL/ARM64/BootNB.S
new file mode 100644
index 00000000..f781ad37
--- /dev/null
+++ b/src/boot/src/HEL/ARM64/BootNB.S
@@ -0,0 +1,40 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifdef __NE_NEBOOT__
+
+.section .boot_hdr
+.align 4
+
+/* BootZ boot header begin */
+
+boot_hdr_mag:
+ .ascii "CB"
+boot_hdr_name:
+ // it has to match ten bytes.
+ .asciz "bootz\0\0\0"
+boot_hdr_ver:
+ .word 0x101
+boot_hdr_proc:
+ .long bootloader_start
+
+/* BootZ boot header end */
+
+.extern bootloader_main
+.extern bootloader_stack
+
+.globl bootloader_start
+bootloader_start:
+ adr x0, bootloader_stack
+ ldr x1, =bootloader_start
+ sub x0, x0, x1
+ ldr x0, [x0]
+ mov sp, x0
+
+ bl bootloader_main
+ ret
+
+#endif // __NE_NEBOOT__ \ No newline at end of file
diff --git a/src/boot/src/HEL/ARM64/BootPlatform.cc b/src/boot/src/HEL/ARM64/BootPlatform.cc
new file mode 100644
index 00000000..2ad9b776
--- /dev/null
+++ b/src/boot/src/HEL/ARM64/BootPlatform.cc
@@ -0,0 +1,28 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/Platform.h>
+#include <BootKit/Protocol.h>
+
+#ifdef __BOOTZ_STANDALONE__
+
+using namespace Boot;
+
+EXTERN_C void rt_halt() {
+ while (Yes)
+ ;
+}
+
+EXTERN_C void rt_cli() {}
+
+EXTERN_C void rt_sti() {}
+
+EXTERN_C void rt_cld() {}
+
+EXTERN_C void rt_std() {}
+
+#endif // __BOOTZ_STANDALONE__
diff --git a/src/boot/src/HEL/POWER/.gitkeep b/src/boot/src/HEL/POWER/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/boot/src/HEL/POWER/.gitkeep
diff --git a/src/boot/src/HEL/POWER/BootNB.S b/src/boot/src/HEL/POWER/BootNB.S
new file mode 100644
index 00000000..45b9c9e1
--- /dev/null
+++ b/src/boot/src/HEL/POWER/BootNB.S
@@ -0,0 +1,34 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+.section .boot_hdr
+.align 4
+
+/* BootZ boot header begin */
+
+boot_hdr_mag:
+ .ascii "CB"
+boot_hdr_name:
+ // it has to match ten bytes.
+ .asciz "bootz\0\0\0"
+boot_hdr_ver:
+ .word 0x101
+boot_hdr_proc:
+ .long bootloader_start
+
+/* BootZ boot header end */
+
+.extern bootloader_main
+.extern bootloader_stack
+
+.globl bootloader_start
+bootloader_start:
+ mflr 4 /* real address of .Laddr */
+ lwz 0,(bootloader_stack-bootloader_start)(4) /* stack address location */
+ mr 1,0 /* use user defined stack */
+
+ bl bootloader_main
+ blr
diff --git a/src/boot/src/New+Delete.cc b/src/boot/src/New+Delete.cc
new file mode 100644
index 00000000..a66d8464
--- /dev/null
+++ b/src/boot/src/New+Delete.cc
@@ -0,0 +1,74 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <BootKit/BootKit.h>
+#include <BootKit/Platform.h>
+#include <BootKit/Protocol.h>
+#include <FirmwareKit/EFI/API.h>
+
+#ifdef __BOOTZ_STANDALONE__
+
+/// @brief Allocates a new object.
+/// @param sz the size.
+/// @return
+void* operator new(size_t sz) {
+ void* buf = nullptr;
+
+ while (BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf) != kEfiOk)
+ ;
+
+ return buf;
+}
+
+/// @brief Allocates a new object.
+/// @param sz the size.
+/// @return
+void* operator new[](size_t sz) {
+ void* buf = nullptr;
+ BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf);
+
+ return buf;
+}
+
+/// @brief Deletes the object.
+/// @param buf the object.
+void operator delete(void* buf) noexcept {
+ if (!buf) return;
+
+ BS->FreePool(buf);
+}
+
+/// @brief Deletes the object.
+/// @param buf the object.
+void operator delete[](void* buf) noexcept {
+ if (!buf) return;
+
+ BS->FreePool(buf);
+}
+
+/// @brief Deletes the object (array specific).
+/// @param buf the object.
+/// @param size it's size.
+void operator delete(void* buf, size_t size) {
+ if (!buf) return;
+
+ NE_UNUSED(size);
+
+ BS->FreePool(buf);
+}
+
+/// @brief Deletes the object (array specific).
+/// @param buf the object.
+/// @param size it's size.
+void operator delete[](void* buf, size_t size) {
+ if (!buf) return;
+
+ NE_UNUSED(size);
+
+ BS->FreePool(buf);
+}
+
+#endif // __BOOTZ_STANDALONE__
diff --git a/src/boot/src/boot_rsrc.rsrc b/src/boot/src/boot_rsrc.rsrc
new file mode 100644
index 00000000..e875fa24
--- /dev/null
+++ b/src/boot/src/boot_rsrc.rsrc
@@ -0,0 +1,25 @@
+#include "../../kernel/CompilerKit/Version.h"
+
+1 VERSIONINFO
+FILEVERSION 1,0,0,0
+PRODUCTVERSION 1,0,0,0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080904E4"
+ BEGIN
+ VALUE "CompanyName", "Amlal El Mahrouss"
+ VALUE "FileDescription", "NeKernel OS Loader."
+ VALUE "FileVersion", BOOTLOADER_VERSION
+ VALUE "InternalName", "bootz"
+ VALUE "LegalCopyright", "Copyright (C) 2024-2025, Amlal El Mahrouss licensed under the Apache 2.0 license."
+ VALUE "OriginalFilename", "ne_bootz"
+ VALUE "ProductName", "bootz"
+ VALUE "ProductVersion", BOOTLOADER_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x809, 1252
+ END
+END
diff --git a/src/boot/src/docs/KERN_VER.md b/src/boot/src/docs/KERN_VER.md
new file mode 100644
index 00000000..c47c3d5b
--- /dev/null
+++ b/src/boot/src/docs/KERN_VER.md
@@ -0,0 +1,18 @@
+# `/props/kern_ver` — NVRAM EFI Variable
+
+The `/props/kern_ver` variable is used to track NeKernel's current version in a BCD format.
+
+## 🛠 Reason
+
+- It is also used for:
+ - Bug tracking and system patching.
+ - Version and compatibility checking.
+
+## 🧪 Usage
+
+N/A
+
+## © License
+
+ Copyright (C) 2025,
+ Amlal El Mahrouss – Licensed under the Apache 2.0 license. \ No newline at end of file
diff --git a/src/boot/src/docs/MKFS_HEFS.md b/src/boot/src/docs/MKFS_HEFS.md
new file mode 100644
index 00000000..b42ad9c2
--- /dev/null
+++ b/src/boot/src/docs/MKFS_HEFS.md
@@ -0,0 +1,106 @@
+# `mkfs.hefs` – OpenHeFS Filesystem Formatter
+
+`mkfs.hefs` is a command-line utility used to format a block device or disk image with the **High-throughput Extended File System (OpenHeFS)** used by NeKernel. This tool initializes a OpenHeFS volume by writing a boot node and configuring directory and inode index regions, block ranges, and volume metadata.
+
+---
+
+## 🛠 Features
+
+- Writes a valid `BootNode` to the specified output device or file.
+- Sets disk size, sector size, and volume label.
+- Supports user-defined ranges for:
+ - Index Node Directory (IND)
+ - Inodes (IN)
+ - Data blocks
+- UTF-8 encoded volume label support.
+- Fully compatible with NeKernel's VFS subsystem.
+
+---
+
+## 🧪 Usage
+
+ mkfs.hefs -L <label> -s <sector_size> \
+ -b <ind_start> -e <ind_end> \
+ -bs <block_start> -be <block_end> \
+ -is <in_start> -ie <in_end> \
+ -S <disk_size> -o <output_device>
+
+---
+
+## 🧾 Arguments
+
+| Option | Description |
+|---------------|-------------------------------------------------------------------------|
+| `-L` | Volume label (UTF-8, internally stored as UTF-16) |
+| `-s` | Sector size (e.g., 512) |
+| `-b` `-e` | Start and end addresses for the **Index Node Directory (IND)** region |
+| `-bs` `-be` | Start and end addresses for the **Block** data region |
+| `-is` `-ie` | Start and end addresses for the **Inode** region |
+| `-S` | Disk size in **gigabytes** |
+| `-o` | Path to the output device or image file |
+
+> All address-based inputs (`-b`, `-e`, etc.) must be specified in **hexadecimal** format.
+
+---
+
+## 🧷 Notes
+
+- Default sector size is `512` bytes.
+- Default volume name is `"HeFS_VOLUME"`, defined as `kOpenHeFSDefaultVolumeName`.
+- The tool writes a `BootNode` at the beginning of the index node range.
+- A CRC-safe magic signature is embedded for boot and integrity validation.
+- After writing the metadata, the tool flushes and closes the file stream.
+
+---
+
+## 💻 Example
+
+ mkfs.hefs -L "MyHeFS" -s 512 \
+ -b 0x1000 -e 0x8000 \
+ -bs 0x8000 -be 0x800000 \
+ -is 0x800000 -ie 0xA00000 \
+ -S 128 -o hefs.img
+
+This will create a 128 GiB formatted OpenHeFS image named `hefs.img` with specified region boundaries.
+
+---
+
+## 📁 BootNode Structure
+
+The `BootNode` stores key filesystem metadata:
+
+ struct BootNode {
+ char magic[8];
+ char16_t volumeName[64];
+ uint16_t version;
+ uint16_t diskKind;
+ uint16_t encoding;
+ uint64_t diskSize;
+ uint32_t sectorSize;
+ uint64_t startIND, endIND;
+ uint64_t startIN, endIN;
+ uint64_t startBlock, endBlock;
+ uint64_t indCount;
+ uint16_t diskStatus;
+ };
+
+---
+
+## ⚠️ Error Handling
+
+- Prints usage and exits on invalid/missing arguments.
+- Exits with error if the output device cannot be opened or written to.
+- Checks for zero sector size or disk size to prevent invalid formatting.
+
+---
+
+## 📚 Source Location
+
+Part of the [OpenHeFS Tooling module](https://github.com/nekernel-org/nekernel) and used during system setup or disk preparation for NeKernel.
+
+---
+
+## © License
+
+ Copyright (C) 2025,
+ Amlal El Mahrouss – Licensed under the Apache 2.0 license. \ No newline at end of file
diff --git a/src/boot/src/root/ifs.json b/src/boot/src/root/ifs.json
new file mode 100644
index 00000000..354ab503
--- /dev/null
+++ b/src/boot/src/root/ifs.json
@@ -0,0 +1,10 @@
+{
+ "type": "IFS",
+ "sys": [
+ "/~drivers/fat32.sys",
+ "/~drivers/ntfs.sys",
+ "/~drivers/ext4.sys",
+ "/~drivers/iso9660.sys",
+ "/~drivers/nfs4.sys"
+ ]
+} \ No newline at end of file
diff --git a/src/hint/CompilerHint.h b/src/hint/CompilerHint.h
new file mode 100644
index 00000000..8b651a17
--- /dev/null
+++ b/src/hint/CompilerHint.h
@@ -0,0 +1,25 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef _NE_COMPILERHINT_H_
+#define _NE_COMPILERHINT_H_
+
+#ifdef __LIBCOMPILER__
+#pragma compiler(hint_manifest)
+#endif
+
+#define _Input
+#define _Output
+
+#define _Optional
+
+#define _StrictCheckInput
+#define _StrictCheckOutput
+
+#define _InOut
+#define _StrictInOut
+
+#endif // ifndef _NE_COMPILERHINT_H_
diff --git a/src/kernel/ArchKit/ArchKit.h b/src/kernel/ArchKit/ArchKit.h
new file mode 100644
index 00000000..626f1e0b
--- /dev/null
+++ b/src/kernel/ArchKit/ArchKit.h
@@ -0,0 +1,108 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Function.h>
+
+#include <FirmwareKit/Handover.h>
+
+#ifdef __NE_AMD64__
+#include <HALKit/AMD64/Hypervisor.h>
+#include <HALKit/AMD64/Paging.h>
+#include <HALKit/AMD64/Processor.h>
+#elif defined(__NE_POWER64__)
+#include <HALKit/POWER/Processor.h>
+#elif defined(__NE_ARM64__)
+#include <HALKit/ARM64/Processor.h>
+#elif defined(__NE_SDK__)
+#include <HALKit/ARM64/Processor.h>
+#else
+#error !!! unknown architecture !!!
+#endif
+
+#define kMaxDispatchCallCount (512U)
+
+namespace Kernel {
+inline SizeT rt_hash_seed(const Char* seed, UInt32 mul) {
+ SizeT hash = 0;
+
+ for (SSizeT idx = 0; seed[idx] != 0; ++idx) {
+ hash += seed[idx];
+ hash ^= mul;
+ }
+
+ return hash;
+}
+
+/// @brief write to mapped memory register
+/// @param base the base address.
+/// @param reg the register.
+/// @param value the write to write on it.
+template <typename DataKind>
+inline Void ke_dma_write(UIntPtr base, DataKind reg, DataKind value) noexcept {
+ *(volatile DataKind*) (base + reg) = value;
+}
+
+/// @brief read from mapped memory register.
+/// @param base base address
+/// @param reg the register.
+/// @return the value inside the register.
+template <typename DataKind>
+inline UInt32 ke_dma_read(UIntPtr base, DataKind reg) noexcept {
+ return *(volatile DataKind*) (base + reg);
+}
+
+/// @brief Hardware Abstraction Layer
+namespace HAL {
+ /// @brief Check whether this pointer is a bitmap object.
+ /// @param ptr argument to verify.
+ /// @param whether successful or not.
+ auto mm_is_bitmap(VoidPtr ptr) -> Bool;
+} // namespace HAL
+} // namespace Kernel
+
+typedef Kernel::Void (*rt_syscall_proc)(Kernel::VoidPtr);
+
+/// @brief System Call Dispatch.
+struct HAL_DISPATCH_ENTRY final {
+ Kernel::UInt64 fHash;
+ Kernel::Bool fHooked;
+ rt_syscall_proc fProc;
+
+ BOOL IsKernCall() { return NO; }
+ BOOL IsSysCall() { return YES; }
+
+ operator bool() { return fHooked; }
+};
+
+typedef Kernel::Void (*rt_kerncall_proc)(Kernel::SizeT, Kernel::VoidPtr, Kernel::SizeT);
+
+/// @brief Kernel Call Dispatch.
+struct HAL_KERNEL_DISPATCH_ENTRY final {
+ Kernel::UInt64 fHash;
+ Kernel::Bool fHooked;
+ rt_kerncall_proc fProc;
+
+ BOOL IsKernCall() { return YES; }
+ BOOL IsSysCall() { return NO; }
+
+ operator bool() { return fHooked; }
+};
+
+inline Kernel::Array<HAL_DISPATCH_ENTRY, kMaxDispatchCallCount> kSysCalls;
+
+inline Kernel::Array<HAL_KERNEL_DISPATCH_ENTRY, kMaxDispatchCallCount> kKernCalls;
+
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+
+inline Kernel::VoidPtr kKernelVM = nullptr;
+
+#endif // __NE_VIRTUAL_MEMORY_SUPPORT__
+
+inline Kernel::SizeT kBitMapCursor = 0UL;
diff --git a/src/kernel/CFKit/GUIDWizard.h b/src/kernel/CFKit/GUIDWizard.h
new file mode 100644
index 00000000..8745a1f9
--- /dev/null
+++ b/src/kernel/CFKit/GUIDWizard.h
@@ -0,0 +1,21 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CFKit/GUIDWrapper.h>
+#include <NeKit/Array.h>
+#include <NeKit/ArrayList.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KString.h>
+#include <NeKit/Ref.h>
+#include <NeKit/Stream.h>
+
+namespace Kernel::CF::XRN::Version1 {
+Ref<GUIDSequence*> cf_make_sequence(const ArrayList<UInt32>& seq);
+ErrorOr<Ref<KString>> cf_try_guid_to_string(Ref<GUIDSequence*>& guid);
+} // namespace Kernel::CF::XRN::Version1
diff --git a/src/kernel/CFKit/GUIDWrapper.h b/src/kernel/CFKit/GUIDWrapper.h
new file mode 100644
index 00000000..2bf7b64e
--- /dev/null
+++ b/src/kernel/CFKit/GUIDWrapper.h
@@ -0,0 +1,48 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+#include <NeKit/Stream.h>
+
+/* GUID for C++ classes. */
+
+#define kXRNNil "@{........-....-M...-N...-............}"
+
+/// @brief eXtended Resource Namespace
+namespace Kernel::CF::XRN {
+union GUIDSequence final {
+ alignas(8) UShort fU8[16];
+ alignas(8) UShort fU16[8];
+ alignas(8) UInt fU32[4];
+ alignas(8) ULong fU64[2];
+
+ struct GUID {
+ alignas(8) UInt fMs1;
+ UShort fMs2;
+ UShort fMs3;
+ UChar fMs4[8];
+ } fUuid;
+};
+
+class GUID final {
+ public:
+ explicit GUID() = default;
+ ~GUID() = default;
+
+ public:
+ NE_COPY_DEFAULT(GUID)
+
+ public:
+ GUIDSequence& operator->() noexcept { return fUUID; }
+ GUIDSequence& Leak() noexcept { return fUUID; }
+
+ private:
+ GUIDSequence fUUID;
+};
+} // namespace Kernel::CF::XRN
diff --git a/src/kernel/CFKit/Property.h b/src/kernel/CFKit/Property.h
new file mode 100644
index 00000000..cfb8a599
--- /dev/null
+++ b/src/kernel/CFKit/Property.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef CFKIT_PROPS_H
+#define CFKIT_PROPS_H
+
+#include <CFKit/GUIDWrapper.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Function.h>
+#include <NeKit/KString.h>
+
+#define kMaxPropLen (256U)
+
+namespace Kernel::CF {
+/// @brief handle to anything (number, ptr, string...)
+using PropertyId = UIntPtr;
+
+/// @brief Kernel property class.
+/// @example /prop/smp_max or /prop/kern_ver
+class Property {
+ public:
+ Property();
+ virtual ~Property();
+
+ public:
+ Property& operator=(const Property&) = default;
+ Property(const Property&) = default;
+
+ BOOL StringEquals(KBasicString<>& name);
+ PropertyId& GetValue();
+ KBasicString<>& GetKey();
+
+ private:
+ KString fName{kMaxPropLen};
+ PropertyId fValue{0UL};
+ Ref<XRN::GUID> fGUID{};
+};
+
+template <SizeT N>
+using PropertyArray = Array<Property, N>;
+} // namespace Kernel::CF
+
+namespace Kernel {
+using namespace Kernel::CF;
+}
+
+#endif // !CFKIT_PROPS_H
diff --git a/src/kernel/CFKit/Utils.h b/src/kernel/CFKit/Utils.h
new file mode 100644
index 00000000..247ad5fb
--- /dev/null
+++ b/src/kernel/CFKit/Utils.h
@@ -0,0 +1,48 @@
+#ifndef CFKIT_UTILS_H
+#define CFKIT_UTILS_H
+
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+
+/// @brief CFKit
+namespace Kernel::CF {
+/// @brief Finds the PE header inside the blob.
+inline auto ldr_find_exec_header(DosHeaderPtr ptrDos) -> LDR_EXEC_HEADER_PTR {
+ if (!ptrDos) return nullptr;
+
+ if (ptrDos->eMagic[0] != kMagMz0) return nullptr;
+
+ if (ptrDos->eMagic[1] != kMagMz1) return nullptr;
+
+#ifdef __NE_AMD64__
+ return (LDR_EXEC_HEADER_PTR) (VoidPtr) (&ptrDos->eLfanew + 1);
+#else
+ return (LDR_EXEC_HEADER_PTR) (VoidPtr) (&ptrDos->eLfanew);
+#endif
+}
+
+/// @brief Finds the PE optional header inside the blob.
+inline auto ldr_find_opt_exec_header(DosHeaderPtr ptrDos) -> LDR_OPTIONAL_HEADER_PTR {
+ if (!ptrDos) return nullptr;
+
+ auto exec = ldr_find_exec_header(ptrDos);
+
+ if (!exec) return nullptr;
+
+ return (LDR_OPTIONAL_HEADER_PTR) (VoidPtr) (&exec->Characteristics + 1);
+}
+
+/// @brief Finds the PE header inside the blob.
+/// @note overloaded function.
+inline auto ldr_find_exec_header(const Char* ptrDos) -> LDR_EXEC_HEADER_PTR {
+ return ldr_find_exec_header((DosHeaderPtr) ptrDos);
+}
+
+/// @brief Finds the PE header inside the blob.
+/// @note overloaded function.
+inline auto ldr_find_opt_exec_header(const Char* ptrDos) -> LDR_OPTIONAL_HEADER_PTR {
+ return ldr_find_opt_exec_header((DosHeaderPtr) ptrDos);
+}
+} // namespace Kernel::CF
+
+#endif // ifndef CFKIT_UTILS_H
diff --git a/src/kernel/CompilerKit/CompilerKit.h b/src/kernel/CompilerKit/CompilerKit.h
new file mode 100644
index 00000000..523a4ecd
--- /dev/null
+++ b/src/kernel/CompilerKit/CompilerKit.h
@@ -0,0 +1,13 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef _INC_CL_H
+#define _INC_CL_H
+
+#include <CompilerKit/Detail.h>
+#include <CompilerKit/Version.h>
+
+#endif /* ifndef _INC_CL_H */
diff --git a/src/kernel/CompilerKit/Detail.h b/src/kernel/CompilerKit/Detail.h
new file mode 100644
index 00000000..93e9b2dd
--- /dev/null
+++ b/src/kernel/CompilerKit/Detail.h
@@ -0,0 +1,27 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#ifdef __NEOSKRNL__
+#include <NeKit/Defines.h>
+#endif // ifdef __NEOSKRNL__
+
+#define NE_COPY_DELETE(KLASS) \
+ KLASS& operator=(const KLASS&) = delete; \
+ KLASS(const KLASS&) = delete;
+
+#define NE_COPY_DEFAULT(KLASS) \
+ KLASS& operator=(const KLASS&) = default; \
+ KLASS(const KLASS&) = default;
+
+#define NE_MOVE_DELETE(KLASS) \
+ KLASS& operator=(KLASS&&) = delete; \
+ KLASS(KLASS&&) = delete;
+
+#define NE_MOVE_DEFAULT(KLASS) \
+ KLASS& operator=(KLASS&&) = default; \
+ KLASS(KLASS&&) = default;
diff --git a/src/kernel/CompilerKit/Version.h b/src/kernel/CompilerKit/Version.h
new file mode 100644
index 00000000..4250531a
--- /dev/null
+++ b/src/kernel/CompilerKit/Version.h
@@ -0,0 +1,9 @@
+// (c) Amlal El Mahrouss
+
+#pragma once
+
+#define BOOTLOADER_VERSION "v0.0.2-bootz"
+#define KERNEL_VERSION "v0.0.2-krnl"
+
+#define BOOTLOADER_VERSION_BCD (0x0002)
+#define KERNEL_VERSION_BCD (0x0002)
diff --git a/src/kernel/DmaKit/DmaPool.h b/src/kernel/DmaKit/DmaPool.h
new file mode 100644
index 00000000..e20f8c69
--- /dev/null
+++ b/src/kernel/DmaKit/DmaPool.h
@@ -0,0 +1,101 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss , licensed under the Apache 2.0 license.
+
+ File: DmaPool.h
+ Purpose: Dma Pool Manager.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DebugOutput.h>
+
+#ifdef __NE_AMD64__
+#include <HALKit/AMD64/Processor.h>
+#define kNeDMAPoolStart (0x1000000)
+#define kNeDMAPoolSize (0x1000000)
+#elif defined(__NE_ARM64__)
+#include <HALKit/ARM64/Processor.h>
+
+/// @todo what reference offset shall we use?
+#define kNeDMAPoolStart (0x1000000)
+#define kNeDMAPoolSize (0x1000000)
+#endif
+
+#define kNeDMABestAlign (8)
+
+namespace Kernel {
+/// @brief DMA pool base pointer, here we're sure that AHCI or whatever tricky standard sees it.
+inline UInt8* kDmaPoolPtr = (UInt8*) kNeDMAPoolStart;
+inline const UInt8* kDmaPoolEnd = (UInt8*) (kNeDMAPoolStart + kNeDMAPoolSize);
+
+/***********************************************************************************/
+/// @brief allocate from the rtl_dma_alloc system.
+/// @param size the size of the chunk to allocate.
+/// @param align alignement of pointer.
+/***********************************************************************************/
+inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) {
+ if (!size) {
+ return nullptr;
+ }
+
+ /// Check alignement according to architecture.
+ if ((align % kNeDMABestAlign) != 0) {
+ return nullptr;
+ }
+
+ UIntPtr addr = (UIntPtr) kDmaPoolPtr;
+
+ /// here we just align the address according to a `align` variable, i'd rather be a power of two
+ /// really.
+ addr = (addr + (align - 1)) & ~(align - 1);
+
+ if ((addr + size) > reinterpret_cast<UIntPtr>(kDmaPoolEnd)) {
+ err_global_get() = kErrorDmaExhausted;
+ return nullptr;
+ }
+
+ kDmaPoolPtr = (UInt8*) (addr + size);
+
+ HAL::mm_memory_fence((VoidPtr) addr);
+
+ return (VoidPtr) addr;
+}
+
+/***********************************************************************************/
+/// @brief Free DMA pointer.
+/***********************************************************************************/
+inline Void rtl_dma_free(SizeT size) {
+ if (!size) return;
+
+ auto ptr = (kDmaPoolPtr - size);
+
+ if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) {
+ err_global_get() = kErrorDmaExhausted;
+ return;
+ }
+
+ kDmaPoolPtr = ptr;
+
+ HAL::mm_memory_fence(ptr);
+}
+
+/***********************************************************************************/
+/// @brief Flush DMA pointer.
+/***********************************************************************************/
+inline Void rtl_dma_flush(VoidPtr ptr, SizeT size_buffer) {
+ if (ptr > kDmaPoolEnd) {
+ return;
+ }
+
+ if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) {
+ err_global_get() = kErrorDmaExhausted;
+ return;
+ }
+
+ for (SizeT buf_idx = 0UL; buf_idx < size_buffer; ++buf_idx) {
+ HAL::mm_memory_fence((VoidPtr) ((UInt8*) ptr + buf_idx));
+ }
+}
+} // namespace Kernel
diff --git a/src/kernel/FSKit/Defines.h b/src/kernel/FSKit/Defines.h
new file mode 100644
index 00000000..c5bf8f88
--- /dev/null
+++ b/src/kernel/FSKit/Defines.h
@@ -0,0 +1,12 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define FSKIT_VERSION "1.0.0"
+#define FSKIT_VERSION_BCD 0x0100
diff --git a/src/kernel/FSKit/Ext2+IFS.h b/src/kernel/FSKit/Ext2+IFS.h
new file mode 100644
index 00000000..01ca4c90
--- /dev/null
+++ b/src/kernel/FSKit/Ext2+IFS.h
@@ -0,0 +1,273 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <FSKit/Ext2.h>
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+/// @brief Context for an EXT2 filesystem on a given drive
+class Ext2Context final {
+ public:
+ DriveTrait* drive{nullptr};
+ EXT2_SUPER_BLOCK* superblock{nullptr};
+
+ /// @brief context with a drive
+ Ext2Context(Kernel::DriveTrait* drv) : drive(drv) {}
+
+ /// @brief Clean up
+ ~Ext2Context() {
+ if (superblock) {
+ Kernel::mm_free_ptr(superblock);
+ superblock = nullptr;
+ }
+ }
+
+ Ext2Context(const Ext2Context&) = delete;
+ Ext2Context& operator=(const Ext2Context&) = delete;
+
+ Ext2Context(Ext2Context&& other) noexcept : drive(other.drive), superblock(other.superblock) {
+ other.drive = nullptr;
+ other.superblock = nullptr;
+ }
+
+ Ext2Context& operator=(Ext2Context&& other) noexcept {
+ if (this != &other) {
+ if (superblock) {
+ Kernel::mm_free_ptr(superblock);
+ }
+ drive = other.drive;
+ superblock = other.superblock;
+ other.drive = nullptr;
+ other.superblock = nullptr;
+ }
+ return *this;
+ }
+
+ SizeT BlockSize() const {
+ if (!superblock) return kExt2FSBlockSizeBase;
+ return kExt2FSBlockSizeBase << superblock->fLogBlockSize;
+ }
+
+ operator BOOL() { return superblock != nullptr; }
+};
+
+/// ======================================================================= ///
+/// IFS FUNCTIONS
+/// ======================================================================= ///
+
+inline BOOL ext2_read_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, VoidPtr buffer,
+ Kernel::UInt32 size) {
+ if (!drv || !buffer) return false;
+
+ Kernel::DriveTrait::DrivePacket pkt{};
+ pkt.fPacketContent = buffer;
+ pkt.fPacketSize = size;
+ pkt.fPacketLba = lba;
+ drv->fInput(pkt);
+
+ return pkt.fPacketGood;
+}
+
+inline BOOL ext2_write_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, const VoidPtr buffer,
+ Kernel::UInt32 size) {
+ if (!drv || !buffer) return false;
+
+ Kernel::DriveTrait::DrivePacket pkt{};
+ pkt.fPacketContent = const_cast<VoidPtr>(buffer);
+ pkt.fPacketSize = size;
+ pkt.fPacketLba = lba;
+ drv->fOutput(pkt);
+ return pkt.fPacketGood;
+}
+
+inline Kernel::ErrorOr<EXT2_SUPER_BLOCK*> ext2_load_superblock(Ext2Context* ctx) {
+ if (!ctx || !ctx->drive) return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorInvalidData);
+
+ auto buf = Kernel::mm_alloc_ptr(sizeof(EXT2_SUPER_BLOCK), true, false);
+ if (!buf) return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorHeapOutOfMemory);
+
+ Kernel::UInt32 blockLba = kExt2FSSuperblockOffset / ctx->drive->fSectorSz;
+
+ if (!ext2_read_block(ctx->drive, blockLba, buf, sizeof(EXT2_SUPER_BLOCK))) {
+ Kernel::mm_free_ptr(buf);
+ return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorDisk);
+ }
+
+ auto sb = reinterpret_cast<EXT2_SUPER_BLOCK*>(buf);
+ if (sb->fMagic != kExt2FSMagic) {
+ Kernel::mm_free_ptr(buf);
+ return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorInvalidData);
+ }
+
+ ctx->superblock = sb;
+ return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(sb);
+}
+
+// Load inode
+inline Kernel::ErrorOr<Ext2Node*> ext2_load_inode(Ext2Context* ctx, Kernel::UInt32 inodeNumber) {
+ if (!ctx || !ctx->superblock) return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorInvalidData);
+
+ auto nodePtr = Kernel::mm_alloc_ptr(sizeof(Ext2Node), true, false);
+ if (!nodePtr) return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorHeapOutOfMemory);
+
+ auto ext2Node = reinterpret_cast<Ext2Node*>(nodePtr);
+ ext2Node->inodeNumber = inodeNumber;
+
+ // Compute block group and index within group
+ Kernel::UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup;
+ Kernel::UInt32 group = (inodeNumber - 1) / inodesPerGroup;
+
+ // dummy: just offset first inode
+ Kernel::UInt32 inodeTableBlock = ctx->superblock->fFirstInode + group;
+
+ if (!ext2_read_block(ctx->drive, inodeTableBlock, &ext2Node->inode, sizeof(EXT2_INODE))) {
+ Kernel::mm_free_ptr(nodePtr);
+ return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorDisk);
+ }
+
+ ext2Node->cursor = 0;
+ return Kernel::ErrorOr<Ext2Node*>(ext2Node);
+}
+
+/*
+ * Ext2FileSystemParser Class
+ *
+ * Provides high-level interface for EXT2 filesystem operations
+ */
+class Ext2FileSystemParser final {
+ private:
+ Ext2Context fCtx; // Internal EXT2 context
+
+ public:
+ /*
+ * Constructor
+ * Initializes the parser with a drive interface
+ *
+ * @param drive: Pointer to drive trait for disk I/O operations
+ */
+ explicit Ext2FileSystemParser(DriveTrait* drive);
+
+ NE_COPY_DELETE(Ext2FileSystemParser)
+
+ /*
+ * Open a file or directory by path
+ *
+ * @param path: Full path to the file/directory (e.g., "/home/user/file.txt")
+ * @param restrict_type: Access mode restriction (e.g., "r", "w", "rw")
+ * @return: VoidPtr handle to the opened file/directory, or nullptr on failure
+ */
+ VoidPtr Open(const char* path, const char* restrict_type);
+
+ /*
+ * Read data from an open file node
+ *
+ * @param node: File node handle returned by Open()
+ * @param flags: Read operation flags
+ * @param size: Number of bytes to read
+ * @return: Pointer to allocated buffer containing read data, or nullptr on failure
+ * Caller is responsible for freeing the returned buffer
+ */
+ VoidPtr Read(VoidPtr node, Int32 flags, SizeT size);
+
+ /*
+ * Write data to an open file node
+ *
+ * @param node: File node handle returned by Open()
+ * @param data: Buffer containing data to write
+ * @param flags: Write operation flags
+ * @param size: Number of bytes to write
+ */
+ Void Write(VoidPtr node, VoidPtr data, Int32 flags, SizeT size);
+
+ /*
+ * Seek to a specific position in the file
+ *
+ * @param node: File node handle
+ * @param offset: Byte offset from beginning of file
+ * @return: true on success, false on failure
+ */
+ BOOL Seek(VoidPtr node, SizeT offset);
+
+ /*
+ * Get current position in the file
+ *
+ * @param node: File node handle
+ * @return: Current byte offset from beginning of file
+ */
+ SizeT Tell(VoidPtr node);
+
+ /*
+ * Reset file position to beginning
+ *
+ * @param node: File node handle
+ * @return: true on success, false on failure
+ */
+ BOOL Rewind(VoidPtr node);
+
+ /*
+ * Read data from a named file within a directory node
+ *
+ * @param name: Name of file within the directory
+ * @param node: Directory node handle
+ * @param flags: Read operation flags
+ * @param size: Number of bytes to read
+ * @return: Pointer to allocated buffer containing read data, or nullptr on failure
+ */
+ VoidPtr Read(const char* name, VoidPtr node, Int32 flags, SizeT size);
+
+ /*
+ * Write data to a named file within a directory node
+ *
+ * @param name: Name of file within the directory
+ * @param node: Directory node handle
+ * @param data: Buffer containing data to write
+ * @param flags: Write operation flags
+ * @param size: Number of bytes to write
+ */
+ Void Write(const char* name, VoidPtr node, VoidPtr data, Int32 flags, SizeT size);
+
+ /*
+ * Create a new regular file
+ *
+ * @param path: Full path for the new file
+ * @return: VoidPtr handle to the created file, or nullptr on failure
+ */
+ VoidPtr Create(const char* path);
+
+ /*
+ * Create a new directory
+ *
+ * @param path: Full path for the new directory
+ * @return: VoidPtr handle to the created directory, or nullptr on failure
+ */
+ VoidPtr CreateDirectory(const char* path);
+
+ /*
+ * Close and free a file/directory node
+ * Note: This method is not shown in the implementation but would typically be needed
+ *
+ * @param node: Node handle to close and free
+ */
+ Void Close(VoidPtr node);
+
+ /*
+ * Get file/directory information
+ * Note: This method is not shown in the implementation but would typically be needed
+ *
+ * @param node: Node handle
+ * @param info: Structure to fill with file information (size, type, permissions, etc.)
+ * @return: true on success, false on failure
+ */
+ BOOL GetInfo(VoidPtr node, VoidPtr info);
+};
+} // namespace Kernel
diff --git a/src/kernel/FSKit/Ext2.h b/src/kernel/FSKit/Ext2.h
new file mode 100644
index 00000000..e979e556
--- /dev/null
+++ b/src/kernel/FSKit/Ext2.h
@@ -0,0 +1,148 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DriveMgr.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <hint/CompilerHint.h>
+
+/// @file Ext2.h
+/// @brief EXT2 filesystem structures, constants, and base wrappers.
+
+/// EXT2 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)
+
+/// EXT2 file types
+enum {
+ kExt2FileTypeUnknown = 0,
+ kExt2FileTypeRegular = 1,
+ kExt2FileTypeDirectory = 2,
+ kExt2FileTypeCharDevice = 3,
+ kExt2FileTypeBlockDevice = 4,
+ kExt2FileTypeFIFO = 5,
+ kExt2FileTypeSocket = 6,
+ kExt2FileTypeSymbolicLink = 7
+};
+
+typedef struct EXT2_GROUP_DESCRIPTOR final {
+ UInt32 fBlockBitmap;
+ UInt32 fInodeBitmap;
+ UInt32 fInodeTable;
+ UInt16 fFreeBlocksCount;
+ UInt16 fFreeInodesCount;
+ UInt16 fBgUsedDirsCount;
+ UInt16 fBgPad;
+ UInt32 fBgReserved[3];
+} EXT2_GROUP_DESCRIPTOR;
+
+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;
+ 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;
+
+ 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]; // direct 0-11, indirect 12, double 13, triple 14
+
+ Kernel::UInt32 fGeneration;
+ Kernel::UInt32 fFileACL;
+ Kernel::UInt32 fDirACL;
+ Kernel::UInt32 fFragmentAddr;
+
+ Kernel::UInt8 fOSD2[12];
+};
+
+/// Directory entry
+struct PACKED EXT2_DIR_ENTRY final {
+ Kernel::UInt32 fInode;
+ Kernel::UInt16 fRecordLength;
+ Kernel::UInt8 fNameLength;
+ Kernel::UInt8 fFileType;
+ Kernel::Char fName[kExt2FSMaxFileNameLen];
+};
+
+/// VFS usage
+struct Ext2Node {
+ Kernel::UInt32 inodeNumber;
+ EXT2_INODE inode;
+ Kernel::UInt32 cursor{0};
+};
diff --git a/src/kernel/FSKit/IndexableProperty.h b/src/kernel/FSKit/IndexableProperty.h
new file mode 100644
index 00000000..a89e78b8
--- /dev/null
+++ b/src/kernel/FSKit/IndexableProperty.h
@@ -0,0 +1,58 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CFKit/Property.h>
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DriveMgr.h>
+
+#define kIndexerCatalogNameLength (256U)
+#define kIndexerClaimed (0xCF)
+#define kIndexerUnclaimed (0xCA)
+
+namespace Kernel {
+namespace Indexer {
+ struct Index final {
+ public:
+ Char Drive[kDriveNameLen]{};
+ Char Path[kIndexerCatalogNameLength]{};
+ };
+
+ class IndexableProperty final : public Property {
+ public:
+ explicit IndexableProperty() : Property() {
+ KBasicString<> strProp(kMaxPropLen);
+ strProp += "/prop/indexable";
+
+ this->GetKey() = strProp;
+ }
+
+ ~IndexableProperty() override = default;
+
+ NE_COPY_DEFAULT(IndexableProperty)
+
+ public:
+ Index& Leak() noexcept;
+
+ public:
+ Void AddFlag(UInt16 flag);
+ Void RemoveFlag(UInt16 flag);
+ UInt16 HasFlag(UInt16 flag);
+
+ private:
+ Index fIndex;
+ UInt32 fFlags{};
+ };
+
+ /// @brief Index a file into the indexer instance.
+ /// @param filename path
+ /// @param filenameLen used bytes in path.
+ /// @param indexer the filesystem indexer.
+ /// @return none.
+ Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer);
+} // namespace Indexer
+} // namespace Kernel
diff --git a/src/kernel/FSKit/NeFS.h b/src/kernel/FSKit/NeFS.h
new file mode 100644
index 00000000..54861dec
--- /dev/null
+++ b/src/kernel/FSKit/NeFS.h
@@ -0,0 +1,413 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ FILE: NeFS.h
+ PURPOSE: NeFS (New extended File System) support.
+
+ Revision History:
+
+ ?/?/?: Added file (amlel)
+ 12/02/24: Add UUID macro for EPM and GPT partition schemes.
+ 3/16/24: Add mandatory sector size, kNeFSSectorSz is set to 2048 by
+default.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DriveMgr.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <hint/CompilerHint.h>
+
+/**
+ @brief New extended File System specification.
+ @author Amlal El Mahrouss (Amlal El Mahrouss, amlalelmahrouss at icloud dot com)
+*/
+
+#define kNeFSInvalidFork (-1)
+#define kNeFSInvalidCatalog (-1)
+#define kNeFSCatalogNameLen (256)
+
+#define kNeFSVolumeName "NeFS Volume"
+
+#define kNeFSMinimumDiskSize (mib_cast(8))
+
+#define kNeFSSectorSz (512)
+
+#define kNeFSIdentLen (8)
+#define kNeFSIdent " NeFS"
+#define kNeFSPadLen (392)
+
+#define kNeFSMetaFilePrefix '$'
+
+#define kNeFSVersionInteger (0x0129)
+#define kNeFSVerionString "1.2.9"
+
+/// @brief Standard fork types.
+#define kNeFSDataFork "main_data"
+#define kNeFSResourceFork "main_rsrc"
+
+#define kNeFSForkSize (sizeof(NEFS_FORK_STRUCT))
+
+#define kNeFSPartitionTypeStandard (7)
+#define kNeFSPartitionTypePage (8)
+#define kNeFSPartitionTypeBoot (9)
+
+#define kNeFSCatalogKindFile (1)
+#define kNeFSCatalogKindDir (2)
+#define kNeFSCatalogKindAlias (3)
+
+//! Shared between network and/or partitions. Export forks as .zip when copying.
+#define kNeFSCatalogKindShared (4)
+
+#define kNeFSCatalogKindResource (5)
+#define kNeFSCatalogKindExecutable (6)
+
+#define kNeFSCatalogKindPage (8)
+
+#define kNeFSCatalogKindDevice (9)
+#define kNeFSCatalogKindLock (10)
+
+#define kNeFSCatalogKindRLE (11)
+#define kNeFSCatalogKindMetaFile (12)
+
+#define kNeFSCatalogKindTTF (13)
+#define kNeFSCatalogKindRIFF (14)
+#define kNeFSCatalogKindMPEG (15)
+#define kNeFSCatalogKindMOFF (16)
+
+#define kNeFSSeparator '/'
+#define kNeFSSeparatorAlt '/'
+
+#define kNeFSUpDir ".."
+#define kNeFSRoot "/"
+#define kNeFSRootAlt "/"
+
+#define kNeFSLF '\r'
+#define kNeFSEOF (-1)
+
+#define kNeFSBitWidth (sizeof(Kernel::Char))
+#define kNeFSLbaType (Kernel::Lba)
+
+/// @note Start after the partition map header. (Virtual addressing)
+#define kNeFSRootCatalogStartAddress (1024)
+#define kNeFSCatalogStartAddress (kNeFSRootCatalogStartAddress + sizeof(NEFS_ROOT_PARTITION_BLOCK))
+
+#define kResourceTypeDialog (10)
+#define kResourceTypeString (11)
+#define kResourceTypeMenu (12)
+#define kResourceTypeSound (13)
+#define kResourceTypeFont (14)
+#define kNeFSPartLen (32)
+
+#define kNeFSFlagDeleted (70)
+#define kNeFSFlagUnallocated (0)
+#define kNeFSFlagCreated (71)
+
+#define kNeFSMimeNameLen (200)
+#define kNeFSForkNameLen (199)
+
+#define kNeFSFrameworkExt ".fwrk/"
+#define kNeFSStepsExt ".step/"
+#define kNeFSApplicationExt ".app/"
+#define kNeFSJournalExt ".jrnl"
+
+struct NEFS_CATALOG_STRUCT;
+struct NEFS_FORK_STRUCT;
+struct NEFS_ROOT_PARTITION_BLOCK;
+
+enum {
+ kNeFSHardDrive = 0xC0, // Hard Drive
+ kNeFSSolidStateDrive = 0xC1, // Solid State Drive
+ kNeFSOpticalDrive = 0x0C, // Blu-Ray/DVD
+ kNeFSMassStorageDevice = 0xCC, // USB
+ kNeFSScsiDrive = 0xC4, // SCSI Hard Drive
+ kNeFSFlashDrive = 0xC6,
+ kNeFSUnknown = 0xFF, // Unknown device.
+ kNeFSDriveCount = 7,
+};
+
+enum {
+ kNeFSStatusUnlocked = 0x18,
+ kNeFSStatusLocked,
+ kNeFSStatusError,
+ kNeFSStatusInvalid,
+ kNeFSStatusCount,
+};
+
+/// @brief Catalog record type.
+struct PACKED NEFS_CATALOG_STRUCT final {
+ BOOL ForkOrCatalog : 1 {0};
+
+ Kernel::Char Name[kNeFSCatalogNameLen] = {0};
+ Kernel::Char Mime[kNeFSMimeNameLen] = {0};
+
+ /// Catalog flags.
+ Kernel::UInt16 Flags;
+
+ /// Catalog allocation status.
+ Kernel::UInt16 Status;
+
+ /// Custom catalog flags.
+ Kernel::UInt16 CatalogFlags;
+
+ /// Catalog kind.
+ Kernel::Int32 Kind;
+
+ /// Size of the data fork.
+ Kernel::Lba DataForkSize;
+
+ /// Size of all resource forks.
+ Kernel::Lba ResourceForkSize;
+
+ /// Forks LBA.
+ Kernel::Lba DataFork;
+ Kernel::Lba ResourceFork;
+
+ /// Buddy allocation tracker.
+ Kernel::Lba NextSibling;
+ Kernel::Lba PrevSibling;
+
+ /// Best-buddy tracker.
+ Kernel::Lba NextBestSibling;
+ Kernel::Lba NextPrevSibling;
+
+ Kernel::UInt32 Checksum;
+};
+
+/// @brief Fork type, contains a data page.
+/// @note The way we store is way different than how other filesystems do, specific chunk of code
+/// are written into either the data fork or resource fork, the resource fork is reserved for file
+/// metadata. whereas the data fork is reserved for file data.
+struct PACKED NEFS_FORK_STRUCT final {
+ BOOL ForkOrCatalog : 1 {1};
+
+ Kernel::Char ForkName[kNeFSForkNameLen] = {0};
+ Kernel::Char CatalogName[kNeFSCatalogNameLen] = {0};
+
+ Kernel::Int32 Flags;
+ Kernel::Int32 Kind;
+
+ Kernel::Int64 ResourceId;
+ Kernel::Int32 ResourceKind;
+ Kernel::Int32 ResourceFlags;
+
+ Kernel::Lba DataOffset; // 8 Where to look for this data?
+ Kernel::SizeT DataSize; /// Data size according using sector count.
+
+ Kernel::Lba NextSibling;
+ Kernel::Lba PreviousSibling;
+};
+
+/// @brief Partition block type
+struct PACKED NEFS_ROOT_PARTITION_BLOCK final {
+ Kernel::Char Ident[kNeFSIdentLen] = {0};
+ Kernel::Char PartitionName[kNeFSPartLen] = {0};
+
+ Kernel::Int32 Flags;
+ Kernel::Int32 Kind;
+
+ Kernel::Lba StartCatalog;
+ Kernel::SizeT CatalogCount;
+
+ Kernel::SizeT DiskSize;
+
+ Kernel::SizeT FreeCatalog;
+ Kernel::SizeT FreeSectors;
+
+ Kernel::SizeT SectorCount;
+ Kernel::SizeT SectorSize;
+
+ Kernel::UInt64 Version;
+
+ Kernel::Lba EpmBlock;
+
+ Kernel::Char Pad[kNeFSPadLen];
+};
+
+namespace Kernel {
+class NeFileSystemParser;
+class NeFileSystemJournal;
+class NeFileSystemHelper;
+
+enum {
+ kNeFSSubDriveA,
+ kNeFSSubDriveB,
+ kNeFSSubDriveC,
+ kNeFSSubDriveD,
+ kNeFSSubDriveInvalid,
+ kNeFSSubDriveCount,
+};
+
+/// \brief Resource fork kind.
+enum { kNeFSRsrcForkKind = 0, kNeFSDataForkKind = 1 };
+
+///
+/// \name NeFileSystemParser
+/// \brief NeFS parser class. (catalog creation, remove removal, root,
+/// forks...) Designed like the DOM, detects the filesystem automatically.
+///
+class NeFileSystemParser final {
+ public:
+ explicit NeFileSystemParser() = default;
+ ~NeFileSystemParser() = default;
+
+ public:
+ NE_COPY_DELETE(NeFileSystemParser)
+
+ NE_MOVE_DELETE(NeFileSystemParser)
+
+ public:
+ /// @brief Creates a new fork inside the NeFS partition.
+ /// @param catalog it's catalog
+ /// @param theFork the fork itself.
+ /// @return the fork
+ _Output BOOL CreateFork(_Input NEFS_FORK_STRUCT& in);
+
+ /// @brief Find fork inside New filesystem.
+ /// @param catalog the catalog.
+ /// @param name the fork name.
+ /// @return the fork.
+ _Output NEFS_FORK_STRUCT* FindFork(_Input NEFS_CATALOG_STRUCT* catalog, _Input const Char* name,
+ Boolean data);
+
+ _Output Void RemoveFork(_Input NEFS_FORK_STRUCT* fork);
+
+ _Output Void CloseFork(_Input NEFS_FORK_STRUCT* fork);
+
+ _Output NEFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalog_name, Lba& ou_lba,
+ Bool search_hidden = YES, Bool local_search = NO);
+
+ _Output NEFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name);
+
+ _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name, _Input const Int32& flags,
+ _Input const Int32& kind);
+
+ _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name);
+
+ _Output Bool WriteCatalog(_Input const Char* catalog, _Input Bool rsrc, _Input VoidPtr data,
+ _Input SizeT sz, _Input const Char* name);
+
+ _Output VoidPtr ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog, _Input Bool isRsrcFork,
+ _Input SizeT dataSz, _Input const Char* forkName);
+
+ _Output Bool Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off);
+
+ _Output SizeT Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog);
+
+ _Output Bool RemoveCatalog(_Input const Char* catalog);
+
+ _Output Bool CloseCatalog(_InOut NEFS_CATALOG_STRUCT* catalog);
+
+ /// @brief Make a EPM+NeFS drive out of the disk.
+ /// @param drive The drive to write on.
+ /// @return If it was sucessful, see err_local_get().
+ _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
+ const Char* part_name);
+
+ public:
+ UInt32 mDriveIndex{kNeFSSubDriveA};
+};
+
+///
+/// \name NeFileSystemHelper
+/// \brief Filesystem helper class.
+///
+
+class NeFileSystemHelper final {
+ public:
+ STATIC const Char* Root();
+ STATIC const Char* UpDir();
+ STATIC Char Separator();
+ STATIC Char MetaFile();
+};
+
+/// @brief Journal class for NeFS.
+class NeFileSystemJournal final {
+ private:
+ NEFS_CATALOG_STRUCT* mNode{nullptr};
+
+ public:
+ explicit NeFileSystemJournal(const char* stamp = nullptr) {
+ if (!stamp) {
+ kout << "Invalid: Journal stamp, using default name.\r";
+ return;
+ }
+
+ (Void)(kout << "Info: Journal stamp: " << stamp << kendl);
+ rt_copy_memory((VoidPtr) stamp, this->mStamp, rt_string_len(stamp));
+ }
+
+ ~NeFileSystemJournal() = default;
+
+ NE_COPY_DEFAULT(NeFileSystemJournal)
+
+ Bool CreateJournal(NeFileSystemParser* parser) {
+ if (!parser) return NO;
+
+ delete parser->CreateCatalog("/etc/xml/", 0, kNeFSCatalogKindDir);
+ mNode = parser->CreateCatalog(mStamp);
+
+ if (!mNode) return NO;
+
+ return YES;
+ }
+
+ Bool GetJournal(NeFileSystemParser* parser) {
+ if (!parser) return NO;
+
+ auto node = parser->GetCatalog(mStamp);
+
+ if (node) {
+ mNode = node;
+ return YES;
+ }
+
+ return NO;
+ }
+
+ Bool ReleaseJournal() {
+ if (mNode) {
+ delete mNode;
+ mNode = nullptr;
+ return YES;
+ }
+
+ return NO;
+ }
+
+ Bool CommitJournal(NeFileSystemParser* parser, Char* xml_data, Char* journal_name) {
+ if (!parser || !mNode) return NO;
+
+ NEFS_FORK_STRUCT new_fork{};
+
+ rt_copy_memory(mStamp, new_fork.CatalogName, rt_string_len(mStamp));
+ rt_copy_memory(journal_name, new_fork.ForkName, rt_string_len(journal_name));
+
+ new_fork.ResourceKind = 0;
+ new_fork.ResourceId = 0;
+ new_fork.ResourceFlags = 0;
+ new_fork.DataSize = rt_string_len(xml_data);
+ new_fork.Kind = kNeFSRsrcForkKind;
+
+ if (!parser->CreateFork(new_fork)) return NO;
+
+ (Void)(kout << "XML commit: " << xml_data << " to fork: " << journal_name << kendl);
+
+ auto ret = parser->WriteCatalog(new_fork.CatalogName, YES, xml_data, rt_string_len(xml_data),
+ new_fork.ForkName);
+
+ return ret;
+ }
+
+ private:
+ Char mStamp[kNeFSCatalogNameLen] = {"/etc/xml/journal" kNeFSJournalExt};
+};
+
+namespace NeFS {
+ Boolean fs_init_nefs(Void) noexcept;
+} // namespace NeFS
+} // namespace Kernel
diff --git a/src/kernel/FSKit/OpenHeFS.h b/src/kernel/FSKit/OpenHeFS.h
new file mode 100644
index 00000000..bd392fc3
--- /dev/null
+++ b/src/kernel/FSKit/OpenHeFS.h
@@ -0,0 +1,434 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/Crc32.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <hint/CompilerHint.h>
+
+/// @file OpenHeFS.h
+/// @brief OpenHeFS filesystem support.
+
+#define kOpenHeFSVersion (0x0104)
+#define kOpenHeFSMagic "OpenHeFS"
+#define kOpenHeFSMagicLen (9U)
+
+#define kOpenHeFSBlockLen (512U)
+#define kOpenHeFSFileNameLen (256U)
+#define kOpenHeFSPartNameLen (128U)
+
+#define kOpenHeFSMinimumDiskSize (gib_cast(128))
+
+#define kOpenHeFSDefaultVolumeName u8"OpenHeFS Volume"
+
+#define kOpenHeFSINDStartOffset (sizeof(HEFS_BOOT_NODE))
+#define kOpenHeFSINStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY))
+
+#define kOpenHeFSRootDirectory "/"
+#define kOpenHeFSRootDirectoryU8 u8"/"
+
+#define kOpenHeFSSeparator '/'
+#define kOpenHeFSUpDir ".."
+
+#define kOpenHeFSRootDirectoryLen (2U)
+
+#define kOpenHeFSSearchAllStr u8"*"
+
+struct HEFS_BOOT_NODE;
+struct HEFS_INDEX_NODE;
+struct HEFS_INDEX_NODE_DIRECTORY;
+struct HEFS_JOURNAL_NODE;
+
+enum : UInt8 {
+ kOpenHeFSHardDrive = 0xC0, // Hard Drive
+ kOpenHeFSSolidStateDrive = 0xC1, // Solid State Drive
+ kOpenHeFSOpticalDrive = 0x0C, // Blu-Ray/DVD
+ kOpenHeFSMassStorageDevice = 0xCC, // USB
+ kOpenHeFSScsiDrive = 0xC4, // SCSI Hard Drive
+ kOpenHeFSFlashDrive = 0xC6,
+ kOpenHeFSUnknown = 0xFF, // Unknown device.
+ kOpenHeFSDriveCount = 8,
+};
+
+enum : UInt8 {
+ kOpenHeFSStatusUnlocked = 0x18,
+ kOpenHeFSStatusLocked,
+ kOpenHeFSStatusError,
+ kOpenHeFSStatusInvalid,
+ kOpenHeFSStatusCount,
+};
+
+enum : UInt16 {
+ kOpenHeFSEncodingFlagsUTF8 = 0x50,
+ kOpenHeFSEncodingFlagsUTF16,
+ kOpenHeFSEncodingFlagsUTF32,
+ kOpenHeFSEncodingFlagsUTF16BE,
+ kOpenHeFSEncodingFlagsUTF16LE,
+ kOpenHeFSEncodingFlagsUTF32BE,
+ kOpenHeFSEncodingFlagsUTF32LE,
+ kOpenHeFSEncodingFlagsUTF8BE,
+ kOpenHeFSEncodingFlagsUTF8LE,
+ kOpenHeFSEncodingFlagsBinary,
+ kOpenHeFSEncodingFlagsCount = 11,
+ kOpenHeFSFlagsNone = 0,
+ kOpenHeFSFlagsReadOnly = 0x100,
+ kOpenHeFSFlagsHidden,
+ kOpenHeFSFlagsSystem,
+ kOpenHeFSFlagsArchive,
+ kOpenHeFSFlagsDevice,
+ kOpenHeFSFlagsCount = 7
+};
+
+inline constexpr UInt16 kOpenHeFSFileKindRegular = 0x00;
+inline constexpr UInt16 kOpenHeFSFileKindDirectory = 0x01;
+inline constexpr UInt16 kOpenHeFSFileKindBlock = 0x02;
+inline constexpr UInt16 kOpenHeFSFileKindCharacter = 0x03;
+inline constexpr UInt16 kOpenHeFSFileKindFIFO = 0x04;
+inline constexpr UInt16 kOpenHeFSFileKindSocket = 0x05;
+inline constexpr UInt16 kOpenHeFSFileKindSymbolicLink = 0x06;
+inline constexpr UInt16 kOpenHeFSFileKindUnknown = 0x07;
+inline constexpr UInt16 kOpenHeFSFileKindCount = 0x08;
+
+/// @brief OpenHeFS blocks are array containing sparse blocks of data.
+/// @details The blocks are used to store the data of a file. Each block is a pointer to a block of
+/// data on the disk.
+inline constexpr UInt16 kOpenHeFSSliceCount = 0x10;
+
+inline constexpr UInt16 kOpenHeFSInvalidVID = 0xFFFF;
+
+namespace Kernel {
+/// @brief Access time type.
+/// @details Used to keep track of the INode, INodeDir allocation status.
+typedef UInt64 ATime;
+
+/// @brief OpenHeFS Boot node.
+/// @details Acts like a superblock, it contains the information about the filesystem.
+/// @note The boot node is the first block of the filesystem.
+struct PACKED HEFS_BOOT_NODE final {
+ Char fMagic[kOpenHeFSMagicLen]; /// @brief Magic number of the filesystem.
+ Utf8Char fVolName[kOpenHeFSPartNameLen]; /// @brief Volume name.
+ UInt32 fVersion; /// @brief Version of the filesystem.
+ UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem.
+ UInt64 fSectorCount; /// @brief Number of sectors in the filesystem.
+ UInt64 fSectorSize; /// @brief Size of the sector.
+ UInt32 fChecksum; /// @brief Checksum of the boot node.
+ UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical
+ /// Drive, etc).
+ UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc).
+ UInt64 fStartIND; /// @brief Start of the INode directory tree.
+ UInt64 fEndIND; /// @brief End of the INode directory tree.
+ UInt64 fINDCount; /// @brief Number of leafs in the INode tree.
+ UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the
+ /// real size of the disk.)
+ UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid).
+ UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc).
+ UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used).
+ UInt64 fStartIN; /// @brief Start INodes range
+ UInt64 fEndIN; /// @brief End INodes range
+ UInt64 fStartBlock; /// @brief Start Blocks range
+ UInt64 fEndBlock; /// @brief End Blocks range
+ UInt64 fJournalLBA; /// @brief Boot Node's COW journal LBA.
+ Char fPad[264];
+};
+
+inline constexpr ATime kOpenHeFSTimeInvalid = 0x0000000000000000;
+inline constexpr ATime kOpenHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1;
+
+/// @brief Journal Node structure
+/// @param fHashPath target hash path
+/// @param fStatus target status
+/// @param fCopyElem copy of element
+/// @param fCopyKind kind of element
+struct PACKED HEFS_JOURNAL_NODE {
+ UInt64 fHashPath;
+ UInt64 fStatus;
+ UInt64 fCopyElem;
+ UInt8 fCopyKind;
+ UInt8 fPad[487];
+};
+
+/// @brief This enum defines the opcode of the journal, here mentioned as 'kinds'
+enum HeFSJournalKind : UInt8 {
+ kJournalKindInvalid = 0x00,
+ kJournalKindWrite = 0x01,
+ kJournalKindRename = 0x02,
+ kJournalKindDelete = 0x03,
+ kJournalKindFlagEdit = 0x04,
+ kJournalKindCreate = 0x05,
+ kJournalKindCount,
+};
+
+/// @brief OpenHeFS index node.
+/// @details This structure is used to store the file information of a file.
+/// @note The index node is a special type of INode that contains the file information.
+/// @note The index node is used to store the file information of a file.
+struct PACKED HEFS_INDEX_NODE final {
+ UInt64 fHashPath; /// @brief File name.
+ UInt32 fFlags; /// @brief File flags.
+ UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
+ /// Symbolic Link, Unknown).
+ UInt32 fSize; /// @brief File size.
+ UInt32 fChecksum; /// @brief Checksum.
+
+ Boolean fSymLink; /// @brief Is this a symbolic link? (if yes, the fName is the path to
+ /// the file and blocklinkstart and end contains it's inodes.)
+
+ ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps.
+ UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
+ UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
+
+ /// @brief Extents system by using blocks
+ /// @details Using an offset to ask fBase, and fLength to compute each slice's length.
+ UInt32 fOffsetSliceLow;
+ UInt32 fOffsetSliceHigh;
+
+ Char fPad[437];
+};
+
+enum {
+ kOpenHeFSInvalidColor = 0,
+ kOpenHeFSRed = 100,
+ kOpenHeFSBlack,
+ kOpenHeFSColorCount,
+};
+
+/// @brief OpenHeFS directory node.
+/// @details This structure is used to store the directory information of a file.
+/// @note The directory node is a special type of INode that contains the directory entries.
+struct PACKED HEFS_INDEX_NODE_DIRECTORY final {
+ UInt64 fHashPath; /// @brief Directory path as FNV hash.
+
+ UInt32 fFlags; /// @brief File flags.
+ UInt16 fReserved; /// @note Reserved for future use.
+ UInt32 fEntryCount; /// @brief Entry Count of this directory inode.
+ UInt32 fChecksum; /// @brief Checksum of the file, index node checksum.
+
+ ATime fCreated, fAccessed, fModified,
+ fDeleted; /// @brief File timestamps and allocation status.
+ UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
+ UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
+
+ /// @note These slices are organized as:
+ /// [0] = OFFSET
+ /// [1] = SIZE
+ /// @note Thus the += 2 when iterating over them.
+ UInt64 fINSlices[kOpenHeFSSliceCount]; /// @brief Start of the index node.
+
+ UInt8 fColor; /// @brief Color of the node. (Red or Black).
+ Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers.
+
+ Char fPad[285];
+};
+} // namespace Kernel
+
+namespace Kernel::Detail {
+/// @brief OpenHeFS get year from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the year value.
+/// @note The year is stored in the upper 32 bits of the ATime value.
+inline UInt32 hefs_year_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 32;
+}
+
+/// @brief OpenHeFS get month from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the month value.
+/// @note The month is stored in the upper 24 bits of the ATime value.
+inline UInt32 hefs_month_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 24;
+}
+
+/// @brief OpenHeFS get day from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the day value.
+/// @note The day is stored in the upper 16 bits of the ATime value.
+inline UInt32 hefs_day_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 16;
+}
+
+/// @brief OpenHeFS get hour from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the hour value.
+/// @note The hour is stored in the upper 8 bits of the ATime value.
+inline UInt32 hefs_hour_get(ATime raw_atime) noexcept {
+ return (raw_atime) >> 8;
+}
+
+/// @brief OpenHeFS get minute from ATime.
+/// @param raw_atime the raw ATime value.
+/// @return the minute value.
+/// @note The minute is stored in the lower 8 bits of the ATime value.
+inline UInt32 hefs_minute_get(ATime raw_atime) noexcept {
+ return (raw_atime) &0xFF;
+}
+
+inline constexpr UInt32 kOpenHeFSBaseYear = 1970;
+inline constexpr UInt32 kOpenHeFSBaseMonth = 1;
+inline constexpr UInt32 kOpenHeFSBaseDay = 1;
+inline constexpr UInt32 kOpenHeFSBaseHour = 0;
+inline constexpr UInt32 kOpenHeFSBaseMinute = 0;
+
+inline const Char* hefs_status_to_string(UInt16 status) noexcept {
+ switch (status) {
+ case kOpenHeFSStatusUnlocked:
+ return "Unlocked";
+ case kOpenHeFSStatusLocked:
+ return "Locked";
+ case kOpenHeFSStatusError:
+ return "Error";
+ case kOpenHeFSStatusInvalid:
+ return "Invalid";
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_drive_kind_to_string(UInt8 kind) noexcept {
+ switch (kind) {
+ case kOpenHeFSHardDrive:
+ return "Hard Drive";
+ case kOpenHeFSSolidStateDrive:
+ return "Solid State Drive";
+ case kOpenHeFSOpticalDrive:
+ return "Optical Drive";
+ case kOpenHeFSMassStorageDevice:
+ return "Mass Storage Device";
+ case kOpenHeFSScsiDrive:
+ return "SCSI/SAS Drive";
+ case kOpenHeFSFlashDrive:
+ return "Flash Drive";
+ case kOpenHeFSUnknown:
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_encoding_to_string(UInt8 encoding) noexcept {
+ switch (encoding) {
+ case kOpenHeFSEncodingFlagsUTF8:
+ return "UTF-8";
+ case kOpenHeFSEncodingFlagsUTF16:
+ return "UTF-16";
+ case kOpenHeFSEncodingFlagsUTF32:
+ return "UTF-32";
+ case kOpenHeFSEncodingFlagsUTF16BE:
+ return "UTF-16BE";
+ case kOpenHeFSEncodingFlagsUTF16LE:
+ return "UTF-16LE";
+ case kOpenHeFSEncodingFlagsUTF32BE:
+ return "UTF-32BE";
+ case kOpenHeFSEncodingFlagsUTF32LE:
+ return "UTF-32LE";
+ case kOpenHeFSEncodingFlagsUTF8BE:
+ return "UTF-8BE";
+ case kOpenHeFSEncodingFlagsUTF8LE:
+ return "UTF-8LE";
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_file_kind_to_string(UInt16 kind) noexcept {
+ switch (kind) {
+ case kOpenHeFSFileKindRegular:
+ return "Regular File";
+ case kOpenHeFSFileKindDirectory:
+ return "Directory";
+ case kOpenHeFSFileKindBlock:
+ return "Block Device";
+ case kOpenHeFSFileKindCharacter:
+ return "Character Device";
+ case kOpenHeFSFileKindFIFO:
+ return "FIFO";
+ case kOpenHeFSFileKindSocket:
+ return "Socket";
+ case kOpenHeFSFileKindSymbolicLink:
+ return "Symbolic Link";
+ case kOpenHeFSFileKindUnknown:
+ default:
+ return "Unknown";
+ }
+}
+
+inline const Char* hefs_file_flags_to_string(UInt32 flags) noexcept {
+ switch (flags) {
+ case kOpenHeFSFlagsNone:
+ return "No Flags";
+ case kOpenHeFSFlagsReadOnly:
+ return "Read Only";
+ case kOpenHeFSFlagsHidden:
+ return "Hidden";
+ case kOpenHeFSFlagsSystem:
+ return "System";
+ case kOpenHeFSFlagsArchive:
+ return "Archive";
+ case kOpenHeFSFlagsDevice:
+ return "Device";
+ default:
+ return "Unknown";
+ }
+}
+} // namespace Kernel::Detail
+
+namespace Kernel {
+/// @brief OpenHeFS filesystem parser class.
+/// @details This class is used to parse the OpenHeFS filesystem.
+class HeFileSystemParser final {
+ public:
+ HeFileSystemParser() = default;
+ ~HeFileSystemParser() = default;
+
+ public:
+ HeFileSystemParser(const HeFileSystemParser&) = delete;
+ HeFileSystemParser& operator=(const HeFileSystemParser&) = delete;
+
+ HeFileSystemParser(HeFileSystemParser&&) = delete;
+ HeFileSystemParser& operator=(HeFileSystemParser&&) = delete;
+
+ public:
+ /// @brief Make a EPM+OpenHeFS drive out of the disk.
+ /// @param drive The drive to write on.
+ /// @return If it was sucessful, see err_local_get().
+ _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* part_name);
+
+ _Output Bool CreateINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir);
+
+ _Output Bool RemoveINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir);
+
+ _Output Bool CreateINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir,
+ const Utf8Char* name, const UInt8 kind);
+
+ _Output Bool DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir,
+ const Utf8Char* name, const UInt8 kind);
+
+ _Output Bool INodeManip(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz,
+ const Utf8Char* dir, const Utf8Char* name, const UInt8 kind,
+ const BOOL input);
+
+ private:
+ _Output Bool INodeCtlManip(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name, const BOOL delete_or_create,
+ const UInt8 kind);
+
+ _Output Bool INodeDirectoryCtlManip(_Input DriveTrait* drive, _Input const Int32 flags,
+ const Utf8Char* dir, const BOOL delete_or_create);
+};
+
+namespace OpenHeFS {
+
+ /// @brief Initialize OpenHeFS inside the main disk.
+ /// @return Whether it successfuly formated it or not.
+ Boolean fs_init_openhefs(Void) noexcept;
+} // namespace OpenHeFS
+} // namespace Kernel
diff --git a/src/kernel/FirmwareKit/.gitkeep b/src/kernel/FirmwareKit/.gitkeep
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/src/kernel/FirmwareKit/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/src/kernel/FirmwareKit/EFI.h b/src/kernel/FirmwareKit/EFI.h
new file mode 100644
index 00000000..f75f0fbe
--- /dev/null
+++ b/src/kernel/FirmwareKit/EFI.h
@@ -0,0 +1,12 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <FirmwareKit/EFI/EFI.h>
+#include <FirmwareKit/GPT.h>
+
+/// @note this header is used to reference the EFI/EFI.h
diff --git a/src/kernel/FirmwareKit/EFI/API.h b/src/kernel/FirmwareKit/EFI/API.h
new file mode 100644
index 00000000..24fceb2b
--- /dev/null
+++ b/src/kernel/FirmwareKit/EFI/API.h
@@ -0,0 +1,88 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __EFI_API__
+#define __EFI_API__
+
+#include <FirmwareKit/EFI/EFI.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+
+#ifdef __BOOTZ__
+// forward decl.
+class BootTextWriter;
+
+#define __BOOTKIT_NO_INCLUDE__ 1
+
+#include <BootKit/BootKit.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#endif // ifdef __BOOTZ__
+
+inline EfiSystemTable* ST = nullptr;
+inline EfiBootServices* BS = nullptr;
+
+EXTERN_C void rt_cli();
+EXTERN_C void rt_halt();
+
+namespace Boot {
+/// @brief Halt and clear interrut flag on x86.
+/// @return
+inline Void Stop() noexcept {
+ while (YES) {
+ rt_cli();
+ rt_halt();
+ }
+}
+
+/**
+@brief Exit EFI API to let the OS load correctly.
+Bascially frees everything we have in the EFI side.
+*/
+inline Void ExitBootServices(UInt64 MapKey, EfiHandlePtr ImageHandle) noexcept {
+ if (!ST) return;
+
+ ST->BootServices->ExitBootServices(ImageHandle, MapKey);
+}
+
+inline UInt32 Platform() noexcept {
+ return kPeMachineAMD64;
+}
+
+/***
+ * @brief Throw an error, stop execution as well.
+ * @param ErrorCode error code to be print.
+ * @param Reason reason to be print.
+ */
+inline void ThrowError(const EfiCharType* ErrorCode, const EfiCharType* Reason) noexcept {
+ ST->ConOut->OutputString(ST->ConOut, L"\r*** STOP ***\r");
+
+ ST->ConOut->OutputString(ST->ConOut, L"*** ERROR: ");
+ ST->ConOut->OutputString(ST->ConOut, ErrorCode);
+
+ ST->ConOut->OutputString(ST->ConOut, L" ***\r *** REASON: ");
+ ST->ConOut->OutputString(ST->ConOut, Reason);
+
+ ST->ConOut->OutputString(ST->ConOut, L" ***\r");
+
+ Boot::Stop();
+}
+} // namespace Boot
+
+inline void fw_init_efi(EfiSystemTable* SystemTable) noexcept {
+ if (!SystemTable) return;
+
+ ST = SystemTable;
+ BS = ST->BootServices;
+}
+
+#ifdef __BOOTZ__
+
+#include <BootKit/Platform.h>
+
+#endif // ifdef __BOOTZ__
+
+#endif /* ifndef __EFI_API__ */
diff --git a/src/kernel/FirmwareKit/EFI/EFI.h b/src/kernel/FirmwareKit/EFI/EFI.h
new file mode 100644
index 00000000..240fb9ea
--- /dev/null
+++ b/src/kernel/FirmwareKit/EFI/EFI.h
@@ -0,0 +1,916 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef FIRMWARE_KIT_EFI_H
+#define FIRMWARE_KIT_EFI_H
+
+/**
+@brief Implementation of the main EFI protocols.
+*/
+
+#include <NeKit/Defines.h>
+
+using namespace Kernel;
+
+/* we always use stdcall in EFI, the pascal way of calling functions. */
+
+#ifndef EPI_API
+#define EFI_API __attribute__((ms_abi))
+#endif // ifndef EPI_API
+
+#ifndef EPIAPI
+#define EFIAPI __attribute__((ms_abi))
+#endif // ifndef EPIAPI
+
+#define IN
+#define OUT
+#define OPTIONAL
+
+#define EFI_STATUS EfiStatusType
+
+#define EFI_FINAL final
+
+// Forward decls
+
+struct EfiTableHeader;
+struct EfiLoadFileProtocol;
+struct EfiSimpleTextOutputProtocol;
+struct EfiDevicePathProtocol;
+struct EfiBootServices;
+struct EfiMemoryDescriptor;
+struct EfiSystemTable;
+struct EFI_GUID;
+struct EfiFileDevicePathProtocol;
+struct EfiHandle;
+struct EfiGraphicsOutputProtocol;
+struct EfiBitmask;
+struct EfiFileProtocol;
+struct EfiSimpleTextInputProtocol;
+
+typedef UInt64 EfiStatusType;
+
+typedef Char16 EfiChar16Type;
+
+/// @brief Core Handle Kind
+/// Self is like NT's Win32 HANDLE type.
+typedef struct EfiHandle {
+} * EfiHandlePtr;
+
+/* UEFI uses wide characters by default. */
+typedef WideChar EfiCharType;
+
+typedef UInt64 EfiPhysicalAddress;
+typedef UIntPtr EfiVirtualAddress;
+
+/// What's BootBolicy?
+/// If TRUE, indicates that the request originates from the boot manager, and
+/// that the boot manager is attempting to load FilePath as a boot selection. If
+/// FALSE, then FilePath must match an exact file to be loaded.
+
+typedef UInt64(EFI_API* EfiTextString)(struct EfiSimpleTextOutputProtocol* Self,
+ const WideChar* OutputString);
+
+typedef UInt64(EFI_API* EfiTextAttrib)(struct EfiSimpleTextOutputProtocol* Self,
+ const WideChar Attribute);
+
+typedef UInt64(EFI_API* EfiTextClear)(struct EfiSimpleTextOutputProtocol* Self);
+
+typedef UInt64(EFI_API* EfiLoadFile)(EfiLoadFileProtocol* Self, EfiFileDevicePathProtocol* FilePath,
+ Boolean BootPolicy, UInt32* BufferSize, VoidPtr Buffer);
+
+typedef UInt64(EFI_API* EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf, SizeT Length);
+
+typedef UInt64(EFI_API* EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length);
+
+typedef UInt64(EFI_API* EfiHandleProtocol)(EfiHandlePtr Handle, EFI_GUID* Guid, VoidPtr* Device);
+
+typedef UInt64(EFI_API* EfiLocateDevicePath)(EFI_GUID* Protocol, EfiDevicePathProtocol** DevicePath,
+ EfiHandlePtr Device);
+
+typedef UInt64(EFI_API* EfiStartImage)(EfiHandlePtr Handle, VoidPtr ArgsSize, VoidPtr ArgsPtr);
+
+typedef UInt64(EFI_API* EfiLoadImage)(Boolean BootPolicy, EfiHandlePtr ParentHandle,
+ EfiFileDevicePathProtocol* DeviceFile, VoidPtr buffer,
+ SizeT size, EfiHandlePtr* ppHandle);
+
+/// EFI pool helpers, taken from iPXE.
+
+typedef enum EfiMemoryType {
+ ///
+ /// Not used.
+ ///
+ EfiReservedMemoryType,
+ ///
+ /// The code portions of a loaded application.
+ /// (Note that UEFI OS loaders are UEFI applications.)
+ ///
+ EfiLoaderCode,
+ ///
+ /// The data portions of a loaded application and the default data allocation
+ /// type used by an application to allocate pool memory.
+ ///
+ EfiLoaderData,
+ ///
+ /// The code portions of a loaded Boot Services Driver.
+ ///
+ EfiBootServicesCode,
+ ///
+ /// The data portions of a loaded Boot Serves Driver, and the default data
+ /// allocation type used by a Boot Services Driver to allocate pool memory.
+ ///
+ EfiBootServicesData,
+ ///
+ /// The code portions of a loaded Runtime Services Driver.
+ ///
+ EfiRuntimeServicesCode,
+ ///
+ /// The data portions of a loaded Runtime Services Driver and the default
+ /// data allocation type used by a Runtime Services Driver to allocate pool
+ /// memory.
+ ///
+ EfiRuntimeServicesData,
+ ///
+ /// Free (unallocated) memory.
+ ///
+ EfiConventionalMemory,
+ ///
+ /// Memory in which errors have been detected.
+ ///
+ EfiUnusableMemory,
+ ///
+ /// Memory that holds the ACPI tables.
+ ///
+ EfiACPIReclaimMemory,
+ ///
+ /// Address space reserved for use by the firmware.
+ ///
+ EfiACPIMemoryNVS,
+ ///
+ /// Used by system firmware to request that a memory-mapped IO region
+ /// be mapped by the OS to a virtual address so it can be accessed by EFI
+ /// runtime services.
+ ///
+ EfiMemoryMappedIO,
+ ///
+ /// System memory-mapped IO region that is used to translate memory
+ /// cycles to IO cycles by the processor.
+ ///
+ EfiMemoryMappedIOPortSpace,
+ ///
+ /// Address space reserved by the firmware for code that is part of the
+ /// processor.
+ ///
+ EfiPalCode,
+ ///
+ /// A memory region that operates as EfiConventionalMemory,
+ /// however it happens to also support byte-addressable non-volatility.
+ ///
+ EfiPersistentMemory,
+ ///
+ /// A memory region that describes system memory that has not been accepted
+ /// by a corresponding call to the underlying isolation architecture.
+ ///
+ EfiUnacceptedMemoryType,
+ ///
+ /// The last type of memory.
+ /// Not a real type.
+ ///
+ EfiMaxMemoryType,
+} EfiMemoryType;
+
+typedef enum EfiAllocateType {
+ /// Anything that satisfy the request.
+ AllocateAnyPages,
+ AllocateMaxAddress,
+ ///
+ /// Allocate pages at a specified address.
+ ///
+ AllocateAddress,
+ ///
+ /// Maximum enumeration value that may be used for bounds checking.
+ ///
+ MaxAllocateType
+} EfiAllocateType;
+
+typedef struct EfiMemoryDescriptor {
+ /// @brief Kind of the memory region.
+ UInt32 Kind;
+
+ /// @brief Physical address of the first byte in the memory region. PhysicalStart
+ EfiPhysicalAddress PhysicalStart;
+ ///
+ /// Virtual address of the first byte in the memory region.
+ /// VirtualStart must be aligned on a 4 KiB boundary,
+ /// and must not be above 0xfffffffffffff000.
+ ///
+ EfiVirtualAddress VirtualStart;
+ ///
+ /// NumberOfPages Number of 4 KiB pages in the memory region.
+ /// NumberOfPages must not be 0, and must not be any value
+ /// that would represent a memory page with a start address,
+ /// either physical or virtual, above 0xfffffffffffff000.
+ ///
+ UInt64 NumberOfPages;
+ ///
+ /// Attributes of the memory region that describe the bit mask of capabilities
+ /// for that memory region, and not necessarily the current settings for that
+ /// memory region.
+ ///
+ UInt64 Attribute;
+} EfiMemoryDescriptor;
+
+typedef UInt64(EFI_API* EfiAllocatePool)(EfiMemoryType PoolType, UInt32 Size, VoidPtr* Buffer);
+
+typedef UInt64(EFI_API* EfiFreePool)(VoidPtr Buffer);
+
+typedef UInt64(EFI_API* EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize, UInt32* CrcOut);
+
+/**
+@brief Present in every header, used to identify a UEFI structure.
+*/
+typedef struct EfiTableHeader {
+ UInt64 Signature;
+ UInt32 Revision;
+ UInt32 HeaderSize;
+ UInt32 Crc32;
+ UInt32 Reserved;
+} EfiTableHeader;
+
+#define EFI_ACPI_TABLE_PROTOCOL_GUID \
+ { \
+ 0xffe06bdd, 0x6107, 0x46a6, { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c } \
+ }
+
+#define EFI_LOAD_FILE_PROTOCOL_GUID \
+ { \
+ 0x56EC3091, 0x954C, 0x11d2, { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define EFI_LOAD_FILE2_PROTOCOL_GUID \
+ { \
+ 0x4006c0c1, 0xfcb3, 0x403e, { 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \
+ }
+
+#define EFI_LOADED_IMAGE_PROTOCOL_GUID \
+ { \
+ 0x5B1B31A1, 0x9562, 0x11d2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \
+ }
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { \
+ 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \
+ }
+
+#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \
+ { \
+ 0xA19832B9, 0xAC25, 0x11D3, { 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION 0x00010000
+
+#define EFI_IP4_PROTOCOL_GUID \
+ { \
+ 0x41d94cd2, 0x35b6, 0x455a, { 0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd } \
+ }
+
+#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { \
+ 0x0964e5b22, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \
+ { \
+ 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } \
+ }
+
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+ { \
+ 0x9576e91, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { \
+ 0x0964e5b22, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+typedef UInt64(EfiImageUnload)(EfiHandlePtr ImageHandle);
+
+enum {
+ kPixelRedGreenBlueReserved8BitPerColor,
+ kPixelBlueGreenRedReserved8BitPerColor,
+ kPixelBitMask,
+ kPixelBltOnly,
+ kPixelFormatMax
+};
+
+struct EFI_SIMPLE_NETWORK_PROTOCOL;
+
+typedef EFI_STATUS(EFI_API* EFI_SIMPLE_NETWORK_START)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This);
+
+typedef EFI_STATUS(EFI_API* EFI_SIMPLE_NETWORK_STOP)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This);
+
+typedef EFI_STATUS(EFI_API* EFI_SIMPLE_NETWORK_INITIALIZE)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN UInt32 ExtraRxBufferSize OPTIONAL,
+ IN UInt32 ExtraTxBufferSize OPTIONAL);
+
+typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_RESET)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN Boolean ExtendedVerification);
+
+typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_SHUTDOWN)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This);
+
+typedef UInt8 EfiMacAddress[32];
+
+#define MAX_MCAST_FILTER_CNT 16
+
+typedef struct {
+ UInt32 State;
+ UInt32 HwAddressSize;
+ UInt32 MediaHeaderSize;
+ UInt32 MaxPacketSize;
+ UInt32 NvRamSize;
+ UInt32 NvRamAccessSize;
+ UInt32 ReceiveFilterMask;
+ UInt32 ReceiveFilterSetting;
+ UInt32 MaxMCastFilterCount;
+ UInt32 MCastFilterCount;
+ EfiMacAddress MCastFilter[MAX_MCAST_FILTER_CNT];
+ EfiMacAddress CurrentAddress;
+ EfiMacAddress BroadcastAddress;
+ EfiMacAddress PermanentAddress;
+ UInt8 IfType;
+ BOOL MacAddressChangeable;
+ BOOL MultipleTxSupported;
+ BOOL MediaPresentSupported;
+ BOOL MediaPresent;
+} EFI_SIMPLE_NETWORK_MODE;
+
+typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_TRANSMIT)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN UInt32 HeaderSize, IN UInt32 BufferSize,
+ IN Void* Buffer,
+ IN EfiMacAddress* SrcAddr OPTIONAL,
+ IN EfiMacAddress* DestAddr OPTIONAL,
+ IN UInt16* Protocol OPTIONAL);
+
+typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_RECEIVE)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ OUT UInt32* HeaderSize OPTIONAL,
+ IN OUT UInt32* BufferSize, OUT Void* Buffer,
+ OUT EfiMacAddress* SrcAddr OPTIONAL,
+ OUT EfiMacAddress* DestAddr OPTIONAL,
+ OUT UInt16* Protocol OPTIONAL);
+
+typedef struct EFI_SIMPLE_NETWORK_PROTOCOL {
+ UInt64 Revision;
+ EFI_SIMPLE_NETWORK_START Start;
+ EFI_SIMPLE_NETWORK_STOP Stop;
+ EFI_SIMPLE_NETWORK_INITIALIZE Initialize;
+ EFI_SIMPLE_NETWORK_RESET Reset;
+ EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown;
+ VoidPtr ReceiveFilters;
+ VoidPtr StationAddress;
+ VoidPtr Statistics;
+ VoidPtr MCastIpToMac;
+ VoidPtr NvData;
+ VoidPtr GetStatus;
+ EFI_SIMPLE_NETWORK_TRANSMIT Transmit;
+ EFI_SIMPLE_NETWORK_RECEIVE Receive;
+ VoidPtr WaitForPacket;
+ EFI_SIMPLE_NETWORK_MODE* Mode;
+} EFI_SIMPLE_NETWORK_PROTOCOL;
+
+typedef struct EfiBitmask {
+ UInt32 RedMask;
+ UInt32 GreenMask;
+ UInt32 BlueMask;
+ UInt32 ReservedMask;
+} EfiBitmask;
+
+typedef struct {
+ UInt8 Blue;
+ UInt8 Green;
+ UInt8 Red;
+ UInt8 Reserved;
+} EfiGraphicsOutputBltPixel;
+
+typedef enum EfiGraphicsOutputProtocolBltOperation {
+ EfiBltVideoFill,
+ EfiBltVideoToBltBuffer,
+ EfiBltBufferToVideo,
+ EfiBltVideoToVideo,
+ EfiGraphicsOutputBltOperationMax
+} EfiGraphicsOutputProtocolBltOperation;
+
+typedef struct EfiGraphicsOutputProtocolModeInformation {
+ UInt32 Version;
+ UInt32 HorizontalResolution;
+ UInt32 VerticalResolution;
+ UInt32 PixelFormat;
+ EfiBitmask PixelInformation;
+ UInt32 PixelsPerScanLine;
+} EfiGraphicsOutputProtocolModeInformation;
+
+typedef UInt64(EFI_API* EfiGraphicsOutputProtocolQueryMode)(
+ EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber, UInt32* SizeOfInfo,
+ EfiGraphicsOutputProtocolModeInformation** Info);
+
+typedef UInt64(EFI_API* EfiGraphicsOutputProtocolSetMode)(EfiGraphicsOutputProtocol* Self,
+ UInt32 ModeNumber);
+
+typedef UInt64(EFI_API* EfiGraphicsOutputProtocolBlt)(
+ EfiGraphicsOutputProtocol* Self, EfiGraphicsOutputBltPixel* BltBuffer,
+ EfiGraphicsOutputProtocolBltOperation BltOperation, UInt32 SourceX, UInt32 SourceY,
+ UInt32 DestinationX, UInt32 DestinationY, UInt32 Width, UInt32 Height, UInt32 Delta);
+
+typedef struct {
+ UInt32 MaxMode;
+ UInt32 Mode;
+ EfiGraphicsOutputProtocolModeInformation* Info;
+ UInt32 SizeOfInfo;
+ UIntPtr FrameBufferBase;
+ UInt32 FrameBufferSize;
+} EfiGraphicsOutputProtocolMode;
+
+typedef struct EfiGraphicsOutputProtocol {
+ EfiGraphicsOutputProtocolQueryMode QueryMode;
+ EfiGraphicsOutputProtocolSetMode SetMode;
+ EfiGraphicsOutputProtocolBlt Blt;
+ EfiGraphicsOutputProtocolMode* Mode;
+} EfiGraphicsOutputProtocol;
+
+typedef struct EfiLoadImageProtocol {
+ UInt32 Revision;
+ EfiHandlePtr ParentHandle;
+ EfiSystemTable* SystemTable;
+
+ // Source location of the image
+ EfiHandlePtr DeviceHandle;
+ EfiDevicePathProtocol* FilePath;
+ Void* Reserved;
+
+ // Image’s load options
+ UInt32 LoadOptionsSize;
+ Void* LoadOptions;
+
+ // Location where image was loaded
+ Void* ImageBase;
+ UInt64 ImageSize;
+ EfiMemoryType ImageCodeType;
+ EfiMemoryType ImageDataType;
+ EfiImageUnload Unload;
+} EfiLoadImageProtocol;
+
+typedef struct EfiLoadFileProtocol {
+ EfiLoadFile LoadFile;
+} EfiLoadFileProtocol;
+
+typedef struct EfiDevicePathProtocol {
+ UInt8 Kind;
+ UInt8 SubType;
+ UInt8 Length[2];
+} EfiDevicePathProtocol;
+
+typedef struct EfiFileDevicePathProtocol {
+ EfiDevicePathProtocol Proto;
+
+ ///
+ /// File Path of this struct
+ ///
+ WideChar Path[kPathLen];
+} EfiFileDevicePathProtocol;
+
+typedef UInt64(EFI_API* EfiExitBootServices)(VoidPtr ImageHandle, UInt32 MapKey);
+
+typedef UInt64(EFI_API* EfiAllocatePages)(EfiAllocateType AllocType, EfiMemoryType MemType,
+ UInt32 Count, EfiPhysicalAddress* Memory);
+
+typedef UInt64(EFI_API* EfiFreePages)(EfiPhysicalAddress* Memory, UInt32 Pages);
+
+typedef UInt64(EFI_API* EfiGetMemoryMap)(UInt32* MapSize, EfiMemoryDescriptor* DescPtr,
+ UInt32* MapKey, UInt32* DescSize, UInt32* DescVersion);
+
+/**
+ * @brief GUID type, something you can also find in CFKit.
+ */
+typedef struct EFI_GUID EFI_FINAL {
+ UInt32 Data1;
+ UInt16 Data2;
+ UInt16 Data3;
+ UInt8 Data4[8];
+} EFI_GUID;
+
+/***
+ * Protocol stuff...
+ */
+
+#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
+ { \
+ 0x387477c1, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+/** some helpers */
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
+
+typedef UInt64(EFI_API* EfiLocateProtocol)(EFI_GUID* Protocol, VoidPtr Registration,
+ VoidPtr* Interface);
+
+typedef UInt64(EFI_API* EfiOpenProtocol)(EfiHandlePtr Handle, EFI_GUID* Guid, VoidPtr* Interface,
+ EfiHandlePtr AgentHandle, EfiHandlePtr ControllerHandle,
+ UInt32 Attributes);
+
+typedef UInt64(EFI_API* EfiEnableCursor)(EfiSimpleTextOutputProtocol* Self, Boolean Visible);
+
+/**
+@name EfiBootServices
+@brief UEFI Boot Services record, it contains functions necessary to a
+firmware level application.
+*/
+typedef struct EfiBootServices {
+ EfiTableHeader SystemTable;
+ VoidPtr RaiseTPL;
+ VoidPtr RestoreTPL;
+ EfiAllocatePages AllocatePages;
+ EfiFreePages FreePages;
+ EfiGetMemoryMap GetMemoryMap;
+ EfiAllocatePool AllocatePool;
+ EfiFreePool FreePool;
+ VoidPtr CreateEvent;
+ VoidPtr SetTimer;
+ VoidPtr WaitForEvent;
+ VoidPtr SignalEvent;
+ VoidPtr CloseEvent;
+ VoidPtr CheckEvent;
+ VoidPtr InstallProtocolInterface;
+ VoidPtr ReinstallProtocolInterface;
+ VoidPtr UninstallProtocolInterface;
+ EfiHandleProtocol HandleProtocol;
+ VoidPtr Reserved;
+ VoidPtr RegisterProtocolNotify;
+ VoidPtr LocateHandle;
+ EfiLocateDevicePath LocateDevicePath;
+ VoidPtr InstallConfigurationTable;
+ EfiLoadImage LoadImage;
+ EfiStartImage StartImage;
+ VoidPtr Exit;
+ VoidPtr UnloadImage;
+ EfiExitBootServices ExitBootServices;
+ VoidPtr GetNextMonotonicCount;
+ VoidPtr Stall;
+ EfiStatusType(EFI_API* SetWatchdogTimer)(UInt32 Timeout, UInt64 WatchdogCode, UInt32 DataSize,
+ EfiCharType* Data);
+ VoidPtr ConnectController;
+ VoidPtr DriveonnectController;
+ EfiOpenProtocol OpenProtocol;
+ VoidPtr CloseProtocol;
+ VoidPtr OpenProtocolInformation;
+ VoidPtr ProtocolsPerHandle;
+ VoidPtr LocateHandleBuffer;
+ EfiLocateProtocol LocateProtocol;
+ VoidPtr InstallMultipleProtocolInterfaces;
+ VoidPtr UninstallMultipleProtocolInterfaces;
+ EfiCalculateCrc32 CalculateCrc32;
+ EfiCopyMem CopyMem;
+ EfiSetMem SetMem;
+ VoidPtr CreateEventEx;
+} EfiBootServices;
+
+#define kEntireDevPath 0xFF
+#define kThisInstancePath 0x01
+
+/**
+@brief PrintF like protocol.
+*/
+typedef struct EfiSimpleTextOutputProtocol {
+ VoidPtr Reset;
+ EfiTextString OutputString;
+ VoidPtr TestString;
+ VoidPtr QueryMode;
+ VoidPtr SetMode;
+ EfiTextAttrib SetAttribute;
+ EfiTextClear ClearScreen;
+ VoidPtr SetCursorPosition;
+ EfiEnableCursor EnableCursor;
+ VoidPtr Mode;
+} EfiSimpleTextOutputProtocol;
+
+typedef struct {
+ UInt16 ScanCode;
+ EfiChar16Type UnicodeChar;
+} EfiInputKey;
+
+typedef EfiStatusType(EFI_API* EfiInputReadKey)(IN EfiSimpleTextInputProtocol* This,
+ OUT EfiInputKey* Key);
+
+typedef EfiStatusType(EFI_API* EfiInputReset)(IN EfiSimpleTextInputProtocol* This,
+ IN Boolean ExtendedChk);
+
+typedef EfiStatusType(EFI_API* EfiWaitForEvent)(IN UInt32 NumberOfEvents, IN VoidPtr Event,
+ OUT UInt32* Index);
+
+typedef struct EfiSimpleTextInputProtocol {
+ EfiInputReset Reset;
+ EfiInputReadKey ReadKeyStroke;
+ EfiWaitForEvent WaitForKey;
+} EfiSimpleTextInputProtocol;
+
+/// @biref Open Volume procedure ptr.
+typedef UInt64(EFI_API* EfiOpenVolume)(struct EfiSimpleFilesystemProtocol*,
+ struct EfiFileProtocol**);
+
+struct EfiSimpleFilesystemProtocol {
+ UInt64 Revision;
+ EfiOpenVolume OpenVolume;
+};
+
+typedef struct EfiRuntimeServices {
+ EfiTableHeader SystemTable;
+ VoidPtr GetTime, SetTime, GetWakeupTime, SetWakeupTime, SetVirtualAddressMap, ConvertPointer;
+ UInt64(EFI_API* GetVariable)(const WideChar* Name, EFI_GUID VendorGUID, UInt32* Attributes,
+ UInt32* DataSize, VoidPtr Data);
+ VoidPtr GetNextVariable;
+ UInt64(EFI_API* SetVariable)(const WideChar* Name, EFI_GUID VendorGUID, UInt32* Attributes,
+ UInt32* DataSize, VoidPtr Data);
+ VoidPtr GetNextHighMonotonicCount;
+ VoidPtr ResetSystem;
+ VoidPtr UpdateCapsule;
+ VoidPtr QueryCapsuleCapabilites;
+ VoidPtr QueryVariableInfo;
+} EfiRuntimeServices;
+
+/**
+@brief The Structure that they give you when booting.
+*/
+typedef struct EfiSystemTable {
+ EfiTableHeader SystemHeader;
+ WideChar* FirmwareVendor;
+ UInt32 FirmwareRevision;
+ EfiHandlePtr ConsoleInHandle;
+ EfiSimpleTextInputProtocol* ConIn;
+ EfiHandlePtr ConsoleOutHandle;
+ EfiSimpleTextOutputProtocol* ConOut;
+ EfiHandlePtr StandardErrorHandle;
+ VoidPtr StdErr;
+ EfiRuntimeServices* RuntimeServices;
+ EfiBootServices* BootServices;
+ UInt64 NumberOfTableEntries;
+ /// The configuration table (contains the RSD PTR entry.)
+ struct {
+ EFI_GUID VendorGUID;
+ VoidPtr VendorTable;
+ } * ConfigurationTable;
+} EfiSystemTable;
+
+#define kEfiOk 0
+#define kEfiFail -1
+#define kBufferTooSmall 5
+
+#define EFI_EXTERN_C extern "C"
+
+typedef struct EfiIPV4 {
+ UInt8 Addr[4];
+} EfiIPV4;
+
+///
+/// 16-byte buffer. An IPv6 internet protocol address.
+///
+typedef struct EfiIPV6 {
+ UInt8 Addr[16];
+} EfiIPV6;
+
+#define kEFIYellow (0x01 | 0x02 | 0x04 | 0x08)
+
+#ifdef __x86_64
+#define __EFI_x86_64__ 1
+#endif // __x86_64
+
+enum {
+ kEFIHwDevicePath = 0x01,
+ kEFIAcpiDevicePath = 0x02,
+ kEFIMessaingDevicePath = 0x03,
+ kEFIMediaDevicePath = 0x04,
+ kEFIBiosBootPath = 0x05,
+ kEFIEndOfPath = 0x06,
+ kEFICount = 6,
+};
+
+#define END_DEVICE_PATH_TYPE 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+
+#define kEfiOffsetOf(T, F) __builtin_offsetof(T, F)
+
+/// File I/O macros
+
+#define kEFIFileRead 0x0000000000000001
+#define kEFIFileWrite 0x0000000000000002
+#define kEFIFileCreate 0x0000000000000000
+
+#define kEFIReadOnly 0x01
+#define kEFIHidden 0x02
+#define kEFISystem 0x04
+#define kEFIReserved 0x08
+#define kEFIDirectory 0x10
+#define kEFIArchive 0x20
+
+#define EFI_FILE_PROTOCOL_REVISION 0x00010000
+#define EFI_FILE_PROTOCOL_REVISION2 0x00020000
+#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2
+
+#define EFI_EXTRA_DESCRIPTOR_SIZE 8
+
+#define EFI_MP_SERVICES_PROTOCOL_GUID \
+ { \
+ 0x3fdda605, 0xa76e, 0x4f46, { 0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08 } \
+ }
+
+#define PROCESSOR_AS_BSP_BIT 0x00000001
+#define PROCESSOR_ENABLED_BIT 0x00000002
+#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004
+
+#define END_OF_CPU_LIST 0xffffffff
+
+typedef struct EfiIOToken {
+ //
+ // If Event is NULL, then blocking I/O is performed.
+ // If Event is not NULL and non-blocking I/O is supported, then non-blocking
+ // I/O is performed, and Event will be signaled when the read request is
+ // completed. The caller must be prepared to handle the case where the
+ // callback associated with Event occurs before the original asynchronous I/O
+ // request call returns.
+ //
+ UInt64 Event;
+
+ //
+ // Defines whether or not the signaled event encountered an error.
+ //
+ UInt64 Status;
+
+ //
+ // For OpenEx(): Not Used, ignored.
+ // For ReadEx(): On input, the size of the Buffer. On output, the amount of
+ // data returned in Buffer.
+ // In both cases, the size is measured in bytes.
+ // For WriteEx(): On input, the size of the Buffer. On output, the amount of
+ // data actually written.
+ // In both cases, the size is measured in bytes.
+ // For FlushEx(): Not used, ignored.
+ //
+ UInt32 BufferSize;
+
+ //
+ // For OpenEx(): Not Used, ignored.
+ // For ReadEx(): The buffer into which the data is read.
+ // For WriteEx(): The buffer of data to write.
+ // For FlushEx(): Not Used, ignored.
+ //
+ Void* Buffer;
+} EfiIOToken;
+
+typedef struct EfiFileProtocol {
+ UInt64 Revision;
+
+ EfiStatusType(EFI_API* Open)(struct EfiFileProtocol* Self, struct EfiFileProtocol** Out,
+ EfiCharType* CharType, UInt64 OpenMode, UInt64 Attrib);
+
+ EfiStatusType(EFI_API* Close)(struct EfiFileProtocol* Self);
+
+ EfiStatusType(EFI_API* Delete)(struct EfiFileProtocol* Self);
+
+ EfiStatusType(EFI_API* Read)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut);
+
+ EfiStatusType(EFI_API* Write)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut);
+
+ EfiStatusType(EFI_API* GetPosition)(EfiFileProtocol* Self, UInt64* Position);
+
+ EfiStatusType(EFI_API* SetPosition)(EfiFileProtocol* Self, UInt64* Position);
+
+ EfiStatusType(EFI_API* GetInfo)(struct EfiFileProtocol*, struct EFI_GUID*, UInt32*, void*);
+
+ EfiStatusType(EFI_API* SetInfo)(struct EfiFileProtocol*, struct EFI_GUID*, UInt32*, void*);
+
+ EfiStatusType(EFI_API* Flush)(EfiFileProtocol*);
+
+ EfiStatusType(EFI_API* OpenEx)(EfiFileProtocol* Self, EfiFileProtocol** OutHandle,
+ EfiCharType* Path, UInt64 Mode, UInt64 Attrib,
+ struct EfiIOToken* Token);
+
+ EfiStatusType(EFI_API* ReadEx)(EfiFileProtocol* Self, struct EfiIOToken* Token);
+
+ EfiStatusType(EFI_API* WriteEx)(EfiFileProtocol* Self, struct EfiIOToken* Token);
+
+ EfiStatusType(EFI_API* FlushEx)(EfiFileProtocol* Self, struct EfiIOToken* Token);
+} EfiFileProtocol, *EfiFileProtocolPtr;
+
+typedef UInt64 EfiCursorType;
+
+typedef struct EfiTime {
+ UInt16 Year;
+ UInt8 Month;
+ UInt8 Day;
+ UInt8 Hour;
+ UInt8 Minute;
+ UInt8 Second;
+ UInt8 Pad1;
+ UInt32 Nanosecond;
+ Int16 TimeZone;
+ UInt8 Daylight;
+ UInt8 Pad2;
+} EfiTime;
+
+#define EFI_FILE_INFO_GUID \
+ { \
+ 0x09576e92, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+ }
+
+struct EfiFileInfo EFI_FINAL {
+ /// @brief Structure size.
+ UInt64 Size;
+ /// @brief File size.
+ UInt64 FileSize;
+ /// @brief Physical size on disk.
+ UInt64 PhysicalSize;
+ /// @brief Create time.
+ EfiTime CreateTime;
+ /// @brief Last access time.
+ EfiTime LastAccessTime;
+ /// @brief Edit time.
+ EfiTime EditTime;
+ /// @brief Attributes.
+ UInt64 Attribute;
+ /// @brief VLA file name.
+ WideChar FileName[1];
+};
+
+//*******************************************************
+// EFI_CPU_PHYSICAL_LOCATION
+// @note As in the EFI specs.
+//*******************************************************
+typedef struct _EfiCPUPhyiscalLocation {
+ UInt32 Package;
+ UInt32 Core;
+ UInt32 Thread;
+} EfiCPUPhyiscalLocation;
+
+typedef union _EfiExtendedProcessorInformation {
+ EfiCPUPhyiscalLocation Location2;
+} EfiExtendedProcessorInformation;
+
+typedef struct _EfiProcessorInformation {
+ UInt64 ProcessorId;
+ UInt32 StatusFlag;
+ EfiCPUPhyiscalLocation Location;
+ EfiExtendedProcessorInformation ExtendedInformation;
+} EfiProcessorInformation;
+
+typedef EfiStatusType EFI_API (*EfiMpServicesGetNumberOfProcessors)(
+ IN struct _EfiMpServicesProtocol* Self, OUT UInt32* NumberOfProcessors,
+ OUT UInt32* NumberOfEnabledProcessors);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesGetProcessorInfo)(
+ IN struct _EfiMpServicesProtocol* Self, IN UInt32* ProcessorNumber,
+ OUT struct _EfiProcessorInformation* NumberOfEnabledProcessors);
+
+typedef void EFI_API (*EFI_AP_PROCEDURE)(IN VoidPtr ProcedureArgument);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesStartupAllAPS)(
+ IN struct _EfiMpServicesProtocol* Self, IN EFI_AP_PROCEDURE Procedure, IN Boolean SingleThread,
+ IN VoidPtr WaitEvent OPTIONAL, // EFI_EVENT first, but unused here.
+ IN UInt32 TimeoutInMicroSeconds, IN Void* ProcedureArgument OPTIONAL,
+ OUT UInt32** FailedCpuList OPTIONAL);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesSwitchBSP)(IN struct _EfiMpServicesProtocol* Self,
+ IN UInt32 ProcessorNumber,
+ IN Boolean EnableOldBSP);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesStartupThisAP)(
+ IN struct _EfiMpServicesProtocol* Self, IN EFI_AP_PROCEDURE Procedure,
+ IN UInt32 ProcessorNumber, IN VoidPtr WaitEvent OPTIONAL, IN UInt32 TimeoutInMicroseconds,
+ IN Void* ProcedureArgument OPTIONAL, OUT Boolean* Finished OPTIONAL);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesDisableThisAP)(IN struct _EfiMpServicesProtocol* Self,
+ IN UInt32 ProcessorNumber,
+ IN Boolean EnableAP,
+ IN UInt32* HealthFlag OPTIONAL);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesWhoAmI)(IN struct _EfiMpServicesProtocol* Self,
+ OUT UInt32* ProcessorNumber);
+
+typedef struct _EfiMpServicesProtocol {
+ EfiMpServicesGetNumberOfProcessors GetNumberOfProcessors;
+ EfiMpServicesGetProcessorInfo GetProcessorInfo;
+ EfiMpServicesStartupAllAPS StartupAllAPs;
+ EfiMpServicesStartupThisAP StartupThisAP;
+ EfiMpServicesSwitchBSP SwitchBSP;
+ EfiMpServicesDisableThisAP EnableDisableAP;
+ EfiMpServicesWhoAmI WhoAmI;
+} EfiMpServicesProtocol;
+
+#endif // ifndef FIRMWARE_KIT_EFI_H
diff --git a/src/kernel/FirmwareKit/EFI/NS.h b/src/kernel/FirmwareKit/EFI/NS.h
new file mode 100644
index 00000000..64e59870
--- /dev/null
+++ b/src/kernel/FirmwareKit/EFI/NS.h
@@ -0,0 +1,18 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Firmware::Detail::EFI {
+using namespace Kernel;
+
+EXTERN_C {
+#include <FirmwareKit/EFI/EFI.h>
+}
+
+} // namespace Firmware::Detail::EFI
diff --git a/src/kernel/FirmwareKit/EPM.h b/src/kernel/FirmwareKit/EPM.h
new file mode 100644
index 00000000..8df4d345
--- /dev/null
+++ b/src/kernel/FirmwareKit/EPM.h
@@ -0,0 +1,112 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/**
+ @brief The Explicit Partition Map scheme.
+*/
+
+#ifndef FIRMWAREKIT_EPM_H
+#define FIRMWAREKIT_EPM_H
+
+#include <NeKit/Defines.h>
+
+#define kEPMNameLength (32)
+#define kEPMFilesystemLength (16)
+#define kEPMMagicLength (5)
+
+/* @brief AMD64 magic for EPM */
+#define kEPMMagic86 "EPMAM"
+
+/* @brief RISC-V magic for EPM */
+#define kEPMMagicRISCV "EPMRV"
+
+/* @brief ARM magic for EPM */
+#define kEPMMagicARM "EPMAR"
+
+/* @brief 64x0 magic for EPM */
+#define kEPMMagic64k "EPM64"
+
+/* @brief 32x0 magic for EPM */
+#define kEPMMagic32k "EPM32"
+
+/* @brief POWER magic for EPM */
+#define kEPMMagicPPC "EPMPC"
+
+/* @brief Invalid magic for EPM */
+#define kEPMMagicError "EPM??"
+
+#ifdef __NE_AMD64__
+#define kEPMMagic kEPMMagic86
+#else
+#ifdef __NE_ARM64__
+#define kEPMMagic kEPMMagicARM
+#else
+#define kEPMMagic kEPMMagicError
+#endif
+#endif
+
+///! @brief partition must start at this address.
+///! Anything below is reserved for Data backup by the Main OS.
+#define kEPMPartBlockLba (sizeof(EPM_PART_BLOCK))
+
+///! @brief Current EPM revision.
+#define kEPMRevisionBcd (0x0100)
+
+/// !@brief EPM boot block address.
+#define kEPMBootBlockLba (0U)
+
+#define kEPMReserveLen (399)
+
+struct EPM_GUID;
+struct EPM_PART_BLOCK;
+
+/* The first 0 > 128 addresses of a disk contains these headers. */
+
+/// @brief EPM GUID structure.
+typedef struct EPM_GUID {
+ Kernel::UInt32 Data1;
+ Kernel::UInt16 Data2;
+ Kernel::UInt16 Data3;
+ Kernel::UInt8 Data4[8];
+} PACKED EPM_GUID;
+
+/**
+ * @brief The EPM boot block.
+ * @note NumBlock and LbaStart are ignored on some platforms.
+ */
+struct PACKED EPM_PART_BLOCK {
+ Kernel::Char Magic[kEPMMagicLength];
+ Kernel::Char Name[kEPMNameLength];
+ EPM_GUID Guid;
+ Kernel::Int32 Version;
+ Kernel::Int64 NumBlocks;
+ Kernel::Int64 SectorSz;
+ Kernel::Int64 LbaStart; // base offset
+ Kernel::Int64 LbaEnd; // end offset
+ Kernel::Int16 Kind;
+ Kernel::Int16 Flags;
+ Kernel::Int32 FsVersion;
+ Kernel::Char Fs[kEPMFilesystemLength]; /* NeFS, OpenHeFS... */
+ Kernel::Char Reserved[kEPMReserveLen]; // to fill a full sector.
+};
+
+///! @brief Version kind enum.
+///! @brief Use in boot block version field.
+
+enum {
+ kEPMInvalid = 0x00,
+ kEPMGeneric = 0xcf, /// @brief Generic OS
+ kEPMLinux = 0x8f, /// @brief Linux on EPM.
+ kEPMBSD = 0x9f, /// @brief BSD on EPM.
+ kEPMNeKernel = 0x1f, /// @brief NeKernel.
+ kEPMLegacy = 0x2f, /// @brief Legacy VMKernel.
+ /// @note ... the rest is reserved for future OSes.
+ kEPMInvalidOS = 0xff,
+};
+
+inline EPM_GUID kEPMNilGuid = {0x0U, 0x0U, 0x0U, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
+
+#endif // ifndef FIRMWAREKIT_EPM_H
diff --git a/src/kernel/FirmwareKit/GPT.h b/src/kernel/FirmwareKit/GPT.h
new file mode 100644
index 00000000..1772cc79
--- /dev/null
+++ b/src/kernel/FirmwareKit/GPT.h
@@ -0,0 +1,48 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <FirmwareKit/EFI/EFI.h>
+#include <NeKit/Defines.h>
+
+#define kSectorAlignGPT_PartTbl (420U)
+#define kSectorAlignGPT_PartEntry (72U)
+#define kMagicLenGPT (8U)
+#define kMagicGPT ("EFI PART") // "EFI PART"
+#define kGPTPartitionTableLBA (512U + sizeof(GPT_PARTITION_TABLE))
+
+namespace Kernel {
+struct GPT_PARTITION_TABLE;
+struct GPT_PARTITION_ENTRY;
+
+struct PACKED GPT_PARTITION_TABLE final {
+ Char Signature[kMagicLenGPT];
+ UInt32 Revision;
+ UInt32 HeaderSize;
+ UInt32 CRC32;
+ UInt32 Reserved1;
+ UInt64 LBAHeader;
+ UInt64 LBAAltHeader;
+ UInt64 FirstGPTEntry;
+ UInt64 LastGPTEntry;
+ EFI_GUID Guid;
+ UInt64 StartingLBA;
+ UInt32 NumPartitionEntries;
+ UInt32 SizeOfEntries;
+ UInt32 CRC32PartEntry;
+ UInt8 Reserved2[kSectorAlignGPT_PartTbl];
+};
+
+struct PACKED GPT_PARTITION_ENTRY {
+ EFI_GUID PartitionTypeGUID;
+ EFI_GUID UniquePartitionGUID;
+ UInt64 StartLBA;
+ UInt64 EndLBA;
+ UInt64 Attributes;
+ UInt8 Name[kSectorAlignGPT_PartEntry];
+};
+} // namespace Kernel
diff --git a/src/kernel/FirmwareKit/Handover.h b/src/kernel/FirmwareKit/Handover.h
new file mode 100644
index 00000000..354b6e57
--- /dev/null
+++ b/src/kernel/FirmwareKit/Handover.h
@@ -0,0 +1,108 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/**
+ * @file Handover.h
+ * @author Amlal El Mahrouss (amlal@nekernel.org)
+ * @brief The handover boot protocol.
+ * @version 1.15
+ * @date 2024-02-23
+ *
+ * @copyright Copyright (c) 2024, Amlal El Mahrouss
+ *
+ */
+
+#pragma once
+
+#include <FirmwareKit/EFI/EFI.h>
+#include <NeKit/Defines.h>
+
+#define kHandoverMagic (0xBADCC)
+#define kHandoverVersion (0x0117)
+
+/* Initial bitmap pointer location and size. */
+#define kHandoverBitMapSz (gib_cast(4))
+#define kHandoverStructSz sizeof(HEL::BootInfoHeader)
+
+namespace Kernel::HEL {
+/**
+@brief The executable type enum.
+*/
+enum {
+ kTypeKernel = 100,
+ kTypeKernelDriver = 101,
+ kTypeRsrc = 102,
+ kTypeInvalid = 103,
+ kTypeCount = 4,
+};
+
+/**
+@brief The executable architecture enum.
+*/
+
+enum {
+ kArchAMD64 = 122,
+ kArchARM64 = 123,
+ kArchRISCV = 124,
+ kArchCount = 3,
+};
+
+struct BootInfoHeader final {
+ UInt64 f_Magic;
+ UInt64 f_Version;
+
+ VoidPtr f_BitMapStart;
+ SizeT f_BitMapSize;
+
+ VoidPtr f_PageStart;
+
+ VoidPtr f_KernelImage;
+ SizeT f_KernelSz;
+
+ VoidPtr f_LibSystemImage;
+ SizeT f_LibSystemSz;
+
+ VoidPtr f_StackTop;
+ SizeT f_StackSz;
+
+ WideChar f_FirmwareVendorName[32];
+ SizeT f_FirmwareVendorLen;
+
+ VoidPtr f_FirmwareCustomTables[2]; // On EFI 0: BS 1: ST
+
+ struct {
+ VoidPtr f_SmBios;
+ VoidPtr f_VendorPtr;
+ VoidPtr f_MpPtr;
+ Bool f_MultiProcessingEnabled;
+ UInt32 f_ImageKey;
+ EfiHandlePtr f_ImageHandle;
+ } f_HardwareTables;
+
+ struct {
+ UIntPtr f_The;
+ SizeT f_Size;
+ UInt32 f_Width;
+ UInt32 f_Height;
+ UInt32 f_PixelFormat;
+ UInt32 f_PixelPerLine;
+ } f_GOP;
+
+ UInt64 f_FirmwareSpecific[8];
+};
+
+enum {
+ kHandoverTableBS,
+ kHandoverTableST,
+ kHandoverTableCount,
+};
+
+/// @brief Alias of bootloader main type.
+typedef Int32 (*HandoverProc)(BootInfoHeader* boot_info);
+} // namespace Kernel::HEL
+
+/// @brief Bootloader information header global variable.
+inline Kernel::HEL::BootInfoHeader* kHandoverHeader = nullptr;
diff --git a/src/kernel/FirmwareKit/NeBoot/BootNet.h b/src/kernel/FirmwareKit/NeBoot/BootNet.h
new file mode 100644
index 00000000..3637bab0
--- /dev/null
+++ b/src/kernel/FirmwareKit/NeBoot/BootNet.h
@@ -0,0 +1,41 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define kBootNetINetMagic "ONET"
+#define kBootNetINetMagicLength (4)
+#define kBootNetVersion (0x001)
+#define kBootNetNameLen (256U)
+
+struct _BOOTNET_INTERNET_HEADER;
+
+/// @brief Netboot Internet Header
+/// Consists of 4 magic characters, and a set of fields describing the current patch that's being
+/// sent (if m_preflight = 0)
+/// @note Can be used to patch ROMs too (if ImpliesProgram = 1)
+typedef struct _BOOTNET_INTERNET_HEADER {
+ Kernel::Char NB1; /// magic char 1 'O'
+ Kernel::Char NB2; /// magic char 2 'N'
+ Kernel::Char NB3; /// magic char 3 'E'
+ Kernel::Char NB4; /// magic char 4 'T'
+
+ Kernel::UInt16 Version;
+
+ Kernel::Char Name[kBootNetNameLen]; /// example: Modjo
+
+ Kernel::Int32 Length; /// the patch length.
+ Kernel::Char Target[kBootNetNameLen]; /// the target file.
+
+ Kernel::Boolean ImpliesProgram : 1; /// does it imply reprogramming?
+
+ Kernel::Boolean Preflight : 1; /// is it a preflight packet.
+ Kernel::Char Data[1]; /// non preflight packet has a patch blob for a **PatchTarget**
+} PACKED BOOTNET_INTERNET_HEADER;
+
+using BOOTNET_INTERNET_HEADER_PTR = BOOTNET_INTERNET_HEADER*;
diff --git a/src/kernel/FirmwareKit/NeBoot/NS.h b/src/kernel/FirmwareKit/NeBoot/NS.h
new file mode 100644
index 00000000..3a6bed6d
--- /dev/null
+++ b/src/kernel/FirmwareKit/NeBoot/NS.h
@@ -0,0 +1,10 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <FirmwareKit/NeBoot/BootNet.h>
+#include <FirmwareKit/NeBoot/NeBoot.h> \ No newline at end of file
diff --git a/src/kernel/FirmwareKit/NeBoot/NeBoot.h b/src/kernel/FirmwareKit/NeBoot/NeBoot.h
new file mode 100644
index 00000000..8e8fd87f
--- /dev/null
+++ b/src/kernel/FirmwareKit/NeBoot/NeBoot.h
@@ -0,0 +1,34 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Firmware::Detail::NeBoot {
+using namespace Kernel;
+
+struct NEBOOT_LINEAR_EXEC;
+
+/// @brief Linear Executable Header
+/// @author Amlal El Mahrouss
+struct ATTRIBUTE(aligned(4)) NEBOOT_LINEAR_EXEC {
+ const Char fMagic[2]; // magic number
+ const Char fName[10]; // operating system name
+ const UInt32 fRevision; // firmware revision
+ const UInt32 fStartAddress; // start address (master/slave(s) thread)
+
+#ifdef NE_IS_EXTENDED_COREBOOT
+ UIntPtr fMasterStructure; // master structure for MP/PM and device tree and such. (ARM)
+ UIntPtr fMasterStructureVersion; // master structure version.
+#endif
+
+#ifdef NE_IS_MBCI_COREBOOT
+ UIntPtr fMBCIStructure; // MBCI structure for MBCI (ARM)
+ UIntPtr fMBCIStructureVersion; // MBCI structure version.
+#endif
+};
+} // namespace Firmware::Detail::NeBoot
diff --git a/src/kernel/FirmwareKit/VEPM.h b/src/kernel/FirmwareKit/VEPM.h
new file mode 100644
index 00000000..b2bee0d3
--- /dev/null
+++ b/src/kernel/FirmwareKit/VEPM.h
@@ -0,0 +1,47 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef FIRMWAREKIT_VEPM_H
+#define FIRMWAREKIT_VEPM_H
+
+#include <FirmwareKit/EFI.h>
+#include <FirmwareKit/EPM.h>
+
+/// =========================================================== ///
+/// @brief The Virtual Explicit Partition Map scheme extension.
+/// =========================================================== ///
+
+#if defined(__NE_VEPM__)
+#ifdef kEPMMagic
+#undef kEPMMagic
+#endif // kEPMMagic
+
+/// =========================================================== ///
+/// @brief VEPM Ident String.
+/// =========================================================== ///
+#define kEPMMagic "EPMVM"
+
+/// =========================================================== ///
+/// @brief VEPM GUID.
+/// @note This is the GUID used to identify a VEPM partition.
+/// =========================================================== ///
+inline EPM_GUID kVEPMGuidEPM = {
+ 0x9a1b3f2e, 0x4c3f, 0x4d52, {0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac}};
+
+/// =========================================================== ///
+/// @brief VEPM GUID.
+/// @note This is the GUID used to identify a VEPM partition (EFI version)
+/// =========================================================== ///
+inline EFI_GUID kVEPMGuidEFI = {
+ 0x9a1b3f2e, 0x4c3f, 0x4d52, {0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac}};
+
+/// =========================================================== ///
+/// @brief VEPM GUID String.
+/// =========================================================== ///
+#define kVEPMGuidStr "9a1b3f2e-4c3f-4d52-a783-9c217b5e4dac"
+#endif // __NE_VEPM__
+
+#endif // FIRMWAREKIT_VEPM_H \ No newline at end of file
diff --git a/src/kernel/GfxKit/FB.h b/src/kernel/GfxKit/FB.h
new file mode 100644
index 00000000..c8a2dc4b
--- /dev/null
+++ b/src/kernel/GfxKit/FB.h
@@ -0,0 +1,52 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+
+namespace Kernel {
+class FBDeviceInterface;
+struct FBDevicePacket;
+
+typedef UInt32 FBCoord2x2;
+typedef UInt32 FBDim2x2;
+typedef UInt32 FBColorProfile;
+typedef UInt32 FBFlags;
+
+/// @brief Framebuffer device interface packet.
+/// @details This structure is used to send and receive data from the framebuffer device.
+/// @note The structure is packed to ensure that the data is aligned correctly for the device.
+struct PACKED FBDevicePacket final {
+ FBCoord2x2 fX;
+ FBCoord2x2 fY;
+ FBDim2x2 fWidth;
+ FBDim2x2 fHeight;
+ FBColorProfile fColor;
+ FBFlags fFlags;
+};
+
+/// @brief Framebuffer device interface.
+/// @details This class is used to send and receive data from the framebuffer device.
+/// @note The class is derived from the DeviceInterface class.
+class FBDeviceInterface NE_DEVICE<FBDevicePacket*> {
+ public:
+ explicit FBDeviceInterface(void (*out)(DeviceInterface* self, FBDevicePacket* out),
+ void (*in)(DeviceInterface* self, FBDevicePacket* in));
+
+ virtual ~FBDeviceInterface() override;
+
+ public:
+ FBDeviceInterface& operator=(const FBDeviceInterface&) = default;
+ FBDeviceInterface(const FBDeviceInterface&) = default;
+
+ const Char* Name() const override;
+
+ public:
+ FBDeviceInterface& operator<<(FBDevicePacket* dat) override;
+ FBDeviceInterface& operator>>(FBDevicePacket* dat) override;
+};
+} // namespace Kernel
diff --git a/src/kernel/HALKit/.gitkeep b/src/kernel/HALKit/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/.gitkeep
diff --git a/src/kernel/HALKit/AMD64/CPUID.h b/src/kernel/HALKit/AMD64/CPUID.h
new file mode 100644
index 00000000..0ab95c07
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/CPUID.h
@@ -0,0 +1,89 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: CPUID.h
+ Purpose: CPUID flags.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+EXTERN_C {
+#include <cpuid.h>
+}
+
+namespace Kernel {
+
+enum {
+ kCPUFeatureSSE3 = 1 << 0,
+ kCPUFeaturePCLMUL = 1 << 1,
+ kCPUFeatureDTES64 = 1 << 2,
+ kCPUFeatureMONITOR = 1 << 3,
+ kCPUFeatureDS_CPL = 1 << 4,
+ kCPUFeatureVMX = 1 << 5,
+ kCPUFeatureSMX = 1 << 6,
+ kCPUFeatureEST = 1 << 7,
+ kCPUFeatureTM2 = 1 << 8,
+ kCPUFeatureSSSE3 = 1 << 9,
+ kCPUFeatureCID = 1 << 10,
+ kCPUFeatureSDBG = 1 << 11,
+ kCPUFeatureFMA = 1 << 12,
+ kCPUFeatureCX16 = 1 << 13,
+ kCPUFeatureXTPR = 1 << 14,
+ kCPUFeaturePDCM = 1 << 15,
+ kCPUFeaturePCID = 1 << 17,
+ kCPUFeatureDCA = 1 << 18,
+ kCPUFeatureSSE4_1 = 1 << 19,
+ kCPUFeatureSSE4_2 = 1 << 20,
+ kCPUFeatureX2APIC = 1 << 21,
+ kCPUFeatureMOVBE = 1 << 22,
+ kCPUFeaturePOP3C = 1 << 23,
+ kCPUFeatureECXTSC = 1 << 24,
+ kCPUFeatureAES = 1 << 25,
+ kCPUFeatureXSAVE = 1 << 26,
+ kCPUFeatureOSXSAVE = 1 << 27,
+ kCPUFeatureAVX = 1 << 28,
+ kCPUFeatureF16C = 1 << 29,
+ kCPUFeatureRDRAND = 1 << 30,
+ kCPUFeatureHYPERVISOR = 1 << 31,
+ kCPUFeatureFPU = 1 << 0,
+ kCPUFeatureVME = 1 << 1,
+ kCPUFeatureDE = 1 << 2,
+ kCPUFeaturePSE = 1 << 3,
+ kCPUFeatureEDXTSC = 1 << 4,
+ kCPUFeatureMSR = 1 << 5,
+ kCPUFeaturePAE = 1 << 6,
+ kCPUFeatureMCE = 1 << 7,
+ kCPUFeatureCX8 = 1 << 8,
+ kCPUFeatureAPIC = 1 << 9,
+ kCPUFeatureSEP = 1 << 11,
+ kCPUFeatureMTRR = 1 << 12,
+ kCPUFeaturePGE = 1 << 13,
+ kCPUFeatureMCA = 1 << 14,
+ kCPUFeatureCMOV = 1 << 15,
+ kCPUFeaturePAT = 1 << 16,
+ kCPUFeaturePSE36 = 1 << 17,
+ kCPUFeaturePSN = 1 << 18,
+ kCPUFeatureCLFLUSH = 1 << 19,
+ kCPUFeatureDS = 1 << 21,
+ kCPUFeatureACPI = 1 << 22,
+ kCPUFeatureMMX = 1 << 23,
+ kCPUFeatureFXSR = 1 << 24,
+ kCPUFeatureSSE = 1 << 25,
+ kCPUFeatureSSE2 = 1 << 26,
+ kCPUFeatureSS = 1 << 27,
+ kCPUFeatureHTT = 1 << 28,
+ kCPUFeatureTM = 1 << 29,
+ kCPUFeatureIA64 = 1 << 30,
+ kCPUFeaturePBE = 1 << 31
+};
+
+typedef Int64 CPUID;
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/CxxAbi.cc b/src/kernel/HALKit/AMD64/CxxAbi.cc
new file mode 100644
index 00000000..9049457b
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/CxxAbi.cc
@@ -0,0 +1,79 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <NeKit/CxxAbi.h>
+
+atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors];
+
+uarch_t __atexit_func_count;
+
+/// @brief dynamic shared object Handle.
+Kernel::UIntPtr __dso_handle;
+
+EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) {
+ (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(PtrDiff frame_size) {
+ char* sp;
+ asm volatile("mov %%rsp, %0" : "=r"(sp));
+
+ for (PtrDiff offset = kPageSize; offset < frame_size; offset += kPageSize) {
+ sp[-offset] = 0;
+ }
+}
+
+EXTERN_C int atexit(void (*f)()) {
+ if (__atexit_func_count >= kAtExitMacDestructors) return 1;
+
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+
+ __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)();
+ };
+ }
+
+ return;
+ }
+
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)();
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+}
+
+namespace cxxabiv1 {
+EXTERN_C int __cxa_guard_acquire(__guard g) {
+ if ((*g & 1) || (*g & 2)) return 1;
+ *g |= 2;
+ return 0;
+}
+
+EXTERN_C void __cxa_guard_release(__guard g) {
+ *g |= 1;
+ *g &= 2;
+}
+
+EXTERN_C void __cxa_guard_abort(__guard g) {
+ *g &= ~2;
+}
+} // namespace cxxabiv1
diff --git a/src/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc b/src/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc
new file mode 100644
index 00000000..83545df8
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc
@@ -0,0 +1,113 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <HALKit/AMD64/Processor.h>
+#include <KernelKit/HeapMgr.h>
+#include <NeKit/KString.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+
+namespace Kernel {
+namespace Detail {
+ struct FADT final : public SDT {
+ UInt32 FirmwareCtrl;
+ UInt32 Dsdt;
+
+ // field used in ACPI 1.0; no longer in use, for compatibility only
+ UInt8 Reserved;
+
+ UInt8 PreferredPowerManagementProfile;
+ UInt16 SCI_Interrupt;
+ UInt32 SMI_CommandPort;
+ UInt8 AcpiEnable;
+ UInt8 AcpiDisable;
+ UInt8 S4BIOS_REQ;
+ UInt8 PSTATE_Control;
+ UInt32 PM1aEventBlock;
+ UInt32 PM1bEventBlock;
+ UInt32 PM1aControlBlock;
+ UInt32 PM1bControlBlock;
+ UInt32 PM2ControlBlock;
+ UInt32 PMTimerBlock;
+ UInt32 GPE0Block;
+ UInt32 GPE1Block;
+ UInt8 PM1EventLength;
+ UInt8 PM1ControlLength;
+ UInt8 PM2ControlLength;
+ UInt8 PMTimerLength;
+ UInt8 GPE0Length;
+ UInt8 GPE1Length;
+ UInt8 GPE1Base;
+ UInt8 CStateControl;
+ UInt16 WorstC2Latency;
+ UInt16 WorstC3Latency;
+ UInt16 FlushSize;
+ UInt16 FlushStride;
+ UInt8 DutyOffset;
+ UInt8 DutyWidth;
+ UInt8 DayAlarm;
+ UInt8 MonthAlarm;
+ UInt8 Century;
+
+ // reserved in ACPI 1.0; used since ACPI 2.0+
+ UInt16 BootArchitecturkMMFlags;
+
+ UInt8 Reserved2;
+ UInt32 Flags;
+
+ // 12 byte structure; see below for details
+ ACPI_ADDRESS ResetReg;
+
+ UInt8 ResetValue;
+ UInt8 Reserved3[3];
+
+ // 64bit pointers - Available on ACPI 2.0+
+ UInt64 X_FirmwareControl;
+ UInt64 X_Dsdt;
+
+ ACPI_ADDRESS X_PM1aEventBlock;
+ ACPI_ADDRESS X_PM1bEventBlock;
+ ACPI_ADDRESS X_PM1aControlBlock;
+ ACPI_ADDRESS X_PM1bControlBlock;
+ ACPI_ADDRESS X_PM2ControlBlock;
+ ACPI_ADDRESS X_PMTimerBlock;
+ ACPI_ADDRESS X_GPE0Block;
+ ACPI_ADDRESS X_GPE1Block;
+ };
+} // namespace Detail
+
+ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {}
+
+Bool ACPIFactoryInterface::Shutdown() {
+ return NO;
+}
+
+/// @brief Reboot machine in either ACPI or by triple faulting.
+/// @return nothing it's a reboot.
+Void ACPIFactoryInterface::Reboot() {
+ asm volatile(
+ ".intel_syntax noprefix; "
+ "rt_reset_hardware:; "
+ "cli; "
+ "wait_gate1: ; "
+ "in al,0x64 ; "
+ "and al,2 ; "
+ "jnz wait_gate1 ; "
+ "mov al,0x0D1 ; "
+ "out 0x64,al ; "
+ "wait_gate2: ; "
+ "in al,0x64 ; "
+ "and al,2 ; "
+ "jnz wait_gate2 ; "
+ "mov al,0x0FE ; "
+ "out 0x60,al ; "
+ "xor rax,rax ; "
+ "lidt [rax] ; "
+ "reset_wait: ; "
+ "jmp reset_wait ; "
+ ".att_syntax; ");
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc b/src/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc
new file mode 100644
index 00000000..36a027a2
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc
@@ -0,0 +1,39 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/AMD64/Processor.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+
+namespace Kernel::HAL {
+/***********************************************************************************/
+/// Constructors.
+/***********************************************************************************/
+LAPICDmaWrapper::LAPICDmaWrapper(VoidPtr base) : fApic(base) {}
+LAPICDmaWrapper::~LAPICDmaWrapper() = default;
+
+/***********************************************************************************/
+/// @brief Read from APIC controller.
+/// @param reg register.
+/***********************************************************************************/
+UInt32 LAPICDmaWrapper::Read(UInt16 reg) noexcept {
+ MUST_PASS(this->fApic);
+
+ UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic;
+ return io_apic[reg];
+}
+
+/***********************************************************************************/
+/// @brief Write to APIC controller.
+/// @param reg register.
+/// @param value value.
+/***********************************************************************************/
+Void LAPICDmaWrapper::Write(UInt16 reg, UInt32 value) noexcept {
+ MUST_PASS(this->fApic);
+
+ UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic;
+ io_apic[reg] = value;
+}
+} // namespace Kernel::HAL
diff --git a/src/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/src/kernel/HALKit/AMD64/HalApplicationProcessor.cc
new file mode 100644
index 00000000..5a530457
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -0,0 +1,221 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/// Different than the MADT, might be confusing to some.
+#define APIC_MAG "APIC"
+
+#define APIC_ICR_LOW 0x300
+#define APIC_ICR_HIGH 0x310
+#define APIC_SIPI_VEC 0x00500
+#define APIC_EIPI_VEC 0x00400
+
+#define LAPIC_REG_TIMER_LVT 0x320
+#define LAPIC_REG_TIMER_INITCNT 0x380
+#define LAPIC_REG_TIMER_CURRCNT 0x390
+#define LAPIC_REG_TIMER_DIV 0x3E0
+#define LAPIC_REG_ENABLE 0x80
+#define LAPIC_REG_SPURIOUS 0xF0
+
+#define APIC_BASE_MSR 0x1B
+#define APIC_BASE_MSR_BSP 0x100
+#define APIC_BASE_MSR_ENABLE 0x800
+
+#include <ArchKit/ArchKit.h>
+#include <HALKit/AMD64/Processor.h>
+#include <KernelKit/BinaryMutex.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/KernelPanic.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+/// @note: _hal_switch_context is internal.
+/// @brief The **HAL** namespace.
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+namespace Kernel::HAL {
+struct HAL_APIC_MADT;
+struct HAL_HARDWARE_THREAD;
+
+struct HAL_HARDWARE_THREAD final {
+ StackFramePtr mFramePtr;
+ ProcessID mThreadID{0};
+};
+
+EXTERN_C Void sched_jump_to_task(StackFramePtr stack_frame);
+
+STATIC HAL_APIC_MADT* kSMPBlock = nullptr;
+STATIC Bool kSMPAware = false;
+STATIC Int64 kSMPCount = 0;
+
+EXTERN_C UIntPtr kApicBaseAddress;
+
+STATIC Int32 kSMPInterrupt = 0;
+STATIC UInt64 kAPICLocales[kMaxAPInsideSched] = {0};
+STATIC VoidPtr kRawMADT = nullptr;
+
+STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}};
+
+/// @brief Multiple APIC Descriptor Table.
+struct HAL_APIC_MADT final SDT_OBJECT {
+ UInt32 Address; // Madt address
+ UInt32 Flags; // Madt flags
+ UInt8 List[1]; // Records List
+};
+
+/// @brief Local APIC Descriptor Table.
+struct LAPIC final {
+ UInt8 Type;
+ UInt8 Length;
+ UInt8 ProcessorID;
+ UInt8 APICID;
+ UInt32 Flags;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+/***********************************************************************************/
+/// @brief Send end IPI for CPU.
+/// @param apic_id
+/// @param vector
+/// @param target
+/// @return
+/***********************************************************************************/
+EXTERN_C Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) {
+ Kernel::ke_dma_write<UInt32>(target, APIC_ICR_HIGH, apic_id << 24);
+ Kernel::ke_dma_write<UInt32>(target, APIC_ICR_LOW, 0x00000600 | 0x00004000 | 0x00000000 | vector);
+
+ while (Kernel::ke_dma_read<UInt32>(target, APIC_ICR_LOW) & 0x1000) {
+ NE_UNUSED(0);
+ }
+}
+
+/***********************************************************************************/
+/// @brief Get current stack frame for a thread.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
+
+EXTERN_C HAL::StackFramePtr mp_get_current_task(ThreadID thrdid) {
+ if (thrdid > kSMPCount) return nullptr;
+ return kHWThread[thrdid].mFramePtr;
+}
+
+/***********************************************************************************/
+/// @brief Register current stack frame for a thread.
+/// @param stack_frame The current stack frame.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
+
+EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ThreadID thrdid) {
+ if (!stack_frame) return NO;
+
+ if (!kSMPAware) {
+ sched_jump_to_task(kHWThread[thrdid].mFramePtr);
+ return YES;
+ }
+
+ if (thrdid > kSMPCount) return NO;
+
+ HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO);
+ kHWThread[thrdid].mFramePtr = stack_frame;
+
+ return YES;
+}
+
+/***********************************************************************************/
+/// @brief Is the current config SMP aware?
+/// @return True if YES, False if not.
+/***********************************************************************************/
+
+Bool mp_is_smp(Void) noexcept {
+ return kSMPAware;
+}
+
+/***********************************************************************************/
+/// @brief Fetch and enable SMP scheduler.
+/// @param vendor_ptr SMP containing structure.
+/***********************************************************************************/
+
+Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
+ if (!vendor_ptr) return;
+
+ PowerFactoryInterface hw_and_pow_int{vendor_ptr};
+
+ auto pwr = hw_and_pow_int.Find(APIC_MAG);
+
+ if (pwr.HasError()) {
+ kSMPAware = NO;
+ return;
+ }
+
+ kRawMADT = pwr.Leak().Leak();
+ kSMPBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT);
+ kSMPAware = NO;
+
+ if (kSMPBlock) {
+ kSMPInterrupt = 0;
+ kSMPCount = 0;
+
+ UInt32 lo = 0U, hi = 0U;
+
+ hal_get_msr(APIC_BASE_MSR, &lo, &hi);
+
+ UInt64 apic_base = ((UInt64) hi << 32) | lo;
+
+ apic_base |= APIC_BASE_MSR_ENABLE; // Enable APIC.
+
+ lo = apic_base & 0xFFFFFFFF;
+ hi = apic_base >> 32;
+
+ hal_set_msr(APIC_BASE_MSR, lo, hi);
+
+ kApicBaseAddress = apic_base & 0xFFFFF000;
+
+ LAPICDmaWrapper controller{(VoidPtr) kApicBaseAddress};
+
+ controller.Write(LAPIC_REG_ENABLE, 0);
+ controller.Write(LAPIC_REG_SPURIOUS, 0x1FF); // Enable bit, spurious interrupt vector register.
+ controller.Write(LAPIC_REG_TIMER_DIV, 0b0011);
+ controller.Write(LAPIC_REG_TIMER_LVT, 0x20 | (1 << 17));
+ controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000);
+
+ volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kSMPBlock->List);
+ volatile UInt8* end_ptr = ((UInt8*) kSMPBlock) + kSMPBlock->Length;
+
+ while (entry_ptr < end_ptr) {
+ UInt8 type = *entry_ptr;
+ UInt8 length = *(entry_ptr + 1);
+
+ if (type == 0 && length == sizeof(struct LAPIC)) {
+ volatile LAPIC* entry_struct = (volatile LAPIC*) entry_ptr;
+
+ if (entry_struct->Flags & 0x1) {
+ kAPICLocales[kSMPCount] = entry_struct->ProcessorID;
+ kHWThread[kSMPCount].mThreadID = kAPICLocales[kSMPCount];
+
+ ++kSMPCount;
+
+ kout << "AP: kind: LAPIC: ON.\r";
+ } else {
+ kout << "AP: kind: LAPIC: OFF.\r";
+ }
+ } else {
+ kout << "AP: kind: UNKNOWN: OFF.\r";
+ }
+
+ entry_ptr += length;
+ }
+
+ kSMPAware = kSMPCount > 1;
+ }
+}
+} // namespace Kernel::HAL
+
+///////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s b/src/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s
new file mode 100644
index 00000000..7b383404
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s
@@ -0,0 +1,23 @@
+ /*
+ * ========================================================
+ *
+ * NeKernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+.text
+
+.global hal_ap_blob_start
+.global hal_ap_blob_length
+
+hal_ap_blob_start:
+ cli
+ hlt
+ jmp hal_ap_blob_start
+
+.data
+
+hal_ap_blob_length:
+ .long 4
diff --git a/src/kernel/HALKit/AMD64/HalCommonAPI.asm b/src/kernel/HALKit/AMD64/HalCommonAPI.asm
new file mode 100644
index 00000000..9f3652bc
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalCommonAPI.asm
@@ -0,0 +1,137 @@
+;; /*
+;; * ========================================================
+;; *
+;; * NeKernel
+;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+section .text
+
+extern rt_wait_400ns
+
+global rt_out8
+global rt_out16
+global rt_out32
+
+global rt_in8
+global rt_in16
+global rt_in32
+
+rt_out8:
+ mov al, dl
+ mov dx, cx
+ out dx, al
+ ret
+
+rt_out16:
+ mov ax, dx
+ mov dx, cx
+ out dx, ax
+ ret
+
+rt_out32:
+ mov eax, edx
+ mov edx, ecx
+ out dx, eax
+ ret
+
+rt_in8:
+ mov dx, cx
+ in al, dx
+ ret
+
+rt_in16:
+ mov edx, ecx
+ in ax, dx
+ ret
+
+rt_in32:
+ mov rdx, rcx
+ in eax, dx
+ ret
+
+extern hal_system_call_enter
+global mp_system_call_handler
+
+mp_system_call_handler:
+ push rbp
+ mov rbp, rsp
+
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+
+ jmp hal_system_call_enter
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+
+ pop rbp
+
+ o64 iret
+
+
+section .text
+
+global sched_jump_to_task
+
+sched_jump_to_task:
+ push rbp
+ mov rbp, rsp
+
+ mov ax, 0x30
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ mov ax, 0x18
+ ltr ax
+
+ push 0x30
+ mov rdx, [rcx + 0x08]
+ push rdx
+ o64 pushf
+ push 0x28
+ mov rdx, [rcx + 0x00]
+ push rdx
+
+ call sched_recover_registers
+
+ o64 iret
+
+global sched_idle_task
+
+sched_idle_task:
+ jmp $
+ ret
+
+sched_recover_registers:
+ push rbp
+ mov rbp, rsp
+
+ mov r8, [rcx + 0x10]
+ mov r9, [rcx + 0x18]
+ mov r10, [rcx + 0x20]
+ mov r11, [rcx + 0x28]
+ mov r12, [rcx + 0x30]
+ mov r13, [rcx + 0x38]
+ mov r14, [rcx + 0x40]
+ mov r15, [rcx + 0x48]
+
+ pop rbp
+
+ ret \ No newline at end of file
diff --git a/src/kernel/HALKit/AMD64/HalControlRegisterAPI.s b/src/kernel/HALKit/AMD64/HalControlRegisterAPI.s
new file mode 100644
index 00000000..90fdeb81
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalControlRegisterAPI.s
@@ -0,0 +1,45 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+.globl hal_write_cr3
+.globl hal_write_cr0
+.globl hal_read_cr2
+.globl hal_read_cr3
+.globl hal_read_cr0
+.globl hal_flush_tlb
+.globl hal_invl_tlb
+
+.text
+
+hal_invl_tlb:
+ invlpg (%rcx)
+ retq
+
+hal_flush_tlb:
+ call hal_read_cr3
+ mov %rax, %rcx
+ call hal_write_cr3
+ retq
+
+hal_read_cr3:
+ movq %cr3, %rax
+ retq
+
+hal_read_cr0:
+ movq %cr0, %rax
+ retq
+
+hal_read_cr2:
+ movq %cr2, %rax
+ retq
+
+hal_write_cr3:
+ movq %rcx, %cr3
+ retq
+
+hal_write_cr0:
+ movq %rcx, %cr0
+ retq
diff --git a/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc b/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
new file mode 100644
index 00000000..f19e49b5
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
@@ -0,0 +1,168 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/KString.h>
+#include <SignalKit/Signals.h>
+
+EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip);
+
+EXTERN_C Kernel::UIntPtr kApicBaseAddress;
+
+STATIC BOOL kIsRunning = NO;
+
+/// @brief Notify APIC and PIC that we're done with the interrupt.
+/// @note
+STATIC void hal_idt_send_eoi(UInt8 vector) {
+ ((volatile UInt32*) kApicBaseAddress)[0xB0 / 4] = 0;
+
+ if (vector >= kPICCommand && vector <= 0x2F) {
+ if (vector >= 0x28) {
+ Kernel::HAL::rt_out8(kPIC2Command, kPICCommand);
+ }
+ Kernel::HAL::rt_out8(kPICCommand, kPICCommand);
+ }
+}
+
+/// @brief Handle GPF fault.
+/// @param rsp
+EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_send_eoi(13);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle page fault.
+/// @param rsp
+EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_send_eoi(14);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle scheduler interrupt.
+EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) {
+ NE_UNUSED(rsp);
+
+ hal_idt_send_eoi(32);
+
+ while (kIsRunning)
+ ;
+
+ kIsRunning = YES;
+
+ Kernel::UserProcessHelper::StartScheduling();
+
+ kIsRunning = NO;
+}
+
+/// @brief Handle math fault.
+/// @param rsp
+EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_send_eoi(8);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = sig_generate_unique<SIGKILL>();
+ ;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle any generic fault.
+/// @param rsp
+EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_send_eoi(30);
+
+ Kernel::kout << "Kernel: Generic Process Fault.\r";
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = sig_generate_unique<SIGSEG>();
+ ;
+ process.Leak().Signal.Status = process.Leak().Status;
+
+ Kernel::kout << "Kernel: SIGKILL status.\r";
+}
+
+EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+
+ hal_idt_send_eoi(3);
+
+ process.Leak().Signal.SignalArg = rip;
+ process.Leak().Signal.SignalID = sig_generate_unique<SIGTRAP>();
+
+ process.Leak().Signal.Status = process.Leak().Status;
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kFrozen;
+}
+
+/// @brief Handle #UD fault.
+/// @param rsp
+EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_send_eoi(6);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = sig_generate_unique<SIGKILL>();
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Enter syscall from assembly (libSystem only)
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash,
+ Kernel::UIntPtr rdx_syscall_arg) {
+ hal_idt_send_eoi(50);
+
+ if (!Kernel::kCurrentUser) return;
+
+ for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) {
+ if (kSysCalls[i].fHooked && rcx_hash == kSysCalls[i].fHash) {
+ if (kSysCalls[i].fProc) {
+ (kSysCalls[i].fProc)((Kernel::VoidPtr) rdx_syscall_arg);
+ }
+ }
+ }
+}
+
+/// @brief Enter Kernel call from assembly (libDDK only).
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt,
+ Kernel::UIntPtr arg, Kernel::SizeT sz) {
+ hal_idt_send_eoi(51);
+
+ if (!Kernel::kRootUser) return;
+ if (Kernel::kCurrentUser != Kernel::kRootUser) return;
+ if (!Kernel::kCurrentUser->IsSuperUser()) return;
+
+ for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) {
+ if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) {
+ if (kKernCalls[i].fProc) {
+ (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz);
+ }
+ }
+ }
+}
diff --git a/src/kernel/HALKit/AMD64/HalCoreSystemCalls.cc b/src/kernel/HALKit/AMD64/HalCoreSystemCalls.cc
new file mode 100644
index 00000000..f50e4abd
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalCoreSystemCalls.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ ======================================== */
+
+#include <ArchKit/ArchKit.h>
+
+using namespace Kernel;
diff --git a/src/kernel/HALKit/AMD64/HalDebugOutput.cc b/src/kernel/HALKit/AMD64/HalDebugOutput.cc
new file mode 100644
index 00000000..8e5f4cbd
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalDebugOutput.cc
@@ -0,0 +1,227 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/New.h>
+#include <NeKit/Utils.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+namespace Kernel {
+enum CommStatus : UInt16 {
+ kStateInvalid = 0x64,
+ kStateReady = 0xCF,
+ kStateTransmit = 0xFC,
+ kStateCnt = 3
+};
+
+namespace Detail {
+ constexpr ATTRIBUTE(unused) const UInt16 kPort = 0x3F8;
+ STATIC ATTRIBUTE(unused) UInt16 kState = kStateInvalid;
+
+ /// @brief Init COM1.
+ /// @return
+ template <UInt16 PORT>
+ bool hal_serial_init() noexcept {
+ if (kState == kStateReady || kState == kStateTransmit) return true;
+
+ HAL::rt_out8(PORT + 1, 0x00); // Disable all interrupts
+ HAL::rt_out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
+ HAL::rt_out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
+ HAL::rt_out8(PORT + 1, 0x00); // (hi byte)
+ HAL::rt_out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
+ HAL::rt_out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
+ HAL::rt_out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
+ HAL::rt_out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
+ HAL::rt_out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if
+ // serial returns same byte)
+
+ // Check if serial is faulty (i.e: not same byte as sent)
+ if (HAL::rt_in8(PORT) != 0xAE) {
+ return false;
+ }
+
+ kState = kStateReady;
+
+ // If serial is not faulty set it in normal operation mode
+ // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
+ HAL::rt_out8(PORT + 4, 0x0F);
+
+ return true;
+ }
+} // namespace Detail
+
+TerminalDevice::~TerminalDevice() = default;
+
+#ifdef __DEBUG__
+STATIC SizeT kX = kFontSizeX, kY = kFontSizeY;
+#endif // __DEBUG__
+
+EXTERN_C void ke_utf_io_write(DeviceInterface<const Utf8Char*>* obj, const Utf8Char* bytes) {
+ NE_UNUSED(bytes);
+ NE_UNUSED(obj);
+
+#ifdef __DEBUG__
+ Detail::hal_serial_init<Detail::kPort>();
+
+ if (!bytes || Detail::kState != kStateReady) return;
+
+ if (*bytes == 0) return;
+
+ Detail::kState = kStateTransmit;
+
+ SizeT index = 0;
+ SizeT len = 0;
+
+ index = 0;
+ len = urt_string_len(bytes);
+
+ Char tmp_str[2];
+
+ while (index < len) {
+ if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r');
+
+ HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]);
+
+ tmp_str[0] = (bytes[index] > 127) ? '?' : bytes[index];
+ tmp_str[1] = 0;
+
+ cg_render_string(tmp_str, kY, kX, RGB(0xff, 0xff, 0xff));
+
+ if (bytes[index] == '\r') {
+ kY += kFontSizeY;
+ kX = kFontSizeX;
+ }
+
+ kX += kFontSizeX;
+
+ if (kX > kHandoverHeader->f_GOP.f_Width) {
+ kX = kFontSizeX;
+ }
+
+ if (kY > kHandoverHeader->f_GOP.f_Height) {
+ kY = kFontSizeY;
+
+ FBDrawInRegion(cg_get_clear_clr(), FB::CGAccessibilty::Height(), FB::CGAccessibilty::Width(),
+ 0, 0);
+ }
+
+ ++index;
+ }
+
+ Detail::kState = kStateReady;
+#endif // __DEBUG__
+}
+
+EXTERN_C void ke_io_write(DeviceInterface<const Char*>* obj, const Char* bytes) {
+ NE_UNUSED(bytes);
+ NE_UNUSED(obj);
+
+#ifdef __DEBUG__
+ Detail::hal_serial_init<Detail::kPort>();
+
+ if (!bytes || Detail::kState != kStateReady) return;
+
+ if (*bytes == 0) return;
+
+ Detail::kState = kStateTransmit;
+
+ SizeT index = 0;
+ SizeT len = 0;
+
+ index = 0;
+ len = rt_string_len(bytes);
+
+ Char tmp_str[2];
+
+ while (index < len) {
+ if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r');
+
+ HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]);
+
+ tmp_str[0] = bytes[index];
+ tmp_str[1] = 0;
+
+ cg_render_string(tmp_str, kY, kX, RGB(0xff, 0xff, 0xff));
+
+ if (bytes[index] == '\r') {
+ kY += kFontSizeY;
+ kX = kFontSizeX;
+ }
+
+ kX += kFontSizeX;
+
+ if (kX > kHandoverHeader->f_GOP.f_Width) {
+ kX = kFontSizeX;
+ }
+
+ if (kY > kHandoverHeader->f_GOP.f_Height) {
+ kY = kFontSizeY;
+
+ FBDrawInRegion(cg_get_clear_clr(), FB::CGAccessibilty::Height(), FB::CGAccessibilty::Width(),
+ 0, 0);
+ }
+
+ ++index;
+ }
+
+ Detail::kState = kStateReady;
+#endif // __DEBUG__
+}
+
+EXTERN_C void ke_io_read(DeviceInterface<const Char*>*, const Char* bytes) {
+ NE_UNUSED(bytes);
+
+#ifdef __DEBUG__
+ Detail::hal_serial_init<Detail::kPort>();
+
+ if (!bytes || Detail::kState != kStateReady) return;
+
+ Detail::kState = kStateTransmit;
+
+ SizeT index = 0;
+
+ ///! TODO: Look on how to wait for the UART to complete.
+ while (true) {
+ auto in = HAL::rt_in8(Detail::kPort);
+
+ ///! If enter pressed then break.
+ if (in == 0xD) {
+ break;
+ }
+
+ if (in < '0' || in < 'A' || in < 'a') {
+ if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || in != ':') {
+ continue;
+ }
+ }
+
+ ((char*) bytes)[index] = in;
+
+ ++index;
+ }
+
+ ((char*) bytes)[index] = 0;
+
+ Detail::kState = kStateReady;
+#endif // __DEBUG__
+}
+
+TerminalDevice TerminalDevice::The() noexcept {
+ TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read);
+ return out;
+}
+
+Utf8TerminalDevice::~Utf8TerminalDevice() = default;
+
+Utf8TerminalDevice Utf8TerminalDevice::The() noexcept {
+ Utf8TerminalDevice out(Kernel::ke_utf_io_write,
+ [](DeviceInterface<const Utf8Char*>*, const Utf8Char*) -> Void {});
+ return out;
+}
+
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/HalDebugProtocol.cc b/src/kernel/HALKit/AMD64/HalDebugProtocol.cc
new file mode 100644
index 00000000..1adfff3e
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalDebugProtocol.cc
@@ -0,0 +1,16 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+//! @file DebuggerPort.cc
+//! @brief UART debug via packets.
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <NetworkKit/NetworkDevice.h>
+
+// after that we have start of additional data.
+
+namespace Kernel {} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/src/kernel/HALKit/AMD64/HalDescriptorLoader.cc
new file mode 100644
index 00000000..65bf0b1e
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalDescriptorLoader.cc
@@ -0,0 +1,71 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <FSKit/NeFS.h>
+#include <HALKit/AMD64/Processor.h>
+
+namespace Kernel::HAL {
+namespace Detail {
+ STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 kInterruptVectorTable[kKernelIdtSize] =
+ {};
+} // namespace Detail
+
+/// @brief Loads the provided Global Descriptor Table.
+/// @param gdt
+/// @return
+Void GDTLoader::Load(Register64& gdt) {
+#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
+ hal_load_gdt(gdt);
+#endif // __NE_MODULAR_KERNEL_COMPONENTS__
+}
+
+Void IDTLoader::Load(Register64& idt) {
+#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
+ rt_cli();
+
+ volatile UIntPtr** ptr_ivt = (volatile UIntPtr**) idt.Base;
+
+ for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) {
+ Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector;
+ Detail::kInterruptVectorTable[idt_indx].Ist = 0;
+ Detail::kInterruptVectorTable[idt_indx].TypeAttributes =
+ kKernelInterruptId ? kUserInterruptGate : kInterruptGate;
+ Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr) ptr_ivt[idt_indx] & 0xFFFF);
+ Detail::kInterruptVectorTable[idt_indx].OffsetMid =
+ (((UIntPtr) ptr_ivt[idt_indx] >> 16) & 0xFFFF);
+ Detail::kInterruptVectorTable[idt_indx].OffsetHigh =
+ (((UIntPtr) ptr_ivt[idt_indx] >> 32) & 0xFFFFFFFF);
+
+ Detail::kInterruptVectorTable[idt_indx].Zero = 0;
+ }
+
+ idt.Base = (UIntPtr) &Detail::kInterruptVectorTable[0];
+ idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * (kKernelIdtSize);
+
+ hal_load_idt(idt);
+ rt_sti();
+#endif // __NE_MODULAR_KERNEL_COMPONENTS__
+
+ return;
+}
+
+/// @brief Loads the Global Descriptor Table into the CPU.
+/// @param gdt GDT register wrapped in a ref.
+void GDTLoader::Load(Ref<Register64>& gdt) {
+ if (!gdt) return;
+
+ GDTLoader::Load(gdt.Leak());
+}
+
+/// @brief Loads the IDT, for interupts.
+/// @param idt IDT register wrapped in a ref.
+void IDTLoader::Load(Ref<Register64>& idt) {
+ if (!idt) return;
+
+ IDTLoader::Load(idt.Leak());
+}
+} // namespace Kernel::HAL
diff --git a/src/kernel/HALKit/AMD64/HalHandoverStub.asm b/src/kernel/HALKit/AMD64/HalHandoverStub.asm
new file mode 100644
index 00000000..c9cabd1c
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalHandoverStub.asm
@@ -0,0 +1,30 @@
+;; /*
+;; * ========================================================
+;; *
+;; * NeKernel
+;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+[bits 64]
+
+%define kTypeKernel 100
+%define kArchAmd64 122
+%define kHandoverMagic 0xBADCC
+
+global _HandoverMagic
+global _HandoverType
+global _HandoverPad
+global _HandoverArch
+
+section .ldr
+
+_HandoverMagic:
+ dq kHandoverMagic
+_HandoverType:
+ dw kTypeKernel
+_HandoverPad:
+ dw 0
+_HandoverArch:
+ dw kArchAmd64
diff --git a/src/kernel/HALKit/AMD64/HalInterruptAPI.asm b/src/kernel/HALKit/AMD64/HalInterruptAPI.asm
new file mode 100644
index 00000000..c761684e
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalInterruptAPI.asm
@@ -0,0 +1,370 @@
+;; /*
+;; * ---------------------------------------------------
+;; *
+;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * File: HalInterruptAPI.asm
+;; * Purpose: Interrupt API, redirect raw interrupts into their handlers.
+;; *
+;; * ---------------------------------------------------
+;; */
+
+[bits 64]
+
+%define kInterruptId 50
+
+%macro IntExp 1
+global __NE_INT_%1
+__NE_INT_%1:
+ cli
+
+ std
+
+ o64 iret
+%endmacro
+
+%macro IntNormal 1
+global __NE_INT_%1
+__NE_INT_%1:
+ cli
+
+ std
+
+ add rsp, 8
+
+ o64 iret
+%endmacro
+
+; This file handles the core interrupt table
+; Last edited 31/01/24
+
+global ke_handle_irq
+global kInterruptVectorTable
+
+extern idt_handle_gpf
+extern idt_handle_pf
+extern ke_io_write
+extern idt_handle_ud
+extern idt_handle_generic
+extern idt_handle_breakpoint
+extern idt_handle_math
+
+section .text
+
+__NE_INT_0:
+ cli
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+__NE_INT_1:
+ cli
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+__NE_INT_2:
+ cli
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched.
+__NE_INT_3:
+ cli
+ push rcx
+ call idt_handle_breakpoint
+ pop rcx
+
+ std
+
+ o64 iret
+
+__NE_INT_4:
+ cli
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+__NE_INT_5:
+ cli
+ std
+
+ o64 iret
+
+;; Invalid opcode interrupt
+__NE_INT_6:
+ cli
+ push rcx
+ call idt_handle_ud
+ pop rcx
+
+ std
+
+ o64 iret
+
+__NE_INT_7:
+ cli
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+;; Invalid opcode interrupt
+__NE_INT_8:
+ cli
+
+ push rcx
+ call idt_handle_math
+ pop rcx
+
+ std
+
+ o64 iret
+
+IntNormal 9
+IntExp 10
+IntExp 11
+
+IntExp 12
+
+__NE_INT_13:
+ cli
+
+ push rcx
+ call idt_handle_gpf
+ pop rcx
+
+ std
+
+ add rsp, 8
+
+ o64 iret
+
+__NE_INT_14:
+ cli
+ push rcx
+ call idt_handle_pf
+ pop rcx
+
+ std
+
+ o64 iret
+
+IntNormal 15
+IntNormal 16
+IntExp 17
+IntNormal 18
+IntNormal 19
+IntNormal 20
+IntNormal 21
+
+IntNormal 22
+
+IntNormal 23
+IntNormal 24
+IntNormal 25
+IntNormal 26
+IntNormal 27
+IntNormal 28
+IntNormal 29
+IntExp 30
+IntNormal 31
+
+[extern idt_handle_scheduler]
+[extern kApicBaseAddress]
+
+__NE_INT_32:
+ cli
+
+ push rax
+ mov rcx, rsp
+ call idt_handle_scheduler
+ pop rax
+
+ std
+
+ o64 iret
+
+IntNormal 33
+
+IntNormal 34
+IntNormal 35
+IntNormal 36
+IntNormal 37
+IntNormal 38
+IntNormal 39
+
+[extern rtl_rtl8139_interrupt_handler]
+
+__NE_INT_40:
+ cli
+
+ push rax
+ mov rcx, rsp
+ call rtl_rtl8139_interrupt_handler
+ pop rax
+
+ std
+
+ o64 iret
+
+IntNormal 41
+
+IntNormal 42
+IntNormal 43
+IntNormal 44
+IntNormal 45
+IntNormal 46
+IntNormal 47
+IntNormal 48
+IntNormal 49
+
+[extern hal_system_call_enter]
+[extern hal_kernel_call_enter]
+
+__NE_INT_50:
+ cli
+
+ push rax
+ mov rax, hal_system_call_enter
+
+ mov rcx, r8
+ mov rdx, r9
+ mov r8, r10
+ mov r9, r11
+
+ call rax
+ pop rax
+
+ std
+
+ o64 iret
+
+__NE_INT_51:
+ cli
+
+ push rax
+ mov rax, hal_kernel_call_enter
+
+ mov rcx, r8
+ mov rdx, r9
+ mov r8, r10
+ mov r9, r11
+
+ call rax
+ pop rax
+
+ std
+
+ o64 iret
+
+IntNormal 52
+
+IntNormal 53
+IntNormal 54
+IntNormal 55
+IntNormal 56
+IntNormal 57
+IntNormal 58
+IntNormal 59
+IntNormal 60
+
+%assign i 61
+%rep 195
+ IntNormal i
+%assign i i+1
+%endrep
+
+section .text
+
+[global hal_load_gdt]
+
+hal_load_gdt:
+ cli
+
+ lgdt [rcx]
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ mov rax, 0x08
+ push rax
+ push hal_reload_segments
+
+ o64 retf
+
+extern hal_real_init
+
+hal_reload_segments:
+ std
+ jmp hal_real_init
+ ret
+
+global hal_load_idt
+
+hal_load_idt:
+ lidt [rcx]
+
+ ; Master PIC initialization
+ mov al, 0x11 ; Start initialization in cascade mode
+ out 0x20, al ; Send initialization command to Master PIC
+ out 0xA0, al ; Send initialization command to Slave PIC
+
+ ; Remap the PIC to use vectors 32-39 for Master and 40-47 for Slave
+ mov al, 0x20 ; Set Master PIC offset to 32
+ out 0x21, al ; Send offset to Master PIC
+
+ mov al, 0x28 ; Set Slave PIC offset to 40
+ out 0xA1, al ; Send offset to Slave PIC
+
+ ; Configure Master PIC to inform Slave PIC at IRQ2
+ mov al, 0x04 ; Tell Master PIC there is a Slave PIC at IRQ2
+ out 0x21, al
+
+ ; Configure Slave PIC identity
+ mov al, 0x02 ; Tell Slave PIC its cascade identity
+ out 0xA1, al
+
+ ; Set both PICs to 8086 mode
+ mov al, 0x01 ; 8086 mode
+ out 0x21, al
+ out 0xA1, al
+
+ ret
+
+section .data
+
+kInterruptVectorTable:
+ %assign i 0
+ %rep 256
+ dq __NE_INT_%+i
+ %assign i i+1
+ %endrep
+
+kApicBaseAddress:
+ dq 0 \ No newline at end of file
diff --git a/src/kernel/HALKit/AMD64/HalKernelMain.cc b/src/kernel/HALKit/AMD64/HalKernelMain.cc
new file mode 100644
index 00000000..e23c5bc1
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalKernelMain.cc
@@ -0,0 +1,160 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <CFKit/Property.h>
+#include <FirmwareKit/EFI/API.h>
+#include <FirmwareKit/EFI/EFI.h>
+#include <KernelKit/CodeMgr.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/Timer.h>
+#include <NetworkKit/IPC.h>
+#include <StorageKit/AHCI.h>
+#include <misc/BenchKit/HWChronometer.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
+EXTERN_C Kernel::VoidPtr kInterruptVectorTable[];
+
+/// @brief Kernel init function.
+/// @param handover_hdr Handover boot header.
+EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
+ using namespace Kernel;
+
+ if (handover_hdr->f_Magic != kHandoverMagic && handover_hdr->f_Version != kHandoverVersion) {
+ return kEfiFail;
+ }
+
+ HAL::rt_sti();
+
+ fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]);
+
+ Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey,
+ handover_hdr->f_HardwareTables.f_ImageHandle);
+
+ kHandoverHeader = handover_hdr;
+
+ kKernelVM = kHandoverHeader->f_PageStart;
+
+ if (!kKernelVM) {
+ MUST_PASS(kKernelVM);
+ return kEfiFail;
+ }
+
+ hal_write_cr3(kKernelVM);
+
+ /************************************** */
+ /* INITIALIZE BIT MAP. */
+ /************************************** */
+
+ kBitMapCursor = 0UL;
+ kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
+ kKernelBitMpStart =
+ reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(kHandoverHeader->f_BitMapStart));
+
+ /************************************** */
+ /* INITIALIZE GDT AND SEGMENTS. */
+ /************************************** */
+
+ STATIC CONST auto kGDTEntriesCount = 8;
+
+ STATIC HAL::Detail::NE_TSS kKernelTSS{};
+
+ kKernelTSS.fRsp0 = (UInt64) kHandoverHeader->f_StackTop;
+ kKernelTSS.fIopb = sizeof(HAL::Detail::NE_TSS);
+
+ /* The GDT, mostly descriptors for user and kernel segments. */
+ STATIC HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = {
+ {.fLimitLow = 0,
+ .fBaseLow = 0,
+ .fBaseMid = 0,
+ .fAccessByte = 0x00,
+ .fFlags = 0x00,
+ .fBaseHigh = 0}, // Null entry
+ {.fLimitLow = 0x0,
+ .fBaseLow = 0,
+ .fBaseMid = 0,
+ .fAccessByte = 0x9A,
+ .fFlags = 0xAF,
+ .fBaseHigh = 0}, // Kernel code
+ {.fLimitLow = 0x0,
+ .fBaseLow = 0,
+ .fBaseMid = 0,
+ .fAccessByte = 0x92,
+ .fFlags = 0xCF,
+ .fBaseHigh = 0}, // Kernel data
+ {}, // TSS data low
+ {}, // TSS data high
+ {.fLimitLow = 0x0,
+ .fBaseLow = 0,
+ .fBaseMid = 0,
+ .fAccessByte = 0xFA,
+ .fFlags = 0xAF,
+ .fBaseHigh = 0}, // User code
+ {.fLimitLow = 0x0,
+ .fBaseLow = 0,
+ .fBaseMid = 0,
+ .fAccessByte = 0xF2,
+ .fFlags = 0xCF,
+ .fBaseHigh = 0}, // User data
+ };
+
+ kGDTArray[3].fLimitLow = sizeof(HAL::Detail::NE_TSS) - 1;
+ kGDTArray[3].fBaseLow = ((UIntPtr) &kKernelTSS) & 0xFFFF;
+ kGDTArray[3].fBaseMid = (((UIntPtr) &kKernelTSS) >> 16) & 0xFF;
+ kGDTArray[3].fAccessByte = 0x89; // Present, type 9 = 64-bit available TSS
+ kGDTArray[3].fFlags = 0x20 | ((((UIntPtr) &kKernelTSS) >> 24) & 0x0F);
+ kGDTArray[3].fBaseHigh = (((UIntPtr) &kKernelTSS) >> 24) & 0xFF;
+
+ kGDTArray[4].fLimitLow = ((UIntPtr) &kKernelTSS >> 32) & 0xFFFF;
+ kGDTArray[4].fBaseLow = 0;
+ kGDTArray[4].fBaseMid = 0;
+ kGDTArray[4].fAccessByte = 0;
+ kGDTArray[4].fFlags = 0;
+ kGDTArray[4].fBaseHigh = 0;
+
+ FB::cg_clear_video();
+
+ // Load memory descriptors.
+ HAL::Register64 gdt_reg;
+
+ gdt_reg.Base = reinterpret_cast<UIntPtr>(kGDTArray);
+ gdt_reg.Limit = (sizeof(HAL::Detail::NE_GDT_ENTRY) * kGDTEntriesCount) - 1;
+
+ //! GDT will load hal_read_init after it successfully loads the segments.
+ HAL::GDTLoader gdt_loader;
+ gdt_loader.Load(gdt_reg);
+
+ return kEfiFail;
+}
+
+EXTERN_C Kernel::Void hal_real_init(Kernel::Void) {
+#ifdef __FSKIT_INCLUDES_OPENHEFS__
+ OpenHeFS::fs_init_openhefs();
+#endif
+
+#ifdef __FSKIT_INCLUDES_NEFS__
+ NeFS::fs_init_nefs();
+#endif
+
+ UserProcessScheduler::The().SwitchTeam(kHighUserTeam);
+
+ rtl_create_user_process([]() -> void { while (YES); }, "NeKernel");
+
+ HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
+
+ HAL::Register64 idt_reg;
+ idt_reg.Base = reinterpret_cast<UIntPtr>(kInterruptVectorTable);
+
+ HAL::IDTLoader idt_loader;
+ idt_loader.Load(idt_reg);
+
+ while (YES)
+ ;
+}
+#endif // ifndef __NE_MODULAR_KERNEL_COMPONENTS__
diff --git a/src/kernel/HALKit/AMD64/HalKernelPanic.cc b/src/kernel/HALKit/AMD64/HalKernelPanic.cc
new file mode 100644
index 00000000..12538667
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalKernelPanic.cc
@@ -0,0 +1,58 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+/* Each error code is attributed with an ID, which will prompt a string onto the
+ * screen. Wait for debugger... */
+
+namespace Kernel {
+/// @brief Dumping factory class.
+class RecoveryFactory final {
+ public:
+ STATIC Void Recover() noexcept;
+};
+
+/***********************************************************************************/
+/// @brief Stops execution of the kernel.
+/// @param id kernel stop ID.
+/***********************************************************************************/
+Void ke_panic(const Kernel::Int32& id, const Char* message) {
+ (Void)(kout << "*** STOP ***\r");
+
+ (Void)(kout << "Kernel_Panic_MSG: " << message << kendl);
+ (Void)(kout << "Kernel_Panic_ID: " << hex_number(id) << kendl);
+ (Void)(kout << "Kernel_Panic_CR2: " << hex_number((UIntPtr) hal_read_cr2()) << kendl);
+
+ RecoveryFactory::Recover();
+}
+
+Void RecoveryFactory::Recover() noexcept {
+ while (YES) {
+ HAL::rt_halt();
+ }
+}
+
+void ke_runtime_check(bool expr, const Char* file, const Char* line) {
+ if (!expr) {
+ (Void)(kout << "*** CHECK ***\r");
+
+ (Void)(kout << "Kernel_Panic_FILE: " << file << kendl);
+ (Void)(kout << "Kernel_Panic_LINE: " << line << kendl);
+
+ ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed
+ }
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/HalPagingMgr.cc b/src/kernel/HALKit/AMD64/HalPagingMgr.cc
new file mode 100644
index 00000000..4043da96
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalPagingMgr.cc
@@ -0,0 +1,167 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HalPagingMgr.cc
+ Purpose: Platform Paging Manager.
+
+======================================== */
+
+#include <HALKit/AMD64/Paging.h>
+#include <HALKit/AMD64/Processor.h>
+
+namespace Kernel::HAL {
+namespace Detail {
+ /// @brief Page Table Entry for AMD64.
+ struct PTE {
+ UInt64 Present : 1;
+ UInt64 Wr : 1;
+ UInt64 User : 1;
+ UInt64 Pwt : 1; // Page-level Write-Through
+ UInt64 Pcd : 1; // Page-level Cache Disable
+ UInt64 Accessed : 1;
+ UInt64 Dirty : 1;
+ UInt64 Pat : 1; // Page Attribute Table (or PS for PDE)
+ UInt64 Global : 1;
+ UInt64 Ignored1 : 3; // Available to software
+ UInt64 PhysicalAddress : 40; // Physical page frame address (bits 12–51)
+ UInt64 Ignored2 : 7; // More software bits / reserved
+ UInt64 ProtectionKey : 4; // Optional (if PKU enabled)
+ UInt64 Reserved : 1; // Usually reserved
+ UInt64 Nx : 1; // No Execute
+ };
+} // namespace Detail
+
+/***********************************************************************************/
+/// \brief Retrieve the page status of a PTE.
+/// \param pte Page Table Entry pointer.
+/***********************************************************************************/
+STATIC Void mmi_page_status(Detail::PTE* pte) {
+ NE_UNUSED(pte);
+
+#ifdef __NE_VERBOSE_BITMAP__
+ (Void)(kout << "Flag: " << (pte->Present ? "Present" : "Not Present") << kendl);
+ (Void)(kout << "Flag: " << (pte->Wr ? "W/R" : "Not W/R") << kendl);
+ (Void)(kout << "Flag: " << (pte->Nx ? "NX" : "Not NX") << kendl);
+ (Void)(kout << "Flag: " << pte->User ? "User" : "Not User") << kendl);
+ (Void)(kout << "Flag: " << (pte->Pcd ? "Not Cached" : "Cached") << kendl);
+ (Void)(kout << "Flag: " << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl);
+ (Void)(kout << "Flag: " << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled")
+ << kendl);
+ (Void)(kout << "Physical Address: " << hex_number(pte->PhysicalAddress) << kendl);
+#endif
+}
+
+/***********************************************************************************/
+/// @brief Gets a physical address from a virtual address.
+/// @param virt a valid virtual address.
+/// @return Physical address.
+/***********************************************************************************/
+EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virt) {
+ const UInt64 kVMAddr = (UInt64) virt;
+ const UInt64 kMask9Bits = 0x1FFULL;
+ const UInt64 kPageOffsetMask = 0xFFFULL;
+
+ UInt64 cr3 = (UInt64) hal_read_cr3() & ~kPageOffsetMask;
+
+ // Level 4
+ auto pml4 = reinterpret_cast<UInt64*>(cr3);
+ UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9Bits];
+
+ if (!(pml4e & 1)) return 0;
+
+ // Level 3
+ auto pdpt = reinterpret_cast<UInt64*>(pml4e & ~kPageOffsetMask);
+ UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9Bits];
+
+ if (!(pdpte & 1)) return 0;
+
+ // Level 2
+ auto pd = reinterpret_cast<UInt64*>(pdpte & ~kPageOffsetMask);
+ UInt64 pde = pd[(kVMAddr >> 21) & kMask9Bits];
+
+ if (!(pde & 1)) return 0;
+
+ // 1 GiB page support
+ if (pde & (1 << 7)) {
+ return (pde & ~((1ULL << 30) - 1)) | (kVMAddr & ((1ULL << 30) - 1));
+ }
+
+ // Level 1
+ auto pt = reinterpret_cast<UInt64*>(pde & ~kPageOffsetMask);
+ Detail::PTE* pte = (Detail::PTE*) pt[(kVMAddr >> 12) & kMask9Bits];
+
+ if (!pte->Present) return 0;
+
+ mmi_page_status((Detail::PTE*) pte);
+
+ return (pte->PhysicalAddress << 12) | (kVMAddr & 0xFFF);
+}
+
+/***********************************************************************************/
+/// @brief clflush+mfence helper function.
+/***********************************************************************************/
+EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address) {
+ if (!virtual_address || !mm_get_page_addr(virtual_address)) return kErrorInvalidData;
+
+ asm volatile("clflush (%0)" : : "r"(virtual_address) : "memory");
+ asm volatile("mfence" ::: "memory");
+
+ return kErrorSuccess;
+}
+
+/***********************************************************************************/
+/// @brief Maps or allocates a page from virtual_address.
+/// @param virtual_address a valid virtual address.
+/// @param phys_addr point to physical address.
+/// @param flags the flags to put on the page.
+/// @return Status code of page manipulation process.
+/***********************************************************************************/
+EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags,
+ UInt32 level) {
+ if (physical_address == 0) return kErrorInvalidData;
+
+ NE_UNUSED(level); /// @todo support PML4, and PDPT levels.
+
+ const UInt64 kVMAddr = (UInt64) virtual_address;
+ constexpr UInt64 kMask9 = 0x1FF;
+ constexpr UInt64 kPageMask = 0xFFF;
+
+ UInt64 cr3 = (UIntPtr) hal_read_cr3() & ~kPageMask;
+
+ auto pml4 = reinterpret_cast<UInt64*>(cr3);
+ UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9];
+
+ if (!(pml4e & 1)) return kErrorInvalidData;
+
+ UInt64* pdpt = reinterpret_cast<UInt64*>(pml4e & ~kPageMask);
+ UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9];
+
+ if (!(pdpte & 1)) return kErrorInvalidData;
+
+ UInt64* pd = reinterpret_cast<UInt64*>(pdpte & ~kPageMask);
+ UInt64 pde = pd[(kVMAddr >> 21) & kMask9];
+
+ if (!(pde & 1)) return kErrorInvalidData;
+
+ UInt64* pt = reinterpret_cast<UInt64*>(pde & ~kPageMask);
+ Detail::PTE* pte = (Detail::PTE*) pt[(kVMAddr >> 12) & kMask9];
+
+ pte->Present = !!(flags & kMMFlagsPresent);
+ pte->Wr = !!(flags & kMMFlagsWr);
+ pte->User = !!(flags & kMMFlagsUser);
+ pte->Nx = !!(flags & kMMFlagsNX);
+ pte->Pcd = !!(flags & kMMFlagsPCD);
+ pte->Pwt = !!(flags & kMMFlagsPwt);
+
+ pte->PhysicalAddress = ((UIntPtr) (physical_address)) >> 12;
+
+ hal_invl_tlb(virtual_address);
+
+ mm_memory_fence(virtual_address);
+
+ mmi_page_status(pte);
+
+ return kErrorSuccess;
+}
+} // namespace Kernel::HAL
diff --git a/src/kernel/HALKit/AMD64/HalProcessor.cc b/src/kernel/HALKit/AMD64/HalProcessor.cc
new file mode 100644
index 00000000..d202a758
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalProcessor.cc
@@ -0,0 +1,89 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HalCPU.cc
+ Purpose: Platform processor routines.
+
+======================================== */
+
+#include <HALKit/AMD64/Paging.h>
+#include <HALKit/AMD64/Processor.h>
+
+/**
+ * @file HalCPU.cc
+ * @brief Common CPU API.
+ */
+
+namespace Kernel::HAL {
+inline Bool hal_has_msr() noexcept {
+ static UInt32 eax, unused, edx; // eax, edx
+
+ __get_cpuid(1, &eax, &unused, &unused, &edx);
+
+ // edx returns the flag for MSR (which is 1 shifted to 5.)
+ return edx & (1 << 5);
+}
+
+Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept {
+ if (!lo || !hi) return;
+ asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr));
+}
+
+Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept {
+ asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr));
+}
+
+Void lrt_hal_out8(UInt16 port, UInt8 value) {
+ asm volatile("outb %%al, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+Void lrt_hal_out16(UInt16 port, UInt16 value) {
+ asm volatile("outw %%ax, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+Void lrt_hal_out32(UInt16 port, UInt32 value) {
+ asm volatile("outl %%eax, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+UInt8 lrt_hal_in8(UInt16 port) {
+ UInt8 value = 0UL;
+ asm volatile("inb %1, %%al" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+UInt16 lrt_hal_in16(UInt16 port) {
+ UInt16 value = 0UL;
+ asm volatile("inw %1, %%ax" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+UInt32 lrt_hal_in32(UInt16 port) {
+ UInt32 value = 0UL;
+ asm volatile("inl %1, %%eax" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+Void rt_halt() {
+ asm volatile("hlt");
+}
+
+Void rt_cli() {
+ asm volatile("cli");
+}
+
+Void rt_sti() {
+ asm volatile("sti");
+}
+
+Void rt_cld() {
+ asm volatile("cld");
+}
+
+Void rt_std() {
+ asm volatile("std");
+}
+} // namespace Kernel::HAL
diff --git a/src/kernel/HALKit/AMD64/HalRoutineWait.s b/src/kernel/HALKit/AMD64/HalRoutineWait.s
new file mode 100644
index 00000000..89051ba4
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalRoutineWait.s
@@ -0,0 +1,11 @@
+.globl rt_wait_400ns
+
+.section .text
+rt_wait_400ns:
+ jmp .loop
+ pause
+ .loop:
+ jmp .loop2
+ pause
+ .loop2:
+ ret
diff --git a/src/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.cc b/src/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.cc
new file mode 100644
index 00000000..44ec2a37
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.cc
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/AMD64/Processor.h>
+#include <KernelKit/ProcessScheduler.h>
+
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Unimplemented function (crashes by default)
+/// @param
+/***********************************************************************************/
+
+EXTERN_C Void __ne_pure_call(USER_PROCESS* process) {
+ if (process) process->Crash();
+}
+
+/***********************************************************************************/
+/// @brief Validate user stack.
+/// @param stack_ptr the frame pointer.
+/***********************************************************************************/
+
+EXTERN_C Bool hal_check_task(HAL::StackFramePtr stack_ptr) {
+ if (!stack_ptr) return No;
+
+ return stack_ptr->SP > 0 && stack_ptr->IP > 0;
+}
+
+/// @brief Wakes up thread.
+/// Wakes up thread from the hang state.
+Void mp_wakeup_thread(HAL::StackFrame* stack) {
+ if (!hal_check_task(stack)) return;
+
+ // RIP is always in R15. R15 is reserved for the RIP.
+ stack->IP = stack->R15;
+
+ Kernel::UserProcessHelper::StartScheduling();
+}
+
+/// @brief makes the thread sleep on a loop.
+/// hooks and hangs thread to prevent code from executing.
+Void mp_hang_thread(HAL::StackFrame* stack) {
+ if (!hal_check_task(stack)) return;
+
+ // Store IP in R15
+ stack->R15 = stack->IP;
+ stack->IP = 0UL;
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/HalTimer.cc b/src/kernel/HALKit/AMD64/HalTimer.cc
new file mode 100644
index 00000000..f6488b05
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalTimer.cc
@@ -0,0 +1,101 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HalTimer.cc
+ Purpose: HAL timer
+
+ Revision History:
+
+ 07/07/24: Added file (amlel)
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Timer.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+
+/// ================================================================================
+/// @note timer slot 0
+/// ================================================================================
+
+#define kHPETSignature ("HPET")
+
+#define kHPETCounterRegValue (0x00)
+#define kHPETConfigRegValue (0x20)
+#define kHPETCompRegValue (0x24)
+#define kHPETInterruptRegValue (0x2C)
+
+/// ================================================================================
+///! BUGS: 0
+///! @file HalTimer.cc
+///! @brief Hardware Timer (HPET)
+/// ================================================================================
+
+namespace Kernel::Detail {
+struct HPET_BLOCK : public Kernel::SDT {
+ Kernel::UInt8 hardware_rev_id;
+ Kernel::UInt8 comparator_count : 5;
+ Kernel::UInt8 counter_size : 1;
+ Kernel::UInt8 reserved : 1;
+ Kernel::UInt8 legacy_replacement : 1;
+ Kernel::UInt16 pci_vendor_id;
+ ACPI_ADDRESS address;
+ Kernel::UInt8 hpet_number;
+ Kernel::UInt16 minimum_tick;
+ Kernel::UInt8 page_protection;
+} PACKED;
+} // namespace Kernel::Detail
+
+using namespace Kernel;
+
+HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) {
+ auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr);
+
+ auto hpet = (Detail::HPET_BLOCK*) power.Find(kHPETSignature).Leak().Leak();
+ MUST_PASS(hpet);
+
+ fDigitalTimer = (UInt8*) hpet->address.Address;
+
+ if (hpet->page_protection) {
+ HAL::mm_map_page((VoidPtr) fDigitalTimer, (VoidPtr) fDigitalTimer,
+ HAL::kMMFlagsWr | HAL::kMMFlagsPCD | HAL::kMMFlagsPwt);
+ }
+
+ // if not enabled yet.
+ if (!(*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) & (1 << 0))) {
+ *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
+ *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) | (1 << 0) |
+ (1 << 3); // enable timer & one shot conf
+ }
+}
+
+HardwareTimer::~HardwareTimer() {
+ fDigitalTimer = nullptr;
+ fWaitFor = 0;
+}
+
+/***********************************************************************************/
+/// @brief Wait for the timer to stop spinning.
+/***********************************************************************************/
+
+BOOL HardwareTimer::Wait() noexcept {
+ if (fWaitFor < 1) return NO;
+ if (fWaitFor > 1'000'000) return NO; // max 1000s = 16 minutes
+
+ UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer));
+ UInt64 femtoseconds_per_tick = (hpet_cap >> 32);
+
+ if (femtoseconds_per_tick == 0) return NO;
+
+ volatile UInt64* timer = (volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue);
+
+ UInt64 now = *timer;
+
+ UInt64 fs_wait = fWaitFor * 1'000'000'000'000ULL;
+ UInt64 stop_at = now + (fs_wait / femtoseconds_per_tick);
+
+ while (*timer < (stop_at)) asm volatile("pause");
+
+ return YES;
+}
diff --git a/src/kernel/HALKit/AMD64/HalUtilsAPI.asm b/src/kernel/HALKit/AMD64/HalUtilsAPI.asm
new file mode 100644
index 00000000..2a0a5eff
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/HalUtilsAPI.asm
@@ -0,0 +1,24 @@
+;; /*
+;; * ========================================================
+;; *
+;; * NeKernel
+;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+[bits 64]
+
+[global rt_install_tib]
+
+section .text
+
+;; changed: rs, fs
+;; expected: rcx, rdx
+
+rt_install_tib:
+ mov rcx, gs ;; TIB -> Thread Information Block
+ mov rdx, fs ;; PIB -> Process Information Block
+ ret
+
+;; //////////////////////////////////////////////////// ;;
diff --git a/src/kernel/HALKit/AMD64/Hypervisor.h b/src/kernel/HALKit/AMD64/Hypervisor.h
new file mode 100644
index 00000000..4cacb003
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Hypervisor.h
@@ -0,0 +1,24 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+MAKE_STRING_ENUM(HYPERVISOR)
+ENUM_STRING(Qemu, "TCGTCGTCGTCG");
+ENUM_STRING(KVM, " KVMKVMKVM ");
+ENUM_STRING(VMWare, "VMwareVMware");
+ENUM_STRING(VirtualBox, "VBoxVBoxVBox");
+ENUM_STRING(Xen, "XenVMMXenVMM");
+ENUM_STRING(Microsoft, "Microsoft Hv");
+ENUM_STRING(Parallels, " prl hyperv ");
+ENUM_STRING(ParallelsAlt, " lrpepyh vr ");
+ENUM_STRING(Bhyve, "bhyve bhyve ");
+ENUM_STRING(Qnx, " QNXQVMBSQG ");
+END_STRING_ENUM()
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
new file mode 100644
index 00000000..f9865139
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
@@ -0,0 +1,129 @@
+/* ========================================
+
+Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <DmaKit/DmaPool.h>
+#include <HALKit/AMD64/Processor.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+
+using namespace Kernel;
+using namespace Kernel::HAL;
+
+STATIC UInt16 kRTLIOBase = 0xFFFF;
+
+STATIC BOOL kTXRXEnabled = NO;
+
+STATIC UInt32 kRXOffset = 0UL;
+STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500;
+
+STATIC UInt8* kRXUpperLayer = nullptr;
+STATIC UInt8* kRXBuffer = nullptr;
+
+/***********************************************************************************/
+///@brief RTL8139 Init routine.
+/***********************************************************************************/
+
+EXTERN_C BOOL rtl_init_nic_rtl8139(UInt16 io_base) noexcept {
+ if (kTXRXEnabled) return NO;
+
+ kRTLIOBase = io_base;
+
+ MUST_PASS(io_base != 0xFFFF);
+
+ kRXBuffer = reinterpret_cast<UInt8*>(rtl_dma_alloc(sizeof(UInt8) * kRXBufferSize, 0));
+
+ MUST_PASS(kRXBuffer);
+
+ /// Reset first.
+
+ rt_out8(io_base + 0x37, 0x10);
+
+ UInt16 timeout = 0U;
+
+ while (rt_in8(io_base + 0x37) & 0x10) {
+ ++timeout;
+ if (timeout > 0x1000) break;
+ }
+
+ if (timeout <= 0x1000) {
+ return NO;
+ }
+
+ rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRXBuffer);
+
+ rt_out8(io_base + 0x37, 0x0C);
+
+ rt_out32(io_base + 0x44, 0xF | (1 << 7));
+
+ rt_out16(io_base + 0x3C, 0x0005);
+
+ kTXRXEnabled = YES;
+
+ return YES;
+}
+
+/***********************************************************************************/
+/// @brief RTL8139 I/O interrupt handler.
+/// @param rsp stack pointer.
+/// @note This function is called when the device interrupts to retrieve network data.
+/***********************************************************************************/
+
+EXTERN_C Void rtl_rtl8139_interrupt_handler(UIntPtr rsp) {
+ if (kRTLIOBase == 0xFFFF || kRTLIOBase == 0) return;
+
+ NE_UNUSED(rsp);
+
+ UInt16 status = rt_in16(kRTLIOBase + 0x3E);
+ rt_out16(kRTLIOBase + 0x3E, status);
+
+ if (status & 0x01) {
+ // While we receive data.
+ while ((rt_in8(kRTLIOBase + 0x37) & 0x01) == 0) {
+ // We grab an offset from the RX buffer.
+ UInt32 offset = kRXOffset % kRXBufferSize;
+
+ // If the offset is too high, we reset it.
+ if (offset >= (kRXBufferSize - 16)) {
+ kRXOffset = 0UL;
+ offset = 0UL;
+ }
+
+ volatile UInt8* packet = kRXBuffer + offset + 4;
+ UInt16 len = *(UInt16*) (kRXBuffer + offset + 2);
+
+ kRXUpperLayer[(offset + 4)] = *packet;
+ kRXOffset += (len + 4);
+
+ rt_out16(kRTLIOBase + 0x38, (UInt16) (kRXOffset - 16));
+ }
+ }
+
+ if (!(status & 0x04)) {
+ err_global_get() = kErrorNoNetwork;
+ }
+}
+
+/***********************************************************************************/
+/// @brief RTL8139 get upper layer function
+/// @return the upper layer.
+/// @retval nullptr if no upper layer is set.
+/// @retval pointer to the upper layer if set.
+/***********************************************************************************/
+
+EXTERN_C UInt8* rtl_rtl8139_get_upper_layer() {
+ return kRXUpperLayer;
+}
+
+/***********************************************************************************/
+/// @brief RTL8139 set upper layer function
+/// @param layer the upper layer.
+/***********************************************************************************/
+
+EXTERN_C BOOL rtl_rtl8139_set_upper_layer(UInt8* layer) {
+ if (!layer) return NO;
+ kRXUpperLayer = layer;
+
+ return YES;
+}
diff --git a/src/kernel/HALKit/AMD64/PCI/DMA.cc b/src/kernel/HALKit/AMD64/PCI/DMA.cc
new file mode 100644
index 00000000..809494b6
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/PCI/DMA.cc
@@ -0,0 +1,72 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/PCI/DMA.h>
+
+namespace Kernel {
+DMAWrapper::operator bool() {
+ return this->fAddress;
+}
+
+bool DMAWrapper::operator!() {
+ return !this->fAddress;
+}
+
+Boolean DMAWrapper::Check(UIntPtr offset) const {
+ if (!this->fAddress) return false;
+
+ if (offset == 0) return false;
+
+ kout << "[DMAWrapper::IsIn] Checking offset...\r";
+ return reinterpret_cast<UIntPtr>(this->fAddress) >= offset;
+}
+
+bool DMAWrapper::Write(UIntPtr& bit, const UInt32& offset) {
+ kout << "[DMAWrapper::Read] Checking this->fAddress...\r";
+
+ if (!this->fAddress) return false;
+
+ (Void)(kout << "[DMAWrapper::Write] Writing at address: "
+ << hex_number(reinterpret_cast<UIntPtr>(this->fAddress) + offset) << kendl);
+
+ ke_dma_write<UInt32>(reinterpret_cast<UIntPtr>(this->fAddress), offset, bit);
+
+ return true;
+}
+
+UIntPtr DMAWrapper::Read(const UInt32& offset) {
+ kout << "[DMAWrapper::Read] Checking this->fAddress...\r";
+
+ if (!this->fAddress) return ~0;
+
+ (Void)(kout << "[DMAWrapper::Write] Writing at address: "
+ << hex_number(reinterpret_cast<UIntPtr>(this->fAddress) + offset) << kendl);
+
+ return (UIntPtr) ke_dma_read<UInt32>(reinterpret_cast<UIntPtr>(this->fAddress), offset);
+}
+
+UIntPtr DMAWrapper::operator[](UIntPtr& offset) {
+ return this->Read(offset);
+}
+
+OwnPtr<IOBuf<Char*>> DMAFactory::Construct(OwnPtr<DMAWrapper>& dma) {
+ if (!dma) return {};
+
+ OwnPtr<IOBuf<Char*>> dmaOwnPtr =
+ mm_make_own_ptr<IOBuf<Char*>, char*>(reinterpret_cast<char*>(dma->fAddress));
+
+ if (!dmaOwnPtr) return {};
+
+ kout << "Returning the new OwnPtr<IOBuf<Char*>>!\r";
+ return dmaOwnPtr;
+}
+
+DMAWrapper& DMAWrapper::operator=(voidPtr Ptr) {
+ this->fAddress = Ptr;
+ return *this;
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/PCI/Database.cc b/src/kernel/HALKit/AMD64/PCI/Database.cc
new file mode 100644
index 00000000..ba3e946c
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/PCI/Database.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/PCI/Database.h>
+
+namespace Kernel {}
diff --git a/src/kernel/HALKit/AMD64/PCI/Device.cc b/src/kernel/HALKit/AMD64/PCI/Device.cc
new file mode 100644
index 00000000..65af2f25
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/PCI/Device.cc
@@ -0,0 +1,142 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/PCI/Device.h>
+
+#define PCI_BAR_IO (0x01)
+#define PCI_BAR_LOWMEM (0x02)
+#define PCI_BAR_64 (0x04)
+#define PCI_BAR_PREFETCH (0x08)
+#define PCI_ENABLE_BIT (0x80000000)
+
+static Kernel::UInt NE_PCIReadRaw(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev,
+ Kernel::UShort fun) {
+ Kernel::UInt target = PCI_ENABLE_BIT | ((Kernel::UInt) bus << 16) | ((Kernel::UInt) dev << 11) |
+ ((Kernel::UInt) fun << 8) | (bar & 0xFC);
+
+ Kernel::HAL::rt_out32((Kernel::UShort) Kernel::PCI::PciConfigKind::ConfigAddress, target);
+
+ Kernel::HAL::rt_wait_400ns();
+
+ return Kernel::HAL::rt_in32((Kernel::UShort) Kernel::PCI::PciConfigKind::ConfigData);
+}
+
+static Kernel::Void NE_PCISetCfgTarget(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev,
+ Kernel::UShort fun) {
+ Kernel::UInt target = 0x80000000 | ((Kernel::UInt) bus << 16) | ((Kernel::UInt) dev << 11) |
+ ((Kernel::UInt) fun << 8) | (bar & 0xFC);
+
+ Kernel::HAL::rt_out32((Kernel::UShort) Kernel::PCI::PciConfigKind::ConfigAddress, target);
+
+ Kernel::HAL::rt_wait_400ns();
+}
+
+namespace Kernel::PCI {
+Device::Device(UShort bus, UShort device, UShort func, UInt32 bar)
+ : fBus(bus), fDevice(device), fFunction(func), fBar(bar) {}
+
+Device::~Device() = default;
+
+UInt Device::Read(UInt bar, Size sz) {
+ // Ensure aligned access by masking to 4-byte boundary
+ NE_PCISetCfgTarget(bar & 0xFC, fBus, fDevice, fFunction);
+
+ // Read 4 bytes and shift out the correct value
+ UInt data = HAL::rt_in32((UShort) PciConfigKind::ConfigData);
+
+ if (sz == 4) return data;
+ if (sz == 2) return (data >> ((bar & 2) * 8)) & 0xFFFF;
+ if (sz == 1) return (data >> ((bar & 3) * 8)) & 0xFF;
+
+ return (UShort) PciConfigKind::Invalid;
+}
+
+void Device::Write(UInt bar, UIntPtr data, Size sz) {
+ NE_PCISetCfgTarget(bar & 0xFC, fBus, fDevice, fFunction);
+
+ if (sz == 4) {
+ HAL::rt_out32((UShort) PciConfigKind::ConfigAddress, (UInt) data);
+ } else if (sz == 2) {
+ UInt temp = HAL::rt_in32((UShort) PciConfigKind::ConfigData);
+
+ temp &= ~(0xFFFF << ((bar & 2) * 8));
+ temp |= (data & 0xFFFF) << ((bar & 2) * 8);
+
+ HAL::rt_out32((UShort) PciConfigKind::ConfigAddress, temp);
+ } else if (sz == 1) {
+ UInt temp = HAL::rt_in32((UShort) PciConfigKind::ConfigData);
+
+ temp &= ~(0xFF << ((bar & 3) * 8));
+ temp |= (data & 0xFF) << ((bar & 3) * 8);
+
+ HAL::rt_out32((UShort) PciConfigKind::ConfigAddress, temp);
+ }
+}
+
+UShort Device::DeviceId() {
+ return (UShort) (NE_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16);
+}
+
+UShort Device::VendorId() {
+ return (UShort) (NE_PCIReadRaw(0x0, fBus, fDevice, fFunction) & 0xFFFF);
+}
+
+UShort Device::InterfaceId() {
+ return (UShort) (NE_PCIReadRaw(0x09, fBus, fDevice, fFunction) >> 16);
+}
+
+UChar Device::Class() {
+ return (UChar) (NE_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 24);
+}
+
+UChar Device::Subclass() {
+ return (UChar) (NE_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 16);
+}
+
+UChar Device::ProgIf() {
+ return (UChar) (NE_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 8);
+}
+
+UChar Device::HeaderType() {
+ return (UChar) (NE_PCIReadRaw(0xC, fBus, fDevice, fFunction) >> 16);
+}
+
+void Device::EnableMmio() {
+ UInt32 command = Read(0x04, sizeof(UInt32));
+ command |= (1 << 1); // Memory Space Enable (bit 1)
+
+ Write(0x04, command, sizeof(UInt32));
+}
+
+void Device::BecomeBusMaster() {
+ UInt32 command = Read(0x04, sizeof(UInt32));
+ command |= (1 << 2); // Bus Master Enable (bit 2)
+ Write(0x04, command, sizeof(UInt32));
+}
+
+UIntPtr Device::Bar(UInt32 bar_in) {
+ UInt32 bar = NE_PCIReadRaw(bar_in, fBus, fDevice, fFunction);
+
+ if (bar & PCI_BAR_IO) return static_cast<UIntPtr>(bar & ~0x03);
+
+ if (bar & PCI_BAR_64) {
+ UInt32 high = NE_PCIReadRaw((bar_in + 4) & ~0x03, fBus, fDevice, fFunction);
+ return (static_cast<UIntPtr>(high) << 32) | (bar & ~0x0F);
+ }
+
+ return static_cast<UIntPtr>(bar & ~0x0F);
+}
+
+UShort Device::Vendor() {
+ UShort vendor = this->VendorId();
+ return vendor;
+}
+
+Device::operator bool() {
+ return this->VendorId() != (UShort) PciConfigKind::Invalid;
+}
+} // namespace Kernel::PCI
diff --git a/src/kernel/HALKit/AMD64/PCI/Express.cc b/src/kernel/HALKit/AMD64/PCI/Express.cc
new file mode 100644
index 00000000..2b6ba8d3
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/PCI/Express.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/PCI/Express.h>
+
+namespace Kernel {}
diff --git a/src/kernel/HALKit/AMD64/PCI/IO.cc b/src/kernel/HALKit/AMD64/PCI/IO.cc
new file mode 100644
index 00000000..233c8ef2
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/PCI/IO.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/PCI/IO.h>
diff --git a/src/kernel/HALKit/AMD64/PCI/Iterator.cc b/src/kernel/HALKit/AMD64/PCI/Iterator.cc
new file mode 100644
index 00000000..103ddb2c
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/PCI/Iterator.cc
@@ -0,0 +1,30 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/PCI/Iterator.h>
+
+namespace Kernel::PCI {
+Iterator::Iterator(const Types::PciDeviceKind type, UInt32 bar) {
+ // probe devices.
+ for (Int32 bus = 0; bus < NE_BUS_COUNT; ++bus) {
+ for (Int32 device = 0; device < NE_DEVICE_COUNT; ++device) {
+ for (Int32 function = 0; function < NE_FUNCTION_COUNT; ++function) {
+ Device dev(bus, device, function, bar);
+
+ if (dev.Class() == type) {
+ fDevices[bus] = dev;
+ }
+ }
+ }
+ }
+}
+
+Iterator::~Iterator() {}
+
+Ref<PCI::Device> Iterator::operator[](const Size& at) {
+ return fDevices[at];
+}
+} // namespace Kernel::PCI
diff --git a/src/kernel/HALKit/AMD64/PCI/PCI.cc b/src/kernel/HALKit/AMD64/PCI/PCI.cc
new file mode 100644
index 00000000..a8c48fb9
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/PCI/PCI.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/PCI/PCI.h>
diff --git a/src/kernel/HALKit/AMD64/Paging.h b/src/kernel/HALKit/AMD64/Paging.h
new file mode 100644
index 00000000..a938700e
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Paging.h
@@ -0,0 +1,91 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#ifdef __NE_AMD64__
+
+/** ---------------------------------------------------
+
+ * THIS FILE CONTAINS CODE FOR X86_64 PAGING.
+
+------------======================================== */
+
+#include <NeKit/Defines.h>
+
+#ifndef kPageMax
+#define kPageMax (0x200)
+#endif //! kPageMax
+
+#ifndef kPageAlign
+#define kPageAlign (0x08)
+#endif //! kPageAlign
+
+#ifndef kPageSize
+#define kPageSize (0x1000)
+#endif // !kPageSize
+
+#ifndef kAlign
+#define kAlign __BIGGEST_ALIGNMENT__
+#endif // !kAlign
+
+EXTERN_C void hal_flush_tlb();
+EXTERN_C void hal_invl_tlb(Kernel::VoidPtr addr);
+EXTERN_C void hal_write_cr3(Kernel::VoidPtr cr3);
+EXTERN_C void hal_write_cr0(Kernel::VoidPtr bit);
+
+EXTERN_C Kernel::VoidPtr hal_read_cr0(); // @brief CPU control register.
+EXTERN_C Kernel::VoidPtr hal_read_cr2(); // @brief Fault address.
+EXTERN_C Kernel::VoidPtr hal_read_cr3(); // @brief Page directory inside cr3 register.
+
+namespace Kernel::HAL {
+namespace Detail {
+ enum class ControlRegisterBits {
+ kProtectedModeEnable = 0,
+ kMonitorCoProcessor = 1,
+ kEmulation = 2,
+ kTaskSwitched = 3,
+ kExtensionType = 4,
+ kNumericError = 5,
+ kWriteProtect = 16,
+ kAlignementMask = 18,
+ kNotWriteThrough = 29,
+ kCacheDisable = 30,
+ kPageEnable = 31,
+ };
+
+ inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); }
+} // namespace Detail
+
+auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr;
+auto mm_free_bitmap(VoidPtr page_ptr) -> Bool;
+} // namespace Kernel::HAL
+
+namespace Kernel {
+struct PTE {
+ UInt64 Present : 1;
+ UInt64 Wr : 1;
+ UInt64 User : 1;
+ UInt64 Pwt : 1; // Page-level Write-Through
+ UInt64 Pcd : 1; // Page-level Cache Disable
+ UInt64 Accessed : 1;
+ UInt64 Dirty : 1;
+ UInt64 Pat : 1; // Page Attribute Table (or PS for PDE)
+ UInt64 Global : 1;
+ UInt64 Ignored1 : 3; // Available to software
+ UInt64 PhysicalAddress : 40; // Physical page frame address (bits 12–51)
+ UInt64 Ignored2 : 7; // More software bits / reserved
+ UInt64 ProtectionKey : 4; // Optional (if PKU enabled)
+ UInt64 Reserved : 1; // Usually reserved
+ UInt64 Nx : 1; // No Execute
+};
+
+struct PDE {
+ ATTRIBUTE(aligned(kib_cast(4))) PTE fPTE[512];
+};
+} // namespace Kernel
+
+#endif // __NE_AMD64__ \ No newline at end of file
diff --git a/src/kernel/HALKit/AMD64/Processor.h b/src/kernel/HALKit/AMD64/Processor.h
new file mode 100644
index 00000000..db1ed573
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Processor.h
@@ -0,0 +1,283 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: Prcoessor.h
+ Purpose: AMD64 processor abstraction.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+#ifdef __NE_AMD64__
+
+#include <FirmwareKit/Handover.h>
+#include <HALKit/AMD64/Paging.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Utils.h>
+
+#include <HALKit/AMD64/CPUID.h>
+
+#define kPITControlPort (0x43)
+#define kPITChannel0Port (0x40)
+#define kPITFrequency (1193180)
+
+#define kPICCommand (0x20)
+#define kPICData (0x21)
+#define kPIC2Command (0xA0)
+#define kPIC2Data (0xA1)
+
+#define kIOAPICRegVal (4)
+#define kIOAPICRegReg (0)
+
+#define rtl_nop_op() asm volatile("nop")
+
+/// @brief Maximum entries of the interrupt descriptor table.
+#define kKernelIdtSize (0x100)
+
+/// @brief interrupt for system call.
+#define kKernelInterruptId (0x32)
+
+#define IsActiveLow(FLG) (FLG & 2)
+#define IsLevelTriggered(FLG) (FLG & 8)
+
+#define kInterruptGate (0x8E)
+#define kUserInterruptGate (0xEE)
+#define kTrapGate (0xEF)
+#define kTaskGate (0b10001100)
+#define kIDTSelector (0x08)
+
+namespace Kernel {
+namespace Detail::AMD64 {
+ struct PACKED InterruptDescriptorAMD64 final {
+ UInt16 OffsetLow; // offset bits 0..15
+ UInt16 Selector; // a code segment selector in GDT or LDT
+ UInt8 Ist;
+ UInt8 TypeAttributes;
+ UInt16 OffsetMid;
+ UInt32 OffsetHigh;
+ UInt32 Zero; // reserved
+ };
+} // namespace Detail::AMD64
+} // namespace Kernel
+
+namespace Kernel::HAL {
+/// @brief Memory Manager mapping flags.
+enum {
+ kMMFlagsInvalid = 1 << 0,
+ kMMFlagsPresent = 1 << 1,
+ kMMFlagsWr = 1 << 2,
+ kMMFlagsUser = 1 << 3,
+ kMMFlagsNX = 1 << 4,
+ kMMFlagsPCD = 1 << 5,
+ kMMFlagsPwt = 1 << 6,
+ kMMFlagsCount = 6,
+};
+
+struct PACKED Register64 final {
+ UShort Limit;
+ UIntPtr Base;
+};
+
+using RawRegister = UInt64;
+using Reg = RawRegister;
+using InterruptId = UInt16; /* For each element in the IVT */
+
+/// @brief Stack frame (as retrieved from assembly.)
+struct PACKED StackFrame {
+ Reg IP;
+ Reg SP;
+ Reg R8;
+ Reg R9;
+ Reg R10;
+ Reg R11;
+ Reg R12;
+ Reg R13;
+ Reg R14;
+ Reg R15;
+};
+
+typedef StackFrame* StackFramePtr;
+
+class InterruptDescriptor final {
+ public:
+ UShort Offset;
+ UShort Selector;
+ UChar Ist;
+ UChar Atrributes;
+
+ UShort SecondOffset;
+ UInt ThirdOffset;
+ UInt Zero;
+
+ operator bool() { return Offset != 0xFFFF; }
+};
+
+using InterruptDescriptorArray = Array<InterruptDescriptor, 256>;
+
+class SegmentDescriptor final {
+ public:
+ UInt16 Base;
+ UInt8 BaseMiddle;
+ UInt8 BaseHigh;
+
+ UShort Limit;
+ UChar Gran;
+ UChar AccessByte;
+};
+
+/***
+ * @brief Segment Boolean operations
+ */
+class SegmentDescriptorComparator final {
+ public:
+ Bool IsValid(SegmentDescriptor& seg) { return seg.Base > seg.Limit; }
+
+ Bool Equals(SegmentDescriptor& seg, SegmentDescriptor& segRight) {
+ return seg.Base == segRight.Base && seg.Limit == segRight.Limit;
+ }
+};
+
+using SegmentArray = Array<SegmentDescriptor, 6>;
+
+class GDTLoader final {
+ public:
+ static Void Load(Register64& gdt);
+ static Void Load(Ref<Register64>& gdt);
+};
+
+class IDTLoader final {
+ public:
+ static Void Load(Register64& idt);
+ static Void Load(Ref<Register64>& idt);
+};
+
+/***********************************************************************************/
+/// @brief Is the current config SMP aware?
+/// @return True if YES, False if not.
+/***********************************************************************************/
+
+Bool mp_is_smp(Void) noexcept;
+
+/***********************************************************************************/
+/// @brief Fetch and enable SMP scheduler.
+/// @param vendor_ptr SMP containing structure.
+/***********************************************************************************/
+Void mp_init_cores(VoidPtr vendor_ptr) noexcept;
+
+/***********************************************************************************/
+/// @brief Do a cpuid to check if MSR exists on CPU.
+/// @retval true it does exists.
+/// @retval false it doesn't.
+/***********************************************************************************/
+Bool hal_has_msr() noexcept;
+
+/***********************************************************************************/
+/// @brief Get Model specific register inside core.
+/// @param msr MSR
+/// @param lo low byte
+/// @param hi high byte
+/***********************************************************************************/
+Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept;
+
+/// @brief Set Model-specific register.
+/// @param msr MSR
+/// @param lo low byte
+/// @param hi high byte
+Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept;
+
+/// @brief Processor specific namespace.
+namespace Detail {
+ /* @brief TSS struct. */
+ struct NE_TSS final {
+ UInt32 fReserved1;
+ UInt64 fRsp0;
+ UInt64 fRsp1;
+ UInt64 fRsp2;
+ UInt64 fReserved2;
+ UInt64 fIst1;
+ UInt64 fIst2;
+ UInt64 fIst3;
+ UInt64 fIst4;
+ UInt64 fIst5;
+ UInt64 fIst6;
+ UInt64 fIst7;
+ UInt64 fReserved3;
+ UInt16 fReserved4;
+ UInt16 fIopb;
+ };
+
+ /**
+ @brief Global descriptor table entry, either null, code or data.
+ */
+
+ struct PACKED NE_GDT_ENTRY final {
+ UInt16 fLimitLow;
+ UInt16 fBaseLow;
+ UInt8 fBaseMid;
+ UInt8 fAccessByte;
+ UInt8 fFlags;
+ UInt8 fBaseHigh;
+ };
+} // namespace Detail
+
+class LAPICDmaWrapper final {
+ public:
+ explicit LAPICDmaWrapper(VoidPtr base);
+ ~LAPICDmaWrapper();
+
+ NE_COPY_DEFAULT(LAPICDmaWrapper)
+
+ public:
+ UInt32 Read(UInt16 reg) noexcept;
+ Void Write(UInt16 reg, UInt32 value) noexcept;
+
+ private:
+ VoidPtr fApic{nullptr};
+};
+
+/// @brief Set a PTE from pd_base.
+/// @param virt_addr a valid virtual address.
+/// @param phys_addr point to physical address.
+/// @param flags the flags to put on the page.
+/// @return Status code of page manip.
+EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags,
+ UInt32 level = 2);
+
+EXTERN_C UInt8 rt_in8(UInt16 port);
+EXTERN_C UInt16 rt_in16(UInt16 port);
+EXTERN_C UInt32 rt_in32(UInt16 port);
+
+EXTERN_C Void rt_out16(UShort port, UShort byte);
+EXTERN_C Void rt_out8(UShort port, UChar byte);
+EXTERN_C Void rt_out32(UShort port, UInt byte);
+
+EXTERN_C Void rt_wait_400ns();
+EXTERN_C Void rt_halt();
+EXTERN_C Void rt_cli();
+EXTERN_C Void rt_sti();
+EXTERN_C Void rt_cld();
+EXTERN_C Void rt_std();
+
+EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address);
+
+EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address);
+} // namespace Kernel::HAL
+
+EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp);
+EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp);
+EXTERN_C Kernel::Void idt_handle_math(Kernel::UIntPtr rsp);
+EXTERN_C Kernel::Void idt_handle_pf(Kernel::UIntPtr rsp);
+
+EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_idt(Kernel::HAL::Register64 ptr);
+EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::Register64 ptr);
+
+inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
+inline Kernel::UIntPtr kKernelBitMpSize = 0UL;
+
+#endif // __NE_AMD64__ */ \ No newline at end of file
diff --git a/src/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/src/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
new file mode 100644
index 00000000..14b40b98
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
@@ -0,0 +1,600 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/**
+ * @file AHCI+Generic.cc
+ * @author Amlal El Mahrouss (amlal@nekernel.org)
+ * @brief AHCI Generic driver.
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ */
+
+#include <DmaKit/DmaPool.h>
+#include <FirmwareKit/EPM.h>
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/LockDelegate.h>
+#include <KernelKit/PCI/Iterator.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/Utils.h>
+#include <StorageKit/AHCI.h>
+#include <modules/AHCI/AHCI.h>
+#include <modules/ATA/ATA.h>
+
+#define kSATAErrTaskFile (1 << 30)
+#define kSATAPxCmdST (0x0001)
+#define kSATAPxCmdFre (0x0010)
+#define kSATAPxCmdFR (0x4000)
+#define kSATAPxCmdCR (0x8000)
+
+#define kSATALBAMode (1 << 6)
+
+#define kSATASRBsy (0x80)
+#define kSATASRDrq (0x08)
+
+#define kSATABohcBiosOwned (1 << 0)
+#define kSATABohcOSOwned (1 << 1)
+
+#define kSATAPortCnt (0x20)
+
+#define kSATASig (0x00000101)
+#define kSATAPISig (0xEB140101)
+
+#define kSATAProgIfAHCI (0x01)
+#define kSATASubClass (0x06)
+#define kSATABar5 (0x24)
+
+using namespace Kernel;
+
+STATIC PCI::Device kSATADev;
+STATIC HbaMemRef kSATAHba;
+STATIC Lba kSATASectorCount = 0UL;
+STATIC UInt16 kSATAIndex = 0U;
+STATIC Char kCurrentDiskModel[50] = {"GENERIC SATA"};
+STATIC UInt16 kSATAPortsImplemented = 0U;
+STATIC ALIGN(kib_cast(4)) UInt8 kIdentifyData[kAHCISectorSize] = {0};
+
+template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
+STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz,
+ SizeT size_buffer) noexcept;
+
+STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept;
+
+STATIC Void drv_compute_disk_ahci() noexcept;
+
+STATIC SizeT drv_get_size_ahci();
+
+STATIC SizeT drv_get_sector_count_ahci();
+
+/***********************************************************************************/
+/// @brief Identify device and read LBA info, Disk OEM vendor.
+/***********************************************************************************/
+STATIC Void drv_compute_disk_ahci() noexcept {
+ kSATASectorCount = 0UL;
+
+ rt_set_memory(kIdentifyData, 0, kAHCISectorSize);
+
+ drv_std_input_output_ahci<NO, YES, YES>(0, kIdentifyData, kAHCISectorSize, kAHCISectorSize);
+
+ // --> Reinterpret the 512-byte buffer as an array of 256 UInt16 words
+ UInt16* identify_words = reinterpret_cast<UInt16*>(kIdentifyData);
+
+ /// Extract 48-bit LBA.
+ UInt64 lba48_sectors = 0UL;
+ lba48_sectors |= (UInt64) identify_words[100];
+ lba48_sectors |= (UInt64) identify_words[101] << 16;
+ lba48_sectors |= (UInt64) identify_words[102] << 32;
+
+ if (lba48_sectors == 0)
+ kSATASectorCount = (identify_words[61] << 16) | identify_words[60];
+ else
+ kSATASectorCount = lba48_sectors;
+
+ for (Int32 i = 0; i < 20; i++) {
+ kCurrentDiskModel[i * 2] = (identify_words[27 + i] >> 8) & 0xFF;
+ kCurrentDiskModel[i * 2 + 1] = identify_words[27 + i] & 0xFF;
+ }
+
+ kCurrentDiskModel[40] = '\0';
+
+ (Void)(kout << "SATA Sector Count: " << hex_number(kSATASectorCount) << kendl);
+ (Void)(kout << "SATA Disk Model: " << kCurrentDiskModel << kendl);
+}
+
+/***********************************************************************************/
+/// @brief Finds a command slot for a HBA port.
+/// @param port The port to search on.
+/// @return The slot, or -1.
+/***********************************************************************************/
+STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept {
+ UInt32 slots = port->Sact | port->Ci;
+
+ for (Int32 i = 0; i < kSATAPortCnt; ++i) // AHCI supports up to 32 slots
+ {
+ if ((slots & (1U << i)) == 0) return i;
+ }
+
+ return -1; // no free slot found
+}
+
+/***********************************************************************************/
+/// @brief Send an AHCI command, according to the template parameters.
+/// @param lba Logical Block Address to look for.
+/// @param buffer The data buffer to transfer.
+/// @param sector_sz The disk's sector size (unused)
+/// @param size_buffer The size of the **buffer** parameter.
+/***********************************************************************************/
+template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
+STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz,
+ SizeT size_buffer) noexcept {
+ if (sector_sz == 0) {
+ kout << "ahci: Invalid sector size.\r";
+ err_global_get() = kErrorDisk;
+ return;
+ }
+
+ lba /= sector_sz;
+
+ if (!buffer || size_buffer == 0) {
+ kout << "ahci: Invalid buffer for AHCI I/O.\r";
+ err_global_get() = kErrorDisk;
+ return;
+ }
+
+ UIntPtr slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]);
+
+ UInt16 timeout = 0;
+
+ constexpr static UInt16 kTimeout = 0x8000;
+
+ while (slot == ~0UL) {
+ if (timeout > kTimeout) {
+ kout << "ahci: No free command slot found, AHCI disk is busy!\r";
+
+ err_global_get() = kErrorDisk;
+ return;
+ }
+
+ slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]);
+ ++timeout;
+ }
+
+ volatile HbaCmdHeader* command_header =
+ (volatile HbaCmdHeader*) ((UInt64) kSATAHba->Ports[kSATAIndex].Clb);
+
+ command_header += slot;
+
+ MUST_PASS(command_header);
+
+ // Clear old command table memory
+ volatile HbaCmdTbl* command_table =
+ (volatile HbaCmdTbl*) (((UInt64) command_header->Ctbau << 32) | command_header->Ctba);
+
+ MUST_PASS(command_table);
+
+ rt_set_memory((VoidPtr) command_table, 0, sizeof(HbaCmdTbl));
+
+ VoidPtr ptr = rtl_dma_alloc(size_buffer, kib_cast(4));
+
+ rtl_dma_flush(ptr, size_buffer);
+
+ if (Write) {
+ rt_copy_memory(buffer, ptr, size_buffer);
+ }
+
+ rtl_dma_flush(ptr, size_buffer);
+
+ // Build the PRD table.
+ SizeT bytes_remaining = size_buffer;
+ SizeT prdt_index = 0;
+ UIntPtr buffer_phys = (UIntPtr) ptr;
+
+ while (bytes_remaining > 0) {
+ SizeT chunk_size = bytes_remaining;
+
+ if (chunk_size > kib_cast(32)) chunk_size = kib_cast(32);
+
+ command_table->Prdt[prdt_index].Dba = (UInt32) (buffer_phys & 0xFFFFFFFF);
+ command_table->Prdt[prdt_index].Dbau = (UInt32) (buffer_phys >> 32);
+ command_table->Prdt[prdt_index].Dbc = (UInt32) (chunk_size - 1);
+ command_table->Prdt[prdt_index].Ie = NO;
+
+ buffer_phys += chunk_size;
+ bytes_remaining -= chunk_size;
+
+ ++prdt_index;
+ }
+
+ // Mark the last PRD entry, for the FIS to process the table.
+ command_table->Prdt[prdt_index - 1].Ie = YES;
+
+ if (bytes_remaining > 0) {
+ kout << "ahci: AHCI PRDT overflow, cannot map full buffer.\r";
+ err_global_get() = kErrorDisk;
+ rtl_dma_free(size_buffer);
+
+ return;
+ }
+
+ command_header->Prdtl = prdt_index;
+ command_header->HbaFlags.Struct.Cfl = sizeof(FisRegH2D) / sizeof(UInt32);
+ command_header->HbaFlags.Struct.Write = Write;
+
+ volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*) (&command_table->Cfis[0]);
+
+ h2d_fis->FisType = kFISTypeRegH2D;
+ h2d_fis->CmdOrCtrl = CommandOrCTRL;
+ h2d_fis->Command =
+ (Identify ? kAHCICmdIdentify : (Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx));
+
+ h2d_fis->Lba0 = (lba >> 0) & 0xFF;
+ h2d_fis->Lba1 = (lba >> 8) & 0xFF;
+ h2d_fis->Lba2 = (lba >> 16) & 0xFF;
+ h2d_fis->Lba3 = (lba >> 24) & 0xFF;
+ h2d_fis->Lba4 = (lba >> 32) & 0xFF;
+ h2d_fis->Lba5 = (lba >> 40) & 0xFF;
+
+ h2d_fis->Device = 0;
+
+ if (Identify) {
+ h2d_fis->CountLow = 1;
+ h2d_fis->CountHigh = 0;
+ } else {
+ h2d_fis->Device = kSATALBAMode;
+ h2d_fis->CountLow = (size_buffer / kAHCISectorSize) & 0xFF;
+ h2d_fis->CountHigh = ((size_buffer / kAHCISectorSize) >> 8) & 0xFF;
+ }
+
+ rtl_dma_flush(ptr, size_buffer);
+
+ // Issue command
+ kSATAHba->Ports[kSATAIndex].Ci = (1 << slot);
+
+ timeout = 0UL;
+
+ while (YES) {
+ if (timeout > kTimeout) {
+ kout << "ahci: disk-hangup, corrupted-disk.\r";
+ err_global_get() = kErrorDiskIsCorrupted;
+ rtl_dma_free(size_buffer);
+
+ return;
+ }
+
+ ++timeout;
+
+ if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) break;
+ }
+
+ rtl_dma_flush(ptr, size_buffer);
+
+ if (kSATAHba->Is & kSATAErrTaskFile) {
+ kout << "ahci: Task File Error during I/O.\r";
+
+ rtl_dma_free(size_buffer);
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return;
+ } else {
+ if (!Write) {
+ rtl_dma_flush(ptr, size_buffer);
+ rt_copy_memory(ptr, buffer, size_buffer);
+ rtl_dma_flush(ptr, size_buffer);
+ }
+
+ if ((kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) == 0) {
+ goto ahci_io_end;
+ } else {
+ kout << "ahci: Disk still busy after command completion!\r";
+ while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq))
+ ;
+ }
+
+ ahci_io_end:
+ rtl_dma_free(size_buffer);
+ err_global_get() = kErrorSuccess;
+ }
+}
+
+/***
+ @brief Gets the number of sectors inside the drive.
+ @return Sector size in bytes.
+ */
+STATIC ATTRIBUTE(unused) SizeT drv_get_sector_count_ahci() {
+ return kSATASectorCount;
+}
+
+/// @brief Get the drive size.
+/// @return Disk size in bytes.
+STATIC ATTRIBUTE(unused) SizeT drv_get_size_ahci() {
+ return drv_std_get_sector_count() * kAHCISectorSize;
+}
+
+/// @brief Enable Host and probe using the IDENTIFY command.
+STATIC BOOL ahci_enable_and_probe() {
+ if (kSATAHba->Cap == 0x0) return NO;
+
+ kSATAHba->Ports[kSATAIndex].Cmd &= ~kSATAPxCmdFre;
+ kSATAHba->Ports[kSATAIndex].Cmd &= ~kSATAPxCmdST;
+
+ while (YES) {
+ if (kSATAHba->Ports[kSATAIndex].Cmd & kSATAPxCmdCR) continue;
+
+ if (kSATAHba->Ports[kSATAIndex].Cmd & kSATAPxCmdFR) continue;
+
+ break;
+ }
+
+ // Now we are ready.
+
+ kSATAHba->Ports[kSATAIndex].Cmd |= kSATAPxCmdFre;
+ kSATAHba->Ports[kSATAIndex].Cmd |= kSATAPxCmdST;
+
+ if (kSATAHba->Bohc & kSATABohcBiosOwned) {
+ kSATAHba->Bohc |= kSATABohcOSOwned;
+
+ while (kSATAHba->Bohc & kSATABohcBiosOwned) {
+ ;
+ }
+ }
+
+ drv_compute_disk_ahci();
+
+ return YES;
+}
+
+STATIC Bool drv_init_command_structures_ahci() {
+ // Allocate 4KiB for Command List (32 headers)
+ VoidPtr clb_mem = rtl_dma_alloc(4096, 1024);
+ if (!clb_mem) {
+ kout << "Failed to allocate CLB memory!\r";
+ return NO;
+ }
+
+ UIntPtr clb_phys = HAL::mm_get_page_addr(clb_mem);
+
+ kSATAHba->Ports[kSATAIndex].Clb = (UInt32) (clb_phys & 0xFFFFFFFF);
+ kSATAHba->Ports[kSATAIndex].Clbu = (UInt32) (clb_phys >> 32);
+
+ // Clear it
+ rt_set_memory(clb_mem, 0, kib_cast(4));
+
+ // For each command slot (up to 32)
+ volatile HbaCmdHeader* header = (volatile HbaCmdHeader*) clb_mem;
+
+ for (Int32 i = 0; i < 32; ++i) {
+ // Allocate 4KiB for Command Table
+ VoidPtr ct_mem = rtl_dma_alloc(4096, 128);
+ if (!ct_mem) {
+ (Void)(kout << "Failed to allocate CTB memory for slot " << hex_number(i));
+ kout << "!\r";
+ return NO;
+ }
+
+ UIntPtr ct_phys = HAL::mm_get_page_addr(ct_mem);
+
+ header[i].Ctba = (UInt32) (ct_phys & 0xFFFFFFFF);
+ header[i].Ctbau = (UInt32) (ct_phys >> 32);
+
+ // Clear the command table
+ rt_set_memory((VoidPtr) ct_mem, 0, 4096);
+ }
+
+ return YES;
+}
+
+/// @brief Initializes an AHCI disk.
+/// @param pi the amount of ports that have been detected.
+/// @param atapi reference value, tells whether we should detect ATAPI instead of SATA.
+/// @return if the disk was successfully initialized or not.
+STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi) {
+ /// AMLALE: TODO: Iterator is good enough, but we need to expand it.
+ PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController, 0x00);
+
+ for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) {
+ kSATADev = iterator[device_index].Leak(); // Leak device.
+
+ if (kSATADev.Subclass() == kSATASubClass && kSATADev.ProgIf() == kSATAProgIfAHCI) {
+ kSATADev.EnableMmio();
+ kSATADev.BecomeBusMaster();
+
+ HbaMem* mem_ahci = (HbaMem*) kSATADev.Bar(kSATABar5);
+
+ HAL::mm_map_page(
+ (VoidPtr) mem_ahci, (VoidPtr) mem_ahci,
+ HAL::kMMFlagsPresent | HAL::kMMFlagsWr | HAL::kMMFlagsPCD | HAL::kMMFlagsPwt);
+
+ UInt32 ports_implemented = mem_ahci->Pi;
+ UInt16 ahci_index = 0;
+
+ pi = ports_implemented;
+
+ const UInt16 kSATAMaxPortsImplemented = ports_implemented;
+ const UInt32 kSATASignature = kSATASig;
+ const UInt32 kSATAPISignature = kSATAPISig;
+ const UInt8 kSATAPresent = 0x03;
+ const UInt8 kSATAIPMActive = 0x01;
+
+ if (kSATAMaxPortsImplemented < 1) continue;
+
+ while (ports_implemented) {
+ UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F;
+ UInt8 det = (mem_ahci->Ports[ahci_index].Ssts & 0x0F);
+
+ if (det != kSATAPresent || ipm != kSATAIPMActive) continue;
+
+ if ((mem_ahci->Ports[ahci_index].Sig == kSATASignature) ||
+ (atapi && kSATAPISignature == mem_ahci->Ports[ahci_index].Sig)) {
+ kSATAIndex = ahci_index;
+ kSATAHba = mem_ahci;
+
+ if (!drv_init_command_structures_ahci()) {
+ err_global_get() = kErrorDisk;
+ }
+
+ goto success_hba_fetch;
+ }
+
+ ports_implemented >>= 1;
+ ++ahci_index;
+ }
+ }
+ }
+
+ err_global_get() = kErrorDisk;
+
+ return NO;
+
+success_hba_fetch:
+ if (ahci_enable_and_probe()) {
+ err_global_get() = kErrorSuccess;
+ }
+
+ return err_global_get() == kErrorSuccess;
+}
+
+/// @brief Checks if an AHCI device is detected.
+/// @return Either if detected, or not found.
+Bool drv_std_detected_ahci() {
+ return kSATADev.DeviceId() != (UShort) PCI::PciConfigKind::Invalid &&
+ kSATADev.Bar(kSATABar5) != 0;
+}
+
+// ================================================================================================
+
+//
+/// @note This applies only if we compile with AHCI as a default disk driver.
+//
+
+// ================================================================================================
+
+#ifdef __AHCI__
+
+////////////////////////////////////////////////////
+///
+////////////////////////////////////////////////////
+Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) {
+ drv_std_input_output_ahci<YES, YES, NO>(lba, reinterpret_cast<UInt8*>(buffer), sector_sz,
+ size_buffer);
+}
+
+////////////////////////////////////////////////////
+///
+////////////////////////////////////////////////////
+Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) {
+ drv_std_input_output_ahci<NO, YES, NO>(lba, reinterpret_cast<UInt8*>(buffer), sector_sz,
+ size_buffer);
+}
+
+////////////////////////////////////////////////////
+///
+////////////////////////////////////////////////////
+Bool drv_std_init(UInt16& pi) {
+ BOOL atapi = NO;
+ return drv_std_init_ahci(pi, atapi);
+}
+
+////////////////////////////////////////////////////
+///
+////////////////////////////////////////////////////
+Bool drv_std_detected(Void) {
+ return drv_std_detected_ahci();
+}
+
+////////////////////////////////////////////////////
+/**
+ @brief Gets the number of sectors inside the drive.
+ @return Sector size in bytes.
+ */
+////////////////////////////////////////////////////
+SizeT drv_std_get_sector_count() {
+ return drv_get_sector_count_ahci();
+}
+
+////////////////////////////////////////////////////
+/// @brief Get the drive size.
+/// @return Disk size in bytes.
+////////////////////////////////////////////////////
+SizeT drv_std_get_size() {
+ return drv_get_size_ahci();
+}
+
+#endif // ifdef __AHCI__
+
+namespace Kernel {
+/// @brief Initialize an AHCI device (StorageKit)
+UInt16 sk_init_ahci_device(BOOL atapi) {
+ UInt16 pi = 0;
+
+ if (drv_std_init_ahci(pi, atapi)) kSATAPortsImplemented = pi;
+
+ return pi;
+}
+
+/// @brief Implementation details namespace.
+namespace Detail {
+ /// @brief Read AHCI device.
+ /// @param self device
+ /// @param mnt mounted disk.
+ STATIC Void sk_io_read_ahci(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) {
+ AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self;
+
+ err_global_get() = kErrorDisk;
+
+ if (!dev) return;
+
+ auto disk = mnt->GetAddressOf(dev->GetIndex());
+
+ if (!disk) return;
+
+ err_global_get() = kErrorSuccess;
+
+ drv_std_input_output_ahci<NO, YES, NO>(disk->fPacket.fPacketLba / kAHCISectorSize,
+ (UInt8*) disk->fPacket.fPacketContent, kAHCISectorSize,
+ disk->fPacket.fPacketSize);
+ }
+
+ /// @brief Write AHCI device.
+ /// @param self device
+ /// @param mnt mounted disk.
+ STATIC Void sk_io_write_ahci(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) {
+ AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self;
+
+ err_global_get() = kErrorDisk;
+
+ if (!dev) return;
+
+ auto disk = mnt->GetAddressOf(dev->GetIndex());
+
+ if (!disk) return;
+
+ err_global_get() = kErrorSuccess;
+
+ drv_std_input_output_ahci<YES, YES, NO>(disk->fPacket.fPacketLba / kAHCISectorSize,
+ (UInt8*) disk->fPacket.fPacketContent, kAHCISectorSize,
+ disk->fPacket.fPacketSize);
+ }
+} // namespace Detail
+
+/// @brief Acquires a new AHCI device with drv_index in mind.
+/// @param drv_index The drive index to assign.
+/// @return A wrapped device interface if successful, or error code.
+ErrorOr<AHCIDeviceInterface> sk_acquire_ahci_device(UInt32 drv_index) {
+ if (!drv_std_detected_ahci()) return ErrorOr<AHCIDeviceInterface>(kErrorDisk);
+
+ AHCIDeviceInterface device(Detail::sk_io_read_ahci, Detail::sk_io_write_ahci);
+
+ device.SetPortsImplemented(kSATAPortsImplemented);
+ device.SetIndex(drv_index);
+
+ return ErrorOr<AHCIDeviceInterface>(device);
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/src/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
new file mode 100644
index 00000000..cf6147d9
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
@@ -0,0 +1,199 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/**
+ * @file DMA+Generic.cc
+ * @author Amlal El Mahrouss (amlal@nekernel.org)
+ * @brief ATA driver (DMA mode).
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) Amlal El Mahrouss
+ *
+ */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/PCI/Iterator.h>
+#include <modules/ATA/ATA.h>
+
+#if defined(__ATA_DMA__)
+
+#define kATADataLen (256)
+
+using namespace Kernel;
+using namespace Kernel::HAL;
+
+/// BUGS: 0
+
+STATIC Boolean kATADetected = false;
+STATIC Int32 kATADeviceType ATTRIBUTE(unused) = kATADeviceCount;
+STATIC UInt16 kATAIdentifyData[kATADataLen] = {0};
+STATIC Kernel::PCI::Device kATADevice;
+STATIC Char kATADiskModel[50] ATTRIBUTE(unused) = {"GENERIC DMA"};
+
+Boolean drv_std_wait_io(UInt16 IO) {
+ for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS);
+
+ATAWaitForIO_Retry:
+ auto status_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry;
+
+ATAWaitForIO_Retry2:
+ status_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if (status_rdy & ATA_SR_ERR) return false;
+
+ if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2;
+
+ return true;
+}
+
+Void drv_std_select(UInt16 Bus) {
+ if (Bus == ATA_PRIMARY_IO)
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL);
+ else
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL);
+}
+
+Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) {
+ NE_UNUSED(Bus);
+ NE_UNUSED(Drive);
+ NE_UNUSED(OutBus);
+ NE_UNUSED(OutMaster);
+
+ PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController);
+
+ for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) {
+ kATADevice = iterator[device_index].Leak(); // And then leak the reference.
+
+ /// IDE interface
+ if (kATADevice.Subclass() == 0x01) {
+ break;
+ }
+ }
+
+ return NO;
+}
+
+namespace Kernel::Detail {
+struct PRDEntry final {
+ UInt32 mAddress;
+ UInt16 mByteCount;
+ UInt16 mFlags; /// @param PRD flags, set to 0x8000 to indicate end of prd.
+};
+} // namespace Kernel::Detail
+
+static UIntPtr kReadAddr = mib_cast(2);
+static UIntPtr kWriteAddr = mib_cast(2) + kib_cast(64);
+
+Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) {
+ Lba /= SectorSz;
+
+ if (Size > kib_cast(64)) return;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ rt_copy_memory((VoidPtr) Buf, (VoidPtr) kReadAddr, Size);
+
+ drv_std_select(IO);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz - 1) / SectorSz));
+
+ rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ Kernel::Detail::PRDEntry* prd =
+ (Kernel::Detail::PRDEntry*) (kATADevice.Bar(0x20) + 4); // The PRDEntry is not correct.
+
+ prd->mAddress = (UInt32) (UIntPtr) kReadAddr;
+ prd->mByteCount = Size - 1;
+ prd->mFlags = 0x8000; // indicate the end of prd.
+
+ rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32) (UIntPtr) prd);
+
+ rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_READ_DMA);
+
+ rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine
+
+ while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01)
+ ;
+
+ rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine
+
+ rt_copy_memory((VoidPtr) kReadAddr, (VoidPtr) Buf, Size);
+
+ delete prd;
+ prd = nullptr;
+}
+
+Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) {
+ Lba /= SectorSz;
+
+ if (Size > kib_cast(64)) return;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ rt_copy_memory((VoidPtr) Buf, (VoidPtr) kWriteAddr, Size);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz - 1)) / SectorSz));
+
+ rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ Kernel::Detail::PRDEntry* prd = (Kernel::Detail::PRDEntry*) (kATADevice.Bar(0x20) + 4);
+
+ prd->mAddress = (UInt32) (UIntPtr) kWriteAddr;
+ prd->mByteCount = Size - 1;
+ prd->mFlags = 0x8000;
+
+ rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32) (UIntPtr) prd);
+ rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA);
+
+ rt_out8(IO + 0x00, 0x09); // Start DMA engine
+
+ while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01)
+ ;
+
+ rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine
+
+ delete prd;
+ prd = nullptr;
+}
+
+/***********************************************************************************/
+/// @brief Is ATA detected?
+/***********************************************************************************/
+Boolean drv_std_detected(Void) {
+ return kATADetected;
+}
+
+/***********************************************************************************/
+/***
+ @brief Gets the number of sectors inside the drive.
+ @return Number of sectors, or zero.
+*/
+/***********************************************************************************/
+Kernel::SizeT drv_std_get_sector_count() {
+ return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60];
+}
+
+/***********************************************************************************/
+/// @brief Get the size of the current drive.
+/***********************************************************************************/
+Kernel::SizeT drv_std_get_size() {
+ return (drv_std_get_sector_count()) * kATASectorSize;
+}
+
+#endif /* ifdef __ATA_DMA__ */
diff --git a/src/kernel/HALKit/AMD64/Storage/NVME+Generic.cc b/src/kernel/HALKit/AMD64/Storage/NVME+Generic.cc
new file mode 100644
index 00000000..88f95a86
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Storage/NVME+Generic.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <modules/NVME/NVME.h>
+
+using namespace Kernel;
diff --git a/src/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/src/kernel/HALKit/AMD64/Storage/PIO+Generic.cc
new file mode 100644
index 00000000..0516be39
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Storage/PIO+Generic.cc
@@ -0,0 +1,278 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/**
+ * @file PIO+Generic.cc
+ * @author Amlal El Mahrouss (amlal@nekernel.org)
+ * @brief ATA driver (PIO mode).
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) Amlal El Mahrouss
+ *
+ */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DriveMgr.h>
+#include <StorageKit/ATA.h>
+#include <modules/ATA/ATA.h>
+
+using namespace Kernel;
+using namespace Kernel::HAL;
+
+/// BUGS: 0
+
+#define kATADataLen 256
+
+STATIC Boolean kATADetected = false;
+STATIC UInt16 kATAIdentifyData[kATADataLen] = {0};
+STATIC Char kATADiskModel[50] = {"GENERIC PIO"};
+
+static Boolean drv_pio_std_wait_io(UInt16 IO) {
+ for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS);
+
+ATAWaitForIO_Retry:
+ auto stat_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if ((stat_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry;
+
+ATAWaitForIO_Retry2:
+ stat_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if (stat_rdy & ATA_SR_ERR) return false;
+
+ if (!(stat_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2;
+
+ return true;
+}
+
+STATIC Void drv_pio_std_select(UInt16 Bus) {
+ if (Bus == ATA_PRIMARY_IO)
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL);
+ else
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL);
+}
+
+Boolean drv_pio_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) {
+ UInt16 IO = Bus;
+
+ NE_UNUSED(Drive);
+
+ drv_pio_std_select(IO);
+
+ // Bus init, NEIN bit.
+ rt_out8(IO + ATA_REG_NEIN, 1);
+
+ // identify until it's good.
+ATAInit_Retry:
+ auto stat_rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if (stat_rdy & ATA_SR_ERR) {
+ return false;
+ }
+
+ if ((stat_rdy & ATA_SR_BSY)) goto ATAInit_Retry;
+
+ OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;
+ OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE;
+
+ drv_pio_std_select(IO);
+
+ rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
+
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
+ ;
+
+ /// fetch serial info
+ /// model, speed, number of sectors...
+
+ for (SizeT i = 0ul; i < kATADataLen; ++i) {
+ kATAIdentifyData[i] = rt_in16(OutBus + ATA_REG_DATA);
+ }
+
+ for (Int32 i = 0; i < 20; i++) {
+ kATADiskModel[i * 2] = (kATAIdentifyData[27 + i] >> 8) & 0xFF;
+ kATADiskModel[i * 2 + 1] = kATAIdentifyData[27 + i] & 0xFF;
+ }
+
+ kATADiskModel[40] = '\0';
+
+ (Void)(kout << "Drive Model: " << kATADiskModel << kendl);
+
+ return true;
+}
+
+Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) {
+ Lba /= SectorSz;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ drv_pio_std_wait_io(IO);
+ drv_pio_std_select(IO);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
+
+ rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
+
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
+ ;
+
+ for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) {
+ drv_pio_std_wait_io(IO);
+
+ auto in = rt_in16(IO + ATA_REG_DATA);
+
+ Buf[IndexOff] = in & 0xFF;
+ Buf[IndexOff + 1] = (in >> 8) & 0xFF;
+ }
+}
+
+Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) {
+ Lba /= SectorSz;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ drv_pio_std_wait_io(IO);
+ drv_pio_std_select(IO);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
+
+ rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
+
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
+ ;
+
+ for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) {
+ drv_pio_std_wait_io(IO);
+
+ UInt8 low = (UInt8) Buf[IndexOff];
+ UInt8 high = (IndexOff + 1 < Size) ? (UInt8) Buf[IndexOff + 1] : 0;
+ UInt16 packed = (high << 8) | low;
+
+ rt_out16(IO + ATA_REG_DATA, packed);
+ }
+}
+
+/// @brief is ATA detected?
+Boolean drv_pio_std_detected(Void) {
+ return kATADetected;
+}
+
+/***
+ @brief Getter, gets the number of sectors inside the drive.
+ */
+SizeT drv_pio_get_sector_count() {
+ return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60];
+}
+
+/// @brief Get the drive size.
+SizeT drv_pio_get_size() {
+ return (drv_pio_get_sector_count()) * kATASectorSize;
+}
+
+namespace Kernel {
+/// @brief Initialize an PIO device (StorageKit function)
+/// @param is_master is the current PIO master?
+/// @return [io:master] for PIO device.
+BOOL sk_init_ata_device(BOOL is_master, UInt16& io, UInt8& master) {
+ return drv_pio_std_init(ATA_SECONDARY_IO, is_master, io, master);
+}
+
+/// @brief Implementation details namespace.
+namespace Detail {
+ /// @brief Read PIO device.
+ /// @param self device
+ /// @param mnt mounted disk.
+ STATIC Void sk_io_read_pio(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) {
+ ATADeviceInterface* dev = (ATADeviceInterface*) self;
+
+ err_global_get() = kErrorDisk;
+
+ if (!dev) return;
+
+ auto disk = mnt->GetAddressOf(dev->GetIndex());
+
+ if (!disk) return;
+
+ err_global_get() = kErrorSuccess;
+
+ drv_pio_std_read(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(),
+ (Char*) disk->fPacket.fPacketContent, kATASectorSize,
+ disk->fPacket.fPacketSize);
+ }
+
+ /// @brief Write PIO device.
+ /// @param self device
+ /// @param mnt mounted disk.
+ STATIC Void sk_io_write_pio(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) {
+ ATADeviceInterface* dev = (ATADeviceInterface*) self;
+
+ err_global_get() = kErrorDisk;
+
+ if (!dev) return;
+
+ auto disk = mnt->GetAddressOf(dev->GetIndex());
+
+ if (!disk) return;
+
+ err_global_get() = kErrorSuccess;
+
+ drv_pio_std_write(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(),
+ (Char*) disk->fPacket.fPacketContent, kATASectorSize,
+ disk->fPacket.fPacketSize);
+ }
+} // namespace Detail
+
+/// @brief Acquires a new PIO device with drv_index in mind.
+/// @param drv_index The drive index to assign.
+/// @return A wrapped device interface if successful, or error code.
+ErrorOr<ATADeviceInterface> sk_acquire_ata_device(Int32 drv_index) {
+ /// here we don't check if we probed ATA, since we'd need to grab IO after that.
+ ATADeviceInterface device(Detail::sk_io_read_pio, Detail::sk_io_write_pio);
+
+ device.SetIndex(drv_index);
+
+ return ErrorOr<ATADeviceInterface>(device);
+}
+} // namespace Kernel
+
+#ifdef __ATA_PIO__
+
+Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) {
+ drv_pio_std_read(Lba, IO, Master, Buf, SectorSz, Size);
+}
+
+Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) {
+ drv_pio_std_write(Lba, IO, Master, Buf, SectorSz, Size);
+}
+
+SizeT drv_std_get_size() {
+ return drv_pio_get_size();
+}
+
+SizeT drv_std_get_sector_count() {
+ return drv_pio_get_sector_count();
+}
+
+Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) {
+ return drv_pio_std_init(Bus, Drive, OutBus, OutMaster);
+}
+
+#endif \ No newline at end of file
diff --git a/src/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc b/src/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc
new file mode 100644
index 00000000..0200ec5a
--- /dev/null
+++ b/src/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc
@@ -0,0 +1,13 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <modules/SCSI/SCSI.h>
+
+using namespace Kernel;
+
+///! @brief ATAPI SCSI packet.
+const ATTRIBUTE(unused) scsi_packet_type_12 kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0,
+ 0, 12, 0x40, 0, 0};
diff --git a/src/kernel/HALKit/ARM64/APM/APM+IO.cc b/src/kernel/HALKit/ARM64/APM/APM+IO.cc
new file mode 100644
index 00000000..c4d0154b
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/APM/APM+IO.cc
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/KPC.h>
+#include <modules/APM/APM.h>
+
+using namespace Kernel;
+
+/// @brief Send APM command to its IO space.
+/// @param base_dma the IO base port.
+/// @param cmd the command.
+/// @return status code.
+EXTERN_C Int32 apm_send_io_command(UInt16 cmd) {
+ switch (cmd) {
+ case kAPMPowerCommandReboot: {
+ asm volatile(
+ "ldr x0, =0x84000004\n"
+ "svc #0\n");
+
+ return kErrorSuccess;
+ }
+ case kAPMPowerCommandShutdown: {
+ asm volatile(
+ "ldr x0, =0x84000008\n"
+ "svc #0\n");
+
+ return kErrorSuccess;
+ }
+ default:
+ return kErrorInvalidData;
+ }
+}
diff --git a/src/kernel/HALKit/ARM64/ApplicationProcessor.h b/src/kernel/HALKit/ARM64/ApplicationProcessor.h
new file mode 100644
index 00000000..208bf82e
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/ApplicationProcessor.h
@@ -0,0 +1,19 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <HALKit/ARM64/Processor.h>
+#include <NeKit/Defines.h>
+
+/************************************************** */
+/* INITIALIZE THE GIC ON THE CURRENT CORE. */
+/* WITH AN EXECUTION LEVEL IN MIND. */
+/************************************************** */
+
+namespace Kernel {
+Void mp_init_cores(Void) noexcept;
+} \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/CxxAbi.cc b/src/kernel/HALKit/ARM64/CxxAbi.cc
new file mode 100644
index 00000000..7b4eca20
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/CxxAbi.cc
@@ -0,0 +1,87 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/CxxAbi.h>
+
+atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors];
+
+uarch_t __atexit_func_count;
+
+/// @brief dynamic shared object Handle.
+Kernel::UIntPtr __dso_handle;
+
+EXTERN_C void __chkstk(void) {}
+
+EXTERN_C int atexit(void (*f)(), void* arg, void* dso) {
+ if (__atexit_func_count >= kAtExitMacDestructors) return 1;
+
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+ __atexit_funcs[__atexit_func_count].obj_ptr = arg;
+ __atexit_funcs[__atexit_func_count].dso_handle = dso;
+
+ __atexit_func_count++;
+
+ return 0;
+}
+
+EXTERN_C void __cxa_finalize(void* f) {
+ uarch_t i = __atexit_func_count;
+ if (!f) {
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)();
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+
+ return;
+ }
+
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)();
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+}
+
+namespace cxxabiv1 {
+EXTERN_C int __cxa_guard_acquire(__guard* g) {
+ (void) g;
+ return 0;
+}
+
+EXTERN_C int __cxa_guard_release(__guard* g) {
+ *(char*) g = 1;
+ return 0;
+}
+
+EXTERN_C void __cxa_guard_abort(__guard* g) {
+ (void) g;
+}
+} // namespace cxxabiv1
+
+EXTERN_C Kernel::Void _purecall(void* self) {
+ (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_epoch(Kernel::Void) {
+ NE_UNUSED(0);
+}
+
+EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) {
+ NE_UNUSED(0);
+}
+
+EXTERN_C Kernel::Int _tls_index = 0UL;
diff --git a/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc b/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc
new file mode 100644
index 00000000..9a8661cd
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc
@@ -0,0 +1,26 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/HeapMgr.h>
+#include <NeKit/KString.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+#include <modules/APM/APM.h>
+
+namespace Kernel {
+ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {}
+
+BOOL ACPIFactoryInterface::Shutdown() {
+ apm_send_io_command(kAPMPowerCommandShutdown);
+ return NO;
+}
+
+/// @brief Reboot machine in either ACPI or by triple faulting.
+/// @return nothing it's a reboot.
+Void ACPIFactoryInterface::Reboot() {
+ apm_send_io_command(kAPMPowerCommandReboot);
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/src/kernel/HALKit/ARM64/HalApplicationProcessor.cc
new file mode 100644
index 00000000..2a3c73e5
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalApplicationProcessor.cc
@@ -0,0 +1,140 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#define GICD_BASE 0x08000000
+#define GICC_BASE 0x08010000
+
+#define GICD_CTLR 0x000
+#define GICD_ISENABLER 0x100
+#define GICD_ICENABLER 0x180
+#define GICD_ISPENDR 0x200
+#define GICD_ICPENDR 0x280
+#define GICD_IPRIORITYR 0x400
+#define GICD_ITARGETSR 0x800
+#define GICD_ICFGR 0xC00
+
+#define GICC_CTLR 0x000
+#define GICC_PMR 0x004
+#define GICC_IAR 0x00C
+#define GICC_EOIR 0x010
+
+#include <HALKit/ARM64/ApplicationProcessor.h>
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/Timer.h>
+
+// ================================================================= //
+
+namespace Kernel {
+struct HAL_HARDWARE_THREAD final {
+ HAL::StackFramePtr mFramePtr;
+ ProcessID mThreadID{0};
+};
+
+STATIC HAL_HARDWARE_THREAD kHWThread[kMaxAPInsideSched] = {{nullptr}};
+
+namespace Detail {
+ STATIC BOOL kGICEnabled = NO;
+
+ /***********************************************************************************/
+ /// @brief Enables the GIC with EL0 configuration.
+ /// @internal
+ /***********************************************************************************/
+ STATIC Void mp_setup_gic_el0(Void) {
+ ke_dma_write<UInt32>(GICD_BASE, GICD_CTLR, YES);
+
+ UInt32 gicc_ctlr = ke_dma_read<UInt32>(GICC_BASE, GICC_CTLR);
+
+ const UInt8 kEnableSignalInt = 0x1;
+
+ gicc_ctlr |= kEnableSignalInt;
+ gicc_ctlr |= (kEnableSignalInt << 0x1);
+
+ ke_dma_write<UInt32>(GICC_BASE, GICC_CTLR, gicc_ctlr);
+
+ ke_dma_write<UInt32>(GICC_BASE, GICC_PMR, 0xFF);
+
+ UInt32 icfgr = ke_dma_read<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4);
+
+ icfgr |= (0x2 << ((32 % 16) * 2));
+
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr);
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8));
+ ke_dma_write<UInt32>(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8));
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ISENABLER + 4, 0x01);
+ }
+
+ EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void) {
+ UInt32 interrupt_id = ke_dma_read<UInt32>(GICC_BASE, GICC_IAR);
+
+ if ((interrupt_id & 0x3FF) < 1020) {
+ auto interrupt = interrupt_id & 0x3FF;
+
+ const UInt16 kInterruptScheduler = 0x20;
+
+ (Void)(kout << "SMP: AP: " << hex_number(interrupt) << kendl);
+
+ switch (interrupt) {
+ case kInterruptScheduler: {
+ ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
+ UserProcessHelper::StartScheduling();
+ break;
+ }
+ default: {
+ ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
+ break;
+ }
+ }
+
+ return YES;
+ }
+
+ return NO;
+ }
+} // namespace Detail
+
+/***********************************************************************************/
+/// @brief Get current stack frame for a thread.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
+
+EXTERN_C HAL::StackFramePtr mp_get_current_task(ProcessID thrdid) {
+ return kHWThread[thrdid].mFramePtr;
+}
+
+/***********************************************************************************/
+/// @brief Register current stack frame for a thread.
+/// @param stack_frame The current stack frame.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
+
+EXTERN_C Bool mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) {
+ MUST_PASS(Detail::kGICEnabled);
+
+ if (!stack_frame) return NO;
+ if (thrdid > kMaxAPInsideSched) return NO;
+
+ const auto process_index = thrdid;
+
+ kHWThread[process_index].mFramePtr = stack_frame;
+ kHWThread[process_index].mThreadID = thrdid;
+
+ return YES;
+}
+
+/***********************************************************************************/
+/// @brief Initialize the Global Interrupt Controller.
+/// @internal
+/***********************************************************************************/
+Void mp_init_cores(Void) noexcept {
+ if (!Detail::kGICEnabled) {
+ Detail::kGICEnabled = YES;
+ Detail::mp_setup_gic_el0();
+ }
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s b/src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s
new file mode 100644
index 00000000..dca52571
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s
@@ -0,0 +1,12 @@
+.text
+
+.global hal_ap_blob_start
+.global hal_ap_blob_length
+
+hal_ap_blob_start:
+ ret
+
+.data
+
+hal_ap_blob_length:
+ .long 4
diff --git a/src/kernel/HALKit/ARM64/HalCommonAPI.s b/src/kernel/HALKit/ARM64/HalCommonAPI.s
new file mode 100644
index 00000000..f0c69368
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalCommonAPI.s
@@ -0,0 +1,9 @@
+/* (c) 2024-2025 Amlal El Mahrouss */
+
+.text
+
+.global hal_flush_tlb
+
+hal_flush_tlb:
+ tlbi vmalle1
+ ret
diff --git a/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc
new file mode 100644
index 00000000..b89f68bd
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc
@@ -0,0 +1,159 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/KString.h>
+#include <SignalKit/Signals.h>
+
+EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip);
+EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void);
+
+EXTERN_C BOOL kEndOfInterrupt;
+EXTERN_C UInt8 kEndOfInterruptVector;
+
+STATIC BOOL kIsRunning = NO;
+
+/// @note This is managed by the system software.
+STATIC void hal_int_send_eoi(UInt8 vector) {
+ kEndOfInterrupt = YES;
+ kEndOfInterruptVector = vector;
+}
+
+/// @brief Handle GPF fault.
+/// @param rsp
+EXTERN_C Kernel::Void int_handle_gpf(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(13);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle page fault.
+/// @param rsp
+EXTERN_C void int_handle_pf(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(14);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle scheduler interrupt.
+EXTERN_C void int_handle_scheduler(Kernel::UIntPtr rsp) {
+ NE_UNUSED(rsp);
+
+ hal_int_send_eoi(32);
+
+ while (kIsRunning)
+ ;
+
+ kIsRunning = YES;
+
+ mp_handle_gic_interrupt_el0();
+
+ kIsRunning = NO;
+}
+
+/// @brief Handle math fault.
+/// @param rsp
+EXTERN_C void int_handle_math(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(8);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle any generic fault.
+/// @param rsp
+EXTERN_C void int_handle_generic(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(30);
+
+ Kernel::kout << "Kernel: Generic Process Fault.\r";
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+
+ Kernel::kout << "Kernel: SIGKILL status.\r";
+}
+
+EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+
+ hal_int_send_eoi(3);
+
+ process.Leak().Signal.SignalArg = rip;
+ process.Leak().Signal.SignalID = SIGTRAP;
+
+ process.Leak().Signal.Status = process.Leak().Status;
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kFrozen;
+}
+
+/// @brief Handle #UD fault.
+/// @param rsp
+EXTERN_C void int_handle_ud(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(6);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Enter syscall from assembly (libSystem only)
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash,
+ Kernel::UIntPtr rdx_syscall_arg) {
+ hal_int_send_eoi(50);
+
+ if (!Kernel::kCurrentUser) return;
+
+ for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) {
+ if (kSysCalls[i].fHooked && rcx_hash == kSysCalls[i].fHash) {
+ if (kSysCalls[i].fProc) {
+ (kSysCalls[i].fProc)((Kernel::VoidPtr) rdx_syscall_arg);
+ }
+ }
+ }
+}
+
+/// @brief Enter Kernel call from assembly (libDDK only).
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt,
+ Kernel::UIntPtr arg, Kernel::SizeT sz) {
+ if (!Kernel::kRootUser) return;
+ if (Kernel::kCurrentUser != Kernel::kRootUser) return;
+ if (!Kernel::kCurrentUser->IsSuperUser()) return;
+
+ for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) {
+ if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) {
+ if (kKernCalls[i].fProc) {
+ (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz);
+ }
+ }
+ }
+}
diff --git a/src/kernel/HALKit/ARM64/HalDebugOutput.cc b/src/kernel/HALKit/ARM64/HalDebugOutput.cc
new file mode 100644
index 00000000..c0da9c3a
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalDebugOutput.cc
@@ -0,0 +1,71 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/New.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+EXTERN_C void ke_io_write(DeviceInterface<const Char*>* self, const Char* bytes) {
+#ifdef __DEBUG__
+ if (*bytes == 0) return;
+
+ SizeT index = 0;
+ SizeT len = 0;
+
+ index = 0;
+ len = rt_string_len(bytes, 256U);
+
+ volatile UInt8* uart_ptr = (UInt8*) 0x09000000;
+
+ while (index < len) {
+ if (bytes[index] == '\r') *uart_ptr = '\r';
+
+ *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index];
+ ++index;
+ }
+#endif // __DEBUG__
+}
+
+TerminalDevice::~TerminalDevice() = default;
+
+EXTERN_C void ke_io_read(DeviceInterface<const Char*>* self, const Char* bytes) {
+#ifdef __DEBUG__
+ SizeT index = 0;
+
+ volatile UInt8* uart_ptr = (UInt8*) 0x09000000;
+
+ ///! TODO: Look on how to wait for the UART to complete.
+ while (Yes) {
+ auto in = *uart_ptr;
+
+ ///! If enter pressed then break.
+ if (in == 0xD) {
+ break;
+ }
+
+ if (in < '0' || in < 'A' || in < 'a') {
+ if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || in != ':') {
+ continue;
+ }
+ }
+
+ ((char*) bytes)[index] = in;
+
+ ++index;
+ }
+
+ ((char*) bytes)[index] = 0;
+#endif // __DEBUG__
+}
+
+TerminalDevice TerminalDevice::The() noexcept {
+ TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read);
+ return out;
+}
+
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalHandoverStub.s b/src/kernel/HALKit/ARM64/HalHandoverStub.s
new file mode 100644
index 00000000..5d5647c4
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalHandoverStub.s
@@ -0,0 +1,19 @@
+;; /*
+;; * ========================================================
+;; *
+;; * NeKernel
+;; * Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+.section .ldr
+
+ ;; // MAGIC
+.quad 0xDAB4
+ ;; // VERSION (1.0.0)
+.word 100
+ ;; // CPU (ARM64)
+.word 0
+ ;; // TYPE (KERNEL)
+.word 122
diff --git a/src/kernel/HALKit/ARM64/HalInterruptAPI.s b/src/kernel/HALKit/ARM64/HalInterruptAPI.s
new file mode 100644
index 00000000..cafebb7d
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalInterruptAPI.s
@@ -0,0 +1,3 @@
+/* (c) 2024-2025 Amlal El Mahrouss */
+
+.text
diff --git a/src/kernel/HALKit/ARM64/HalKernelMain.cc b/src/kernel/HALKit/ARM64/HalKernelMain.cc
new file mode 100644
index 00000000..e36535c3
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalKernelMain.cc
@@ -0,0 +1,63 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <CFKit/Property.h>
+#include <FirmwareKit/Handover.h>
+#include <HALKit/ARM64/ApplicationProcessor.h>
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/CodeMgr.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Json.h>
+#include <NetworkKit/IPC.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+#include <modules/CoreGfx/CoreGfx.h>
+
+#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
+EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
+ using namespace Kernel;
+
+ /************************************************** */
+ /* INITIALIZE AND VALIDATE HEADER. */
+ /************************************************** */
+
+ kHandoverHeader = handover_hdr;
+
+ if (kHandoverHeader->f_Magic != kHandoverMagic &&
+ kHandoverHeader->f_Version != kHandoverVersion) {
+ return;
+ }
+
+#ifdef __NE_ARM64_EFI__
+ fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]);
+
+ Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey,
+ handover_hdr->f_HardwareTables.f_ImageHandle);
+#endif
+
+ FB::cg_clear_video();
+
+ /************************************** */
+ /* INITIALIZE BIT MAP. */
+ /************************************** */
+
+ kBitMapCursor = 0UL;
+ kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
+ kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>(
+ reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));
+
+ /// @note do initialize the interrupts after it.
+
+ Kernel::mp_init_cores();
+
+ while (YES)
+ ;
+}
+#endif
diff --git a/src/kernel/HALKit/ARM64/HalKernelPanic.cc b/src/kernel/HALKit/ARM64/HalKernelPanic.cc
new file mode 100644
index 00000000..6837ba1c
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalKernelPanic.cc
@@ -0,0 +1,54 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+/* Each error code is attributed with an ID, which will prompt a string onto the
+ * screen. Wait for debugger... */
+
+namespace Kernel {
+/// @brief Dumping factory class.
+class RecoveryFactory final {
+ public:
+ STATIC Void Recover() noexcept;
+};
+
+/***********************************************************************************/
+/// @brief Stops execution of the kernel.
+/// @param id kernel stop ID.
+/***********************************************************************************/
+Void ke_panic(const Kernel::Int32& id, const Char* message) {
+ (Void)(kout << "*** STOP ***\r");
+ (Void)(kout << "Kernel_Panic_MSG: " << message << kendl);
+ (Void)(kout << "Kernel_Panic_ID: " << hex_number(id) << kendl);
+
+ RecoveryFactory::Recover();
+}
+
+Void RecoveryFactory::Recover() noexcept {
+ while (YES) {
+ HAL::rt_halt();
+ }
+}
+
+void ke_runtime_check(bool expr, const Char* file, const Char* line) {
+ if (!expr) {
+ (Void)(kout << "Kernel_Panic_FILE: " << file << kendl);
+ (Void)(kout << "Kernel_Panic_LINE: " << line << kendl);
+
+ ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed
+ }
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalPagingMgr.cc b/src/kernel/HALKit/ARM64/HalPagingMgr.cc
new file mode 100644
index 00000000..d597ccce
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalPagingMgr.cc
@@ -0,0 +1,86 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HalPagingMgr.cc
+ Purpose: Platform Paging Manager.
+
+======================================== */
+
+#include <HALKit/ARM64/Paging.h>
+#include <HALKit/ARM64/Processor.h>
+
+namespace Kernel::HAL {
+typedef UInt32 PageTableIndex;
+
+EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address) {
+ if (!virtual_address) return 0;
+
+ UInt64 ttbr0_val = 0;
+
+ asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val));
+ volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val);
+
+ UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF;
+ UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF;
+ UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF;
+
+ if (!l1_table[l1_idx]) return 0;
+
+ volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL);
+
+ if (!l2_table[l2_idx]) return 0;
+
+ volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL);
+
+ if (!l3_table[l3_idx]) return 0;
+
+ return (l3_table[l3_idx] & ~0xFFFUL);
+}
+
+/// @brief Maps or allocates a page from virtual_address.
+/// @param virtual_address a valid virtual address.
+/// @param phys_addr point to physical address.
+/// @param flags the flags to put on the page.
+/// @return Status code of page manipulation process.
+EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags,
+ UInt32 level) {
+ if (!virtual_address || !flags || !physical_address) return kErrorInvalidData;
+
+ UInt64 ttbr0_val = 0;
+
+ asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val));
+ volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val);
+
+ UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF;
+ UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF;
+ UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF;
+
+ if (!l1_table[l1_idx]) return kErrorInvalidData;
+
+ volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL);
+
+ if (!l2_table[l2_idx]) return kErrorInvalidData;
+
+ volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL);
+
+ l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
+
+ switch (level) {
+ case 2: {
+ l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
+ return kErrorSuccess;
+ }
+ case 1: {
+ l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
+ return kErrorSuccess;
+ }
+ case 0: {
+ l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
+ return kErrorSuccess;
+ }
+ }
+
+ return kErrorInvalidData;
+}
+} // namespace Kernel::HAL
diff --git a/src/kernel/HALKit/ARM64/HalSchedulerCore.cc b/src/kernel/HALKit/ARM64/HalSchedulerCore.cc
new file mode 100644
index 00000000..467547b0
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalSchedulerCore.cc
@@ -0,0 +1,21 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/ProcessScheduler.h>
+
+namespace Kernel {
+/// @brief Wakes up thread.
+/// Wakes up thread from the hang state.
+Void mp_wakeup_thread(HAL::StackFrame* stack) {
+ NE_UNUSED(stack);
+}
+
+/// @brief makes the thread sleep on a loop.
+/// hooks and hangs thread to prevent code from executing.
+Void mp_hang_thread(HAL::StackFrame* stack) {
+ NE_UNUSED(stack);
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc
new file mode 100644
index 00000000..b1728bac
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc
@@ -0,0 +1,30 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/ProcessScheduler.h>
+
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Unimplemented function (crashes by default)
+/// @param process The process handle.
+/***********************************************************************************/
+
+EXTERN_C Void __ne_pure_call(USER_PROCESS* process) {
+ if (process) process->Crash();
+}
+
+/***********************************************************************************/
+/// @brief Validate user stack.
+/// @param stack_ptr the frame pointer.
+/***********************************************************************************/
+
+EXTERN_C Bool hal_check_task(HAL::StackFramePtr stack_ptr) {
+ if (!stack_ptr) return No;
+
+ return stack_ptr->SP != 0 && stack_ptr->IP != 0;
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalTimer.cc b/src/kernel/HALKit/ARM64/HalTimer.cc
new file mode 100644
index 00000000..2f524a1b
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalTimer.cc
@@ -0,0 +1,15 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HalTimer.cc
+ Purpose: HAL timer
+
+ Revision History:
+
+ 07/07/24: Added file (amlel)
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Timer.h> \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/Paging.h b/src/kernel/HALKit/ARM64/Paging.h
new file mode 100644
index 00000000..766210b3
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Paging.h
@@ -0,0 +1,107 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/** ---------------------------------------------------
+
+ * THIS FILE CONTAINS CODE FOR ARMV8 PAGING.
+
+------------======================================== */
+
+#ifdef __NE_ARM64__
+
+#include <NeKit/Defines.h>
+
+#ifndef kPageMax
+#define kPageMax (0x200)
+#endif //! kPageMax
+
+#ifndef kPageAlign
+#define kPageAlign (0x1000)
+#endif //! kPageAlign
+
+#ifndef kPageSize
+#define kPageSize (0x1000)
+#endif // !kPageSize
+
+//! short format address range
+
+#define c16KBPage 0b000
+#define c8KBPage 0b001
+#define c4KBPage 0b010
+#define c2KBPage 0b011
+#define c1KBPage 0b100
+#define c512BPage 0b101
+#define c256BPage 0b110
+#define c128BPage 0b111
+
+/// Long format address range
+
+#define cPageMAll \
+ { 0b000, 0b000 }
+#define cPageMToMax(M) \
+ { M, 0b000 }
+#define cPageMaxToM(M) \
+ { 0b000, M }
+#define cPageMToN(M, N) \
+ { M, N }
+
+namespace Kernel::HAL {
+struct PACKED PTE_4KB final {
+ UInt64 Valid : 1;
+ UInt64 Table : 1;
+ UInt64 AttrIndex : 3;
+ UInt64 NS : 1;
+ UInt64 AP : 2;
+ UInt64 SH : 2;
+ UInt64 AF : 1;
+ UInt64 NG : 1;
+ UInt64 Reserved1 : 1;
+ UInt64 Contiguous : 1;
+ UInt64 Dirty : 1;
+ UInt64 Reserved : 2;
+ UInt64 PhysicalAddress : 36;
+ UInt64 Reserved3 : 4;
+ UInt64 PXN : 1;
+ UInt64 XN : 1;
+ UInt64 Reserved4 : 9;
+};
+
+namespace Detail {
+ enum class ControlRegisterBits {
+ ProtectedModeEnable = 0,
+ MonitorCoProcessor = 1,
+ Emulation = 2,
+ TaskSwitched = 3,
+ ExtensionType = 4,
+ NumericError = 5,
+ WriteProtect = 16,
+ AlignementMask = 18,
+ NotWriteThrough = 29,
+ CacheDisable = 30,
+ PageEnable = 31,
+ };
+
+ inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); }
+} // namespace Detail
+
+struct PDE_4KB final {
+ PTE_4KB ALIGN(kPageAlign) fEntries[kPageMax];
+};
+
+auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr;
+auto mm_free_bitmap(VoidPtr page_ptr) -> Bool;
+} // namespace Kernel::HAL
+
+namespace Kernel {
+typedef HAL::PTE_4KB PTE;
+typedef HAL::PDE_4KB PDE;
+} // namespace Kernel
+
+EXTERN_C void hal_flush_tlb();
+
+#endif // __NE_ARM64__ \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/Processor.h b/src/kernel/HALKit/ARM64/Processor.h
new file mode 100644
index 00000000..716d317b
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Processor.h
@@ -0,0 +1,78 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#ifdef __NE_ARM64__
+
+#include <FirmwareKit/Handover.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Utils.h>
+
+#define kCPUBackendName "aarch64"
+
+namespace Kernel::HAL {
+struct PACKED Register64 final {
+ UShort Limit;
+ UIntPtr Base;
+};
+
+/// @brief Memory Manager mapping flags.
+enum {
+ kMMFlagsInvalid = 1 << 0,
+ kMMFlagsPresent = 1 << 1,
+ kMMFlagsWr = 1 << 2,
+ kMMFlagsUser = 1 << 3,
+ kMMFlagsNX = 1 << 4,
+ kMMFlagsCount = 4,
+};
+
+/// @brief Set a PTE from pd_base.
+/// @param virt_addr a valid virtual address.
+/// @param phys_addr point to physical address.
+/// @param flags the flags to put on the page.
+/// @return Status code of page manip.
+EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags,
+ UInt32 level = 2);
+
+EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address);
+
+typedef UIntPtr Reg;
+typedef Register64 Register;
+
+/// @note let's keep the same name as AMD64 HAL.
+struct PACKED StackFrame {
+ Reg IP;
+ Reg SP;
+ Reg R8;
+ Reg R9;
+ Reg R10;
+ Reg R11;
+ Reg R12;
+ Reg R13;
+ Reg R14;
+ Reg R15;
+};
+
+typedef StackFrame* StackFramePtr;
+
+inline Void rt_halt() noexcept {
+ while (Yes) {
+ }
+}
+
+inline Void hal_wfi(Void) {
+ asm volatile("wfi");
+}
+} // namespace Kernel::HAL
+
+inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
+inline Kernel::UIntPtr kKernelBitMpSize = 0UL;
+
+#include <HALKit/ARM64/Paging.h>
+
+#endif // __NE_ARM64__ \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc b/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc
new file mode 100644
index 00000000..0200ec5a
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc
@@ -0,0 +1,13 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <modules/SCSI/SCSI.h>
+
+using namespace Kernel;
+
+///! @brief ATAPI SCSI packet.
+const ATTRIBUTE(unused) scsi_packet_type_12 kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0,
+ 0, 12, 0x40, 0, 0};
diff --git a/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc b/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc
new file mode 100644
index 00000000..9971b2a8
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc
@@ -0,0 +1,8 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/// @file UFS.cc
+/// @brief UFS Flash Memory support.
diff --git a/src/kernel/HALKit/POWER/.gitkeep b/src/kernel/HALKit/POWER/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/POWER/.gitkeep
diff --git a/src/kernel/HALKit/POWER/AP.h b/src/kernel/HALKit/POWER/AP.h
new file mode 100644
index 00000000..efe4ceff
--- /dev/null
+++ b/src/kernel/HALKit/POWER/AP.h
@@ -0,0 +1,39 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: AP.h
+ Purpose: POWER hardware threads.
+
+ Revision History:
+
+ 14/04/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+struct HAL_HARDWARE_THREAD;
+
+/// @brief hardware thread indentification type.
+typedef Kernel::Int32 hal_ap_kind;
+
+/// @brief Hardware thread information structure.
+typedef struct HAL_HARDWARE_THREAD {
+ Kernel::UIntPtr fStartAddress;
+ Kernel::UIntPtr fStackPtr;
+ Kernel::UIntPtr fFramePtr;
+ Kernel::UInt8 fPrivileged : 1;
+ Kernel::UInt32 fPageMemoryFlags;
+ hal_ap_kind fIdentNumber;
+} HAL_HARDWARE_THREAD;
+
+/// @brief Set PC to specific hart.
+/// @param hart the hart
+/// @param epc the pc.
+/// @return
+EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc);
+} // namespace Kernel
diff --git a/src/kernel/HALKit/POWER/APM/.gitkeep b/src/kernel/HALKit/POWER/APM/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/POWER/APM/.gitkeep
diff --git a/src/kernel/HALKit/POWER/HalApplicationProcessor.cc b/src/kernel/HALKit/POWER/HalApplicationProcessor.cc
new file mode 100644
index 00000000..84d9b1c1
--- /dev/null
+++ b/src/kernel/HALKit/POWER/HalApplicationProcessor.cc
@@ -0,0 +1,43 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/POWER/AP.h>
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
+
+/// @note This part of the HAL needs an owner.
+
+namespace Kernel::Detail {
+STATIC void mp_hang_fn(void) {
+ while (YES)
+ ;
+}
+} // namespace Kernel::Detail
+
+namespace Kernel {
+/// @brief wakes up thread.
+/// wakes up thread from hang.
+void mp_wakeup_thread(HAL::StackFramePtr stack) {
+ if (!stack) return;
+
+ MUST_PASS(stack->R15 > 0);
+ MUST_PASS(stack->IP > 0);
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15),
+ reinterpret_cast<VoidPtr>(stack->IP));
+}
+
+/// @brief makes thread sleep.
+/// hooks and hangs thread to prevent code from executing.
+void mp_hang_thread(HAL::StackFramePtr stack) {
+ if (!stack) return;
+
+ MUST_PASS(stack->R15 > 0);
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15),
+ reinterpret_cast<VoidPtr>(Kernel::Detail::mp_hang_fn));
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/POWER/HalDebugOutput.cc b/src/kernel/HALKit/POWER/HalDebugOutput.cc
new file mode 100644
index 00000000..0c4be809
--- /dev/null
+++ b/src/kernel/HALKit/POWER/HalDebugOutput.cc
@@ -0,0 +1,24 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
+
+using namespace Kernel;
+
+/// @brief Writes to COM1.
+/// @param bytes
+void ke_io_write(const Char* bytes) {
+ if (!bytes) return;
+
+ SizeT index = 0;
+ SizeT len = rt_string_len(bytes, 256U);
+
+ while (index < len) {
+ // TODO
+ ++index;
+ }
+}
diff --git a/src/kernel/HALKit/POWER/HalHardwareThread.cc b/src/kernel/HALKit/POWER/HalHardwareThread.cc
new file mode 100644
index 00000000..c77040f7
--- /dev/null
+++ b/src/kernel/HALKit/POWER/HalHardwareThread.cc
@@ -0,0 +1,8 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
diff --git a/src/kernel/HALKit/POWER/HalStartSequence.s b/src/kernel/HALKit/POWER/HalStartSequence.s
new file mode 100644
index 00000000..194e220e
--- /dev/null
+++ b/src/kernel/HALKit/POWER/HalStartSequence.s
@@ -0,0 +1,14 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+.globl __ImageStart
+.extern hal_init_platform
+.align 4
+.text
+
+__ImageStart:
+ bl hal_init_platform
+ blr
diff --git a/src/kernel/HALKit/POWER/HalVirtualMemory.cc b/src/kernel/HALKit/POWER/HalVirtualMemory.cc
new file mode 100644
index 00000000..cd9511c9
--- /dev/null
+++ b/src/kernel/HALKit/POWER/HalVirtualMemory.cc
@@ -0,0 +1,46 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/POWER/MMU.h>
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
+
+/// @note Refer to SoC documentation.
+
+using namespace Kernel;
+
+EXTERN_C Void hal_write_tlb(UInt32 mas0, UInt32 mas1, UInt32 mas2, UInt32 mas3, UInt32 mas7) {
+ hal_mtspr(MAS0, mas0);
+ hal_mtspr(MAS1, mas1);
+ hal_mtspr(MAS2, mas2);
+ hal_mtspr(MAS3, mas3);
+ hal_mtspr(MAS7, mas7);
+
+ hal_flush_tlb();
+}
+
+EXTERN_C Bool hal_set_tlb(UInt8 tlb, UInt32 epn, UInt64 rpn, UInt8 perms, UInt8 wimge, UInt8 ts,
+ UInt8 esel, UInt8 tsize, UInt8 iprot) {
+ if ((hal_mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1)) {
+ // this MMU does not allow odd tsize values
+ return false;
+ }
+
+ UInt32 mas0 = FSL_BOOKE_MAS0(tlb, esel, 0);
+ UInt32 mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize);
+ UInt32 mas2 = FSL_BOOKE_MAS2(epn, wimge);
+ UInt32 mas3 = FSL_BOOKE_MAS3(rpn, 0, perms);
+ UInt32 mas7 = FSL_BOOKE_MAS7(rpn);
+
+ hal_write_tlb(mas0, mas1, mas2, mas3, mas7);
+
+ return true;
+}
+
+/// @brief Flush TLB
+EXTERN_C void hal_flush_tlb() {
+ asm volatile("isync;tlbwe;msync;isync");
+}
diff --git a/src/kernel/HALKit/POWER/Processor.h b/src/kernel/HALKit/POWER/Processor.h
new file mode 100644
index 00000000..46cda33e
--- /dev/null
+++ b/src/kernel/HALKit/POWER/Processor.h
@@ -0,0 +1,60 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ Purpose: POWER processor header.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/Utils.h>
+
+#define rtl_nop_op() asm volatile("mr 0, 0")
+#define kHalPPCAlignment __attribute__((aligned(4)))
+
+namespace Kernel::HAL {
+typedef UIntPtr Reg;
+
+/// @brief Stack frame (as retrieved from assembly.)
+struct PACKED StackFrame final {
+ Reg R8{0};
+ Reg R9{0};
+ Reg R10{0};
+ Reg R11{0};
+ Reg R12{0};
+ Reg R13{0};
+ Reg R14{0};
+ Reg R15{0};
+ Reg SP{0};
+ Reg IP{0};
+};
+
+typedef StackFrame* StackFramePtr;
+
+inline void rt_halt() {
+ while (true) {
+ NoOp(); // no oop.
+ }
+}
+
+inline void rt_cli() {
+ NoOp(); // no oop
+}
+} // namespace Kernel::HAL
+
+EXTERN_C Kernel::Void int_handle_math(Kernel::UIntPtr sp);
+EXTERN_C Kernel::Void int_handle_pf(Kernel::UIntPtr sp);
+
+/// @brief Set TLB.
+Kernel::Bool hal_set_tlb(Kernel::UInt8 tlb, Kernel::UInt32 epn, Kernel::UInt64 rpn,
+ Kernel::UInt8 perms, Kernel::UInt8 wimge, Kernel::UInt8 ts,
+ Kernel::UInt8 esel, Kernel::UInt8 tsize, Kernel::UInt8 iprot);
+
+/// @brief Write TLB.
+Kernel::Void hal_write_tlb(Kernel::UInt32 mas0, Kernel::UInt32 mas1, Kernel::UInt32 mas2,
+ Kernel::UInt32 mas3, Kernel::UInt32 mas7);
+
+/// @brief Flush TLB.
+EXTERN_C Kernel::Void hal_flush_tlb();
diff --git a/src/kernel/HALKit/RISCV/.keep b/src/kernel/HALKit/RISCV/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/RISCV/.keep
diff --git a/src/kernel/HALKit/RISCV/AP.h b/src/kernel/HALKit/RISCV/AP.h
new file mode 100644
index 00000000..1061b637
--- /dev/null
+++ b/src/kernel/HALKit/RISCV/AP.h
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: AP.h
+ Purpose: RISC-V hardware threads.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+typedef Int64 hal_ap_kind;
+
+typedef struct HAL_HARDWARE_THREAD {
+ Kernel::UIntPtr fStartAddress;
+ Kernel::UIntPtr fStackPtr;
+ Kernel::UIntPtr fFramePtr;
+ Kernel::UInt8 fPrivileged : 1;
+ Kernel::UInt32 fPageMemoryFlags;
+ hal_ap_kind fIdentNumber;
+} HAL_HARDWARE_THREAD;
+
+/// @brief Set PC to specific hart.
+/// @param hart the hart
+/// @param epc the pc.
+/// @return
+EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc);
+} // namespace Kernel
diff --git a/src/kernel/HALKit/RISCV/APM/.gitkeep b/src/kernel/HALKit/RISCV/APM/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/RISCV/APM/.gitkeep
diff --git a/src/kernel/HALKit/RISCV/HalApplicationProcessor.cc b/src/kernel/HALKit/RISCV/HalApplicationProcessor.cc
new file mode 100644
index 00000000..520481d1
--- /dev/null
+++ b/src/kernel/HALKit/RISCV/HalApplicationProcessor.cc
@@ -0,0 +1,40 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/RISCV/AP.h>
+#include <HALKit/RISCV/Processor.h>
+#include <KernelKit/DebugOutput.h>
+
+using namespace Kernel;
+
+namespace Kernel {
+namespace Detail {
+ STATIC void mp_hang_fn(void) {
+ while (YES)
+ ;
+ }
+
+} // namespace Detail
+
+/// @brief wakes up thread.
+/// wakes up thread from hang.
+void mp_wakeup_thread(HAL::StackFramePtr stack) {
+ if (!stack) return;
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15),
+ reinterpret_cast<VoidPtr>(stack->IP));
+}
+
+/// @brief makes thread sleep.
+/// hooks and hangs thread to prevent code from executing.
+void mp_hang_thread(HAL::StackFramePtr stack) {
+ if (!stack) return;
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15),
+ reinterpret_cast<VoidPtr>(Kernel::Detail::mp_hang_fn));
+}
+
+} // namespace Kernel
diff --git a/src/kernel/HALKit/RISCV/Storage/.gitkeep b/src/kernel/HALKit/RISCV/Storage/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/RISCV/Storage/.gitkeep
diff --git a/src/kernel/HALKit/X86S/.gitkeep b/src/kernel/HALKit/X86S/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/X86S/.gitkeep
diff --git a/src/kernel/HALKit/X86S/ACPI/.gitkeep b/src/kernel/HALKit/X86S/ACPI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/X86S/ACPI/.gitkeep
diff --git a/src/kernel/HALKit/X86S/Storage/.gitkeep b/src/kernel/HALKit/X86S/Storage/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/HALKit/X86S/Storage/.gitkeep
diff --git a/src/kernel/KernelKit/BinaryMutex.h b/src/kernel/KernelKit/BinaryMutex.h
new file mode 100644
index 00000000..5431ab72
--- /dev/null
+++ b/src/kernel/KernelKit/BinaryMutex.h
@@ -0,0 +1,39 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+class USER_PROCESS;
+
+/// @brief Access control class, which locks a task until one is done.
+class BinaryMutex final {
+ public:
+ explicit BinaryMutex() = default;
+ ~BinaryMutex() = default;
+
+ public:
+ bool IsLocked() const;
+ bool Unlock() noexcept;
+
+ public:
+ BOOL WaitForProcess(const UInt32& sec) noexcept;
+
+ public:
+ bool Lock(USER_PROCESS* process);
+ bool LockAndWait(USER_PROCESS* process, TimerInterface* timer);
+
+ public:
+ NE_COPY_DEFAULT(BinaryMutex)
+
+ private:
+ USER_PROCESS* fLockingProcess{nullptr};
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/CodeMgr.h b/src/kernel/KernelKit/CodeMgr.h
new file mode 100644
index 00000000..e537b26d
--- /dev/null
+++ b/src/kernel/KernelKit/CodeMgr.h
@@ -0,0 +1,49 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: CodeMgr.h
+ Purpose: Code Mgr.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+ 3/8/24: Add UPP struct.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/CoreProcessScheduler.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <KernelKit/PE32CodeMgr.h>
+#include <KernelKit/PEFCodeMgr.h>
+
+/// @file CodeMgr.h
+/// @brief Code Manager header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+namespace Kernel {
+/// @brief Main process entrypoint.
+typedef void (*rtl_main_kind)(void);
+
+/// @brief C++ Constructor entrypoint.
+typedef void (*rtl_cxx_ctor_kind)(void);
+
+/// @brief C++ Destructor entrypoint.
+typedef void (*rtl_cxx_dtor_kind)(void);
+
+/// @brief Executes a new process from a function. Kernel code only.
+/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be
+/// accessible.
+/// @param main the start of the process.
+/// @return The team's process id.
+BOOL rtl_create_kernel_task(HAL::StackFramePtr main, const KID kid) noexcept;
+
+/// @brief Executes a new process from a function. User code only.
+/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be
+/// accessible.
+/// @param main the start of the process.
+/// @return The team's process id.
+ProcessID rtl_create_user_process(rtl_main_kind main, const Char* process_name) noexcept;
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/CoreProcessScheduler.h b/src/kernel/KernelKit/CoreProcessScheduler.h
new file mode 100644
index 00000000..54a0614a
--- /dev/null
+++ b/src/kernel/KernelKit/CoreProcessScheduler.h
@@ -0,0 +1,273 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+
+/// @file CoreProcessScheduler.h
+/// @brief Core Process Scheduler header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#define kSchedMinMicroTime (AffinityKind::kStandard)
+#define kSchedInvalidPID (-1)
+#define kSchedProcessLimitPerTeam (32U)
+#define kSchedTeamCount (256U)
+
+#define kSchedMaxMemoryLimit (gib_cast(128)) /* max physical memory limit */
+#define kSchedMaxStackSz (kib_cast(8)) /* maximum stack size */
+
+#define kSchedNameLen (128U)
+
+EXTERN_C void sched_idle_task(void);
+
+namespace Kernel {
+class USER_PROCESS;
+class KERNEL_TASK;
+class KernelTaskScheduler;
+class UserProcessScheduler;
+class UserProcessTeam;
+
+template <typename T>
+struct PROCESS_HEAP_TREE;
+
+template <typename T>
+struct PROCESS_SPECIAL_TREE;
+
+template <typename T>
+struct PROCESS_FILE_TREE;
+
+enum {
+ kInvalidTreeKind = 0U,
+ kRedTreeKind = 100U,
+ kBlackTreeKind = 101U,
+ kTreeKindCount = 3U,
+};
+
+template <typename T>
+struct PROCESS_HEAP_TREE {
+ static constexpr auto kHeap = true;
+ static constexpr auto kFile = false;
+ static constexpr auto kSpecial = false;
+
+ T Entry{nullptr};
+ SizeT EntrySize{0UL};
+ SizeT EntryPad{0UL};
+
+ UInt32 Color{kBlackTreeKind};
+
+ struct PROCESS_HEAP_TREE<T>* Parent {
+ nullptr
+ };
+ struct PROCESS_HEAP_TREE<T>* Child {
+ nullptr
+ };
+
+ struct PROCESS_HEAP_TREE<T>* Prev {
+ nullptr
+ };
+ struct PROCESS_HEAP_TREE<T>* Next {
+ nullptr
+ };
+};
+
+template <typename T>
+struct PROCESS_FILE_TREE {
+ static constexpr auto kHeap = false;
+ static constexpr auto kFile = true;
+ static constexpr auto kSpecial = false;
+
+ T Entry{nullptr};
+ SizeT EntrySize{0UL};
+ SizeT EntryPad{0UL};
+
+ UInt32 Color{kBlackTreeKind};
+
+ struct PROCESS_FILE_TREE<T>* Parent {
+ nullptr
+ };
+
+ struct PROCESS_FILE_TREE<T>* Child {
+ nullptr
+ };
+
+ struct PROCESS_FILE_TREE<T>* Prev {
+ nullptr
+ };
+
+ struct PROCESS_FILE_TREE<T>* Next {
+ nullptr
+ };
+};
+
+using ProcessCtx = UInt32;
+
+template <typename T>
+struct PROCESS_SPECIAL_TREE {
+ static constexpr auto kHeap = false;
+ static constexpr auto kFile = false;
+ static constexpr auto kSpecial = true;
+
+ T Entry{nullptr};
+ SizeT EntrySize{0UL};
+ SizeT EntryPad{0UL};
+
+ /// @brief a context is where the resource comes from.
+ ProcessCtx EntryContext{0UL}; // could be a socket, printer, device...
+
+ UInt32 Color{kBlackTreeKind};
+
+ struct PROCESS_SPECIAL_TREE<T>* Parent {
+ nullptr
+ };
+
+ struct PROCESS_SPECIAL_TREE<T>* Child {
+ nullptr
+ };
+
+ struct PROCESS_SPECIAL_TREE<T>* Prev {
+ nullptr
+ };
+
+ struct PROCESS_SPECIAL_TREE<T>* Next {
+ nullptr
+ };
+};
+
+/***********************************************************************************/
+/// @brief Subsystem enum type.
+/***********************************************************************************/
+
+enum class ProcessSubsystem : Int32 {
+ kProcessSubsystemSecurity = 100,
+ kProcessSubsystemUser,
+ kProcessSubsystemService,
+ kProcessSubsystemDriver,
+ kProcessSubsystemKernel,
+ kProcessSubsystemCount = kProcessSubsystemKernel - kProcessSubsystemSecurity + 1,
+ kProcessSubsystemInvalid = 0xFFFFFFF,
+};
+
+/***********************************************************************************/
+//! @brief Local Process status enum.
+/***********************************************************************************/
+enum class ProcessStatusKind : Int32 {
+ kInvalid = 0,
+ kStarting = 100,
+ kRunning,
+ kKilled,
+ kFrozen,
+ kFinished,
+ kCount = kFinished - kStarting + 1,
+};
+
+/***********************************************************************************/
+//! @brief Affinity is the amount of nano-seconds this process is going to run.
+/***********************************************************************************/
+enum class AffinityKind : Int32 {
+ kInvalid = 0,
+ kRealTime = 100,
+ kVeryHigh = 150,
+ kHigh = 200,
+ kStandard = 1000,
+ kLowUsage = 1500,
+ kVeryLowUsage = 2000,
+};
+
+/***********************************************************************************/
+//! Operators for AffinityKind
+/***********************************************************************************/
+
+inline bool operator<(AffinityKind lhs, AffinityKind rhs) {
+ Int32 lhs_int = static_cast<Int32>(lhs);
+ Int32 rhs_int = static_cast<Int32>(rhs);
+
+ return lhs_int < rhs_int;
+}
+
+inline bool operator>(AffinityKind lhs, AffinityKind rhs) {
+ Int32 lhs_int = static_cast<Int32>(lhs);
+ Int32 rhs_int = static_cast<Int32>(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<Int32>(rhs);
+
+ return lhs_int <= rhs_int;
+}
+
+inline bool operator>=(AffinityKind lhs, AffinityKind rhs) {
+ Int32 lhs_int = static_cast<Int32>(lhs);
+ Int32 rhs_int = static_cast<Int32>(rhs);
+
+ return lhs_int >= rhs_int;
+}
+
+using PTime = UInt64;
+using ProcessTime = PTime;
+
+/***********************************************************************************/
+//! @brief Local Process Identifier type.
+/***********************************************************************************/
+using ProcessID = Int64;
+
+/***********************************************************************************/
+/// @note For User manager, tells where we run the code.
+/***********************************************************************************/
+enum class ProcessLevelRing : Int32 {
+ kRingStdUser = 1,
+ kRingSuperUser = 2,
+ kRingGuestUser = 5,
+ kRingCount = 3,
+};
+
+/***********************************************************************************/
+/// @brief Helper type to describe a code image.
+/***********************************************************************************/
+using ImagePtr = VoidPtr;
+
+/***********************************************************************************/
+/// @brief Helper class to contain a process's image and blob.
+/***********************************************************************************/
+struct ProcessImage final {
+ explicit ProcessImage() = default;
+
+ private:
+ friend USER_PROCESS;
+ friend KERNEL_TASK;
+
+ friend UserProcessScheduler;
+ friend KernelTaskScheduler;
+
+ ImagePtr fCode{};
+ ImagePtr fBlob{};
+
+ public:
+ Bool HasCode() const { return this->fCode != nullptr; }
+
+ Bool HasImage() const { return this->fBlob != nullptr; }
+
+ ErrorOr<ImagePtr> LeakImage() {
+ if (this->fCode) {
+ return ErrorOr<ImagePtr>{this->fCode};
+ }
+
+ return ErrorOr<ImagePtr>{kErrorInvalidData};
+ }
+
+ ErrorOr<ImagePtr> LeakBlob() {
+ if (this->fBlob) {
+ return ErrorOr<ImagePtr>{this->fBlob};
+ }
+
+ return ErrorOr<ImagePtr>{kErrorInvalidData};
+ }
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/DebugOutput.h b/src/kernel/KernelKit/DebugOutput.h
new file mode 100644
index 00000000..3f9b5125
--- /dev/null
+++ b/src/kernel/KernelKit/DebugOutput.h
@@ -0,0 +1,207 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DeviceMgr.h>
+#include <NeKit/OwnPtr.h>
+#include <NeKit/Stream.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+class TerminalDevice;
+class DTraceDevice;
+class NeTraceDevice;
+class Utf8TerminalDevice;
+
+inline TerminalDevice end_line();
+inline TerminalDevice number(const Long& x);
+inline TerminalDevice hex_number(const Long& x);
+
+// @brief Emulates a VT100 terminal.
+class TerminalDevice final NE_DEVICE<const Char*> {
+ public:
+ TerminalDevice(void (*print)(DeviceInterface*, const Char*),
+ void (*gets)(DeviceInterface*, const Char*))
+ : DeviceInterface<const Char*>(print, gets) {}
+
+ ~TerminalDevice() override;
+
+ /// @brief returns device name (terminal name)
+ /// @return string type (const Char*)
+ const Char* Name() const override { return ("TerminalDevice"); }
+
+ NE_COPY_DEFAULT(TerminalDevice)
+
+ STATIC TerminalDevice The() noexcept;
+};
+
+class Utf8TerminalDevice final NE_DEVICE<const Utf8Char*> {
+ public:
+ Utf8TerminalDevice(void (*print)(DeviceInterface*, const Utf8Char*),
+ void (*gets)(DeviceInterface*, const Utf8Char*))
+ : DeviceInterface<const Utf8Char*>(print, gets) {}
+
+ ~Utf8TerminalDevice() override;
+
+ /// @brief returns device name (terminal name)
+ /// @return string type (const Char*)
+ const Char* Name() const override { return ("Utf8TerminalDevice"); }
+
+ NE_COPY_DEFAULT(Utf8TerminalDevice)
+
+ STATIC Utf8TerminalDevice The() noexcept;
+};
+
+inline TerminalDevice end_line() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\r");
+ return self;
+}
+
+inline Utf8TerminalDevice utf_end_line() {
+ Utf8TerminalDevice self = Utf8TerminalDevice::The();
+
+ self.operator<<(u8"\r");
+ return self;
+}
+
+inline TerminalDevice carriage_return() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\r");
+ return self;
+}
+
+inline TerminalDevice tabulate() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\t");
+ return self;
+}
+
+/// @brief emulate a terminal bell, like the VT100 does.
+inline TerminalDevice bell() {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\a");
+ return self;
+}
+
+namespace Detail {
+ inline TerminalDevice _write_number(const Long& x, TerminalDevice& term) {
+ UInt64 y = (x > 0 ? x : -x) / 10;
+ UInt64 h = (x > 0 ? x : -x) % 10;
+
+ if (y) _write_number(y, term);
+
+ /* fail if the number is not base-10 */
+ if (h > 10) {
+ _write_number('?', term);
+ return term;
+ }
+
+ if (y == ~0UL) y = -y;
+
+ const Char kNumbers[11] = "0123456789";
+
+ Char buf[2];
+ buf[0] = kNumbers[h];
+ buf[1] = 0;
+
+ term.operator<<(buf);
+ return term;
+ }
+
+ inline TerminalDevice _write_number_hex(const Long& x, TerminalDevice& term) {
+ UInt64 y = (x > 0 ? x : -x) / 16;
+ UInt64 h = (x > 0 ? x : -x) % 16;
+
+ if (y) _write_number_hex(y, term);
+
+ /* fail if the hex number is not base-16 */
+ if (h > 16) {
+ _write_number_hex('?', term);
+ return term;
+ }
+
+ if (y == ~0UL) y = -y;
+
+ const Char kNumbers[17] = "0123456789ABCDEF";
+
+ Char buf[2];
+ buf[0] = kNumbers[h];
+ buf[1] = 0;
+
+ term.operator<<(buf);
+ return term;
+ }
+} // namespace Detail
+
+inline TerminalDevice hex_number(const Long& x) {
+ TerminalDevice self = TerminalDevice::The();
+
+ self << "0x";
+ Detail::_write_number_hex(x, self);
+
+ return self;
+}
+
+inline TerminalDevice number(const Long& x) {
+ TerminalDevice self = TerminalDevice::The();
+
+ Detail::_write_number(x, self);
+
+ return self;
+}
+
+inline TerminalDevice get_console_in(Char* buf) {
+ TerminalDevice self = TerminalDevice::The();
+
+ self >> buf;
+
+ return self;
+}
+
+inline constexpr auto kDebugPort = 51820;
+inline constexpr auto kDebugMagic = "VMK1.0.0;";
+inline constexpr auto kDebugVersion = 0x0100;
+
+inline constexpr SizeT kDebugCmdLen = 256U;
+
+typedef Char rt_debug_cmd[kDebugCmdLen];
+
+inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) {
+ src = number(num);
+ return src;
+}
+} // namespace Kernel
+
+#ifdef kout
+#undef kout
+#endif // ifdef kout
+
+#define kout TerminalDevice::The()
+
+#ifdef kendl
+#undef kendl
+#endif // ifdef kendl
+
+#define kendl end_line()
+
+#ifdef kout8
+#undef kout8
+#endif // ifdef kout8
+
+#define kout8 Utf8TerminalDevice::The()
+
+#ifdef kendl8
+#undef kendl8
+#endif // ifdef kendl8
+
+#define kendl8 utf_end_line()
diff --git a/src/kernel/KernelKit/Defines.h b/src/kernel/KernelKit/Defines.h
new file mode 100644
index 00000000..e88441d2
--- /dev/null
+++ b/src/kernel/KernelKit/Defines.h
@@ -0,0 +1,19 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define KERNELKIT_VERSION "0.0.1-kernelkit"
+#define KERNELKIT_VERSION_BCD 0x0001
+
+namespace Kernel {
+class UserProcessScheduler;
+class IDylibObject;
+class USER_PROCESS;
+class KERNEL_TASK;
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/DeviceMgr.h b/src/kernel/KernelKit/DeviceMgr.h
new file mode 100644
index 00000000..1dbad161
--- /dev/null
+++ b/src/kernel/KernelKit/DeviceMgr.h
@@ -0,0 +1,129 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/* ========================================
+
+ Revision History:
+
+ 31/01/24: Add kDeviceCnt (amlel)
+ 15/11/24: Add NE_DEVICE macro, to inherit from device object.
+
+ ======================================== */
+
+#pragma once
+
+/* @note Device Mgr. */
+/* @file KernelKit/DeviceMgr.h */
+/* @brief Device abstraction and I/O buffer. */
+
+#include <NeKit/ErrorOr.h>
+#include <NeKit/Ref.h>
+
+#define kDeviceMgrRootDirPath "/devices/"
+
+#define NE_DEVICE : public ::Kernel::DeviceInterface
+
+// Last Rev: Wed, May 27, 2025 6:22 PM
+
+namespace Kernel {
+template <typename T>
+class DeviceInterface;
+
+template <typename T>
+class IOBuf;
+
+/***********************************************************************************/
+/// @brief Device contract interface, represents an HW device.
+/***********************************************************************************/
+template <typename T>
+class DeviceInterface {
+ public:
+ DeviceInterface() = default;
+
+ explicit DeviceInterface(void (*Out)(DeviceInterface<T>*, T), void (*In)(DeviceInterface<T>*, T))
+ : fOut(Out), fIn(In) {}
+
+ virtual ~DeviceInterface() = default;
+
+ public:
+ DeviceInterface& operator=(const DeviceInterface<T>&) = default;
+ DeviceInterface(const DeviceInterface<T>&) = default;
+
+ public:
+ virtual DeviceInterface<T>& operator<<(T Data) {
+ fOut(this, Data);
+ return *this;
+ }
+
+ virtual DeviceInterface<T>& operator>>(T Data) {
+ fIn(this, Data);
+ return *this;
+ }
+
+ virtual const char* Name() const { return "/devices/null"; }
+
+ operator bool() { return fOut && fIn; }
+
+ Bool operator!() { return !fOut || !fIn; }
+
+ protected:
+ Void (*fOut)(DeviceInterface<T>*, T Data) = {nullptr};
+ Void (*fIn)(DeviceInterface<T>*, T Data) = {nullptr};
+};
+
+///
+/// @brief Input Output abstract class.
+/// Used mainly to communicate between OS to hardware.
+///
+template <typename T>
+class IOBuf final {
+ public:
+ explicit IOBuf(T dma_addr) : fData(dma_addr) {
+ // At least pass something valid when instancating this struct.
+ MUST_PASS(fData);
+ }
+
+ IOBuf& operator=(const IOBuf<T>&) = default;
+ IOBuf(const IOBuf<T>&) = default;
+
+ ~IOBuf() = default;
+
+ public:
+ template <typename R>
+ R operator->() const {
+ return fData;
+ }
+
+ template <typename R>
+ R& operator[](Size index) const {
+ return fData[index];
+ }
+
+ private:
+ T fData;
+};
+
+///! @brief Device enum types.
+enum {
+ kDeviceTypeInvalid = 0,
+ kDeviceTypeIDE = 100,
+ kDeviceTypeEthernet,
+ kDeviceTypeWiFi,
+ kDeviceTypeFW,
+ kDeviceTypeBT,
+ kDeviceTypeRS232,
+ kDeviceTypeSCSI,
+ kDeviceTypeAHCI,
+ kDeviceTypeMBCI,
+ kDeviceTypeATA,
+ kDeviceTypeUSB,
+ kDeviceTypeAPM, // Adv. Pwr. Mgmt.
+ kDeviceTypePCI,
+ kDeviceTypeVGA,
+ kDeviceTypeGPU,
+ kDeviceTypeCount,
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/DriveMgr.h b/src/kernel/KernelKit/DriveMgr.h
new file mode 100644
index 00000000..daf93b89
--- /dev/null
+++ b/src/kernel/KernelKit/DriveMgr.h
@@ -0,0 +1,175 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_DRIVE_MANAGER_H
+#define INC_DRIVE_MANAGER_H
+
+/// @file DriveMgr.h
+/// @brief Drive Manager.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <NeKit/Ref.h>
+
+#define kDriveMaxCount (4U)
+#define kDriveSectorSz (512U)
+#define kDriveInvalidID (-1)
+#define kDriveNameLen (32)
+
+#define drv_sector_cnt(SIZE, SECTOR_SZ) (((SIZE) + (SECTOR_SZ)) / (SECTOR_SZ))
+
+#define kDriveHiddenPrefix '~'
+
+namespace Kernel {
+enum {
+ kInvalidDrive = -1,
+
+ /// Storage types, combine with flags.
+ kBlockDevice = 0xAD,
+ kMassStorageDrive = 0xDA,
+ kFloppyDrive = 0xCD,
+ kOpticalDrive = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray
+ kTapeDrive = 0xD7,
+
+ /// Storage flags, combine with types.
+ kReadOnlyDrive = 0x10, // Read only drive
+ kEPMDrive = 0x11, // Explicit Partition Map.
+ kVEPMDrive = 0x12, // ESP w/ EPM partition.
+ kMBRDrive = 0x13, // PC classic partition scheme
+ kGPTDrive = 0x14, // PC new partition scheme
+ kUnformattedDrive = 0x15,
+ kStorageCount = 9,
+};
+
+/// @brief Media drive trait type.
+struct DriveTrait final {
+ Char fName[kDriveNameLen] = "/media/null"; // /System, /boot, //./Devices/USB...
+ UInt32 fKind{}; // fMassStorage, fFloppy, fOpticalDrive.
+ UInt32 fFlags{}; // fReadOnly, fEPMDrive...
+
+ /// @brief Packet drive (StorageKit compilant.)
+ struct DrivePacket final {
+ VoidPtr fPacketContent{nullptr}; //! packet body.
+ Char fPacketMime[kDriveNameLen] = "*/*"; //! identify what we're sending.
+ SizeT fPacketSize{0UL}; //! packet size
+ UInt32 fPacketCRC32{0UL}; //! sanity crc, in case if good is set to false
+ Boolean fPacketGood{YES};
+ Lba fPacketLba{0UL};
+ Boolean fPacketReadOnly{NO};
+ } fPacket;
+
+ Lba fLbaStart{0}, fLbaEnd{0};
+ SizeT fSectorSz{kDriveSectorSz};
+
+ Void (*fInput)(DrivePacket& packet){nullptr};
+ Void (*fOutput)(DrivePacket& packet){nullptr};
+ Void (*fVerify)(DrivePacket& packet){nullptr};
+ Void (*fInit)(DrivePacket& packet){nullptr};
+ const Char* (*fProtocol)(Void){nullptr};
+};
+
+namespace Probe {
+ Void io_detect_drive(DriveTrait& trait);
+}
+
+///! drive as a device.
+typedef DriveTrait* DriveTraitPtr;
+
+/**
+ * @brief Mounted drives interface.
+ * @note This class has all of it's drive set to nullptr, allocate them using
+ * GetAddressOf(index).
+ */
+class IMountpoint final {
+ public:
+ explicit IMountpoint() = default;
+ ~IMountpoint() = default;
+
+ NE_COPY_DEFAULT(IMountpoint)
+
+ public:
+ DriveTrait& A() { return mA; }
+
+ DriveTrait& B() { return mB; }
+
+ DriveTrait& C() { return mC; }
+
+ DriveTrait& D() { return mD; }
+
+ enum {
+ kDriveIndexA = 0,
+ kDriveIndexB,
+ kDriveIndexC,
+ kDriveIndexD,
+ kDriveIndexInvalid,
+ };
+
+ DriveTraitPtr GetAddressOf(const Int32& index) {
+ err_local_get() = kErrorSuccess;
+
+ switch (index) {
+ case kDriveIndexA:
+ return &mA;
+ case kDriveIndexB:
+ return &mB;
+ case kDriveIndexC:
+ return &mC;
+ case kDriveIndexD:
+ return &mD;
+ default: {
+ err_local_get() = kErrorNoSuchDisk;
+ kout << "No such disc letter.\n";
+
+ break;
+ }
+ }
+
+ return nullptr;
+ }
+
+ private:
+ DriveTrait mA, mB, mC, mD;
+};
+
+/// @brief Unimplemented drive.
+/// @param pckt the packet to read.
+/// @return
+Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) noexcept;
+
+/// @brief Gets the drive kind (ATA, SCSI, AHCI...)
+/// @param void none.
+/// @return the drive kind (ATA, Flash, NVM)
+const Char* io_drv_kind(Void);
+
+/// @brief Makes a new drive.
+/// @return the new drive as a trait.
+DriveTrait io_construct_blank_drive(Void) noexcept;
+
+/// @brief Fetches the main drive.
+/// @param trait the new drive as a trait.
+Void io_construct_main_drive(DriveTrait& trait) noexcept;
+
+/// @brief Fetches the main drive.
+/// @return the new drive as a trait.
+/// @deprecated use io_construct_main_drive(DriveTrait& trait) instead.
+DriveTrait io_construct_main_drive(Void) noexcept;
+
+namespace Detect {
+ Void io_detect_drive(DriveTrait& trait);
+}
+
+Void io_drv_input(DriveTrait::DrivePacket pckt);
+
+Void io_drv_output(DriveTrait::DrivePacket pckt);
+} // namespace Kernel
+
+#endif /* ifndef INC_DRIVE_MANAGER_H */
diff --git a/src/kernel/KernelKit/FileMgr.h b/src/kernel/KernelKit/FileMgr.h
new file mode 100644
index 00000000..93d5f580
--- /dev/null
+++ b/src/kernel/KernelKit/FileMgr.h
@@ -0,0 +1,445 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss , licensed under the Apache 2.0 license.
+
+ File: FileMgr.h
+ Purpose: Kernel file manager.
+ Author: Amlal El Mahrouss (amlal@nekernel.org)
+
+======================================== */
+
+/* ========================================
+
+ Revision History:
+
+ 31/01/24: Update documentation (amlel)
+ 05/07/24: NeFS support, and fork support, updated constants and specs
+ as well.
+ 18/01/25: Patches to FileStream class.
+
+ ======================================== */
+
+#ifndef INC_FILEMGR_H
+#define INC_FILEMGR_H
+
+/// @file FileMgr.h
+/// @brief File Manager System.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+//! Include filesystems that NeKernel supports.
+#include <FSKit/Ext2+IFS.h>
+#include <FSKit/NeFS.h>
+#include <FSKit/OpenHeFS.h>
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/Ref.h>
+#include <NeKit/Stream.h>
+#include <hint/CompilerHint.h>
+
+/// @brief Filesystem manager, abstraction over mounted filesystem.
+/// Works like an VFS (Virtual File System) or IFS subsystem on NT/OS 2.
+
+#define kRestrictR "r"
+#define kRestrictRB "rb"
+#define kRestrictW "w"
+#define kRestrictWR "rw"
+#define kRestrictWRB "rwb"
+
+#define kRestrictMax (5U)
+
+#define rtl_node_cast(PTR) reinterpret_cast<Kernel::NodePtr>(PTR)
+
+#define kFileMimeGeneric "ne-application-kind/all"
+
+/** @brief invalid position. (n-pos) */
+#define kFileMgrNPos (~0UL)
+
+namespace Kernel {
+enum {
+ kFileIOInvalid = 0,
+ kFileWriteAll = 100,
+ kFileReadAll = 101,
+ kFileReadChunk = 102,
+ kFileWriteChunk = 103,
+ // File flags (HFS+, NeFS specific)
+ kFileFlagRsrc = 104,
+ kFileFlagData = 105,
+ kFileIOCnt = (kFileFlagData - kFileWriteAll) + 1,
+};
+
+using NodePtr = VoidPtr;
+
+/**
+@brief Filesystem Mgr Interface class
+@brief Used to provide common I/O for a specific filesystem.
+*/
+class IFilesystemMgr {
+ public:
+ explicit IFilesystemMgr() = default;
+ virtual ~IFilesystemMgr() = default;
+
+ public:
+ NE_COPY_DEFAULT(IFilesystemMgr)
+
+ public:
+ /// @brief Mounts a new filesystem into an active state.
+ /// @param interface the filesystem interface
+ /// @return
+ static bool Mount(IFilesystemMgr* interface);
+
+ /// @brief Unmounts the active filesystem
+ /// @return
+ static IFilesystemMgr* Unmount();
+
+ /// @brief Getter, gets the active filesystem.
+ /// @return
+ static IFilesystemMgr* GetMounted();
+
+ public:
+ virtual NodePtr Create(_Input const Char* path) = 0;
+ virtual NodePtr CreateAlias(_Input const Char* path) = 0;
+ virtual NodePtr CreateDirectory(_Input const Char* path) = 0;
+ virtual NodePtr CreateSwapFile(const Char* path) = 0;
+
+ public:
+ virtual bool Remove(_Input const Char* path) = 0;
+
+ public:
+ virtual NodePtr Open(_Input const Char* path, _Input const Char* r) = 0;
+
+ public:
+ virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) = 0;
+
+ virtual Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data,
+ _Input Int32 flags, _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) = 0;
+
+ public:
+ virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0;
+
+ public:
+ virtual SizeT Tell(_Input NodePtr node) = 0;
+ virtual bool Rewind(_Input NodePtr node) = 0;
+};
+
+#ifdef __FSKIT_INCLUDES_NEFS__
+/**
+ * @brief Based of IFilesystemMgr, takes care of managing NeFS
+ * disks.
+ */
+class NeFileSystemMgr final : public IFilesystemMgr {
+ public:
+ explicit NeFileSystemMgr();
+ ~NeFileSystemMgr() override;
+
+ public:
+ NE_COPY_DEFAULT(NeFileSystemMgr)
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+ NodePtr CreateSwapFile(const Char* path) override;
+
+ public:
+ bool Remove(_Input const Char* path) override;
+ NodePtr Open(_Input const Char* path, _Input const Char* r) override;
+ Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT sz) override;
+ VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override;
+ bool Seek(_Input NodePtr node, _Input SizeT off) override;
+ SizeT Tell(_Input NodePtr node) override;
+ bool Rewind(_Input NodePtr node) override;
+
+ Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ /// @brief Get NeFS parser class.
+ /// @return The filesystem parser class.
+ NeFileSystemParser* GetParser() noexcept;
+
+ private:
+ NeFileSystemParser* mParser{nullptr};
+};
+
+#endif // ifdef __FSKIT_INCLUDES_NEFS__
+
+#ifdef __FSKIT_INCLUDES_EXT2__
+/**
+ * @brief Based of IFilesystemMgr, takes care of managing NeFS
+ * disks.
+ */
+class Ext2FileSystemMgr final : public IFilesystemMgr {
+ public:
+ explicit Ext2FileSystemMgr();
+ ~Ext2FileSystemMgr() override;
+
+ public:
+ NE_COPY_DEFAULT(Ext2FileSystemMgr)
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+ NodePtr CreateSwapFile(const Char* path) override;
+
+ public:
+ bool Remove(_Input const Char* path) override;
+ NodePtr Open(_Input const Char* path, _Input const Char* r) override;
+ Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT sz) override;
+ VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override;
+ bool Seek(_Input NodePtr node, _Input SizeT off) override;
+ SizeT Tell(_Input NodePtr node) override;
+ bool Rewind(_Input NodePtr node) override;
+
+ Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ /// @brief Get NeFS parser class.
+ /// @return The filesystem parser class.
+ Ext2FileSystemParser* GetParser() noexcept;
+
+ private:
+ Ext2FileSystemParser* mParser{nullptr};
+};
+
+#endif // ifdef __FSKIT_INCLUDES_EXT2__
+
+#ifdef __FSKIT_INCLUDES_OPENHEFS__
+/**
+ * @brief Based of IFilesystemMgr, takes care of managing NeFS
+ * disks.
+ */
+class HeFileSystemMgr final : public IFilesystemMgr {
+ public:
+ explicit HeFileSystemMgr();
+ ~HeFileSystemMgr() override;
+
+ public:
+ NE_COPY_DEFAULT(HeFileSystemMgr)
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+ NodePtr CreateSwapFile(const Char* path) override;
+
+ public:
+ bool Remove(_Input const Char* path) override;
+ NodePtr Open(_Input const Char* path, _Input const Char* r) override;
+ Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT sz) override;
+ VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override;
+ bool Seek(_Input NodePtr node, _Input SizeT off) override;
+ SizeT Tell(_Input NodePtr node) override;
+ bool Rewind(_Input NodePtr node) override;
+
+ Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ /// @brief Get NeFS parser class.
+ /// @return The filesystem parser class.
+ HeFileSystemParser* GetParser() noexcept;
+
+ private:
+ HeFileSystemParser* mParser{nullptr};
+};
+
+#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__
+
+/**
+ * FileStream class.
+ * @tparam Encoding file encoding (char, wchar_t...)
+ * @tparam FSClass Filesystem contract who takes care of it.
+ */
+template <typename Encoding = Char, typename FSClass = IFilesystemMgr>
+class FileStream final {
+ public:
+ explicit FileStream(const Encoding* path, const Encoding* restrict_type);
+ ~FileStream();
+
+ public:
+ FileStream& operator=(const FileStream&);
+ FileStream(const FileStream&);
+
+ public:
+ ErrorOr<Int64> Write(SizeT offset, const VoidPtr data, SizeT len) noexcept {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictWrite &&
+ this->fFileRestrict != kFileMgrRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr) return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ man->Write(offset, fFile, data, len);
+ return ErrorOr<Int64>(kErrorSuccess);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ ErrorOr<Int64> Write(const Char* name, const VoidPtr data, SizeT len) noexcept {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictWrite &&
+ this->fFileRestrict != kFileMgrRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr) return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ man->Write(name, fFile, data, 0, len);
+ return ErrorOr<Int64>(kErrorSuccess);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ VoidPtr Read(const Char* name, SizeT sz) noexcept {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictRead &&
+ this->fFileRestrict != kFileMgrRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ VoidPtr ret = man->Read(name, fFile, kFileReadAll, sz);
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ VoidPtr Read(SizeT offset, SizeT sz) {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictRead &&
+ this->fFileRestrict != kFileMgrRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man) {
+ man->Seek(fFile, offset);
+ auto ret = man->Read(fFile, kFileReadChunk, sz);
+
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ public:
+ /// @brief Leak node pointer.
+ /// @return The node pointer.
+ NodePtr Leak() { return fFile; }
+
+ /// @brief Leak MIME.
+ /// @return The MIME.
+ Char* MIME() noexcept { return const_cast<Char*>(fMime); }
+
+ enum {
+ kFileMgrRestrictRead = 100,
+ kFileMgrRestrictReadBinary,
+ kFileMgrRestrictWrite,
+ kFileMgrRestrictWriteBinary,
+ kFileMgrRestrictReadWrite,
+ kFileMgrRestrictReadWriteBinary,
+ };
+
+ private:
+ NodePtr fFile{nullptr};
+ Int32 fFileRestrict{kFileMgrRestrictReadBinary};
+ const Char* fMime{kFileMimeGeneric};
+};
+
+using FileStreamASCII = FileStream<Char>;
+using FileStreamUTF8 = FileStream<Utf8Char>;
+using FileStreamUTF16 = FileStream<WideChar>;
+
+typedef UInt64 CursorType;
+
+inline STATIC const auto kRestrictStrLen = 8U;
+
+/// @brief restrict information about the file descriptor.
+struct FILEMGR_RESTRICT final {
+ Char fRestrict[kRestrictStrLen];
+ Int32 fMappedTo;
+};
+
+/// @brief constructor
+template <typename Encoding, typename Class>
+inline FileStream<Encoding, Class>::FileStream(const Encoding* path, const Encoding* restrict_type)
+ : fFile(Class::GetMounted()->Open(path, restrict_type)) {
+ SizeT kRestrictCount = kRestrictMax;
+ const FILEMGR_RESTRICT kRestrictList[] = {{
+ .fRestrict = kRestrictR,
+ .fMappedTo = kFileMgrRestrictRead,
+ },
+ {
+ .fRestrict = kRestrictRB,
+ .fMappedTo = kFileMgrRestrictReadBinary,
+ },
+ {
+ .fRestrict = kRestrictWRB,
+ .fMappedTo = kFileMgrRestrictReadWriteBinary,
+ },
+ {
+ .fRestrict = kRestrictW,
+ .fMappedTo = kFileMgrRestrictWrite,
+ },
+ {
+ .fRestrict = kRestrictWR,
+ .fMappedTo = kFileMgrRestrictReadWrite,
+ }};
+
+ for (SizeT index = 0; index < kRestrictCount; ++index) {
+ if (rt_string_cmp(restrict_type, kRestrictList[index].fRestrict,
+ rt_string_len(kRestrictList[index].fRestrict)) == 0) {
+ fFileRestrict = kRestrictList[index].fMappedTo;
+ break;
+ }
+ }
+
+ kout << "FileMgr: Open file at: " << path << ".\r";
+}
+
+/// @brief destructor of the file stream.
+template <typename Encoding, typename Class>
+inline FileStream<Encoding, Class>::~FileStream() {
+ mm_free_ptr(fFile);
+ fFile = nullptr;
+}
+} // namespace Kernel
+
+#endif // ifndef INC_FILEMGR_H
diff --git a/src/kernel/KernelKit/HardwareThreadScheduler.h b/src/kernel/KernelKit/HardwareThreadScheduler.h
new file mode 100644
index 00000000..36a870ba
--- /dev/null
+++ b/src/kernel/KernelKit/HardwareThreadScheduler.h
@@ -0,0 +1,135 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __INC_MP_MANAGER_H__
+#define __INC_MP_MANAGER_H__
+
+#include <ArchKit/ArchKit.h>
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Ref.h>
+
+/// @note Last Rev Sun 28 Jul CET 2024
+/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM
+
+#define kMaxAPInsideSched (4U)
+
+namespace Kernel {
+class HardwareThread;
+class HardwareThreadScheduler;
+
+using ThreadID = UInt32;
+
+enum ThreadKind {
+ kAPInvalid = 0,
+ kAPSystemReserved = 100, // System reserved thread, well user can't use it
+ kAPStandard, // user thread, cannot be used by Kernel
+ kAPRealTime, // fallback thread, cannot be used by user if not clear or
+ // used by Kernel.
+ kAPBoot, // The core we booted from, the mama.
+ kAPCount,
+};
+
+typedef enum ThreadKind ThreadKind;
+typedef ThreadID ThreadID;
+
+/***********************************************************************************/
+///
+/// \name HardwareThread
+/// \brief Abstraction over the CPU's core, used to run processes or threads.
+///
+/***********************************************************************************/
+
+class HardwareThread final {
+ public:
+ explicit HardwareThread();
+ ~HardwareThread();
+
+ public:
+ NE_COPY_DEFAULT(HardwareThread)
+
+ public:
+ operator bool();
+
+ public:
+ void Wake(const BOOL wakeup = false) noexcept;
+ void Busy(const BOOL busy = false) noexcept;
+
+ public:
+ BOOL Switch(HAL::StackFramePtr frame);
+ BOOL IsWakeup() noexcept;
+
+ public:
+ HAL::StackFramePtr StackFrame() noexcept;
+ ThreadKind& Kind() noexcept;
+ BOOL IsBusy() noexcept;
+ ThreadID& ID() noexcept;
+
+ private:
+ HAL::StackFramePtr fStack{nullptr};
+ ThreadKind fKind{ThreadKind::kAPStandard};
+ ThreadID fID{0};
+ Bool fWakeup{NO};
+ Bool fBusy{NO};
+ UInt64 fPTime{0};
+
+ private:
+ friend class HardwareThreadScheduler;
+ friend class UserProcessHelper;
+};
+
+///
+/// \name HardwareThreadScheduler
+/// \brief Class to manage the thread scheduling.
+///
+
+class HardwareThreadScheduler final : public ISchedulable {
+ private:
+ friend class UserProcessHelper;
+
+ public:
+ explicit HardwareThreadScheduler();
+ ~HardwareThreadScheduler();
+ NE_COPY_DEFAULT(HardwareThreadScheduler)
+
+ public:
+ HAL::StackFramePtr Leak() noexcept;
+
+ public:
+ Ref<HardwareThread*> operator[](SizeT idx);
+ bool operator!() noexcept;
+ operator bool() noexcept;
+
+ Bool IsUser() override { return Yes; }
+
+ Bool IsKernel() override { return No; }
+
+ Bool HasMP() override { return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; }
+
+ public:
+ /// @brief Shared instance of the MP Mgr.
+ /// @return the reference to the mp manager class.
+ STATIC HardwareThreadScheduler& The();
+
+ public:
+ /// @brief Returns the amount of threads present in the system.
+ /// @returns SizeT the amount of cores present.
+ SizeT Capacity() noexcept;
+
+ private:
+ Array<HardwareThread, kMaxAPInsideSched> fThreadList;
+ ThreadID fCurrentThreadIdx{0};
+};
+
+/// @brief wakes up thread.
+/// wakes up thread from hang.
+Void mp_wakeup_thread(HAL::StackFramePtr stack);
+
+/// @brief makes thread sleep.
+/// hooks and hangs thread to prevent code from executing.
+Void mp_hang_thread(HAL::StackFramePtr stack);
+} // namespace Kernel
+
+#endif // !__INC_MP_MANAGER_H__
diff --git a/src/kernel/KernelKit/HeapMgr.h b/src/kernel/KernelKit/HeapMgr.h
new file mode 100644
index 00000000..58bac7a5
--- /dev/null
+++ b/src/kernel/KernelKit/HeapMgr.h
@@ -0,0 +1,58 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_KERNEL_HEAP_H
+#define INC_KERNEL_HEAP_H
+
+/// @date 30/01/24
+/// @file: HeapMgr.h
+/// @brief: Memory allocation support for the NeKernel.
+
+#include <KernelKit/KPC.h>
+#include <NeKit/KernelPanic.h>
+#include <hint/CompilerHint.h>
+
+namespace Kernel {
+/// @brief Declare pointer as free.
+/// @param heap_ptr the pointer.
+/// @return a status code regarding the deallocation.
+Int32 mm_free_ptr(VoidPtr heap_ptr);
+
+/// @brief Check if pointer is a valid Kernel pointer.
+/// @param heap_ptr the pointer
+/// @return if it exists it returns true.
+Boolean mm_is_valid_ptr(VoidPtr heap_ptr);
+
+/// @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, or nullptr.
+VoidPtr mm_alloc_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount = 0);
+
+/// @brief Protect the heap with a CRC value.
+/// @param heap_ptr pointer.
+/// @return if it valid: point has crc now., otherwise fail.
+Boolean mm_protect_ptr(VoidPtr heap_ptr);
+
+/// @brief Makes a Kernel page.
+/// @param heap_ptr the page pointer.
+/// @return status code
+Int32 mm_make_page(VoidPtr heap_ptr);
+
+/// @brief Overwrites and set the flags of a heap header.
+/// @param heap_ptr the pointer to update.
+/// @param flags the flags to set.
+Int32 mm_set_ptr_flags(VoidPtr heap_ptr, UInt64 flags);
+
+/// @brief Gets the flags of a heap header.
+/// @param heap_ptr the pointer to get.
+UInt64 mm_get_ptr_flags(VoidPtr heap_ptr);
+} // namespace Kernel
+
+#include <KernelKit/HeapMgr.inl>
+
+#endif // !INC_KERNEL_HEAP_H
diff --git a/src/kernel/KernelKit/HeapMgr.inl b/src/kernel/KernelKit/HeapMgr.inl
new file mode 100644
index 00000000..3231d33c
--- /dev/null
+++ b/src/kernel/KernelKit/HeapMgr.inl
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#ifndef INC_KERNEL_HEAP_H
+#include <KernelKit/HeapMgr.h>
+#endif // !INC_KERNEL_HEAP_H
+
+namespace Kernel {
+/// @brief Allocate C++ class.
+/// @param cls The class to allocate.
+/// @param args The args to pass.
+template <typename T, typename... Args>
+inline BOOL mm_new_class(_Input _Output T** cls, _Input Args&&... args) {
+ if (*cls) {
+ err_global_get() = Kernel::kErrorInvalidData;
+ return NO;
+ }
+
+ *cls = new T(move(args)...);
+ return *cls;
+}
+
+/// @brief Delete and nullify C++ class.
+/// @param cls The class to delete.
+template <typename T>
+inline Void mm_delete_class(_Input _Output T** cls) {
+ delete *cls;
+ *cls = nullptr;
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/IDylibObject.h b/src/kernel/KernelKit/IDylibObject.h
new file mode 100644
index 00000000..ef6b96db
--- /dev/null
+++ b/src/kernel/KernelKit/IDylibObject.h
@@ -0,0 +1,45 @@
+/*
+ * ========================================================
+ *
+ * Kernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+
+#define NE_DYLIB_OBJECT : public IDylibObject
+
+namespace Kernel {
+class IDylibObject;
+
+/// @brief Dylib class object. A handle to a shared library.
+class IDylibObject {
+ public:
+ explicit IDylibObject() = default;
+ virtual ~IDylibObject() = default;
+
+ struct DylibTraits final {
+ VoidPtr ImageObject{nullptr};
+ VoidPtr ImageEntrypointOffset{nullptr};
+
+ VoidPtr Image() const { return ImageObject; }
+ Bool IsValid() const { return ImageObject && ImageEntrypointOffset; }
+ };
+
+ NE_COPY_DEFAULT(IDylibObject)
+
+ virtual DylibTraits** GetAddressOf() = 0;
+ virtual DylibTraits* Get() = 0;
+
+ virtual Void Mount(DylibTraits* to_mount) = 0;
+ virtual Void Unmount() = 0;
+};
+
+/// @brief Pure implementation, missing method/function handler.
+EXTERN_C void __ne_pure_call(void);
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/IFS.h b/src/kernel/KernelKit/IFS.h
new file mode 100644
index 00000000..7118a935
--- /dev/null
+++ b/src/kernel/KernelKit/IFS.h
@@ -0,0 +1,25 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DriveMgr.h>
+
+namespace Kernel {
+/// @brief Read from IFS disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_read(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex);
+
+/// @brief Write to IFS disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_write(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex);
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/ILoader.h b/src/kernel/KernelKit/ILoader.h
new file mode 100644
index 00000000..28dd1ed9
--- /dev/null
+++ b/src/kernel/KernelKit/ILoader.h
@@ -0,0 +1,32 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+#include <hint/CompilerHint.h>
+
+namespace Kernel {
+/// @brief This interface is used to make loader contracts (MSCOFF, PEF).
+/// @author @Amlal-El-Mahrouss
+class ILoader {
+ public:
+ explicit ILoader() = default;
+ virtual ~ILoader() = default;
+
+ NE_COPY_DEFAULT(ILoader)
+
+ public:
+ virtual _Output ErrorOr<VoidPtr> GetBlob() = 0;
+ virtual _Output const Char* AsString() = 0;
+ virtual _Output const Char* MIME() = 0;
+ virtual _Output const Char* Path() = 0;
+ virtual _Output ErrorOr<VoidPtr> FindStart() = 0;
+ virtual _Output ErrorOr<VoidPtr> FindSymbol(_Input const Char* name, _Input Int32 kind) = 0;
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/IPEFDylibObject.h b/src/kernel/KernelKit/IPEFDylibObject.h
new file mode 100644
index 00000000..17ef02d5
--- /dev/null
+++ b/src/kernel/KernelKit/IPEFDylibObject.h
@@ -0,0 +1,86 @@
+/*
+ * ========================================================
+ *
+ * Kernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#ifndef __KERNELKIT_PEF_SHARED_OBJECT_H__
+#define __KERNELKIT_PEF_SHARED_OBJECT_H__
+
+#include <KernelKit/IDylibObject.h>
+#include <KernelKit/PEF.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+/**
+ * @brief Shared Library class
+ * Load library from this class
+ */
+class IPEFDylibObject final NE_DYLIB_OBJECT {
+ public:
+ explicit IPEFDylibObject() = default;
+ ~IPEFDylibObject() = default;
+
+ public:
+ NE_COPY_DEFAULT(IPEFDylibObject)
+
+ private:
+ DylibTraits* fMounted{nullptr};
+
+ public:
+ DylibTraits** GetAddressOf() { return &fMounted; }
+
+ DylibTraits* Get() { return fMounted; }
+
+ public:
+ void Mount(DylibTraits* to_mount) noexcept {
+ if (!to_mount || !to_mount->ImageObject) return;
+
+ fMounted = to_mount;
+
+ if (fLoader && to_mount) {
+ delete fLoader;
+ fLoader = nullptr;
+ }
+
+ if (!fLoader) {
+ fLoader = new PEFLoader(fMounted->ImageObject);
+ }
+ }
+
+ void Unmount() noexcept {
+ if (fMounted) fMounted = nullptr;
+ };
+
+ template <typename SymbolType>
+ SymbolType Load(const Char* symbol_name, const SizeT& len, const UInt32& kind) {
+ if (symbol_name == nullptr || *symbol_name == 0) return nullptr;
+ if (len > kPathLen || len < 1) return nullptr;
+
+ auto ret = reinterpret_cast<SymbolType>(fLoader->FindSymbol(symbol_name, kind).Leak().Leak());
+
+ if (!ret) {
+ if (kind == kPefCode) return (VoidPtr) &__ne_pure_call;
+
+ return nullptr;
+ }
+
+ return ret;
+ }
+
+ private:
+ PEFLoader* fLoader{nullptr};
+};
+
+typedef IPEFDylibObject* IDylibRef;
+
+EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& header);
+EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& header, IDylibRef lib, Bool* successful);
+} // namespace Kernel
+
+#endif /* ifndef __KERNELKIT_PEF_SHARED_OBJECT_H__ */
diff --git a/src/kernel/KernelKit/KPC.h b/src/kernel/KernelKit/KPC.h
new file mode 100644
index 00000000..dbdc2a93
--- /dev/null
+++ b/src/kernel/KernelKit/KPC.h
@@ -0,0 +1,78 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+/// @file KPC.h
+/// @brief Kernel Procedure Code.
+
+#define err_local_ok() \
+ (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode() == \
+ Kernel::kErrorSuccess)
+#define err_local_fail() \
+ (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode() != \
+ Kernel::kErrorSuccess)
+#define err_local_get() \
+ (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode())
+
+#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess)
+#define err_global_fail() (Kernel::kErrorLocalNumber != Kernel::kErrorSuccess)
+#define err_global_get() (Kernel::kErrorLocalNumber)
+
+namespace Kernel {
+typedef Int32 KPCError;
+
+inline KPCError kErrorLocalNumber = 0UL;
+
+inline constexpr KPCError kErrorSuccess = 0;
+inline constexpr KPCError kErrorExecutable = 33;
+inline constexpr KPCError kErrorExecutableLib = 34;
+inline constexpr KPCError kErrorFileNotFound = 35;
+inline constexpr KPCError kErrorDirectoryNotFound = 36;
+inline constexpr KPCError kErrorDiskReadOnly = 37;
+inline constexpr KPCError kErrorDiskIsFull = 38;
+inline constexpr KPCError kErrorProcessFault = 39;
+inline constexpr KPCError kErrorSocketHangUp = 40;
+inline constexpr KPCError kErrorThreadLocalStorage = 41;
+inline constexpr KPCError kErrorMath = 42;
+inline constexpr KPCError kErrorNoNetwork = 43;
+inline constexpr KPCError kErrorHeapOutOfMemory = 44;
+inline constexpr KPCError kErrorNoSuchDisk = 45;
+inline constexpr KPCError kErrorFileExists = 46;
+inline constexpr KPCError kErrorFormatFailed = 47;
+inline constexpr KPCError kErrorNetworkTimeout = 48;
+inline constexpr KPCError kErrorInternal = 49;
+inline constexpr KPCError kErrorForkAlreadyExists = 50;
+inline constexpr KPCError kErrorOutOfTeamSlot = 51;
+inline constexpr KPCError kErrorHeapNotPresent = 52;
+inline constexpr KPCError kErrorNoEntrypoint = 53;
+inline constexpr KPCError kErrorDiskIsCorrupted = 54;
+inline constexpr KPCError kErrorDisk = 55;
+inline constexpr KPCError kErrorInvalidData = 56;
+inline constexpr KPCError kErrorAsync = 57;
+inline constexpr KPCError kErrorNonBlocking = 58;
+inline constexpr KPCError kErrorIPC = 59;
+inline constexpr KPCError kErrorSign = 60;
+inline constexpr KPCError kErrorInvalidCreds = 61;
+inline constexpr KPCError kErrorCDTrayBroken = 62;
+inline constexpr KPCError kErrorUnrecoverableDisk = 63;
+inline constexpr KPCError kErrorFileLocked = 64;
+inline constexpr KPCError kErrorDiskIsTooTiny = 65;
+inline constexpr KPCError kErrorDmaExhausted = 66;
+inline constexpr KPCError kErrorOutOfBitMapMemory = 67;
+inline constexpr KPCError kErrorTimeout = 68;
+inline constexpr KPCError kErrorAccessDenied = 69;
+inline constexpr KPCError kErrorUnavailable = 70;
+/// Generic errors.
+inline constexpr KPCError kErrorUnimplemented = -1;
+
+/// @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;
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/KernelTaskScheduler.h b/src/kernel/KernelKit/KernelTaskScheduler.h
new file mode 100644
index 00000000..9bfce1d6
--- /dev/null
+++ b/src/kernel/KernelKit/KernelTaskScheduler.h
@@ -0,0 +1,47 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/// @file KernelTaskScheduler.h
+/// @brief Kernel Task Scheduler header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/CoreProcessScheduler.h>
+#include <KernelKit/LockDelegate.h>
+
+namespace Kernel {
+class KernelTaskHelper;
+
+typedef ProcessID KID;
+
+/// @brief Equivalent of USER_PROCESS, but for kernel tasks.
+/// @author Amlal
+class KERNEL_TASK final {
+ public:
+ Char Name[kSchedNameLen] = {"KERNEL_TASK"};
+ ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemKernel};
+ HAL::StackFramePtr StackFrame{nullptr};
+ UInt8* StackReserve{nullptr};
+ SizeT StackSize{kSchedMaxStackSz};
+ ProcessImage Image{};
+ /// @brief a KID is a Kernel ID, it is used to find a task running within
+ /// the kernel.
+ KID Kid{0};
+};
+
+/// @brief Equivalent of UserProcessHelper, but for kernel tasks.
+/// @author Amlal
+class KernelTaskHelper final {
+ public:
+ STATIC Bool Add(HAL::StackFramePtr frame_ptr, ProcessID new_kid);
+ STATIC Bool Remove(const KID kid);
+ STATIC Bool CanBeScheduled(const KERNEL_TASK& process);
+ STATIC ErrorOr<KID> TheCurrentKID();
+ STATIC SizeT StartScheduling();
+};
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/LockDelegate.h b/src/kernel/KernelKit/LockDelegate.h
new file mode 100644
index 00000000..8ff67f19
--- /dev/null
+++ b/src/kernel/KernelKit/LockDelegate.h
@@ -0,0 +1,58 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Atom.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+enum {
+ kLockInvalid = 0,
+ kLockDone = 200,
+ kLockTimedOut = 300,
+ kLockCount = 3,
+};
+
+/// @brief Lock condition pointer.
+typedef Boolean* LockPtr;
+
+/// @brief Locking delegate class, hangs until limit.
+/// @tparam N the amount of cycles to wait.
+template <SizeT N>
+class LockDelegate final {
+ public:
+ LockDelegate() = delete;
+
+ public:
+ explicit LockDelegate(LockPtr expr) {
+ auto spin = 0U;
+
+ while (spin < N) {
+ if (*expr) {
+ fLockStatus | kLockDone;
+ break;
+ }
+
+ ++spin;
+ }
+
+ if (spin > N) fLockStatus | kLockTimedOut;
+ }
+
+ ~LockDelegate() = default;
+
+ LockDelegate& operator=(const LockDelegate&) = delete;
+ LockDelegate(const LockDelegate&) = delete;
+
+ bool Done() { return fLockStatus[kLockDone] == kLockDone; }
+
+ bool HasTimedOut() { return fLockStatus[kLockTimedOut] != kLockTimedOut; }
+
+ private:
+ Atom<UInt> fLockStatus;
+};
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/MSDOS.h b/src/kernel/KernelKit/MSDOS.h
new file mode 100644
index 00000000..8c58b65b
--- /dev/null
+++ b/src/kernel/KernelKit/MSDOS.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: MSDOS.h
+ Purpose: MS-DOS header for Kernel.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+======================================== */
+
+#ifndef __MSDOS_EXEC__
+#define __MSDOS_EXEC__
+
+#include <KernelKit/PE.h>
+#include <NeKit/Defines.h>
+
+// Last Rev
+// Sat Feb 24 CET 2024
+
+#define kMagMz0 'M'
+#define kMagMz1 'Z'
+
+typedef Kernel::UInt32 DosWord;
+typedef Kernel::Long DosLong;
+
+typedef struct _DosHeader {
+ Kernel::UInt8 eMagic[2];
+ DosWord eMagLen;
+ DosWord ePagesCount;
+ DosWord eCrlc;
+ DosWord eCParHdr;
+ DosWord eMinAlloc;
+ DosWord eMaxAlloc;
+ DosWord eStackSeg;
+ DosWord eStackPtr;
+ DosWord eChksum;
+ DosWord eIp;
+ DosWord eCs;
+ DosWord eLfarlc;
+ DosWord eOvno;
+ DosWord eRes[4];
+ DosWord eOemid;
+ DosWord eOeminfo;
+ DosWord eRes2[10];
+ DosLong eLfanew;
+} DosHeader, *DosHeaderPtr;
+
+#endif /* ifndef __MSDOS_EXEC__ */
diff --git a/src/kernel/KernelKit/PCI/DMA.h b/src/kernel/KernelKit/PCI/DMA.h
new file mode 100644
index 00000000..80103dab
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/DMA.h
@@ -0,0 +1,75 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/PCI/Device.h>
+#include <NeKit/Array.h>
+#include <NeKit/OwnPtr.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+enum class DmaKind {
+ PCI = 10, // Bus mastering is required to be turned on. Basiaclly a request
+ // control system. 64-Bit access depends on the PAE bit and the device
+ // (if Double Address Cycle is available)
+ ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM.
+ Count = 2,
+ Invalid = 0,
+};
+
+class DMAWrapper final {
+ public:
+ explicit DMAWrapper() = delete;
+
+ public:
+ explicit DMAWrapper(nullPtr) = delete;
+ explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) : fAddress(Ptr), fKind(Kind) {}
+
+ public:
+ DMAWrapper& operator=(voidPtr Ptr);
+
+ public:
+ DMAWrapper& operator=(const DMAWrapper&) = default;
+ DMAWrapper(const DMAWrapper&) = default;
+
+ public:
+ ~DMAWrapper() = default;
+
+ template <class T>
+ T* operator->();
+
+ template <class T>
+ T* Get(UIntPtr off = 0);
+
+ public:
+ operator bool();
+ bool operator!();
+
+ public:
+ bool Write(UIntPtr& bit, const UInt32& offset);
+ UIntPtr Read(const UInt32& offset);
+ Boolean Check(UIntPtr offset) const;
+
+ public:
+ UIntPtr operator[](UIntPtr& offset);
+
+ private:
+ voidPtr fAddress{nullptr};
+ DmaKind fKind{DmaKind::Invalid};
+
+ private:
+ friend class DMAFactory;
+};
+
+class DMAFactory final {
+ public:
+ static OwnPtr<IOBuf<Char*>> Construct(OwnPtr<DMAWrapper>& dma);
+};
+} // namespace Kernel
+
+#include <KernelKit/PCI/DMA.inl>
diff --git a/src/kernel/KernelKit/PCI/DMA.inl b/src/kernel/KernelKit/PCI/DMA.inl
new file mode 100644
index 00000000..d81a632e
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/DMA.inl
@@ -0,0 +1,17 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+namespace Kernel {
+template <class T>
+T* DMAWrapper::operator->() {
+ return this->fAddress;
+}
+
+template <class T>
+T* DMAWrapper::Get(UIntPtr offset) {
+ return reinterpret_cast<T*>((UIntPtr) this->fAddress + offset);
+}
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/PCI/Database.h b/src/kernel/KernelKit/PCI/Database.h
new file mode 100644
index 00000000..463fde38
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Database.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+#pragma once
+
+#include <KernelKit/PCI/Device.h>
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+namespace Types {
+ // https://wiki.osdev.org/PCI
+ enum class PciDeviceKind : UChar {
+ MassStorageController = 0x1,
+ NetworkController = 0x2,
+ DisplayController = 0x3,
+ MultimediaController = 0x4,
+ MemoryController = 0x5,
+ Bridge = 0x6,
+ CommunicationController = 0x7,
+ GenericSystemPeripheral = 0x8,
+ InputDeviceController = 0x9,
+ DockingStation = 0xa,
+ Processor = 0xb,
+ SerialBusController = 0xc,
+ WirelessController = 0xd,
+ IntelligentController = 0xe,
+ SatelliteCommunicationsController = 0xf,
+ CoProcessor = 0x40,
+ Unassgined = 0xf,
+ Invalid = Unassgined,
+ };
+} // namespace Types
+} // namespace Kernel
+
+inline BOOL operator!=(const Kernel::Types::PciDeviceKind& lhs, Kernel::UChar rhs) {
+ return rhs != (Kernel::UChar) lhs;
+}
+
+inline BOOL operator==(const Kernel::Types::PciDeviceKind& lhs, Kernel::UChar rhs) {
+ return rhs == (Kernel::UChar) lhs;
+}
+
+inline BOOL operator!=(Kernel::UChar lhs, const Kernel::Types::PciDeviceKind& rhs) {
+ return lhs != (Kernel::UChar) rhs;
+}
+
+inline BOOL operator==(Kernel::UChar lhs, const Kernel::Types::PciDeviceKind& rhs) {
+ return lhs == (Kernel::UChar) rhs;
+} \ No newline at end of file
diff --git a/src/kernel/KernelKit/PCI/Device.h b/src/kernel/KernelKit/PCI/Device.h
new file mode 100644
index 00000000..f2111e40
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Device.h
@@ -0,0 +1,73 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel::PCI {
+enum class PciConfigKind : UShort {
+ ConfigAddress = 0xCF8,
+ ConfigData = 0xCFC,
+ CommandReg = 0x0004,
+ Invalid = 0xFFFF,
+};
+
+/// @brief Device interface class
+class Device final {
+ public:
+ Device() = default;
+
+ public:
+ Device(UShort bus, UShort device, UShort function, UInt32 bar);
+
+ Device& operator=(const Device&) = default;
+ Device(const Device&) = default;
+
+ ~Device();
+
+ public:
+ UInt Read(UInt bar, Size szData);
+ void Write(UInt bar, UIntPtr data, Size szData);
+
+ public:
+ operator bool();
+
+ public:
+ template <typename T>
+ UInt Read(UInt bar) {
+ static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported");
+ return Read(bar, sizeof(T));
+ }
+
+ template <typename T>
+ void Write(UInt bar, UIntPtr data) {
+ static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported");
+ Write(bar, data, sizeof(T));
+ }
+
+ public:
+ UShort DeviceId();
+ UShort VendorId();
+ UShort InterfaceId();
+ UChar Class();
+ UChar Subclass();
+ UChar ProgIf();
+ UChar HeaderType();
+ UIntPtr Bar(UInt32 bar_in);
+
+ public:
+ void EnableMmio();
+ void BecomeBusMaster(); // for PCI-DMA, PC-DMA does not need that.
+
+ UShort Vendor();
+
+ private:
+ UShort fBus;
+ UShort fDevice;
+ UShort fFunction;
+ UInt32 fBar;
+};
+} // namespace Kernel::PCI
diff --git a/src/kernel/KernelKit/PCI/Express.h b/src/kernel/KernelKit/PCI/Express.h
new file mode 100644
index 00000000..484739ec
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Express.h
@@ -0,0 +1,12 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/PCI/PCI.h>
+#include <NeKit/Defines.h>
+
+#define PCI_EXPRESS_BUS_COUNT (4096)
diff --git a/src/kernel/KernelKit/PCI/IO.h b/src/kernel/KernelKit/PCI/IO.h
new file mode 100644
index 00000000..2ab72269
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/IO.h
@@ -0,0 +1,63 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <ArchKit/ArchKit.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+template <SizeT Sz>
+class IOArray final {
+ public:
+ IOArray() = delete;
+
+ IOArray(nullPtr) = delete;
+
+ explicit IOArray(Array<UShort, Sz>& ports) : fPorts(ports) {}
+
+ ~IOArray() {}
+
+ IOArray& operator=(const IOArray&) = default;
+
+ IOArray(const IOArray&) = default;
+
+ operator bool() { return !fPorts.Empty(); }
+
+ public:
+ template <typename T>
+ T In(SizeT index);
+
+ template <typename T>
+ void Out(SizeT index, T value);
+
+ private:
+ Array<UShort, Sz> fPorts;
+};
+
+inline constexpr UInt16 kMaxPorts = 16;
+
+using IOArray16 = IOArray<kMaxPorts>;
+
+template <SizeT Sz>
+inline Array<UShort, Sz> make_ports(UShort base) {
+ Array<UShort, Sz> ports;
+
+ for (UShort i = 0; i < Sz; ++i) {
+ ports[i] = base + i;
+ }
+
+ return ports;
+}
+} // namespace Kernel
+
+#ifdef __NE_AMD64__
+#include <KernelKit/PCI/IOArray+AMD64.inl>
+#else
+#error Please provide platform specific code for the I/O
+#endif // ifdef __NE_AMD64__
diff --git a/src/kernel/KernelKit/PCI/IOArray+AMD64.inl b/src/kernel/KernelKit/PCI/IOArray+AMD64.inl
new file mode 100644
index 00000000..2b9125e0
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/IOArray+AMD64.inl
@@ -0,0 +1,49 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: IO-Impl-AMD64.h
+ Purpose: I/O for AMD64.
+
+ Revision History:
+
+ 30/01/24: Add file. (amlel)
+ 02/02/24: Update I/O routines. (amlel)
+
+======================================== */
+
+namespace Kernel {
+template <SizeT Sz>
+template <typename T>
+T IOArray<Sz>::In(SizeT index) {
+ switch (sizeof(T)) {
+#ifdef __NE_AMD64__
+ case 4:
+ return HAL::rt_in32(fPorts[index].Leak());
+ case 2:
+ return HAL::rt_in16(fPorts[index].Leak());
+ case 1:
+ return HAL::rt_in8(fPorts[index].Leak());
+#endif
+ default:
+ return 0xFFFF;
+ }
+}
+
+template <SizeT Sz>
+template <typename T>
+void IOArray<Sz>::Out(SizeT index, T value) {
+ switch (sizeof(T)) {
+#ifdef __NE_AMD64__
+ case 4:
+ HAL::rt_out32(fPorts[index].Leak(), value);
+ case 2:
+ HAL::rt_out16(fPorts[index].Leak(), value);
+ case 1:
+ HAL::rt_out8(fPorts[index].Leak(), value);
+#endif
+ default:
+ break;
+ }
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/PCI/Iterator.h b/src/kernel/KernelKit/PCI/Iterator.h
new file mode 100644
index 00000000..5926049b
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/Iterator.h
@@ -0,0 +1,41 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __PCI_ITERATOR_H__
+#define __PCI_ITERATOR_H__
+
+#include <KernelKit/PCI/Database.h>
+#include <KernelKit/PCI/Device.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+
+#define NE_BUS_COUNT (256)
+#define NE_DEVICE_COUNT (33)
+#define NE_FUNCTION_COUNT (8)
+
+namespace Kernel::PCI {
+class Iterator final {
+ public:
+ Iterator() = delete;
+
+ public:
+ explicit Iterator(const Types::PciDeviceKind deviceType, UInt32 bar);
+
+ Iterator& operator=(const Iterator&) = default;
+ Iterator(const Iterator&) = default;
+
+ ~Iterator();
+
+ public:
+ Ref<PCI::Device> operator[](const Size& sz);
+
+ private:
+ Array<PCI::Device, NE_BUS_COUNT> fDevices;
+};
+} // namespace Kernel::PCI
+
+#endif // __PCI_ITERATOR_H__
diff --git a/src/kernel/KernelKit/PCI/PCI.h b/src/kernel/KernelKit/PCI/PCI.h
new file mode 100644
index 00000000..f76270da
--- /dev/null
+++ b/src/kernel/KernelKit/PCI/PCI.h
@@ -0,0 +1,54 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define kPCIConfigAddressPort (0xCF8)
+#define kPCIConfigDataPort (0xCFC)
+
+#define kPCIDeviceCount (32)
+#define kPCIFuncCount (8)
+#define kPCIBusCount (256U)
+
+namespace Kernel::PCI {
+// model
+struct DeviceHeader {
+ UInt16 VendorId;
+ UInt16 DeviceId;
+ UInt8 Command;
+ UInt8 Status;
+ UInt8 RevisionId;
+ UInt8 ProgIf;
+ UInt8 SubClass;
+ UInt8 Class;
+ UInt8 CacheLineSz;
+ UInt8 LatencyTimer;
+ UInt8 HeaderType;
+ UInt8 Bist;
+ UInt8 Bus;
+ UInt8 Device;
+ UInt8 Function;
+};
+
+namespace Detail {
+ class BAR {
+ public:
+ UIntPtr BAR;
+ SizeT Size;
+ };
+} // namespace Detail
+
+class BAR {
+ public:
+ Detail::BAR BAR1;
+ Detail::BAR BAR2;
+ Detail::BAR BAR3;
+ Detail::BAR BAR4;
+ Detail::BAR BAR5;
+};
+} // namespace Kernel::PCI
diff --git a/src/kernel/KernelKit/PE.h b/src/kernel/KernelKit/PE.h
new file mode 100644
index 00000000..b4b4576e
--- /dev/null
+++ b/src/kernel/KernelKit/PE.h
@@ -0,0 +1,130 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: PE.h
+ Purpose: Portable Executable for Kernel.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+======================================== */
+
+#ifndef __KERNELKIT_INC_PE_H__
+#define __KERNELKIT_INC_PE_H__
+
+#include <NeKit/Defines.h>
+
+#define kPeSignature (0x00004550)
+
+#define kPeMagic32 (0x010b)
+#define kPeMagic64 (0x020b)
+
+#define kPeMachineAMD64 (0x8664)
+#define kPeMachineARM64 (0xaa64)
+
+typedef struct LDR_EXEC_HEADER final {
+ Kernel::UInt32 Signature;
+ Kernel::UInt16 Machine;
+ Kernel::UInt16 NumberOfSections;
+ Kernel::UInt32 TimeDateStamp;
+ Kernel::UInt32 PointerToSymbolTable;
+ Kernel::UInt32 NumberOfSymbols;
+ Kernel::UInt16 SizeOfOptionalHeader;
+ Kernel::UInt16 Characteristics;
+} LDR_EXEC_HEADER, *LDR_EXEC_HEADER_PTR;
+
+typedef struct LDR_OPTIONAL_HEADER final {
+ Kernel::UInt16 Magic; // 0x010b - PE32, 0x020b - PE32+ (64 bit)
+ Kernel::UInt8 MajorLinkerVersion;
+ Kernel::UInt8 MinorLinkerVersion;
+ Kernel::UInt32 SizeOfCode;
+ Kernel::UInt32 SizeOfInitializedData;
+ Kernel::UInt32 SizeOfUninitializedData;
+ Kernel::UInt32 AddressOfEntryPoint;
+ Kernel::UInt32 BaseOfCode;
+ Kernel::UInt64 ImageBase;
+ Kernel::UInt32 SectionAlignment;
+ Kernel::UInt32 FileAlignment;
+ Kernel::UInt16 MajorOperatingSystemVersion;
+ Kernel::UInt16 MinorOperatingSystemVersion;
+ Kernel::UInt16 MajorImageVersion;
+ Kernel::UInt16 MinorImageVersion;
+ Kernel::UInt16 MajorSubsystemVersion;
+ Kernel::UInt16 MinorSubsystemVersion;
+ Kernel::UInt32 Win32VersionValue;
+ Kernel::UInt32 SizeOfImage;
+ Kernel::UInt32 SizeOfHeaders;
+ Kernel::UInt32 CheckSum;
+ Kernel::UInt16 Subsystem;
+ Kernel::UInt16 DllCharacteristics;
+ Kernel::UInt32 SizeOfStackReserve;
+ Kernel::UInt32 SizeOfStackCommit;
+ Kernel::UInt32 SizeOfHeapReserve;
+ Kernel::UInt32 SizeOfHeapCommit;
+ Kernel::UInt32 LoaderFlags;
+ Kernel::UInt32 NumberOfRvaAndSizes;
+} LDR_OPTIONAL_HEADER, *LDR_OPTIONAL_HEADER_PTR;
+
+typedef struct LDR_SECTION_HEADER final {
+ Kernel::Char Name[8];
+ Kernel::UInt32 VirtualSize;
+ Kernel::UInt32 VirtualAddress;
+ Kernel::UInt32 SizeOfRawData;
+ Kernel::UInt32 PointerToRawData;
+ Kernel::UInt32 PointerToRelocations;
+ Kernel::UInt32 PointerToLineNumbers;
+ Kernel::UInt16 NumberOfRelocations;
+ Kernel::UInt16 NumberOfLinenumbers;
+ Kernel::UInt32 Characteristics;
+} LDR_SECTION_HEADER, *LDR_SECTION_HEADER_PTR;
+
+enum kExecDataDirParams {
+ kExecExport,
+ kExecImport,
+ kExecInvalid,
+ kExecCount,
+};
+
+typedef struct LDR_EXPORT_DIRECTORY {
+ Kernel::UInt32 Characteristics;
+ Kernel::UInt32 TimeDateStamp;
+ Kernel::UInt16 MajorVersion;
+ Kernel::UInt16 MinorVersion;
+ Kernel::UInt32 Name;
+ Kernel::UInt32 Base;
+ Kernel::UInt32 NumberOfFunctions;
+ Kernel::UInt32 NumberOfNames;
+ Kernel::UInt32 AddressOfFunctions; // export table rva
+ Kernel::UInt32 AddressOfNames;
+ Kernel::UInt32 AddressOfNameOrdinal; // ordinal table rva
+} LDR_EXPORT_DIRECTORY, *LDR_EXPORT_DIRECTORY_PTR;
+
+typedef struct LDR_IMPORT_DIRECTORY {
+ union {
+ Kernel::UInt32 Characteristics;
+ Kernel::UInt32 OriginalFirstThunk;
+ };
+ Kernel::UInt32 TimeDateStamp;
+ Kernel::UInt32 ForwarderChain;
+ Kernel::UInt32 NameRva;
+ Kernel::UInt32 ThunkTableRva;
+} LDR_IMPORT_DIRECTORY, *LDR_IMPORT_DIRECTORY_PTR;
+
+typedef struct LDR_DATA_DIRECTORY {
+ Kernel::UInt32 VirtualAddress;
+ Kernel::UInt32 Size;
+} LDR_DATA_DIRECTORY, *LDR_DATA_DIRECTORY_PTR;
+
+typedef struct LDR_IMAGE_HEADER {
+ LDR_EXEC_HEADER Header;
+ LDR_OPTIONAL_HEADER OptHdr;
+} LDR_IMAGE_HEADER, *LDR_IMAGE_HEADER_PTR;
+
+enum {
+ kUserSection = 0x00000020,
+ kPEResourceId = 0xFFaadd00,
+};
+
+#endif /* ifndef __KERNELKIT_INC_PE_H__ */
diff --git a/src/kernel/KernelKit/PE32CodeMgr.h b/src/kernel/KernelKit/PE32CodeMgr.h
new file mode 100644
index 00000000..52bc22b4
--- /dev/null
+++ b/src/kernel/KernelKit/PE32CodeMgr.h
@@ -0,0 +1,91 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: PE32CodeMgr.h
+ Purpose: PE32+ Code Mgr and Dylib mgr.
+
+ Revision History:
+
+ 12/02/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+////////////////////////////////////////////////////
+
+// LAST REV: Mon Feb 12 13:52:01 CET 2024
+
+////////////////////////////////////////////////////
+
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/ILoader.h>
+#include <KernelKit/PE.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KString.h>
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/ProcessScheduler.h>
+#endif
+
+#define kPeStackSizeSymbol "__NESizeOfReserveStack"
+#define kPeHeapSizeSymbol "__NESizeOfReserveHeap"
+#define kPeNameSymbol "__NEProgramName"
+
+#define kPeApplicationMime "application/vnd-portable-executable"
+
+#define kPeImageStart "__ImageStart"
+
+namespace Kernel {
+///
+/// \name PE32Loader
+/// \brief PE32+ loader class.
+///
+class PE32Loader : public ILoader {
+ private:
+ explicit PE32Loader() = delete;
+
+ public:
+ explicit PE32Loader(const VoidPtr blob);
+ explicit PE32Loader(const Char* path);
+ ~PE32Loader() override;
+
+ public:
+ NE_COPY_DEFAULT(PE32Loader)
+
+ public:
+ const Char* Path() override;
+ const Char* AsString() override;
+ const Char* MIME() override;
+
+ public:
+ ErrorOr<VoidPtr> FindStart() override;
+ ErrorOr<VoidPtr> FindSectionByName(const Char* name);
+ ErrorOr<VoidPtr> FindSymbol(const Char* name, Int32 kind) override;
+ ErrorOr<VoidPtr> GetBlob() override;
+
+ public:
+ bool IsLoaded() noexcept;
+
+ private:
+#ifdef __FSKIT_INCLUDES_NEFS__
+ OwnPtr<FileStream<Char, NeFileSystemMgr>> fFile;
+#elif defined(__FSKIT_INCLUDES_OPENHEFS__)
+ OwnPtr<FileStream<Char, HeFileSystemMgr>> fFile;
+#else
+ OwnPtr<FileStream<Char>> fFile;
+#endif // __FSKIT_INCLUDES_NEFS__
+
+ Ref<KString> fPath;
+ VoidPtr fCachedBlob;
+ BOOL fBad;
+};
+
+enum { kPEPlatformInvalid, kPEPlatformAMD64 = 100, kPEPlatformARM64 };
+enum { kPETypeInvalid, kPETypeText = 100, kPETypeData, kPETypeBSS };
+
+typedef LDR_SECTION_HEADER PE_SECTION_INFO;
+
+ProcessID rtl_create_user_process(PE32Loader& exec, const Int32& process_kind) noexcept;
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/PEF.h b/src/kernel/KernelKit/PEF.h
new file mode 100644
index 00000000..94284c98
--- /dev/null
+++ b/src/kernel/KernelKit/PEF.h
@@ -0,0 +1,117 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: PEF.h
+ Purpose: Preferred Executable Format for Kernel.
+
+ Revision History:
+
+ ?/?/23: Added file (amlel)
+
+======================================== */
+
+#ifndef __KERNELKIT_PEF_H__
+#define __KERNELKIT_PEF_H__
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/ILoader.h>
+#include <NeKit/Defines.h>
+
+#define kPefMagic "Open"
+#define kPefMagicFat "nepO"
+
+#define kPefMagicLen (5)
+
+#define kPefVersion (0x0500)
+#define kPefNameLen (256U)
+
+/* not mandatory, only for non fork based filesystems. */
+#define kPefExt ".exec"
+#define kPefDylibExt ".dylib"
+#define kPefLibExt ".lib"
+#define kPefObjectExt ".obj"
+#define kPefDebugExt ".dbg"
+#define kPefDriverExt ".sys"
+
+// Kernel System Binary Interface.
+#define kPefAbi (0x5046)
+
+#define kPefBaseOrigin (0x40000000)
+
+#define kPefStart "__ImageStart"
+#define kPefMainSymbol "_NeMain"
+
+#define kPefForkKind kPefMagic
+#define kPefForkKindFAT kPefMagicFat
+
+namespace Kernel {
+enum {
+ kPefArchIntel86S,
+ kPefArchAMD64,
+ kPefArchRISCV,
+ kPefArch64x0, /* 64x0. ISA */
+ kPefArch32x0, /* 32x0. ISA */
+ kPefArchPowerPC,
+ kPefArchARM64,
+ kPefArchCount = (kPefArchARM64 - kPefArchIntel86S) + 1,
+ kPefArchInvalid = 0xFF,
+};
+
+enum {
+ kPefSubArchGeneric = 0,
+ kPefSubArchAMD = 200,
+ kPefSubArchIntel,
+ kPefSubArchARM,
+ kPefSubArchIBM,
+};
+
+enum {
+ kPefKindInvalid = 0,
+ kPefKindExec = 1, /* .exec */
+ kPefKindDylib = 2, /* .dylib */
+ kPefKindObject = 4, /* .obj */
+ kPefKindDebug = 5, /* .dbg */
+ kPefKindDriver = 6,
+ kPefKindCount,
+};
+
+typedef struct PEFContainer final {
+ Char Magic[kPefMagicLen];
+ UInt32 Linker;
+ UInt32 Version;
+ UInt32 Kind;
+ UInt32 Abi;
+ UInt32 Cpu;
+ UInt32 SubCpu; /* Cpu specific information */
+ UIntPtr Start;
+ SizeT HdrSz; /* Size of header */
+ SizeT Count; /* container header count */
+ UInt32 Checksum;
+} PACKED PEFContainer;
+
+/* First PEFCommandHeader starts after PEFContainer */
+
+typedef struct PEFCommandHeader final {
+ Char Name[kPefNameLen]; /* container name */
+ UInt32 Cpu; /* container cpu */
+ UInt32 SubCpu; /* container sub-cpu */
+ UInt32 Flags; /* container flags */
+ UInt16 Kind; /* container kind */
+ UIntPtr Offset; /* content offset */
+ SizeT OffsetSize; /* offset size (physical size inside the file) */
+ UIntPtr VMAddress; /* Virtual Address */
+ SizeT VMSize; /* Virtual Size */
+} PACKED PEFCommandHeader;
+
+enum {
+ kPefInvalid = 0x0,
+ kPefCode = 0xC,
+ kPefData = 0xD,
+ kPefZero = 0xE,
+ kPefLinkerID = 0x1,
+ kPefCount = 4,
+};
+} // namespace Kernel
+
+#endif /* ifndef __KERNELKIT_PEF_H__ */
diff --git a/src/kernel/KernelKit/PEFCodeMgr.h b/src/kernel/KernelKit/PEFCodeMgr.h
new file mode 100644
index 00000000..41b135e0
--- /dev/null
+++ b/src/kernel/KernelKit/PEFCodeMgr.h
@@ -0,0 +1,75 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef _INC_CODE_MANAGER_PEF_H_
+#define _INC_CODE_MANAGER_PEF_H_
+
+/// @file PEFCodeMgr.h
+/// @brief PEF Code Manager header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/PEF.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KString.h>
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/ProcessScheduler.h>
+#endif
+
+#define kPefApplicationMime "application/vnd-nekernel-executable"
+
+namespace Kernel {
+///
+/// \name PEFLoader
+/// \brief PEF loader class.
+///
+class PEFLoader : public ILoader {
+ private:
+ explicit PEFLoader() = delete;
+
+ public:
+ explicit PEFLoader(const VoidPtr blob);
+ explicit PEFLoader(const Char* path);
+ ~PEFLoader() override;
+
+ public:
+ NE_COPY_DEFAULT(PEFLoader)
+
+ public:
+ const Char* Path() override;
+ const Char* AsString() override;
+ const Char* MIME() override;
+
+ public:
+ ErrorOr<VoidPtr> FindStart() override;
+ ErrorOr<VoidPtr> FindSymbol(const Char* name, Int32 kind) override;
+ ErrorOr<VoidPtr> GetBlob() override;
+
+ public:
+ bool IsLoaded() noexcept;
+
+ private:
+#ifdef __FSKIT_INCLUDES_NEFS__
+ OwnPtr<FileStream<Char, NeFileSystemMgr>> fFile;
+#elif defined(__FSKIT_INCLUDES_OPENHEFS__)
+ OwnPtr<FileStream<Char, HeFileSystemMgr>> fFile;
+#else
+ OwnPtr<FileStream<Char>> fFile;
+#endif // __FSKIT_INCLUDES_NEFS__
+
+ Ref<KString> fPath;
+ VoidPtr fCachedBlob;
+ BOOL fFatBinary{};
+ BOOL fBad{};
+};
+
+namespace Utils {
+ ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& procKind) noexcept;
+} // namespace Utils
+} // namespace Kernel
+
+#endif // ifndef _INC_CODE_MANAGER_PEF_H_
diff --git a/src/kernel/KernelKit/ProcessScheduler.h b/src/kernel/KernelKit/ProcessScheduler.h
new file mode 100644
index 00000000..7414e4fe
--- /dev/null
+++ b/src/kernel/KernelKit/ProcessScheduler.h
@@ -0,0 +1,18 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/KernelTaskScheduler.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+#ifdef __NEOSKRNL__
+namespace Kernel {
+inline UserProcessTeam kLowUserTeam;
+inline UserProcessTeam kHighUserTeam;
+inline UserProcessTeam kMidUserTeam;
+} // namespace Kernel
+#endif \ No newline at end of file
diff --git a/src/kernel/KernelKit/Semaphore.h b/src/kernel/KernelKit/Semaphore.h
new file mode 100644
index 00000000..831774a5
--- /dev/null
+++ b/src/kernel/KernelKit/Semaphore.h
@@ -0,0 +1,110 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/// @author Amlal El Mahrouss
+/// @file Semaphore.h
+/// @brief Semaphore structure and functions for synchronization in the kernel.
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/Defines.h>
+
+#define kSemaphoreOwnerIndex (0U)
+#define kSemaphoreCountIndex (1U)
+
+#define kSemaphoreCount (2U)
+
+#define kSemaphoreIncrementOwner(sem) (sem[kSemaphoreOwnerIndex]++)
+#define kSemaphoreDecrementOwner(sem) (sem[kSemaphoreOwnerIndex]--)
+
+namespace Kernel {
+/// @brief Semaphore structure used for synchronization.
+typedef UInt64 SemaphoreArr[kSemaphoreCount];
+
+/// @brief Checks if the semaphore is valid.
+inline BOOL rtl_sem_is_valid(const SemaphoreArr& sem, UInt64 owner = 0) {
+ return sem[kSemaphoreOwnerIndex] == owner && sem[kSemaphoreCountIndex] > 0;
+}
+
+/// @brief Releases the semaphore, resetting its owner and count.
+/// @param sem
+/// @return
+inline BOOL rtl_sem_release(SemaphoreArr& sem) {
+ sem[kSemaphoreOwnerIndex] = 0;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Initializes the semaphore with an owner and a count of zero.
+/// @param sem the semaphore array to use.
+/// @param owner the owner to set, could be anything identifitable.
+/// @return
+inline BOOL rtl_sem_acquire(SemaphoreArr& sem, UInt64 owner) {
+ if (!owner) {
+ err_global_get() = kErrorInvalidData;
+ return FALSE; // Invalid owner
+ }
+
+ sem[kSemaphoreOwnerIndex] = owner;
+ sem[kSemaphoreCountIndex] = 0;
+
+ return TRUE;
+}
+
+/// @brief Waits for the semaphore to be available, blocking until it is.
+/// @param sem
+/// @param timeout
+/// @param condition condition pointer.
+/// @return
+inline BOOL rtl_sem_wait(SemaphoreArr& sem, UInt64 owner, UInt64 timeout,
+ BOOL* condition = nullptr) {
+ if (!rtl_sem_is_valid(sem, owner)) {
+ return FALSE;
+ }
+
+ if (timeout <= 0) {
+ err_global_get() = kErrorTimeout;
+
+ return FALSE;
+ }
+
+ if (!condition || *condition) {
+ if (sem[kSemaphoreCountIndex] == 0) {
+ err_global_get() = kErrorUnavailable;
+ return FALSE;
+ }
+
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+
+ HardwareTimer timer(timeout);
+ BOOL ret = timer.Wait();
+
+ if (ret) {
+ if (!condition || *condition) {
+ if (sem[kSemaphoreCountIndex] == 0) {
+ err_global_get() = kErrorUnavailable;
+ return FALSE;
+ }
+
+ err_global_get() = kErrorSuccess;
+ sem[kSemaphoreCountIndex]--;
+
+ return TRUE;
+ }
+ }
+
+ err_global_get() = kErrorTimeout;
+
+ return FALSE; // Failed to acquire semaphore
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/ThreadLocalStorage.h b/src/kernel/KernelKit/ThreadLocalStorage.h
new file mode 100644
index 00000000..205d6df9
--- /dev/null
+++ b/src/kernel/KernelKit/ThreadLocalStorage.h
@@ -0,0 +1,68 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef KERNELKIT_TLS_H
+#define KERNELKIT_TLS_H
+
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+
+///! @brief Thread Local Storage for NeKernel.
+
+#define kCookieMag0Idx (0U)
+#define kCookieMag1Idx (1U)
+#define kCookieMag2Idx (2U)
+
+#define kCookieMag0 'N'
+#define kCookieMag1 'K'
+#define kCookieMag2 'O'
+
+#define kCookieMagLen (3U)
+
+struct THREAD_INFORMATION_BLOCK;
+
+/// @brief Thread Information Block.
+/// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64)
+struct PACKED THREAD_INFORMATION_BLOCK final {
+ Kernel::Char Cookie[kCookieMagLen]{0}; //! Thread Magic Number.
+ Kernel::VoidPtr UserData{nullptr}; //! Thread Information Record (User defined canary structure)
+};
+
+///! @brief Cookie Sanity check.
+Kernel::Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* the_tib);
+
+///! @brief new ptr syscall.
+template <typename T>
+T* tls_new_ptr(void) noexcept;
+
+///! @brief delete ptr syscall.
+template <typename T>
+Kernel::Boolean tls_delete_ptr(T* ptr) noexcept;
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept;
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept;
+
+template <typename T, typename... Args>
+T* tls_new_class(Args&&... args);
+
+/// @brief TLS install TIB and PIB. (syscall)
+EXTERN_C Kernel::Void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB);
+
+/// @brief TLS check (syscall)
+EXTERN_C Kernel::Bool tls_check_syscall_impl(Kernel::VoidPtr TIB) noexcept;
+
+#include <KernelKit/ThreadLocalStorage.inl>
+
+// last rev 7/7/24
+
+#endif /* ifndef KERNELKIT_TLS_H */
diff --git a/src/kernel/KernelKit/ThreadLocalStorage.inl b/src/kernel/KernelKit/ThreadLocalStorage.inl
new file mode 100644
index 00000000..66a3d282
--- /dev/null
+++ b/src/kernel/KernelKit/ThreadLocalStorage.inl
@@ -0,0 +1,89 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+//! @file ThreadLocalStorage.inl
+//! @brief Allocate resources from the process's heap storage.
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/ProcessScheduler.h>
+#endif
+
+template <typename T>
+inline T* tls_new_ptr(void) noexcept {
+ using namespace Kernel;
+
+ auto ref_process = UserProcessScheduler::The().TheCurrentProcess();
+ MUST_PASS(ref_process);
+
+ auto pointer = ref_process.Leak().New(sizeof(T));
+
+ if (pointer.Error()) return nullptr;
+
+ return reinterpret_cast<T*>(pointer.Leak().Leak());
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(T* obj) noexcept {
+ using namespace Kernel;
+
+ if (!obj) return No;
+
+ auto ref_process = UserProcessScheduler::The().TheCurrentProcess();
+ MUST_PASS(ref_process);
+
+ ErrorOr<T*> obj_wrapped{obj};
+
+ return ref_process.Leak().Delete(obj_wrapped);
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept {
+ return tls_delete_ptr(obj.Leak());
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept {
+ return tls_delete_ptr(obj->Leak());
+}
+
+/// @brief Allocate a C++ class, and then call the constructor of it.
+/// @tparam T class type.
+/// @tparam ...Args varg class type.
+/// @param args arguments list.
+/// @return Class instance.
+template <typename T, typename... Args>
+T* tls_new_class(Args&&... args) {
+ using namespace Kernel;
+
+ T* obj = tls_new_ptr<T>();
+
+ if (obj) {
+ *obj = T(forward(args)...);
+ return obj;
+ }
+
+ return nullptr;
+}
+
+/// @brief Delete a C++ class (call constructor first.)
+/// @tparam T
+/// @param obj
+/// @return
+template <typename T>
+inline Kernel::Bool tls_delete_class(T* obj) {
+ using namespace Kernel;
+
+ if (!obj) return No;
+
+ obj->~T();
+ return tls_delete_ptr(obj);
+}
diff --git a/src/kernel/KernelKit/Timer.h b/src/kernel/KernelKit/Timer.h
new file mode 100644
index 00000000..46db5671
--- /dev/null
+++ b/src/kernel/KernelKit/Timer.h
@@ -0,0 +1,75 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/KPC.h>
+
+namespace Kernel {
+class SoftwareTimer;
+class TimerInterface;
+
+inline constexpr Int16 kTimeUnit = 1000;
+
+class TimerInterface {
+ public:
+ /// @brief Default constructor
+ explicit TimerInterface() = default;
+ virtual ~TimerInterface() = default;
+
+ public:
+ NE_COPY_DEFAULT(TimerInterface)
+
+ public:
+ virtual BOOL Wait() noexcept;
+};
+
+class SoftwareTimer final : public TimerInterface {
+ public:
+ explicit SoftwareTimer(Int64 seconds);
+ ~SoftwareTimer() override;
+
+ public:
+ NE_COPY_DEFAULT(SoftwareTimer)
+
+ public:
+ BOOL Wait() noexcept override;
+
+ private:
+ UIntPtr* fDigitalTimer{nullptr};
+ Int64 fWaitFor{0};
+};
+
+class HardwareTimer final : public TimerInterface {
+ public:
+ explicit HardwareTimer(UInt64 seconds);
+ ~HardwareTimer() override;
+
+ public:
+ NE_COPY_DEFAULT(HardwareTimer)
+
+ public:
+ BOOL Wait() noexcept override;
+
+ private:
+ volatile UInt8* fDigitalTimer{nullptr};
+ Int64 fWaitFor{0};
+};
+
+inline UInt64 rtl_microseconds(UInt64 time) {
+ if (time < 1) return 0;
+
+ // TODO: nanoseconds maybe?
+ return time / kTimeUnit;
+}
+
+inline UInt64 rtl_milliseconds(UInt64 time) {
+ if (time < 1) return 0;
+
+ return time;
+}
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/TraceSrv.h b/src/kernel/KernelKit/TraceSrv.h
new file mode 100644
index 00000000..df188ea2
--- /dev/null
+++ b/src/kernel/KernelKit/TraceSrv.h
@@ -0,0 +1,22 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ NeKernel is licensed under the Apache License 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+
+namespace Kernel {
+namespace Detail {
+ inline constexpr auto kDebugCmdLen = 256U;
+ inline constexpr auto kDebugPort = 51820;
+ inline constexpr auto kDebugMagic = "NE1.0.0;";
+ inline constexpr auto kDebugVersion = 0x0100;
+ inline constexpr auto kDebugDelim = ';';
+ inline constexpr auto kDebugEnd = '\r';
+ typedef UInt64 dk_socket_type;
+} // namespace Detail
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/KernelKit/UserMgr.h b/src/kernel/KernelKit/UserMgr.h
new file mode 100644
index 00000000..3ce6254d
--- /dev/null
+++ b/src/kernel/KernelKit/UserMgr.h
@@ -0,0 +1,95 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_USER_H
+#define INC_USER_H
+
+/* ========================================
+
+ Revision History:
+
+ 04/03/25: Set users directory as /libSystem/ instead of /usr/
+
+ ======================================== */
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+
+///! We got the MGMT, STD (%s format) and GUEST users,
+///! all are used to make authorized operations.
+#define kMgmtUser "NEKERNEL/MGMT/%s"
+#define kGuestUser "NEKERNEL/GUEST/%s"
+#define kStdUser "NEKERNEL/STD/%s"
+
+#define kUsersDir "/users/"
+
+#define kMaxUserNameLen (256U)
+#define kMaxUserTokenLen (256U)
+
+namespace Kernel {
+class User;
+
+enum class UserRingKind : Int32 {
+ kRingInvalid = 0,
+ kRingStdUser = 444,
+ kRingSuperUser = 666,
+ kRingGuestUser = 777,
+ kRingCount = 3,
+};
+
+typedef Char* UserPublicKey;
+typedef Char UserPublicKeyType;
+
+/// @brief System User class.
+class User final {
+ public:
+ User() = delete;
+
+ User(const Int32& sel, const Char* username);
+ User(const UserRingKind& kind, const Char* username);
+
+ ~User();
+
+ public:
+ NE_COPY_DEFAULT(User)
+
+ public:
+ bool operator==(const User& lhs);
+ bool operator!=(const User& lhs);
+
+ public:
+ /// @brief Get software ring
+ const UserRingKind& Ring() noexcept;
+
+ /// @brief Get user name
+ Char* Name() noexcept;
+
+ /// @brief Is he a standard user?
+ Bool IsStdUser() noexcept;
+
+ /// @brief Is she a super user?
+ Bool IsSuperUser() noexcept;
+
+ /// @brief Saves a password from the public key.
+ Bool Save(const UserPublicKey password) noexcept;
+
+ /// @brief Checks if a password matches the **password**.
+ /// @param password the password to check.
+ Bool Login(const UserPublicKey password) noexcept;
+
+ private:
+ UserRingKind mUserRing{UserRingKind::kRingStdUser};
+ Char mUserName[kMaxUserNameLen] = {0};
+ UInt64 mUserFNV{0UL};
+};
+
+inline User* kCurrentUser = nullptr;
+inline User* kRootUser = nullptr;
+} // namespace Kernel
+
+#endif /* ifndef INC_USER_H */
diff --git a/src/kernel/KernelKit/UserProcessScheduler.h b/src/kernel/KernelKit/UserProcessScheduler.h
new file mode 100644
index 00000000..b2ab7dc2
--- /dev/null
+++ b/src/kernel/KernelKit/UserProcessScheduler.h
@@ -0,0 +1,243 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#define INC_PROCESS_SCHEDULER_H
+
+/// @file UserProcessScheduler.h
+/// @brief User Process Scheduler header file.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/CoreProcessScheduler.h>
+#include <KernelKit/LockDelegate.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/MutableArray.h>
+
+////////////////////////////////////////////////////
+// Last revision date is: Fri Mar 28 2025 //
+////////////////////////////////////////////////////
+
+namespace Kernel {
+//! @brief Forward declarations.
+
+class IDylibObject;
+class UserProcessScheduler;
+class UserProcessHelper;
+
+/***********************************************************************************/
+/// @name USER_PROCESS
+/// @brief USER_PROCESS class, holds information about the running process/thread.
+/***********************************************************************************/
+class USER_PROCESS final {
+ public:
+ explicit USER_PROCESS();
+ ~USER_PROCESS();
+
+ public:
+ NE_COPY_DEFAULT(USER_PROCESS)
+
+ public:
+ Char Name[kSchedNameLen] = {"USER_PROCESS"};
+ ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemUser};
+ User* Owner{nullptr};
+ HAL::StackFramePtr StackFrame{nullptr};
+ AffinityKind Affinity{AffinityKind::kStandard};
+ ProcessStatusKind Status{ProcessStatusKind::kKilled};
+ UInt8 StackReserve[kSchedMaxStackSz];
+ ProcessImage Image{};
+ SizeT StackSize{kSchedMaxStackSz};
+ IDylibObject* DylibDelegate{nullptr};
+ SizeT MemoryCursor{0UL};
+ SizeT MemoryLimit{kSchedMaxMemoryLimit};
+ SizeT UsedMemory{0UL};
+
+ struct USER_PROCESS_SIGNAL final {
+ UIntPtr SignalArg{0};
+ ProcessStatusKind Status{ProcessStatusKind::kKilled};
+ UIntPtr SignalID{0};
+ };
+
+ USER_PROCESS_SIGNAL Signal;
+ PROCESS_FILE_TREE<VoidPtr>* FileTree{nullptr};
+ PROCESS_HEAP_TREE<VoidPtr>* HeapTree{nullptr};
+ UserProcessTeam* ParentTeam;
+
+ VoidPtr VMRegister{0UL};
+
+ enum {
+ kInvalidExecutableKind,
+ kExecutableKind,
+ kExecutableDylibKind,
+ kExecutableKindCount,
+ };
+
+ ProcessTime PTime{0}; //! @brief Process allocated tine.
+ ProcessTime RTime{0}; //! @brief Process run time.
+ ProcessTime UTime{0}; //! #brief Process used time.
+
+ ProcessID ProcessId{kSchedInvalidPID};
+ Int32 Kind{kExecutableKind};
+
+ public:
+ /***********************************************************************************/
+ //! @brief boolean operator, check status.
+ /***********************************************************************************/
+ explicit operator bool();
+
+ /***********************************************************************************/
+ ///! @brief Crashes the app, exits with code ~0.
+ /***********************************************************************************/
+ Void Crash();
+
+ /***********************************************************************************/
+ ///! @brief Spawns a dynamic library handle if dylib.
+ /***********************************************************************************/
+ Bool InitDylib();
+
+ /***********************************************************************************/
+ ///! @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.
+ /***********************************************************************************/
+ KPCError& 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.
+ /***********************************************************************************/
+ KPCError& GetLocalCode() noexcept;
+
+ const User* GetOwner() noexcept;
+ const ProcessStatusKind& GetStatus() noexcept;
+ const AffinityKind& GetAffinity() noexcept;
+
+ private:
+ KPCError LastExitCode{0};
+ KPCError LocalCode{0};
+
+ friend UserProcessScheduler;
+ friend UserProcessHelper;
+};
+
+typedef Array<USER_PROCESS, kSchedProcessLimitPerTeam> USER_PROCESS_ARRAY;
+typedef Ref<USER_PROCESS> USER_PROCESS_REF;
+
+/// \brief Processs Team (contains multiple processes inside it.)
+/// Equivalent to a process batch
+class UserProcessTeam final {
+ public:
+ explicit UserProcessTeam();
+ ~UserProcessTeam() = default;
+
+ NE_COPY_DEFAULT(UserProcessTeam)
+
+ Array<USER_PROCESS, kSchedProcessLimitPerTeam>& AsArray();
+ Ref<USER_PROCESS>& AsRef();
+ ProcessID& Id() noexcept;
+
+ public:
+ USER_PROCESS_ARRAY mProcessList;
+ USER_PROCESS_REF mCurrentProcess;
+ ProcessID mTeamId{0};
+ ProcessID mProcessCur{0};
+};
+
+/***********************************************************************************/
+/// @brief USER_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_DELETE(UserProcessScheduler)
+ NE_MOVE_DELETE(UserProcessScheduler)
+
+ public:
+ explicit operator bool();
+ bool operator!();
+
+ public:
+ UserProcessTeam& TheCurrentTeam();
+ BOOL SwitchTeam(UserProcessTeam& team);
+
+ 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:
+ USER_PROCESS_REF& TheCurrentProcess();
+ SizeT Run() noexcept;
+
+ public:
+ STATIC UserProcessScheduler& The();
+
+ private:
+ UserProcessTeam mTeam{};
+};
+
+/***********************************************************************************/
+/**
+ * \brief USER_PROCESS helper class, which contains needed utilities for the scheduler.
+ */
+/***********************************************************************************/
+
+class UserProcessHelper final {
+ public:
+ STATIC Bool Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid);
+ STATIC Bool CanBeScheduled(const USER_PROCESS& process);
+ STATIC ErrorOr<ProcessID> TheCurrentPID();
+ STATIC SizeT StartScheduling();
+};
+} // namespace Kernel
+
+#include <KernelKit/ThreadLocalStorage.h>
+#include <KernelKit/UserProcessScheduler.inl>
+
+////////////////////////////////////////////////////
+// END
+////////////////////////////////////////////////////
+
+#endif /* ifndef INC_PROCESS_SCHEDULER_H */
diff --git a/src/kernel/KernelKit/UserProcessScheduler.inl b/src/kernel/KernelKit/UserProcessScheduler.inl
new file mode 100644
index 00000000..3d3659d6
--- /dev/null
+++ b/src/kernel/KernelKit/UserProcessScheduler.inl
@@ -0,0 +1,64 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ FILE: UserProcessScheduler.inl
+ PURPOSE: Low level/Ring-3 process scheduler.
+
+======================================== */
+
+/// @brief USER_PROCESS inline definitions.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+/// @date Tue Apr 22 22:01:07 CEST 2025
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/UserProcessScheduler.h>
+#endif // INC_PROCESS_SCHEDULER_H
+
+namespace Kernel {
+/***********************************************************************************/
+/** @brief Free pointer/file from usage. */
+/***********************************************************************************/
+
+template <typename T>
+BOOL USER_PROCESS::Delete(ErrorOr<T*> ptr) {
+ if (!ptr) return No;
+
+ if (!this->HeapTree) {
+ kout << "USER_PROCESS's heap is empty.\r";
+ return No;
+ }
+
+ PROCESS_HEAP_TREE<VoidPtr>* entry = this->HeapTree;
+
+ while (entry != nullptr) {
+ if (entry->Entry == ptr.Leak().Leak()) {
+ this->UsedMemory -= entry->EntrySize;
+
+#ifdef __NE_AMD64__
+ auto pd = hal_read_cr3();
+
+ hal_write_cr3(this->VMRegister);
+
+ auto ret = mm_free_ptr(entry->Entry);
+
+ hal_write_cr3(pd);
+
+ return ret == kErrorSuccess;
+#else
+ Bool ret = mm_free_ptr(ptr.Leak().Leak());
+
+ return ret == kErrorSuccess;
+#endif
+ }
+
+ entry = entry->Next;
+ }
+
+ kout << "USER_PROCESS: Trying to free a pointer which doesn't exist.\r";
+
+ this->Crash();
+
+ return No;
+}
+} // namespace Kernel
diff --git a/src/kernel/KernelKit/XCOFF.h b/src/kernel/KernelKit/XCOFF.h
new file mode 100644
index 00000000..cbee6100
--- /dev/null
+++ b/src/kernel/KernelKit/XCOFF.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: XCOFF.h
+ Purpose: XCOFF for Kernel.
+
+ Revision History:
+
+ 04/07/24: Added file (amlel)
+
+======================================== */
+
+#ifndef INC_XOCFF_H
+#define INC_XOCFF_H
+
+#include <NeKit/Defines.h>
+
+#define kXCOFF64Magic (0x01F7)
+#define kXCOFF64ForkNameLen (256U)
+
+#define kXCOFFRelFlg (0x0001)
+#define kXCOFFExecutable (0x0002)
+#define kXCOFFLnno (0x0004)
+#define kXCOFFLSyms (0x0008)
+
+struct XCOFF_FILE_HEADER;
+struct XCOFF_FORK_HEADER;
+
+/// @brief XCoff file header, meant for POWER apps.
+typedef struct XCOFF_FILE_HEADER {
+ Kernel::UInt16 fMagic;
+ Kernel::UInt16 fTarget;
+ Kernel::UInt16 fNumSecs;
+ Kernel::UInt32 fTimeDat;
+ Kernel::UIntPtr fSymPtr;
+ Kernel::UInt32 fNumSyms;
+ Kernel::UInt16 fOptHdr; // ?: Number of bytes in optional header
+} XCOFF_FILE_HEADER, XCOFF_FILE_HEADER32, XCOFF_FILE_HEADER64;
+
+/// @brief This the executable's manifest fork, designed for NeFS.
+/// @param fPropertiesXMLFork The XML fork of the executable.
+/// @param fDynamicLoaderFork The DYLD fork metadata.
+/// @param fCodeSignFork Executable's certificate contained in a fork.
+typedef struct XCOFF_FORK_HEADER {
+ Kernel::Char fPropertiesXMLFork[kXCOFF64ForkNameLen];
+ Kernel::Char fDynamicLoaderFork[kXCOFF64ForkNameLen];
+ Kernel::Char fCodeSignFork[kXCOFF64ForkNameLen];
+} XCOFF_FORK_HEADER;
+
+#endif // ifndef INC_XOCFF_H
diff --git a/src/kernel/KernelKit/ZXD.h b/src/kernel/KernelKit/ZXD.h
new file mode 100644
index 00000000..a4b07bfa
--- /dev/null
+++ b/src/kernel/KernelKit/ZXD.h
@@ -0,0 +1,53 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define kZXDMagicNumber (0x2010AF)
+#define kZXDVersion (0x0001)
+
+namespace Kernel {
+struct ZXD_EXEC_HEADER;
+struct ZXD_STUB_HEADER;
+
+enum ZXD_FLAGS {
+ kZXDFlagsInvalid,
+ kZXDFlagsDriver,
+ kZXDFlagsCount,
+};
+
+/// @brief ZXD executable header
+/// @details This header is used to identify ZXD executable files.
+struct PACKED ZXD_EXEC_HEADER final {
+ UInt32 fMagic;
+ UInt32 fVersion;
+ UInt32 fFlags;
+ UInt32 fHdrSize;
+ UInt32 fCRC32;
+ UInt32 fAssigneeSignature;
+ UInt32 fIssuerSingature;
+ UIntPtr fExecOffset;
+ SizeT fExecSize;
+ UIntPtr fStubOffset;
+ SizeT fStubSize;
+ SizeT fStubAlign;
+ SizeT fStubCount;
+};
+
+/// @brief ZXD stub header
+/// @details This header is used to identify ZXD stub files. It contains the size of the stub, the
+/// offset of the stub, and the CRC32 checksum of the stub.
+struct PACKED ZXD_STUB_HEADER final {
+ UInt32 fStubSize;
+ UInt32 fStubOffset;
+ UInt32 fStubCRC32;
+};
+
+using ZXD_EXEC_HEADER_PTR = ZXD_EXEC_HEADER*;
+using ZXD_STUB_HEADER_PTR = ZXD_STUB_HEADER*;
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Array.h b/src/kernel/NeKit/Array.h
new file mode 100644
index 00000000..5b8371db
--- /dev/null
+++ b/src/kernel/NeKit/Array.h
@@ -0,0 +1,46 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+
+namespace Kernel {
+template <typename T, SizeT N>
+class Array final {
+ public:
+ explicit Array() = default;
+ ~Array() = default;
+
+ Array& operator=(const Array&) = default;
+ Array(const Array&) = default;
+
+ T& operator[](SizeT at) { return fArray[at]; }
+
+ Boolean Empty() { return this->Count() > 0; }
+
+ SizeT Capacity() { return N; }
+
+ SizeT Count() {
+ const static SizeT kArrCnt = N;
+ return kArrCnt; // avoid constexpr error.
+ }
+
+ const T* CData() { return fArray; }
+
+ operator bool() { return !Empty(); }
+
+ private:
+ T fArray[N];
+};
+
+template <typename ValueType>
+auto make_list(ValueType val) {
+ return Array<ValueType, ARRAY_SIZE(val)>{val};
+}
+} // namespace Kernel
diff --git a/src/kernel/NeKit/ArrayList.h b/src/kernel/NeKit/ArrayList.h
new file mode 100644
index 00000000..54613b67
--- /dev/null
+++ b/src/kernel/NeKit/ArrayList.h
@@ -0,0 +1,44 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+template <typename T>
+class ArrayList final {
+ public:
+ explicit ArrayList(T* list, SizeT length) : fList(reinterpret_cast<T>(list)), fLen(length) {}
+
+ ~ArrayList() = default;
+
+ ArrayList& operator=(const ArrayList&) = default;
+ ArrayList(const ArrayList&) = default;
+
+ T* Data() { return fList; }
+
+ const T* CData() { return fList; }
+
+ T& operator[](SizeT index) const {
+ MUST_PASS(index < this->Count());
+ return fList[index];
+ }
+
+ operator bool() { return fList; }
+
+ SizeT Count() const { return fLen; }
+
+ private:
+ T* fList{nullptr};
+ SizeT fLen{0};
+};
+
+template <typename ValueType>
+ArrayList<ValueType> make_list(ValueType val) {
+ return ArrayList<ValueType>{val};
+}
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Atom.h b/src/kernel/NeKit/Atom.h
new file mode 100644
index 00000000..0f8eefbc
--- /dev/null
+++ b/src/kernel/NeKit/Atom.h
@@ -0,0 +1,33 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+template <typename T>
+class Atom final {
+ public:
+ explicit Atom() = default;
+ ~Atom() = default;
+
+ public:
+ Atom& operator=(const Atom&) = delete;
+ Atom(const Atom&) = delete;
+
+ public:
+ T operator[](Size bit) { return (fArrayOfAtoms & (1 << bit)); }
+
+ void operator|(Size bit) { fArrayOfAtoms |= (1 << bit); }
+
+ friend Boolean operator==(Atom<T>& atomic, const T& idx) { return atomic[idx] == idx; }
+
+ friend Boolean operator!=(Atom<T>& atomic, const T& idx) { return atomic[idx] == idx; }
+
+ private:
+ T fArrayOfAtoms;
+};
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Crc32.h b/src/kernel/NeKit/Crc32.h
new file mode 100644
index 00000000..3c6a904f
--- /dev/null
+++ b/src/kernel/NeKit/Crc32.h
@@ -0,0 +1,20 @@
+/*
+ * ========================================================
+ *
+ * NeKernel
+ * Date Added: 13/02/2023
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#ifndef NEKIT_CRC32_H
+#define NEKIT_CRC32_H
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+UInt32 ke_calculate_crc32(const VoidPtr crc, Int32 len) noexcept;
+} // namespace Kernel
+
+#endif // !NEKIT_CRC32_H
diff --git a/src/kernel/NeKit/CxxAbi.h b/src/kernel/NeKit/CxxAbi.h
new file mode 100644
index 00000000..7b13d6b3
--- /dev/null
+++ b/src/kernel/NeKit/CxxAbi.h
@@ -0,0 +1,26 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#ifndef __NECTI__
+
+#define kAtExitMacDestructors (128)
+
+struct atexit_func_entry_t {
+ void (*destructor_func)();
+ void* obj_ptr;
+ void* dso_handle;
+};
+
+typedef Kernel::UInt32 uarch_t;
+
+namespace cxxabiv1 {
+typedef Kernel::SizeT* __guard;
+}
+
+#endif // !__NECTI__
diff --git a/src/kernel/NeKit/Defines.h b/src/kernel/NeKit/Defines.h
new file mode 100644
index 00000000..1a6a2cf6
--- /dev/null
+++ b/src/kernel/NeKit/Defines.h
@@ -0,0 +1,179 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Macros.h>
+
+#define NEKIT_VERSION_STR "0.0.1"
+#define NEKIT_VERSION_BCD 0x0001
+
+#ifndef __cplusplus
+#error !!! Kernel compiles only with a C++ compiler. !!!
+#endif
+
+#if __cplusplus <= 201703L
+#define char8_t char
+#endif
+
+#ifdef __has_feature
+#if !__has_feature(cxx_nullptr)
+#if !__has_nullptr
+#error !!! You must at least have nullptr featured on your C++ compiler. !!!
+#endif
+#endif
+#endif
+
+/// @brief The **Kernel** namespace.
+namespace Kernel {
+using voidPtr = void*;
+using VoidPtr = void*;
+using nullPtr = decltype(nullptr);
+using NullPtr = decltype(nullptr);
+
+using Int = int;
+using Int32 = __INT32_TYPE__;
+using UShort = __UINT16_TYPE__;
+using UInt16 = __UINT16_TYPE__;
+using Short = short;
+using Int16 = __INT16_TYPE__;
+using UInt = __UINT32_TYPE__;
+using UInt32 = __UINT32_TYPE__;
+using Long = __INT64_TYPE__;
+using Int64 = __INT64_TYPE__;
+using ULong = __UINT64_TYPE__;
+using UInt64 = __UINT64_TYPE__;
+using Boolean = bool;
+using Bool = bool;
+using Char = char;
+using Int8 = __INT8_TYPE__;
+using Char8 = char8_t;
+using UChar = __UINT8_TYPE__;
+using UInt8 = __UINT8_TYPE__;
+
+using SSize = long;
+using SSizeT = long;
+using Size = __SIZE_TYPE__;
+using SizeT = __SIZE_TYPE__;
+using IntPtr = __INTPTR_TYPE__;
+using UIntPtr = __UINTPTR_TYPE__;
+using IntFast = __INT_FAST32_TYPE__;
+using IntFast64 = __INT_FAST64_TYPE__;
+using PtrDiff = __PTRDIFF_TYPE__;
+
+using SInt16 = Int16;
+using SInt32 = Int32;
+using SInt64 = Int64;
+
+typedef UIntPtr* Ptr64;
+typedef UInt32* Ptr32;
+typedef UInt8* Ptr8;
+
+using Utf8Char = char8_t;
+using Utf16Char = char16_t;
+using WideChar = wchar_t;
+using Utf32Char = char32_t;
+
+using LongDouble = long double;
+using Double = double;
+using Float = float;
+
+typedef UInt32 PhysicalAddressKind;
+typedef UIntPtr VirtualAddressKind;
+
+using Void = void;
+using Any = void*;
+
+using Lba = UInt64;
+
+using Char16 = char16_t;
+
+enum class Endian : UInt8 { kEndianInvalid, kEndianBig, kEndianLittle, kEndianMixed, kEndianCount };
+
+/// @brief Forward object.
+/// @tparam Args the object type.
+/// @param arg the object.
+/// @return object's rvalue
+template <typename Args>
+inline Args&& forward(Args& arg) {
+ return static_cast<Args&&>(arg);
+}
+
+/// @brief Move object.
+/// @tparam Args the object type.
+/// @param arg the object.
+/// @return object's rvalue
+template <typename Args>
+inline Args&& move(Args&& arg) {
+ return static_cast<Args&&>(arg);
+}
+
+/// @brief Encoding interface, used as a proxy to convert T to Char*
+/// Used to cast A to B or B to A.
+class ICodec {
+ public:
+ explicit ICodec() = default;
+ virtual ~ICodec() = default;
+
+ ICodec& operator=(const ICodec&) = default;
+ ICodec(const ICodec&) = default;
+
+ public:
+ /// @brief Convert type to bytes.
+ /// @tparam T the type.
+ /// @param type (a1) the data.
+ /// @return a1 as Char*
+ template <typename T>
+ const Char* AsBytes(T type) noexcept {
+ NE_UNUSED(type);
+ return nullptr;
+ }
+
+ /// @brief Construct from type to class.
+ /// @tparam T the type to convert.
+ /// @param type (a1) the data.
+ /// @return a1 as Char*
+ template <typename OutputClass, typename FactoryClass>
+ OutputClass* Construct(Char* type) noexcept {
+ FactoryClass class_fac;
+ return class_fac.template From<OutputClass>(type);
+ }
+
+ /// @brief Convert T class to Y class.
+ /// @tparam T the class type of type.
+ /// @tparam Y the result class.
+ /// @param type the class to cast.
+ /// @return the class as Y.
+ template <typename T, typename Y>
+ Y As(T type) noexcept {
+ if (type.template IsSerializable()) {
+ return reinterpret_cast<Char*>(type);
+ }
+
+ return type.template As<Y>();
+ }
+};
+
+/// \brief Scheduler interface, represents a scheduler object.
+/// @note This is used to schedule tasks, such as threads, drivers, user threads, etc.
+class ISchedulable {
+ public:
+ explicit ISchedulable() = default;
+ virtual ~ISchedulable() = default;
+
+ ISchedulable& operator=(const ISchedulable&) = default;
+ ISchedulable(const ISchedulable&) = default;
+
+ /// @brief Is this object only accepting user tasks?
+ virtual Bool IsUser() { return NO; }
+
+ /// @brief Is this object only accepting kernel tasks?
+ virtual Bool IsKernel() { return NO; }
+
+ /// @brief Is this object offloading to another CPU?
+ virtual Bool HasMP() { return NO; }
+};
+} // namespace Kernel
diff --git a/src/kernel/NeKit/ErrorOr.h b/src/kernel/NeKit/ErrorOr.h
new file mode 100644
index 00000000..d930fe17
--- /dev/null
+++ b/src/kernel/NeKit/ErrorOr.h
@@ -0,0 +1,62 @@
+/*
+ * ========================================================
+ *
+ * NeKernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+using ErrorT = Int32;
+
+/// ================================================================================
+/// @brief ErrorOr class for error handling.
+/// ================================================================================
+template <typename T>
+class ErrorOr final {
+ public:
+ explicit ErrorOr() = default;
+ ~ErrorOr() = default;
+
+ public:
+ explicit ErrorOr(ErrorT err) : mRef((T*) RTL_ALLOCA(sizeof(T))), mId(err) {}
+
+ explicit ErrorOr(nullPtr) {}
+
+ explicit ErrorOr(T* Class) : mRef(Class) {}
+
+ explicit ErrorOr(T Class) : mRef(Class) {}
+
+ ErrorOr& operator=(const ErrorOr&) = default;
+ ErrorOr(const ErrorOr&) = default;
+
+ ErrorOr& operator=(const Ref<T>& refErr) {
+ mRef = refErr;
+ return *this;
+ }
+
+ const T& Value() { return mRef.TryLeak(); }
+
+ Ref<T>& Leak() { return mRef; }
+
+ ErrorT Error() { return mId; }
+
+ /// @note DO NOT MAKE THIS EXPLICIT! IT WILL BREAK THE COMPILATION.
+ operator bool() { return mRef; }
+
+ BOOL HasError() { return this->mId < 0; }
+
+ private:
+ Ref<T> mRef;
+ ErrorT mId{0};
+};
+
+using ErrorOrAny = ErrorOr<voidPtr>;
+
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Function.h b/src/kernel/NeKit/Function.h
new file mode 100644
index 00000000..70242bc3
--- /dev/null
+++ b/src/kernel/NeKit/Function.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+
+namespace Kernel {
+/// ================================================================================
+/// @brief Function wrapper class.
+/// ================================================================================
+template <typename T, typename... Args>
+class Function final {
+ public:
+ Function() = default;
+
+ public:
+ explicit Function(T (*Fn)(Args... args)) : fFn(Fn) {}
+
+ ~Function() = default;
+
+ Function& operator=(const Function&) = default;
+ Function(const Function&) = default;
+
+ template <typename... XArgs>
+ T operator()(Args&&... args) {
+ return fFn(args...);
+ }
+
+ template <typename... XArgs>
+ T Call(Args&&... args) {
+ return fFn(args...);
+ }
+
+ operator bool() { return fFn; }
+
+ bool operator!() { return !fFn; }
+
+ private:
+ T(*fFn)
+ (Args... args){nullptr};
+};
+
+template <typename T, typename... Args>
+using FunctionOr = ErrorOr<Function<T, Args...>>;
+} // namespace Kernel
+
diff --git a/src/kernel/NeKit/Json.h b/src/kernel/NeKit/Json.h
new file mode 100644
index 00000000..1e804354
--- /dev/null
+++ b/src/kernel/NeKit/Json.h
@@ -0,0 +1,146 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/// @brief Kernel JSON API.
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <NeKit/Stream.h>
+#include <NeKit/Utils.h>
+
+#define kNeJsonMaxLen (8196)
+#define kNeJsonLen (256)
+#define kNeJsonNullArr "[]"
+#define kNeJsonNullObj "{}"
+#define kNeJsonNullKey "null"
+#define kNeJsonNullValue kNeJsonNullKey
+
+namespace Kernel {
+/// ================================================================================
+/// @brief JSON object representation.
+/// ================================================================================
+template <typename CharKind = Char>
+class JsonObject final {
+ public:
+ explicit JsonObject() {
+ KBasicString<CharKind> key = KString(kNeJsonMaxLen);
+ key += kNeJsonNullValue;
+
+ this->AsKey() = key;
+ this->AsValue() = key;
+ }
+
+ explicit JsonObject(SizeT lhsLen, SizeT rhsLen) : fKey(lhsLen), fValue(rhsLen) {
+
+ KBasicString<CharKind> key = KString(lhsLen);
+ this->AsKey() = key;
+
+ KBasicString<CharKind> value = KString(rhsLen);
+ this->AsValue() = value;
+ }
+
+ ~JsonObject() = default;
+
+ NE_COPY_DEFAULT(JsonObject)
+ NE_MOVE_DEFAULT(JsonObject)
+
+ Bool& IsUndefined() { return fUndefined; }
+
+ private:
+ Bool fUndefined; // is this instance undefined?
+ KBasicString<CharKind> fKey;
+ KBasicString<CharKind> fValue;
+
+ public:
+ /// @brief returns the key of the json
+ /// @return the key as string view.
+ KBasicString<CharKind>& AsKey() { return fKey; }
+
+ /// @brief returns the value of the json.
+ /// @return the key as string view.
+ KBasicString<CharKind>& AsValue() { return fValue; }
+
+ STATIC JsonObject<CharKind> kNull;
+};
+
+/// ================================================================================
+/// @brief JsonObject stream reader helper for ASCII.
+/// ================================================================================
+struct AsciiJsonStreamReader final {
+ STATIC JsonObject<Char> In(const Char* full_array) {
+ auto start_val = '{';
+ auto end_val = '}';
+ Boolean probe_value = false;
+
+ if (full_array[0] != start_val) {
+ if (full_array[0] != '[') return JsonObject<Char>{0, 0};
+
+ start_val = '[';
+ end_val = ']';
+
+ probe_value = true;
+ }
+
+ SizeT len = rt_string_len(full_array);
+
+ SizeT key_len = 0;
+ SizeT value_len = 0;
+
+ JsonObject<Char> type(kNeJsonMaxLen, kNeJsonMaxLen);
+
+ for (SizeT i = 1; i < len; ++i) {
+ if (full_array[i] == '\r' || full_array[i] == '\n') continue;
+
+ if (probe_value) {
+ if (full_array[i] == end_val || full_array[i] == ',') {
+ probe_value = false;
+
+ ++value_len;
+ } else {
+ if (full_array[i] == '\'') {
+ type.AsValue().Data()[value_len] = 0;
+ break;
+ }
+
+ type.AsValue().Data()[value_len] = full_array[i];
+
+ ++value_len;
+ }
+ } else {
+ if (start_val == '[') continue;
+
+ if (full_array[i] == ':') {
+ type.AsKey().Data()[key_len] = 0;
+ ++key_len;
+
+ ++i;
+
+ while (full_array[i] == ' ' || full_array[i] == '\t') ++i;
+
+ probe_value = true;
+ } else {
+ type.AsKey().Data()[key_len] = full_array[i];
+
+ ++key_len;
+ }
+ }
+ }
+
+ type.AsValue().Data()[value_len] = 0;
+
+ return type;
+ }
+};
+
+/// ================================================================================
+/// @brief AsciiJsonStream type definition.
+/// ================================================================================
+using AsciiJsonStream = Stream<AsciiJsonStreamReader, JsonObject<Char>>;
+} // namespace Kernel
diff --git a/src/kernel/NeKit/KString.h b/src/kernel/NeKit/KString.h
new file mode 100644
index 00000000..fa83fed4
--- /dev/null
+++ b/src/kernel/NeKit/KString.h
@@ -0,0 +1,92 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+inline auto kMinimumStringSize = 8196;
+
+/// @brief Kernel string class, not dynamic.
+template <typename CharKind = Char>
+class KBasicString final {
+ public:
+ explicit KBasicString() {
+ fDataSz = kMinimumStringSize;
+
+ fData = new CharKind[fDataSz];
+ MUST_PASS(fData);
+
+ rt_set_memory(fData, 0, fDataSz);
+ }
+
+ explicit KBasicString(SizeT Sz) : fDataSz(Sz) {
+ MUST_PASS(Sz > 1);
+
+ fData = new CharKind[Sz];
+ MUST_PASS(fData);
+
+ rt_set_memory(fData, 0, Sz);
+ }
+
+ ~KBasicString() {
+ if (fData) {
+ delete[] fData;
+ fData = nullptr;
+ }
+ }
+
+ NE_COPY_DEFAULT(KBasicString)
+
+ CharKind* Data();
+ const CharKind* CData() const;
+ Size Length() const;
+
+ bool operator==(const CharKind* rhs) const;
+ bool operator!=(const CharKind* rhs) const;
+
+ bool operator==(const KBasicString<CharKind>& rhs) const;
+ bool operator!=(const KBasicString<CharKind>& rhs) const;
+
+ KBasicString<CharKind>& operator+=(const CharKind* rhs);
+ KBasicString<CharKind>& operator+=(const KBasicString<CharKind>& rhs);
+
+ operator const char*() { return fData; }
+
+ operator bool() { return fData; }
+
+ bool operator!() { return fData; }
+
+ private:
+ CharKind* fData{nullptr};
+ Size fDataSz{0};
+ Size fCur{0};
+
+ friend class KStringBuilder;
+};
+
+using KString = KBasicString<>;
+using KStringOr = ErrorOr<KString>;
+
+class KStringBuilder final {
+ public:
+ template <typename CharKind = Char>
+ static ErrorOr<KBasicString<CharKind>> Construct(const CharKind* data);
+ template <typename CharKind = Char>
+ static const CharKind* FromBool(const CharKind* fmt, bool n);
+ template <typename CharKind = Char>
+ static const CharKind* Format(const CharKind* fmt, const CharKind* from);
+ template <typename CharKind = Char>
+ static bool Equals(const CharKind* lhs, const CharKind* rhs);
+};
+} // namespace Kernel
+
+#include <NeKit/KString.inl>
diff --git a/src/kernel/NeKit/KString.inl b/src/kernel/NeKit/KString.inl
new file mode 100644
index 00000000..3a73e90f
--- /dev/null
+++ b/src/kernel/NeKit/KString.inl
@@ -0,0 +1,174 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/// @file KBasicString.inl
+/// @brief Kernel String manipulation file.
+
+namespace Kernel {
+template <typename CharKind>
+inline void ort_string_append(CharKind* lhs, const CharKind* rhs, Int32 cur) {
+ SizeT sz_rhs = oe_string_len<CharKind>(rhs);
+ SizeT rhs_i = 0;
+
+ for (; rhs_i < sz_rhs; ++rhs_i) {
+ lhs[rhs_i + cur] = rhs[rhs_i];
+ }
+}
+
+template <typename CharKind>
+inline CharKind* KBasicString<CharKind>::Data() {
+ return this->fData;
+}
+
+template <typename CharKind>
+inline const CharKind* KBasicString<CharKind>::CData() const {
+ return const_cast<const CharKind*>(this->fData);
+}
+
+template <typename CharKind>
+inline SizeT KBasicString<CharKind>::Length() const {
+ return this->fDataSz;
+}
+
+template <typename CharKind>
+inline bool KBasicString<CharKind>::operator==(const KBasicString<CharKind>& 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;
+}
+
+template <typename CharKind>
+inline bool KBasicString<CharKind>::operator==(const CharKind* rhs) const {
+ if (oe_string_len<CharKind>(rhs) != this->Length()) return false;
+
+ for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) {
+ if (rhs[index] != this->fData[index]) return false;
+ }
+
+ return true;
+}
+
+template <typename CharKind>
+inline bool KBasicString<CharKind>::operator!=(const KBasicString<CharKind>& 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;
+}
+
+template <typename CharKind>
+inline bool KBasicString<CharKind>::operator!=(const CharKind* rhs) const {
+ if (oe_string_len<CharKind>(rhs) != this->Length()) return false;
+
+ for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) {
+ if (rhs[index] == this->fData[index]) return false;
+ }
+
+ return true;
+}
+
+template <typename CharKind>
+inline KBasicString<CharKind>& KBasicString<CharKind>::operator+=(
+ const KBasicString<CharKind>& rhs) {
+ if (oe_string_len<CharKind>(rhs.fData) > this->Length()) return *this;
+
+ ort_string_append(this->fData, const_cast<CharKind*>(rhs.fData), this->fCur);
+ this->fCur += oe_string_len<CharKind>(const_cast<CharKind*>(rhs.fData));
+
+ return *this;
+}
+
+template <typename CharKind>
+inline KBasicString<CharKind>& KBasicString<CharKind>::operator+=(const CharKind* rhs) {
+ ort_string_append(this->fData, const_cast<CharKind*>(rhs), this->fCur);
+ this->fCur += oe_string_len<CharKind>(const_cast<CharKind*>(rhs));
+
+ return *this;
+}
+
+template <typename CharKind>
+inline ErrorOr<KBasicString<CharKind>> KStringBuilder::Construct(const CharKind* data) {
+ if (!data || *data == 0) return ErrorOr<KBasicString<CharKind>>(nullptr);
+
+ KBasicString<CharKind>* view = new KBasicString<CharKind>(oe_string_len<CharKind>(data));
+ (*view) += data;
+
+ return ErrorOr<KBasicString<CharKind>>(*view);
+}
+template <typename CharKind>
+inline const CharKind* KStringBuilder::FromBool(const CharKind* fmt, bool i) {
+ if (!fmt) return ("?");
+
+ const CharKind* boolean_expr = i ? "YES" : "NO";
+ CharKind* ret =
+ (CharKind*) RTL_ALLOCA(oe_string_len<CharKind>(boolean_expr) + oe_string_len<CharKind>(fmt));
+
+ if (!ret) return ("?");
+
+ const auto fmt_len = oe_string_len<CharKind>(fmt);
+ const auto res_len = oe_string_len<CharKind>(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;
+}
+template <typename CharKind>
+inline bool KStringBuilder::Equals(const CharKind* lhs, const CharKind* rhs) {
+ if (oe_string_len<CharKind>(rhs) != oe_string_len<CharKind>(lhs)) return false;
+
+ for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) {
+ if (rhs[index] != lhs[index]) return false;
+ }
+
+ return true;
+}
+template <typename CharKind>
+inline const CharKind* KStringBuilder::Format(const CharKind* fmt, const CharKind* fmt2) {
+ if (!fmt || !fmt2) return ("?");
+
+ CharKind* ret = (CharKind*) RTL_ALLOCA(
+ sizeof(char) * (oe_string_len<CharKind>(fmt2) + oe_string_len<CharKind>(fmt)));
+
+ if (!ret) return ("?");
+
+ const auto len = oe_string_len<CharKind>(fmt);
+
+ for (Size idx = 0; idx < len; ++idx) {
+ if (fmt[idx] == '%' && idx < oe_string_len<CharKind>(fmt) && fmt[idx] == 's') {
+ Size result_cnt = idx;
+
+ for (Size y_idx = 0; y_idx < oe_string_len<CharKind>(fmt2); ++y_idx) {
+ ret[result_cnt] = fmt2[y_idx];
+ ++result_cnt;
+ }
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+}
+} // namespace Kernel
diff --git a/src/kernel/NeKit/KernelPanic.h b/src/kernel/NeKit/KernelPanic.h
new file mode 100644
index 00000000..f716e6de
--- /dev/null
+++ b/src/kernel/NeKit/KernelPanic.h
@@ -0,0 +1,69 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+void ke_runtime_check(bool expr, const Char* file, const Char* line);
+}
+
+#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG)
+
+#ifdef TRY
+#undef TRY
+#endif
+
+#define TRY(X) \
+ { \
+ auto fn = X; \
+ if ((fn()) == NO) { \
+ MUST_PASS(NO); \
+ } \
+ }
+
+#ifdef __MUST_PASS
+#undef __MUST_PASS
+#endif
+
+#define __MUST_PASS(EXPR, FILE, LINE) Kernel::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE))
+
+#ifdef __DEBUG__
+#define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__)
+#define assert(EXPR) MUST_PASS(EXPR)
+#else
+#define MUST_PASS(EXPR) (Kernel::Void)(EXPR)
+#define assert(EXPR) (Kernel::Void)(EXPR)
+#endif
+
+enum RUNTIME_CHECK {
+ RUNTIME_CHECK_FAILED = 1111,
+ RUNTIME_CHECK_POINTER,
+ RUNTIME_CHECK_EXPRESSION,
+ RUNTIME_CHECK_FILE,
+ RUNTIME_CHECK_IPC,
+ RUNTIME_CHECK_TLS,
+ RUNTIME_CHECK_HANDSHAKE,
+ RUNTIME_CHECK_ACPI,
+ RUNTIME_CHECK_INVALID_PRIVILEGE,
+ RUNTIME_CHECK_PROCESS,
+ RUNTIME_CHECK_BAD_BEHAVIOR,
+ RUNTIME_CHECK_BOOTSTRAP,
+ RUNTIME_CHECK_UNEXCPECTED,
+ RUNTIME_CHECK_FILESYSTEM,
+ RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM,
+ RUNTIME_CHECK_PAGE,
+ RUNTIME_CHECK_INVALID,
+ RUNTIME_CHECK_COUNT,
+};
+
+typedef enum RUNTIME_CHECK RTL_RUNTIME_CHECK;
+
+namespace Kernel {
+void ke_panic(const Int32& id, const Char* message = nullptr);
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Macros.h b/src/kernel/NeKit/Macros.h
new file mode 100644
index 00000000..5949b414
--- /dev/null
+++ b/src/kernel/NeKit/Macros.h
@@ -0,0 +1,151 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/***********************************************************************************/
+/// @file NeKit/Macros.h
+/// @brief Core Types and Macros.
+/***********************************************************************************/
+
+#ifndef KIB
+#define KIB(X) (Kernel::UInt64)((X) / 1024)
+#endif
+
+#ifndef kib_cast
+#define kib_cast(X) (Kernel::UInt64)((X) *1024)
+#endif
+
+#ifndef MIB
+#define MIB(X) (Kernel::UInt64)((Kernel::UInt64) KIB(X) / 1024)
+#endif
+
+#ifndef mib_cast
+#define mib_cast(X) (Kernel::UInt64)((Kernel::UInt64) kib_cast(X) * 1024)
+#endif
+
+#ifndef GIB
+#define GIB(X) (Kernel::UInt64)((Kernel::UInt64) MIB(X) / 1024)
+#endif
+
+#ifndef gib_cast
+#define gib_cast(X) (Kernel::UInt64)((Kernel::UInt64) mib_cast(X) * 1024)
+#endif
+
+#ifndef TIB
+#define TIB(X) (Kernel::UInt64)((Kernel::UInt64) GIB(X) / 1024)
+#endif
+
+#ifndef tib_cast
+#define tib_cast(X) ((Kernel::UInt64) gib_cast(X) * 1024)
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) \
+ (((sizeof(a) / sizeof(*(a))) / (static_cast<Kernel::Size>(!(sizeof(a) % sizeof(*(a)))))))
+#endif
+
+#define DEPRECATED ATTRIBUTE(deprecated)
+
+#ifndef ALIGN
+#define ALIGN(X) __attribute__((aligned(X)))
+#endif // #ifndef ALIGN
+
+#ifndef ATTRIBUTE
+#define ATTRIBUTE(...) __attribute__((__VA_ARGS__))
+#endif // #ifndef ATTRIBUTE
+
+#ifndef __NE_VER__
+#define __NE_VER__ (2024)
+#endif // !__NE_VER__
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+#ifndef EXTERN_C
+#define EXTERN_C extern "C"
+#endif
+
+#ifndef MAKE_ENUM
+#define MAKE_ENUM(NAME) enum NAME {
+#endif
+
+#ifndef END_ENUM
+#define END_ENUM() \
+ } \
+ ;
+#endif
+
+#ifndef MAKE_STRING_ENUM
+#define MAKE_STRING_ENUM(NAME) namespace NAME {
+#endif
+
+#ifndef ENUM_STRING
+#define ENUM_STRING(NAME, VAL) inline constexpr const char* e##NAME = VAL
+#endif
+
+#ifndef END_STRING_ENUM
+#define END_STRING_ENUM() }
+#endif
+
+#ifndef RTL_ALLOCA
+#define RTL_ALLOCA(sz) __builtin_alloca(sz)
+#endif // #ifndef RTL_ALLOCA
+
+#ifndef CANT_REACH
+#define CANT_REACH() __builtin_unreachable()
+#endif
+
+#define kInvalidAddress 0xFBFBFBFBFBFBFBFB
+#define kBadAddress 0x0000000000000000
+#define kMaxAddr 0xFFFFFFFFFFFFFFFF
+#define kPathLen 0x100
+
+#define PACKED ATTRIBUTE(packed)
+#define NO_EXEC ATTRIBUTE(noexec)
+
+#define EXTERN extern
+#define STATIC static
+
+#define CONST const
+
+#define STRINGIFY(X) #X
+#define NE_UNUSED(X) ((Kernel::Void) X)
+
+#ifndef RGB
+#define RGB(R, G, B) ((Kernel::UInt32)((0xFF << 24) | ((R) << 16) | ((G) << 8) | (B)))
+#endif // !RGB
+
+#ifdef __NE_AMD64__
+#define DBG_TRAP() asm volatile("int $3")
+#else
+#define DBG_TRAP() ((Kernel::Void) 0)
+#endif
+
+#define LIKELY(ARG) ((ARG) ? MUST_PASS(NO) : ((Kernel::Void) 0))
+#define UNLIKELY(ARG) LIKELY(!(ARG))
+
+#define RTL_ENDIAN(address, value) \
+ (((reinterpret_cast<Kernel::Char*>(address)[0]) == (value)) ? (Kernel::Endian::kEndianBig) \
+ : (Kernel::Endian::kEndianLittle))
+
+#define Yes true
+#define No false
+
+#define YES true
+#define NO false
+
+#define TRUE true
+#define FALSE false
+
+#define BOOL Kernel::Boolean
+
+#ifdef RTL_INIT_OBJECT
+#undef RTL_INIT_OBJECT
+#endif // ifdef RTL_INIT_OBJECT
+
+#define RTL_INIT_OBJECT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__)
diff --git a/src/kernel/NeKit/MutableArray.h b/src/kernel/NeKit/MutableArray.h
new file mode 100644
index 00000000..e1138b3b
--- /dev/null
+++ b/src/kernel/NeKit/MutableArray.h
@@ -0,0 +1,203 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+
+#define RTL_TRY_FIND_NODE(NAME, NODE) \
+ auto* NAME = NODE; \
+ while (NAME) { \
+ if (NAME->fIndex == Index) return NAME->fVal; \
+ NAME = NAME->fNext; \
+ }
+
+#define RTL_TRY_FIND_NODE2(NAME, NODE) \
+ auto* NAME = NODE; \
+ while (NAME) { \
+ if (NAME->fIndex == Index) return Ref<T>{NAME->fVal}; \
+ NAME = NAME->fNext; \
+ }
+
+#define RTL_TRY_REMOVE_NODE(NODE) \
+ if (NODE && NODE->fIndex == Index) { \
+ NODE->fUsed = false; \
+ NODE->fIndex = 0; \
+ \
+ return true; \
+ }
+
+// FIXME: this is a shitty algorithm, because it is memory heavy.
+// Remove and occurences of that, and remove that class.
+namespace Kernel {
+template <typename T>
+class MutableArray;
+
+template <typename T, T _PlaceHolderValue>
+class NullableMutableArray;
+
+template <typename T>
+class MutableLinkedList {
+ public:
+ T fVal;
+ SizeT fIndex{0};
+ Boolean fUsed{false};
+
+ MutableLinkedList* fPrev{nullptr};
+ MutableLinkedList* fNext{nullptr};
+};
+
+template <typename T, T _PlaceHolderValue>
+class NullableMutableArray {
+ public:
+ // explicit this.
+ explicit NullableMutableArray() : fFirstNode(new MutableLinkedList<T>()) {}
+
+ /*
+ * We free all the nodes allocated by the array
+ * and store the next one inside "NextIt"
+ */
+
+ virtual ~NullableMutableArray() {
+ auto* It = fFirstNode;
+ MutableLinkedList<T>* NextIt = nullptr;
+
+ while (It) {
+ NextIt = It->fNext;
+ delete It;
+
+ It = NextIt;
+ }
+ }
+
+ NullableMutableArray& operator=(const NullableMutableArray&) = default;
+ NullableMutableArray(const NullableMutableArray&) = default;
+
+ operator bool() { return Count() > 1; }
+
+ public:
+ T operator[](SizeT Index) const {
+ RTL_TRY_FIND_NODE(first, fFirstNode);
+ RTL_TRY_FIND_NODE(last, fLastNode);
+
+ return _PlaceHolderValue;
+ }
+
+ SizeT Count() const { return fNodeCount; }
+
+ public:
+ Boolean Remove(SizeT Index) {
+ RTL_TRY_REMOVE_NODE(fFirstNode);
+ RTL_TRY_REMOVE_NODE(fLastNode);
+
+ return false;
+ }
+
+ Boolean Add(const T val) {
+ auto* iterationNode = fFirstNode;
+ MUST_PASS(iterationNode);
+
+ while (iterationNode) {
+ if (!iterationNode->fUsed) {
+ iterationNode->fVal = val;
+ iterationNode->fIndex = 0;
+
+ iterationNode->fUsed = true;
+
+ ++fNodeCount;
+
+ return true;
+ }
+
+ iterationNode = iterationNode->fNext;
+ }
+
+ return false;
+ }
+
+ private:
+ /* Avoid useless lookups */
+ MutableLinkedList<T>* fLastNode{nullptr};
+ MutableLinkedList<T>* fFirstNode{nullptr};
+
+ /* Number of nodes inside of this dynamic array. */
+ Kernel::SizeT fNodeCount{0};
+
+ private:
+ // don't remove that
+ friend MutableArray<T>;
+};
+
+template <typename T>
+class MutableArray : public NullableMutableArray<voidPtr, nullptr> {
+ public:
+ // explicit this.
+ explicit MutableArray() = default;
+ virtual ~MutableArray() = default;
+
+ NE_COPY_DEFAULT(MutableArray)
+
+ public:
+ Boolean Add(const T val) {
+ auto* iterationNode = fFirstNode;
+
+ if (!iterationNode) {
+ fFirstNode = new MutableLinkedList<T>();
+ iterationNode = fFirstNode;
+ }
+
+ MUST_PASS(iterationNode);
+
+ while (iterationNode) {
+ if (!iterationNode->fUsed) {
+ iterationNode->fVal = val;
+ iterationNode->fIndex = 0;
+
+ iterationNode->fUsed = true;
+
+ ++fNodeCount;
+
+ return true;
+ }
+
+ iterationNode = iterationNode->fNext;
+ }
+
+ return false;
+ }
+
+ public:
+ Ref<T> operator[](SizeT Index) const {
+ RTL_TRY_FIND_NODE2(first, fFirstNode);
+ RTL_TRY_FIND_NODE2(last, fLastNode);
+
+ return {};
+ }
+
+ SizeT Count() const { return fNodeCount; }
+
+ bool Contains(T& value) noexcept {
+ MutableLinkedList<T>* first = fFirstNode;
+
+ while (first) {
+ if (first->fVal == value && first->fUsed) return true;
+
+ first = first->fNext;
+ }
+
+ return false;
+ }
+
+ private:
+ /* Avoid useless lookups */
+ MutableLinkedList<T>* fLastNode{nullptr};
+ MutableLinkedList<T>* fFirstNode{nullptr};
+
+ /* Number of nodes inside of this dynamic array. */
+ Kernel::SizeT fNodeCount{0};
+};
+} // namespace Kernel
diff --git a/src/kernel/NeKit/NeKit.h b/src/kernel/NeKit/NeKit.h
new file mode 100644
index 00000000..4b1e64ca
--- /dev/null
+++ b/src/kernel/NeKit/NeKit.h
@@ -0,0 +1,20 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Array.h>
+#include <NeKit/ArrayList.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/Json.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/MutableArray.h>
+#include <NeKit/New.h>
+#include <NeKit/OwnPtr.h>
+#include <NeKit/Ref.h>
+#include <NeKit/Stream.h>
+#include <NeKit/Utils.h>
diff --git a/src/kernel/NeKit/New.h b/src/kernel/NeKit/New.h
new file mode 100644
index 00000000..36830129
--- /dev/null
+++ b/src/kernel/NeKit/New.h
@@ -0,0 +1,20 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/HeapMgr.h>
+
+/// @note compatible with tk too.
+typedef __SIZE_TYPE__ size_t;
+
+void* operator new(size_t);
+void* operator new[](size_t);
+
+void operator delete(void*) noexcept;
+void operator delete(void*, unsigned long);
+void operator delete[](void*) noexcept;
diff --git a/src/kernel/NeKit/OwnPtr.h b/src/kernel/NeKit/OwnPtr.h
new file mode 100644
index 00000000..c8ceb1a2
--- /dev/null
+++ b/src/kernel/NeKit/OwnPtr.h
@@ -0,0 +1,67 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+template <typename T>
+class OwnPtr;
+
+template <typename T>
+class NonNullRefPtr;
+
+template <typename T>
+class OwnPtr final {
+ public:
+ OwnPtr() {}
+ ~OwnPtr() { this->Delete(); }
+
+ OwnPtr& operator=(const OwnPtr&) = default;
+ OwnPtr(const OwnPtr&) = default;
+
+ public:
+ template <typename... Args>
+ bool New(Args&&... arg) {
+ if (fCls) {
+ return false;
+ }
+
+ fCls = new T(arg...);
+ return fCls;
+ }
+
+ void Delete() {
+ if (fCls) delete fCls;
+
+ fCls = nullptr;
+ }
+
+ T* operator->() const { return fCls; }
+
+ T* Raw() { return fCls; }
+
+ Ref<T> AsRef() { return Ref<T>(fCls); }
+
+ operator bool() { return fCls; }
+ bool operator!() { return !fCls; }
+
+ private:
+ T* fCls;
+};
+
+template <typename T, typename... Args>
+inline OwnPtr<T> mm_make_own_ptr(Args... args) {
+ OwnPtr<T> ret;
+ ret.template New<Args...>(forward(args)...);
+
+ return ret;
+}
+} // namespace Kernel
diff --git a/src/kernel/NeKit/PageMgr.h b/src/kernel/NeKit/PageMgr.h
new file mode 100644
index 00000000..6cdd5a5c
--- /dev/null
+++ b/src/kernel/NeKit/PageMgr.h
@@ -0,0 +1,76 @@
+// a way to create and find our pages.
+// I'm thinking about a separate way of getting a paged area.
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+class PageMgr;
+
+class PTEWrapper final {
+ public:
+ explicit PTEWrapper(Boolean Rw = false, Boolean User = false, Boolean ExecDisable = false,
+ UIntPtr Address = 0);
+
+ ~PTEWrapper();
+
+ PTEWrapper& operator=(const PTEWrapper&) = default;
+ PTEWrapper(const PTEWrapper&) = default;
+
+ public:
+ UIntPtr VirtualAddress();
+
+ Void NoExecute(const bool enable = false);
+ Bool NoExecute();
+
+ operator bool() { return fVirtAddr; }
+
+ bool Reclaim();
+ bool Shareable();
+ bool Present();
+ bool Access();
+
+ private:
+ Boolean fRw;
+ Boolean fUser;
+ Boolean fExecDisable;
+ UIntPtr fVirtAddr;
+ Boolean fCache;
+ Boolean fShareable;
+ Boolean fWt;
+ Boolean fPresent;
+ Boolean fAccessed;
+
+ private:
+ friend class PageMgr;
+ friend class Pmm;
+};
+
+struct PageMgr final {
+ public:
+ PageMgr() = default;
+ ~PageMgr() = default;
+
+ PageMgr& operator=(const PageMgr&) = default;
+ PageMgr(const PageMgr&) = default;
+
+ public:
+ PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad);
+ bool Free(Ref<PTEWrapper>& wrapper);
+
+ private:
+ void FlushTLB();
+
+ private:
+ friend PTEWrapper;
+ friend class Pmm;
+};
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Pair.h b/src/kernel/NeKit/Pair.h
new file mode 100644
index 00000000..c8914ec6
--- /dev/null
+++ b/src/kernel/NeKit/Pair.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+
+namespace Kernel {
+template <typename T1, typename T2>
+class Pair;
+
+class PairBuilder;
+
+template <typename T1, typename T2>
+class Pair final {
+ T1 fFirst{nullptr};
+ T2 fSecond{nullptr};
+
+ friend PairBuilder;
+
+ public:
+ explicit Pair() = default;
+ ~Pair() = default;
+
+ NE_COPY_DEFAULT(Pair)
+
+ T1& First() { return fFirst; }
+ T2& Second() { return fSecond; }
+
+ const T1& First() const { return *fFirst; }
+ const T2& Second() const { return *fSecond; }
+
+ private:
+ Pair(T1 first, T2 second) : fFirst(first), fSecond(second) {}
+};
+
+class PairBuilder final {
+ template <typename T1, typename T2>
+ STATIC Pair<T1, T2> Construct(T1 first, T2 second) {
+ return Pair(first, second);
+ }
+};
+
+template <typename T1, typename T2>
+using PairOr = ErrorOr<Pair<T1, T2>>;
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Pmm.h b/src/kernel/NeKit/Pmm.h
new file mode 100644
index 00000000..8c117a67
--- /dev/null
+++ b/src/kernel/NeKit/Pmm.h
@@ -0,0 +1,39 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/PageMgr.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+class Pmm;
+class PTEWrapper;
+
+class Pmm final {
+ public:
+ explicit Pmm();
+ ~Pmm();
+
+ Pmm& operator=(const Pmm&) = delete;
+ Pmm(const Pmm&) = default;
+
+ Ref<PTEWrapper> RequestPage(Boolean user = false, Boolean readWrite = false);
+ Boolean FreePage(Ref<PTEWrapper> refPage);
+
+ Boolean ToggleRw(Ref<PTEWrapper> refPage, Boolean enable = true);
+ Boolean TogglePresent(Ref<PTEWrapper> refPage, Boolean enable = true);
+ Boolean ToggleUser(Ref<PTEWrapper> refPage, Boolean enable = true);
+ Boolean ToggleShare(Ref<PTEWrapper> refPage, Boolean enable = true);
+
+ /// @brief Get the page manager of this.
+ Ref<PageMgr>& Leak() { return fPageMgr; }
+
+ private:
+ Ref<PageMgr> fPageMgr;
+};
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Ref.h b/src/kernel/NeKit/Ref.h
new file mode 100644
index 00000000..dac701e0
--- /dev/null
+++ b/src/kernel/NeKit/Ref.h
@@ -0,0 +1,77 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef _NEKIT_REF_H_
+#define _NEKIT_REF_H_
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/HeapMgr.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KernelPanic.h>
+
+namespace Kernel {
+/// =========================================================== ///
+/// @brief Reference wrapper class. ///
+/// =========================================================== ///
+template <typename T>
+class Ref final {
+ public:
+ explicit Ref() = default;
+ ~Ref() = default;
+
+ public:
+ Ref(T* cls) : fClass(*cls) {}
+ Ref(T cls) : fClass(cls) {}
+
+ Ref& operator=(T ref) {
+ fClass = ref;
+ return *this;
+ }
+
+ NE_COPY_DEFAULT(Ref)
+
+ public:
+ T operator->() const { return fClass; }
+
+ T& Leak() noexcept { return fClass; }
+
+ T& TryLeak() noexcept { return fClass; }
+
+ T operator*() { return fClass; }
+
+ operator bool() noexcept { return true; }
+
+ private:
+ T fClass;
+};
+
+template <typename T>
+class NonNullRef final {
+ public:
+ NonNullRef() = delete;
+ NonNullRef(nullPtr) = delete;
+
+ NonNullRef(T* ref) : fRef(ref) { MUST_PASS(ref); }
+ NonNullRef(Ref<T> ref) : fRef(ref) { MUST_PASS(ref); }
+
+ Ref<T>& operator->() {
+ MUST_PASS(fRef);
+ return fRef;
+ }
+
+ NonNullRef& operator=(const NonNullRef<T>& ref) = delete;
+ NonNullRef(const NonNullRef<T>& ref) = default;
+
+ private:
+ Ref<T> fRef{};
+};
+
+using RefAny = Ref<Any>;
+using NonNullRefAny = NonNullRef<Any>;
+} // namespace Kernel
+
+#endif // ifndef _NEKIT_REF_H_
diff --git a/src/kernel/NeKit/Stream.h b/src/kernel/NeKit/Stream.h
new file mode 100644
index 00000000..1a53e7f0
--- /dev/null
+++ b/src/kernel/NeKit/Stream.h
@@ -0,0 +1,45 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+template <typename StreamTrait, typename Kind>
+class Stream final {
+ public:
+ explicit Stream(Ref<Stream> ref) : fStream(ref) {}
+
+ ~Stream() = default;
+
+ Stream& operator=(const Stream&) = default;
+ Stream(const Stream&) = default;
+
+ template <typename Data>
+ friend Stream<StreamTrait, Kind>& operator>>(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf) {
+ Ks.fKind = Ks.fStream->In(Buf);
+ return *Ks;
+ }
+
+ template <typename Data>
+ friend Stream<StreamTrait, Kind>& operator<<(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf) {
+ Ks.fKind = Buf;
+ Ks.fStream->Out(Buf.Leak());
+ return *Ks;
+ }
+
+ Ref<StreamTrait>& AsStreamTrait() { return fStream; }
+
+ Ref<Kind>& AsType() { return fKind; }
+
+ private:
+ Ref<StreamTrait> fStream;
+ Ref<Kind> fKind;
+};
+} // namespace Kernel
diff --git a/src/kernel/NeKit/TOML.h b/src/kernel/NeKit/TOML.h
new file mode 100644
index 00000000..dee273ad
--- /dev/null
+++ b/src/kernel/NeKit/TOML.h
@@ -0,0 +1,15 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+namespace Kernel {
+class TOMLObject final {
+ public:
+ explicit TOMLObject() = delete;
+ ~TOMLObject() = default;
+};
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/NeKit/Utils.h b/src/kernel/NeKit/Utils.h
new file mode 100644
index 00000000..caabd2af
--- /dev/null
+++ b/src/kernel/NeKit/Utils.h
@@ -0,0 +1,62 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+/// =========================================================== ///
+/// @brief ASCII API
+/// =========================================================== ///
+
+Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len);
+Int rt_move_memory(const voidPtr src, voidPtr dst, Size len);
+voidPtr rt_set_memory(voidPtr dst, UInt32 val, Size len);
+void rt_zero_memory(voidPtr pointer, Size len);
+Int rt_string_cmp(const Char* src, const Char* cmp, Size len);
+const Char* rt_alloc_string(const Char* text);
+Size rt_string_len(const Char* str);
+Size rt_string_len(const Char* str, SizeT _len);
+Boolean rt_to_string(Char* str_out, UInt64 base, Int32 limit);
+Boolean rt_is_newln(Int chr);
+Boolean rt_is_space(Int chr);
+Int32 rt_is_alnum(Int character);
+Int rt_to_uppercase(Int c);
+Int rt_to_lower(Int c);
+voidPtr rt_string_in_string(const Char* in, const Char* needle);
+char* rt_string_has_char(Char* str, Char chr);
+
+/// =========================================================== ///
+/// @brief Safe memory functions API
+/// =========================================================== ///
+
+Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size);
+voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size);
+
+/// =========================================================== ///
+/// @brief UNICODE API
+/// =========================================================== ///
+
+Int urt_string_cmp(const Utf8Char* src, const Utf8Char* cmp, Size len);
+Void urt_set_memory(const voidPtr src, UInt32 dst, Size len);
+Int urt_copy_memory(const voidPtr src, voidPtr dst, Size len);
+Size urt_string_len(const Utf8Char* str);
+
+/// =========================================================== ///
+/// @brief OpenEncoding API
+/// =========================================================== ///
+
+template <typename CharType = Char>
+inline SizeT oe_string_len(const CharType* str) {
+ if (!str) return 0;
+
+ SizeT len{0};
+
+ while (str[len] != 0) ++len;
+ return len;
+}
+} // namespace Kernel
diff --git a/src/kernel/NeKit/Variant.h b/src/kernel/NeKit/Variant.h
new file mode 100644
index 00000000..7bcd0dff
--- /dev/null
+++ b/src/kernel/NeKit/Variant.h
@@ -0,0 +1,71 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <NeKit/Json.h>
+#include <NeKit/TOML.h>
+#include <NeKit/KString.h>
+#include <SwapKit/DiskSwap.h>
+
+namespace Kernel {
+class Variant final {
+ public:
+ enum class VariantKind {
+ kInvalid = 0,
+ kString = 200,
+ kBlob,
+ kNull,
+ kJson,
+ kTOML,
+ kSwap,
+ };
+
+ public:
+ explicit Variant() = delete;
+
+ public:
+ NE_COPY_DEFAULT(Variant)
+
+ ~Variant() = default;
+
+ public:
+ template <typename CharKind>
+ explicit Variant(KBasicString<CharKind>* stringView)
+ : fPtr((VoidPtr) stringView), fKind(VariantKind::kString) {}
+
+ explicit Variant(JsonObject<>* json) : fPtr((VoidPtr) json), fKind(VariantKind::kJson) {}
+
+ explicit Variant(TOMLObject* toml) : fPtr((VoidPtr) toml), fKind(VariantKind::kTOML) {}
+
+ explicit Variant(nullPtr ptr) : fPtr(ptr), fKind(VariantKind::kNull) {}
+
+ explicit Variant(SWAP_DISK_HEADER* ptr) : fPtr(ptr), fKind(VariantKind::kSwap) {}
+
+ explicit Variant(VoidPtr ptr) : fPtr(ptr), fKind(VariantKind::kBlob) {}
+
+ public:
+ const Char* ToString();
+
+ /// ========================================================================
+ /// @brief Returns the underlying pointer.
+ /// @return the underlying pointer.
+ /// ========================================================================
+ VoidPtr Leak();
+
+ template <typename T>
+ T* As() noexcept {
+ return reinterpret_cast<T*>(fPtr);
+ }
+
+ VariantKind& Kind();
+
+ private:
+ VoidPtr fPtr{nullptr};
+ VariantKind fKind{VariantKind::kNull};
+};
+} // namespace Kernel
diff --git a/src/kernel/NetworkKit/IP.h b/src/kernel/NetworkKit/IP.h
new file mode 100644
index 00000000..b19d132f
--- /dev/null
+++ b/src/kernel/NetworkKit/IP.h
@@ -0,0 +1,76 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <NeKit/Ref.h>
+
+namespace Kernel {
+class RawIPAddress6;
+class RawIPAddress;
+class IPFactory;
+
+class RawIPAddress final {
+ private:
+ explicit RawIPAddress(UInt8 bytes[4]);
+ ~RawIPAddress() = default;
+
+ RawIPAddress& operator=(const RawIPAddress&) = delete;
+ RawIPAddress(const RawIPAddress&) = default;
+
+ public:
+ UInt8* Address();
+
+ UInt8& operator[](const Size& index);
+
+ BOOL operator==(const RawIPAddress& ipv6);
+ BOOL operator!=(const RawIPAddress& ipv6);
+
+ private:
+ UInt8 fAddr[4];
+
+ friend IPFactory; // it is the one creating these addresses, thus this
+ // is why the constructors are private.
+};
+
+/**
+ * @brief IPv6 address.
+ */
+class RawIPAddress6 final {
+ private:
+ explicit RawIPAddress6(UInt8 Bytes[16]);
+ ~RawIPAddress6() = default;
+
+ RawIPAddress6& operator=(const RawIPAddress6&) = delete;
+ RawIPAddress6(const RawIPAddress6&) = default;
+
+ public:
+ UInt8* Address() { return fAddr; }
+
+ UInt8& operator[](const Size& index);
+
+ bool operator==(const RawIPAddress6& ipv6);
+ bool operator!=(const RawIPAddress6& ipv6);
+
+ private:
+ UInt8 fAddr[16];
+
+ friend IPFactory;
+};
+
+/**
+ * @brief IP Creation helpers
+ */
+class IPFactory final {
+ public:
+ static ErrorOr<KString> ToKString(Ref<RawIPAddress6>& ipv6);
+ static ErrorOr<KString> ToKString(Ref<RawIPAddress>& ipv4);
+ static bool IpCheckVersion4(const Char* ip);
+};
+} // namespace Kernel
diff --git a/src/kernel/NetworkKit/IPC.h b/src/kernel/NetworkKit/IPC.h
new file mode 100644
index 00000000..c08a9457
--- /dev/null
+++ b/src/kernel/NetworkKit/IPC.h
@@ -0,0 +1,90 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license..
+
+ File: IPC.h.
+ Purpose: IPC protocol.
+
+======================================== */
+
+#ifndef INC_IPC_H
+#define INC_IPC_H
+
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <hint/CompilerHint.h>
+
+/// @file IPC.h
+/// @brief IPC comm. protocol.
+
+/// IA separator.
+#define kIPCRemoteSeparator ":"
+
+/// Interchange address, consists of ProcessID:TEAM.
+#define kIPCRemoteInvalid "00:00"
+
+#define kIPCHeaderMagic (0x4950434)
+
+namespace Kernel {
+struct IPC_ADDR;
+struct IPC_MSG;
+
+/// @brief 128-bit IPC address.
+struct PACKED IPC_ADDR final {
+ UInt64 UserProcessID;
+ UInt64 UserProcessTeam;
+
+ ////////////////////////////////////
+ // some operators.
+ ////////////////////////////////////
+
+ BOOL operator==(const IPC_ADDR& addr) noexcept;
+ BOOL operator==(IPC_ADDR& addr) noexcept;
+ BOOL operator!=(const IPC_ADDR& addr) noexcept;
+ BOOL operator!=(IPC_ADDR& addr) noexcept;
+};
+
+typedef struct IPC_ADDR IPC_ADDR;
+
+enum {
+ kIPCLittleEndian = 0,
+ kIPCBigEndian = 1,
+ kIPCMixedEndian = 2,
+};
+
+constexpr inline auto kIPCMsgSize = 6094U;
+
+enum {
+ kIPCLockInvalid = 0,
+ kIPCLockFree = 1,
+ kIPCLockUsed = 2,
+};
+
+/// @brief IPC connection header, message cannot be greater than 6K.
+typedef struct IPC_MSG final {
+ UInt32 IpcHeaderMagic; // cRemoteHeaderMagic
+ UInt8 IpcEndianess; // 0 : LE, 1 : BE
+ SizeT IpcPacketSize;
+ IPC_ADDR IpcFrom;
+ IPC_ADDR IpcTo;
+ UInt32 IpcCRC32;
+ UInt32 IpcMsg;
+ UInt32 IpcMsgSz;
+ UInt8 IpcData[kIPCMsgSize];
+ UInt32 IpcLock;
+ /// @brief Passes the message to target, could be anything, HTTP packet, JSON or whatever.
+ static Bool Pass(IPC_MSG* self, IPC_MSG* target) noexcept;
+} PACKED ALIGN(8) IPC_MSG;
+
+/// @brief Sanitize packet function
+/// @retval true packet is correct.
+/// @retval false packet is incorrect and process has crashed.
+BOOL ipc_sanitize_packet(_Input IPC_MSG* pckt_in);
+
+/// @brief Construct packet function
+/// @retval true packet is correct.
+/// @retval false packet is incorrect and process has crashed.
+BOOL ipc_construct_packet(_Output _Input IPC_MSG** pckt_in);
+} // namespace Kernel
+
+#endif // INC_IPC_H
diff --git a/src/kernel/NetworkKit/LTE.h b/src/kernel/NetworkKit/LTE.h
new file mode 100644
index 00000000..c29f1687
--- /dev/null
+++ b/src/kernel/NetworkKit/LTE.h
@@ -0,0 +1,16 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license..
+
+ File: LTE.h.
+ Purpose: LTE protocol classes.
+
+======================================== */
+
+#ifndef _INC_NETWORK_LTE_H_
+#define _INC_NETWORK_LTE_H_
+
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+
+#endif // ifndef _INC_NETWORK_LTE_H_
diff --git a/src/kernel/NetworkKit/MAC.h b/src/kernel/NetworkKit/MAC.h
new file mode 100644
index 00000000..382eca77
--- /dev/null
+++ b/src/kernel/NetworkKit/MAC.h
@@ -0,0 +1,34 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+
+#define kMACAddrLen (32U)
+
+namespace Kernel {
+class MacAddressGetter;
+
+/// \brief This retrieves the MAC address of the device.
+/// \note Listens for the current NIC.
+class MacAddressGetter final {
+ public:
+ MacAddressGetter() = default;
+ ~MacAddressGetter() = default;
+
+ NE_COPY_DEFAULT(MacAddressGetter)
+
+ public:
+ Array<UInt8, kMACAddrLen>& AsBytes();
+
+ private:
+ Array<UInt8, kMACAddrLen> fMacAddress;
+};
+
+} // namespace Kernel
diff --git a/src/kernel/NetworkKit/NetworkDevice.h b/src/kernel/NetworkKit/NetworkDevice.h
new file mode 100644
index 00000000..3afa8484
--- /dev/null
+++ b/src/kernel/NetworkKit/NetworkDevice.h
@@ -0,0 +1,83 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __INC_NETWORK_DEVICE_H__
+#define __INC_NETWORK_DEVICE_H__
+
+#include <KernelKit/DeviceMgr.h>
+#include <NetworkKit/IP.h>
+
+/// @note Can either work with: Ethernet, GPRS, WiFi
+
+namespace Kernel {
+struct NetworkDeviceCommand;
+class NetworkDevice;
+
+/**
+ * \brief Network device interface, establishes a connection to the NIC.
+ */
+class NetworkDevice final NE_DEVICE<NetworkDeviceCommand> {
+ public:
+ NetworkDevice(void (*out)(DeviceInterface<NetworkDeviceCommand>*, NetworkDeviceCommand),
+ void (*in)(DeviceInterface<NetworkDeviceCommand>*, NetworkDeviceCommand),
+ void (*cleanup)(void) = nullptr);
+
+ ~NetworkDevice() override;
+
+ public:
+ NetworkDevice& operator=(const NetworkDevice&) = default;
+ NetworkDevice(const NetworkDevice&) = default;
+
+ public:
+ const Char* Name() const override;
+ Boolean Name(const Char* newStr);
+
+ private:
+ Void (*fCleanup)(void);
+};
+
+struct NetworkDeviceCommand final {
+ UInt32 CommandName;
+ UInt32 CommandType;
+ UInt32 CommandFlags;
+ VoidPtr CommandBuffer;
+ SizeT CommandSizeBuffer;
+};
+
+/// @brief TCP device.
+using TCPNetworkDevice = NetworkDevice;
+
+/// @brief UDP device.
+using UDPNetworkDevice = NetworkDevice;
+
+/// @brief PPP device.
+using PPPNetworkDevice = NetworkDevice;
+
+/// @brief IPC device.
+using IPCNetworkDevice = NetworkDevice;
+
+/// @brief GRPS device.
+using GPRSNetworkDevice = NetworkDevice;
+
+/// @brief GSM device.
+using GSMNetworkDevice = NetworkDevice;
+
+/// @brief Bluetooth device.
+using BTNetworkDevice = NetworkDevice;
+
+/// @brief Printer device.
+using PrinterNetworkDevice = NetworkDevice;
+
+/// @brief Debug device.
+using DBGNetworkDevice = NetworkDevice;
+
+/// @brief LTE device.
+using LTENetworkDevice = NetworkDevice;
+} // namespace Kernel
+
+#include <NetworkKit/NetworkDevice.inl>
+
+#endif // !__INC_NETWORK_DEVICE_H__
diff --git a/src/kernel/NetworkKit/NetworkDevice.inl b/src/kernel/NetworkKit/NetworkDevice.inl
new file mode 100644
index 00000000..a86d7e56
--- /dev/null
+++ b/src/kernel/NetworkKit/NetworkDevice.inl
@@ -0,0 +1,32 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/***
+ Dtor and ctors.
+*/
+
+#ifndef __INC_NETWORK_DEVICE_H__
+#include <NetworkKit/NetworkDevice.h>
+#endif // __INC_NETWORK_DEVICE_H__
+
+namespace Kernel {
+inline NetworkDevice::NetworkDevice(void (*out)(DeviceInterface<NetworkDeviceCommand>*,
+ NetworkDeviceCommand),
+ void (*in)(DeviceInterface<NetworkDeviceCommand>*,
+ NetworkDeviceCommand),
+ void (*on_cleanup)(void))
+ : DeviceInterface<NetworkDeviceCommand>(out, in), fCleanup(on_cleanup) {
+ kout << "NetworkDevice initialized.\r";
+
+ MUST_PASS(out && in && on_cleanup);
+}
+
+inline NetworkDevice::~NetworkDevice() {
+ kout << "NetworkDevice cleanup.\r";
+
+ if (fCleanup) fCleanup();
+}
+} // namespace Kernel
diff --git a/src/kernel/SignalKit/Signals.h b/src/kernel/SignalKit/Signals.h
new file mode 100644
index 00000000..b4e72fc4
--- /dev/null
+++ b/src/kernel/SignalKit/Signals.h
@@ -0,0 +1,51 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define SIGKILL 1 /* kill */
+#define SIGPAUS 2 /* pause */
+#define SIGEXEC 3 /* execute */
+#define SIGTRAP 4 /* trap */
+#define SIGABRT 5 /* abort */
+#define SIGCONT 6 /* continue */
+#define SIGSEG 7 /* process fault */
+#define SIGBREK 8
+#define SIGATCH 9
+#define SIGDTCH 10
+
+/// @author Amlal El Mahrouss
+/// @brief Signal Generation API.
+
+namespace Kernel {
+typedef SizeT rt_signal_kind;
+
+/// @brief Standard signal seed for general purpose usage.
+inline constexpr auto kUserSignalSeed = 0x0895034fUL;
+
+/// @brief Special signal seed for kernel usage.
+inline constexpr auto kKernelSignalSeed = 0x0895034f9fUL;
+
+/// @brief Generate signal from **Sig**
+template <rt_signal_kind Sig, SizeT Seed = kUserSignalSeed>
+inline rt_signal_kind sig_generate_unique() {
+ static_assert(Sig > 0, "Signal is zero (invalid)");
+ return Sig ^ Seed;
+}
+
+/// @brief Checks if the signal matches the seed (user_seed or kernel_seed)
+template <SizeT Seed>
+inline BOOL sig_matches_seed(rt_signal_kind sig) {
+ return (sig & 0xFF000000) == (Seed & 0xFF000000);
+}
+
+/// @brief Validate signal from **sig**
+inline BOOL sig_validate_unique(rt_signal_kind sig) {
+ return sig > 0;
+}
+} // namespace Kernel
diff --git a/src/kernel/StorageKit/AHCI.h b/src/kernel/StorageKit/AHCI.h
new file mode 100644
index 00000000..82bd9747
--- /dev/null
+++ b/src/kernel/StorageKit/AHCI.h
@@ -0,0 +1,49 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/DriveMgr.h>
+#include <NeKit/OwnPtr.h>
+
+namespace Kernel {
+/// @brief AHCIDeviceInterface class
+/// @details This class is used to send and receive data from the AHCI device.
+/// @note The class is derived from the DeviceInterface class.
+class AHCIDeviceInterface NE_DEVICE<IMountpoint*> {
+ public:
+ explicit AHCIDeviceInterface(void (*out)(DeviceInterface* self, IMountpoint* out),
+ void (*in)(DeviceInterface* self, IMountpoint* in));
+
+ virtual ~AHCIDeviceInterface() override;
+
+ public:
+ AHCIDeviceInterface& operator=(const AHCIDeviceInterface&) = default;
+ AHCIDeviceInterface(const AHCIDeviceInterface&) = default;
+
+ const Char* Name() const override;
+
+ const UInt16& GetPortsImplemented();
+
+ Void SetPortsImplemented(const UInt16& pi);
+
+ const UInt32& GetIndex();
+
+ Void SetIndex(const UInt32& drv);
+
+ public:
+ AHCIDeviceInterface& operator<<(IMountpoint* Data) override;
+ AHCIDeviceInterface& operator>>(IMountpoint* Data) override;
+
+ private:
+ UInt16 fPortsImplemented{0U};
+ UInt32 fDriveIndex{0U};
+};
+
+UInt16 sk_init_ahci_device(BOOL atapi);
+ErrorOr<AHCIDeviceInterface> sk_acquire_ahci_device(UInt32 drv_index);
+} // namespace Kernel
diff --git a/src/kernel/StorageKit/ATA.h b/src/kernel/StorageKit/ATA.h
new file mode 100644
index 00000000..f92e09d3
--- /dev/null
+++ b/src/kernel/StorageKit/ATA.h
@@ -0,0 +1,56 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/DriveMgr.h>
+#include <NeKit/OwnPtr.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+/// @brief ATA device interface class.
+class ATADeviceInterface : public DeviceInterface<IMountpoint*> {
+ public:
+ explicit ATADeviceInterface(void (*Out)(DeviceInterface*, IMountpoint* outpacket),
+ void (*In)(DeviceInterface*, IMountpoint* inpacket));
+
+ virtual ~ATADeviceInterface();
+
+ public:
+ ATADeviceInterface& operator<<(IMountpoint* Data) override;
+ ATADeviceInterface& operator>>(IMountpoint* Data) override;
+
+ public:
+ ATADeviceInterface& operator=(const ATADeviceInterface&) = default;
+ ATADeviceInterface(const ATADeviceInterface&) = default;
+
+ const Char* Name() const override;
+
+ const UInt16& GetIO();
+ Void SetIO(const UInt16& io);
+
+ const UInt16& GetMaster();
+ Void SetMaster(const UInt16& master);
+
+ const UInt32& GetIndex();
+ Void SetIndex(const UInt32& drv);
+
+ private:
+ UInt32 fDriveIndex{0U};
+ UInt16 fIO, fMaster{0U};
+};
+
+/// @brief Initialize an PIO device (StorageKit function)
+/// @param is_master is the current PIO master?
+/// @return [io:master] for PIO device.
+BOOL sk_init_ata_device(BOOL is_master, UInt16& io, UInt8& master);
+
+/// @brief Acquires a new PIO device with drv_index in mind.
+/// @param drv_index The drive index to assign.
+/// @return A wrapped device interface if successful, or error code.
+ErrorOr<ATADeviceInterface> sk_acquire_ata_device(Int32 drv_index);
+} // namespace Kernel
diff --git a/src/kernel/StorageKit/NVME.h b/src/kernel/StorageKit/NVME.h
new file mode 100644
index 00000000..d1c036ab
--- /dev/null
+++ b/src/kernel/StorageKit/NVME.h
@@ -0,0 +1,32 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/DriveMgr.h>
+
+namespace Kernel {
+class NVMEDeviceInterface final NE_DEVICE<IMountpoint*> {
+ public:
+ explicit NVMEDeviceInterface(Void (*out)(DeviceInterface*, IMountpoint* out_packet),
+ Void (*in)(DeviceInterface*, IMountpoint* in_packet),
+ Void (*cleanup)(Void));
+
+ ~NVMEDeviceInterface() override;
+
+ public:
+ NE_COPY_DEFAULT(NVMEDeviceInterface)
+
+ const Char* Name() const override;
+
+ public:
+ OwnPtr<IMountpoint*> operator()(UInt32 dma_low, UInt32 dma_high, SizeT dma_sz);
+
+ private:
+ Void (*fCleanup)(Void) = {nullptr};
+};
+} // namespace Kernel
diff --git a/src/kernel/StorageKit/PRDT.h b/src/kernel/StorageKit/PRDT.h
new file mode 100644
index 00000000..44eb11be
--- /dev/null
+++ b/src/kernel/StorageKit/PRDT.h
@@ -0,0 +1,33 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/PCI/DMA.h>
+#include <KernelKit/PCI/Iterator.h>
+#include <NeKit/Ref.h>
+
+#define kPrdtTransferSize (sizeof(Kernel::UShort))
+
+namespace Kernel {
+/// @brief Tranfer information about PRD.
+enum {
+ kPRDTTransferInProgress,
+ kPRDTTransferIsDone,
+ kPRDTTransferCount,
+};
+
+/// @brief Physical Region Descriptor Table.
+struct PRDT final {
+ UInt32 fPhysAddress;
+ UInt32 fSectorCount;
+ UInt8 fEndBit;
+};
+
+void construct_prdt(Ref<PRDT>& prd);
+
+EXTERN_C Int32 kPRDTTransferStatus;
+} // namespace Kernel
diff --git a/src/kernel/StorageKit/SCSI.h b/src/kernel/StorageKit/SCSI.h
new file mode 100644
index 00000000..4dad00ad
--- /dev/null
+++ b/src/kernel/StorageKit/SCSI.h
@@ -0,0 +1,11 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <modules/SCSI/SCSI.h>
+
+namespace Kernel {} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/StorageKit/StorageKit.h b/src/kernel/StorageKit/StorageKit.h
new file mode 100644
index 00000000..c9633392
--- /dev/null
+++ b/src/kernel/StorageKit/StorageKit.h
@@ -0,0 +1,21 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#define kDriveSectorSizeHDD (512U)
+#define kDriveSectorSizeSSD (512U)
+#define kDriveSectorSizeOptical (2048U)
+
+namespace Kernel {
+template <typename T>
+class DeviceInterface;
+
+class NVMEDeviceInterface;
+class AHCIDeviceInterface;
+class ATADeviceInterface;
+class SCSIDeviceInterface;
+} // namespace Kernel
diff --git a/src/kernel/SwapKit/DiskSwap.h b/src/kernel/SwapKit/DiskSwap.h
new file mode 100644
index 00000000..cd81b13a
--- /dev/null
+++ b/src/kernel/SwapKit/DiskSwap.h
@@ -0,0 +1,72 @@
+
+/* ========================================
+
+ Copyright (C) 2024-2025 Amlal El Mahrouss , licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+#include <hint/CompilerHint.h>
+
+#define kSwapBlockMaxSize (mib_cast(16))
+#define kSwapPageFilePath "/boot/pagefile.sys"
+
+/// @file SwapDisk.h
+/// @brief Virtual memory swap disk.
+
+namespace Kernel {
+struct SWAP_DISK_HEADER;
+class DiskSwapInterface;
+
+/// @brief Virtual memory interface to swap memory chunks onto disk.
+/// @note The class only supports the NeFS as of right now, as it is using forks to write data into
+/// disk.
+class DiskSwapInterface final {
+ public:
+ explicit DiskSwapInterface() = default;
+ ~DiskSwapInterface() = default;
+
+ NE_COPY_DELETE(DiskSwapInterface)
+ NE_MOVE_DELETE(DiskSwapInterface)
+
+ public:
+ /***********************************************************************************/
+ /// @brief Write memory chunk onto disk.
+ /// @param name The swap name to recognize this memory region.
+ /// @param name_len length of fork name.
+ /// @param data the data packet.
+ /// @return Whether the swap was written to disk, or not.
+ /***********************************************************************************/
+ BOOL Write(const Char* name, SizeT name_len, SWAP_DISK_HEADER* data);
+
+ /***********************************************************************************/
+ /// @brief Read memory chunk from disk.
+ /// @param name The swap name to recognize this memory region.
+ /// @param name_len length of fork name.
+ /// @param data the data packet length.
+ /// @return Whether the swap was fetched to disk, or not.
+ /***********************************************************************************/
+ _Output SWAP_DISK_HEADER* Read(const Char* name, SizeT name_len, SizeT data_len);
+};
+
+/// @brief Swap disk header, containing information about the held virtual memory.
+/// @param fMagic Ident number.
+/// @param fHeaderSz This header size.
+/// @param fTeamID Process Team ID.
+/// @param fProcessID Process ID.
+/// @param fVirtualAddress Virtual address pointed by data.
+/// @param fBlobSz Blob's size.
+/// @param fBlob Data blob.
+typedef struct SWAP_DISK_HEADER {
+ UInt32 fMagic;
+ SizeT fHeaderSz;
+ UInt64 fTeamID;
+ UInt64 fProcessID;
+ UInt64 fVirtualAddress;
+ SizeT fBlobSz;
+ UInt8 fBlob[1];
+} PACKED ALIGN(8) SWAP_DISK_HEADER;
+} // namespace Kernel
diff --git a/src/kernel/amd64-ci.make b/src/kernel/amd64-ci.make
new file mode 100644
index 00000000..203d0dc9
--- /dev/null
+++ b/src/kernel/amd64-ci.make
@@ -0,0 +1,77 @@
+##################################################
+# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license.
+# This is the NeKernel's makefile.
+##################################################
+
+CXX = x86_64-w64-mingw32-g++
+LD = x86_64-w64-mingw32-ld
+CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Werror -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEKERNEL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot
+
+ASM = nasm
+
+DISK_DRV =
+
+ifneq ($(ATA_PIO_SUPPORT), )
+DISK_DRV = -D__ATA_PIO__
+endif
+
+ifneq ($(ATA_DMA_SUPPORT), )
+DISK_DRV = -D__ATA_DMA__
+endif
+
+ifneq ($(AHCI_SUPPORT), )
+DISK_DRV = -D__AHCI__
+endif
+
+DEBUG_MACRO = -D__DEBUG__
+
+COPY = cp
+
+# Add assembler, linker, and object files variables.
+ASMFLAGS = -f win64
+
+# Kernel subsystem is 17 and entrypoint is hal_init_platform
+LDFLAGS = -e hal_init_platform --subsystem=17 --image-base 0x4000000
+LDOBJ = obj/*.obj
+
+# This file is the Kernel, responsible of task, memory, driver, sci, disk and device management.
+KERNEL_IMG = ne_kernel
+
+.PHONY: error
+error:
+ @echo "=== ERROR ==="
+ @echo "=> Use a specific target."
+
+MOVEALL=./move-all-x64.sh
+WINDRES=x86_64-w64-mingw32-windres
+
+.PHONY: nekernel-amd64-epm
+nekernel-amd64-epm: clean
+ $(WINDRES) kernel_rsrc.rsrc -O coff -o kernel_rsrc.obj
+ $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s)
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalHandoverStub.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtilsAPI.asm
+ $(MOVEALL)
+
+OBJCOPY=x86_64-w64-mingw32-objcopy
+
+.PHONY: link-amd64-epm
+link-amd64-epm:
+ $(LD) $(LDFLAGS) $(LDOBJ) -o $(KERNEL_IMG)
+
+.PHONY: all
+all: nekernel-amd64-epm link-amd64-epm
+ @echo "Kernel => OK."
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "all: Build Kernel and link it."
+ @echo "link-amd64-epm: Link Kernel for EPM based disks."
+ @echo "nekernel-amd64-epm: Build Kernel for EPM based disks."
+
+.PHONY: clean
+clean:
+ rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL_IMG)
diff --git a/src/kernel/amd64-desktop.make b/src/kernel/amd64-desktop.make
new file mode 100644
index 00000000..081bf75b
--- /dev/null
+++ b/src/kernel/amd64-desktop.make
@@ -0,0 +1,79 @@
+##################################################
+# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license.
+# This is the NeKernel's makefile.
+##################################################
+
+CXX = x86_64-w64-mingw32-g++
+LD = x86_64-w64-mingw32-ld
+CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_OPENHEFS__ -D__FSKIT_INCLUDES_EXT2__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__NEKERNEL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot
+
+ASM = nasm
+
+DISK_DRV =
+
+ifneq ($(ATA_PIO_SUPPORT), )
+DISK_DRV = -D__ATA_PIO__
+endif
+
+ifneq ($(ATA_DMA_SUPPORT), )
+DISK_DRV = -D__ATA_DMA__
+endif
+
+ifneq ($(AHCI_SUPPORT), )
+DISK_DRV = -D__AHCI__
+endif
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG_MACRO = -D__DEBUG__
+endif
+
+COPY = cp
+
+# Add assembler, linker, and object files variables.
+ASMFLAGS = -f win64
+
+# Kernel subsystem is 17 and entrypoint is hal_init_platform
+LDFLAGS = -e hal_init_platform --subsystem=17 --image-base 0x10000000
+LDOBJ = obj/*.obj
+
+# This file is the Kernel, responsible of task, memory, driver, sci, disk and device management.
+KERNEL_IMG = ne_kernel
+
+.PHONY: error
+error:
+ @echo "=== ERROR ==="
+ @echo "=> Use a specific target."
+
+MOVEALL=./move-all-x64.sh
+WINDRES=x86_64-w64-mingw32-windres
+
+.PHONY: nekernel-amd64-epm
+nekernel-amd64-epm: clean
+ $(WINDRES) kernel_rsrc.rsrc -O coff -o kernel_rsrc.obj
+ $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/Network/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s)
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalHandoverStub.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtilsAPI.asm
+ $(MOVEALL)
+
+OBJCOPY=x86_64-w64-mingw32-objcopy
+
+.PHONY: link-amd64-epm
+link-amd64-epm:
+ $(LD) $(LDFLAGS) $(LDOBJ) -o $(KERNEL_IMG)
+
+.PHONY: all
+all: nekernel-amd64-epm link-amd64-epm
+ @echo "Kernel => OK."
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "all: Build Kernel and link it."
+ @echo "link-amd64-epm: Link Kernel for EPM based disks."
+ @echo "nekernel-amd64-epm: Build Kernel for EPM based disks."
+
+.PHONY: clean
+clean:
+ rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL_IMG)
diff --git a/src/kernel/arm64-desktop.make b/src/kernel/arm64-desktop.make
new file mode 100644
index 00000000..f5228d6b
--- /dev/null
+++ b/src/kernel/arm64-desktop.make
@@ -0,0 +1,64 @@
+##################################################
+# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license.
+# This is the microKernel makefile.
+##################################################
+
+CC = clang++
+LD = lld-link
+CCFLAGS = -fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__NE_ARM64__ -fno-rtti -fno-exceptions -I./ \
+ -target aarch64-unknown-windows \
+ -std=c++20 -O3 -D__NEKERNEL__ -D__NEOSKRNL__ -D__NE_VEPM__ -D__NE_MINIMAL_OS__ -D__NE_NO_BUILTIN__ -D__HAVE_NE_APIS__ -D__NE__ -I../
+
+ASM = clang++
+
+DISKDRIVER = -D__USE_FLASH_MEM__
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG = -D__DEBUG__
+endif
+
+COPY = cp
+
+LDFLAGS = -subsystem:efi_application -entry:hal_init_platform /nodefaultlib
+LDOBJ = obj/*.obj
+
+# This file is the Kernel, responsible of task management and memory.
+KERNEL = ne_kernel
+
+.PHONY: error
+error:
+ @echo "=== ERROR ==="
+ @echo "=> Use a specific target."
+
+MOVEALL=./move-all-aarch64.sh
+
+.PHONY: nekernel-arm64-epm
+nekernel-arm64-epm: clean
+ $(CC) $(CCFLAGS) $(DISKDRIVER) $(DEBUG) $(wildcard src/*.cc) \
+ $(wildcard src/FS/*.cc) $(wildcard HALKit/ARM64/Storage/*.cc) \
+ $(wildcard HALKit/ARM64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) \
+ $(wildcard HALKit/ARM64/*.cc) $(wildcard HALKit/ARM64/*.cc) \
+ $(wildcard HALKit/ARM64/*.s) $(wildcard HALKit/ARM64/APM/*.cc)
+
+ $(MOVEALL)
+
+OBJCOPY=x86_64-w64-mingw32-objcopy
+
+.PHONY: link-arm64-epm
+link-arm64-epm:
+ $(LD) $(LDFLAGS) $(LDOBJ) /out:$(KERNEL)
+
+.PHONY: all
+all: nekernel-arm64-epm link-arm64-epm
+ @echo "Kernel => OK."
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "all: Build Kernel and link it."
+ @echo "link-arm64-epm: Link Kernel for EPM based disks."
+ @echo "nekernel-arm64-epm: Build Kernel for EPM based disks."
+
+.PHONY: clean
+clean:
+ rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL)
diff --git a/src/kernel/kernel_rsrc.rsrc b/src/kernel/kernel_rsrc.rsrc
new file mode 100644
index 00000000..0a43086e
--- /dev/null
+++ b/src/kernel/kernel_rsrc.rsrc
@@ -0,0 +1,25 @@
+#include "CompilerKit/Version.h"
+
+1 VERSIONINFO
+FILEVERSION 1,0,0,0
+PRODUCTVERSION 1,0,0,0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080904E4"
+ BEGIN
+ VALUE "CompanyName", "Amlal El Mahrouss"
+ VALUE "FileDescription", "NeKernel"
+ VALUE "FileVersion", KERNEL_VERSION
+ VALUE "InternalName", "ne_kernel"
+ VALUE "LegalCopyright", "(c) 2024-2025 Amlal El Mahrouss, licensed under the Apache 2.0 license."
+ VALUE "OriginalFilename", "ne_kernel"
+ VALUE "ProductName", "NeKernel"
+ VALUE "ProductVersion", KERNEL_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x809, 1252
+ END
+END
diff --git a/src/kernel/move-all-aarch64.sh b/src/kernel/move-all-aarch64.sh
new file mode 100755
index 00000000..35e0909e
--- /dev/null
+++ b/src/kernel/move-all-aarch64.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+for file in *.o; do
+ mv -- "$file" "${file%.o}.obj"
+done
+
+mv *.obj obj/
diff --git a/src/kernel/move-all-x64.sh b/src/kernel/move-all-x64.sh
new file mode 100755
index 00000000..1c135d06
--- /dev/null
+++ b/src/kernel/move-all-x64.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+for file in *.o; do
+ mv -- "$file" "${file%.o}.obj"
+done
+
+mv *.obj HALKit/AMD64/*.obj obj/
diff --git a/src/kernel/obj/.gitkeep b/src/kernel/obj/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/obj/.gitkeep
diff --git a/src/kernel/power64-cb.make b/src/kernel/power64-cb.make
new file mode 100644
index 00000000..c46a00d0
--- /dev/null
+++ b/src/kernel/power64-cb.make
@@ -0,0 +1,4 @@
+##################################################
+# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license.
+# This is the microKernel makefile.
+##################################################
diff --git a/src/kernel/riscv64-cb.make b/src/kernel/riscv64-cb.make
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/kernel/riscv64-cb.make
diff --git a/src/kernel/src/ACPIFactoryInterface.cc b/src/kernel/src/ACPIFactoryInterface.cc
new file mode 100644
index 00000000..42819b7e
--- /dev/null
+++ b/src/kernel/src/ACPIFactoryInterface.cc
@@ -0,0 +1,88 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/HeapMgr.h>
+#include <NeKit/KString.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+
+namespace Kernel {
+constexpr STATIC const auto kMinACPIVer = 1U;
+
+/// @brief Finds a descriptor table inside ACPI XSDT.
+ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) {
+ if (this->fRsdp) return ErrorOr<voidPtr>{-kErrorInvalidData};
+ if (!signature) return ErrorOr<voidPtr>{-kErrorInvalidData};
+ if (*signature == 0) return ErrorOr<voidPtr>{-kErrorInvalidData};
+
+ RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp);
+
+ if (rsp_ptr->Revision < kMinACPIVer) return ErrorOr<voidPtr>{-kErrorInvalidData};
+
+ RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress);
+
+ Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64);
+
+ /***
+ crucial to avoid underflows.
+ */
+ if (num < 1) {
+ /// stop here, we should have entries...
+ ke_panic(RUNTIME_CHECK_ACPI);
+ return ErrorOr<voidPtr>{-kErrorInvalidData};
+ }
+
+ this->fEntries = num;
+
+ (Void)(kout << "ACPI: Number of entries: " << number(this->fEntries) << kendl);
+ (Void)(kout << "ACPI: Revision: " << number(xsdt->Revision) << kendl);
+ (Void)(kout << "ACPI: Signature: " << xsdt->Signature << kendl);
+ (Void)(kout << "ACPI: Address of XSDT: " << hex_number((UIntPtr) xsdt) << kendl);
+
+ static constexpr const UInt16 cAcpiSignatureLength = 4U;
+
+ for (Size index = 0; index < this->fEntries; ++index) {
+ SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]);
+
+ (Void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl);
+ (Void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl);
+
+ for (UInt16 signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) {
+ if (sdt->Signature[signature_index] != signature[signature_index]) break;
+
+ if (signature_index == (cAcpiSignatureLength - 1)) {
+ (Void)(kout << "ACPI: SDT Signature: " << sdt->Signature << kendl);
+ (Void)(kout << "ACPI: SDT OEM ID: " << sdt->OemId << kendl);
+ return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index]));
+ }
+ }
+ }
+
+ return ErrorOr<voidPtr>{-kErrorInvalidData};
+}
+
+/***
+@brief Checksum on SDT header.
+@param checksum the header to checksum
+@param len the length of it.
+*/
+bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) {
+ if (len == 0 || !checksum) return NO;
+
+ Char chr = 0;
+
+ for (SSizeT index = 0L; index < len; ++index) {
+ chr += checksum[index];
+ }
+
+ return chr == 0;
+}
+
+ErrorOr<voidPtr> ACPIFactoryInterface::operator[](const Char* signature) {
+ if (!signature) return ErrorOr<voidPtr>{-kErrorInvalidData};
+ return this->Find(signature);
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Array.cc b/src/kernel/src/Array.cc
new file mode 100644
index 00000000..c792ef93
--- /dev/null
+++ b/src/kernel/src/Array.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Array.h>
diff --git a/src/kernel/src/ArrayList.cc b/src/kernel/src/ArrayList.cc
new file mode 100644
index 00000000..37042320
--- /dev/null
+++ b/src/kernel/src/ArrayList.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/ArrayList.h>
diff --git a/src/kernel/src/AsciiUtils.cc b/src/kernel/src/AsciiUtils.cc
new file mode 100644
index 00000000..1f1ab0f6
--- /dev/null
+++ b/src/kernel/src/AsciiUtils.cc
@@ -0,0 +1,161 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) {
+ for (Size i = 0; i < size; ++i) {
+ if (src[i] != cmp[i]) return static_cast<Int32>(src[i]) - static_cast<Int32>(cmp[i]);
+ }
+ return 0;
+}
+
+SizeT rt_string_len(const Char* str, SizeT max_len) {
+ SizeT len = 0;
+ while (len < max_len && str[len] != '\0') ++len;
+ return len;
+}
+
+Size rt_string_len(const Char* ptr) {
+ Size cnt = 0;
+ while (ptr[cnt] != '\0') ++cnt;
+ return cnt;
+}
+
+const Char* rt_alloc_string(const Char* src) {
+ SizeT slen = rt_string_len(src);
+ Char* buffer = new Char[slen + 1];
+ if (!buffer) return nullptr;
+
+ if (rt_copy_memory_safe(reinterpret_cast<voidPtr>(const_cast<Char*>(src)),
+ reinterpret_cast<voidPtr>(buffer), slen, slen + 1) < 0) {
+ delete[] buffer;
+ return nullptr;
+ }
+
+ buffer[slen] = '\0';
+ return buffer;
+}
+
+Int32 rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size) {
+ if (!src || !dst || len > dst_size) {
+ if (dst && dst_size) {
+ rt_set_memory_safe(dst, 0, dst_size, dst_size);
+ }
+ return -1;
+ }
+
+ auto s = reinterpret_cast<const UInt8*>(src);
+ auto d = reinterpret_cast<UInt8*>(dst);
+
+ for (Size i = 0; i < len; ++i) d[i] = s[i];
+
+ return static_cast<Int>(len);
+}
+
+voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size) {
+ if (!dst || len > dst_size) return nullptr;
+ auto p = reinterpret_cast<UInt8*>(dst);
+ UInt8 v = static_cast<UInt8>(value & 0xFF);
+ for (Size i = 0; i < len; ++i) p[i] = v;
+ return dst;
+}
+
+Void rt_zero_memory(voidPtr pointer, Size len) {
+ rt_set_memory_safe(pointer, 0, len, len);
+}
+
+#ifdef __NE_ENFORCE_DEPRECATED_WARNINGS
+[[deprecated("Use rt_set_memory_safe instead")]]
+#endif
+voidPtr
+rt_set_memory(voidPtr src, UInt32 value, Size len) {
+ if (!src) return nullptr;
+ auto p = reinterpret_cast<UInt8*>(src);
+ UInt8 v = static_cast<UInt8>(value & 0xFF);
+ for (Size i = 0; i < len; ++i) p[i] = v;
+ return src;
+}
+
+#ifdef __NE_ENFORCE_DEPRECATED_WARNINGS
+[[deprecated("Use rt_copy_memory_safe instead")]]
+#endif
+Int32 rt_copy_memory(const voidPtr src, voidPtr dst, Size len) {
+ if (!src || !dst) return -1;
+ auto s = reinterpret_cast<const UInt8*>(src);
+ auto d = reinterpret_cast<UInt8*>(dst);
+
+ for (Size i = 0; i < len; ++i) d[i] = s[i];
+
+ return static_cast<Int>(len);
+}
+
+Int32 rt_to_uppercase(Int ch) {
+ return (ch >= 'a' && ch <= 'z') ? ch - 0x20 : ch;
+}
+
+Int32 rt_to_lower(Int ch) {
+ return (ch >= 'A' && ch <= 'Z') ? ch + 0x20 : ch;
+}
+
+Int32 rt_is_alnum(Int ch) {
+ return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9');
+}
+
+Boolean rt_is_space(Int ch) {
+ return ch == ' ';
+}
+
+Boolean rt_is_newln(Int ch) {
+ return ch == '\n';
+}
+
+Char rt_to_char(UInt64 value, Int32 base) {
+ static constexpr Char kDigits[] = "0123456789ABCDEF";
+ return kDigits[value % base];
+}
+
+Bool rt_to_string(Char* str, UInt64 value, Int32 base) {
+ if (!str || base < 2 || base > 16) return NO;
+
+ Int i = 0;
+ do {
+ str[i++] = rt_to_char(value, base);
+ value /= base;
+ } while (value);
+ str[i] = '\0';
+ // in-place
+ for (Int j = 0; j < i / 2; ++j) {
+ Char tmp = str[j];
+ str[j] = str[i - j - 1];
+ str[i - j - 1] = tmp;
+ }
+
+ return YES;
+}
+
+VoidPtr rt_string_in_string(const Char* haystack, const Char* needle) {
+ if (!haystack || !needle) return nullptr;
+
+ SizeT needle_len = rt_string_len(needle);
+ SizeT hay_len = rt_string_len(haystack);
+
+ if (needle_len > hay_len) return nullptr;
+ for (SizeT i = 0; i <= hay_len - needle_len; ++i) {
+ if (rt_string_cmp(haystack + i, needle, needle_len) == 0) {
+ return reinterpret_cast<voidPtr>(const_cast<Char*>(haystack + i));
+ }
+ }
+ return nullptr;
+}
+
+Char* rt_string_has_char(Char* str, Char ch) {
+ if (!str) return nullptr;
+ while (*str && *str != ch) ++str;
+ return (*str == ch) ? str : nullptr;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Atom.cc b/src/kernel/src/Atom.cc
new file mode 100644
index 00000000..c6c1dd40
--- /dev/null
+++ b/src/kernel/src/Atom.cc
@@ -0,0 +1,10 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Atom.h>
+
+// @file Atom.cc
+// @brief Atomic primitives
diff --git a/src/kernel/src/BinaryMutex.cc b/src/kernel/src/BinaryMutex.cc
new file mode 100644
index 00000000..3c332b33
--- /dev/null
+++ b/src/kernel/src/BinaryMutex.cc
@@ -0,0 +1,70 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/BinaryMutex.h>
+#include <KernelKit/ProcessScheduler.h>
+
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Unlocks the binary mutex.
+/***********************************************************************************/
+
+Bool BinaryMutex::Unlock() noexcept {
+ if (fLockingProcess->Status == ProcessStatusKind::kRunning) {
+ fLockingProcess = nullptr;
+
+ return Yes;
+ }
+
+ return No;
+}
+
+/***********************************************************************************/
+/// @brief Locks process in the binary mutex.
+/***********************************************************************************/
+
+Bool BinaryMutex::Lock(USER_PROCESS* process) {
+ if (!process || this->IsLocked()) return No;
+
+ this->fLockingProcess = process;
+
+ return Yes;
+}
+
+/***********************************************************************************/
+/// @brief Checks if process is locked.
+/***********************************************************************************/
+
+Bool BinaryMutex::IsLocked() const {
+ return this->fLockingProcess->Status == ProcessStatusKind::kRunning;
+}
+
+/***********************************************************************************/
+/// @brief Try lock or wait.
+/***********************************************************************************/
+
+Bool BinaryMutex::LockAndWait(USER_PROCESS* process, TimerInterface* timer) {
+ if (timer == nullptr) return No;
+
+ this->Lock(process);
+
+ timer->Wait();
+
+ return this->Lock(process);
+}
+
+/***********************************************************************************/
+/// @brief Wait for process **sec** until we check if it's free.
+/// @param sec seconds.
+/***********************************************************************************/
+
+BOOL BinaryMutex::WaitForProcess(const UInt32& sec) noexcept {
+ HardwareTimer hw_timer(rtl_milliseconds(sec));
+ hw_timer.Wait();
+
+ return !this->IsLocked();
+}
+} // namespace Kernel
diff --git a/src/kernel/src/BitMapMgr.cc b/src/kernel/src/BitMapMgr.cc
new file mode 100644
index 00000000..d7ecb810
--- /dev/null
+++ b/src/kernel/src/BitMapMgr.cc
@@ -0,0 +1,206 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifdef __NE_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#elif defined(__NE_ARM64__)
+#include <HALKit/ARM64/Paging.h>
+#endif
+
+#include <ArchKit/ArchKit.h>
+#include <NeKit/KernelPanic.h>
+
+#define kBitMapMagic (0x10210U)
+
+#define kBitMapMagIdx (0U)
+#define kBitMapSizeIdx (1U)
+#define kBitMapUsedIdx (2U)
+
+///! @author Amlal El Mahrouss (amlal@nekernel.org)
+
+namespace Kernel {
+namespace HAL {
+ namespace Detail {
+ /***********************************************************************************/
+ /// \brief Proxy Interface to manage a bitmap allocator.
+ /***********************************************************************************/
+ class IBitMapProxy final {
+ public:
+ explicit IBitMapProxy() = default;
+ ~IBitMapProxy() = default;
+
+ NE_COPY_DELETE(IBitMapProxy)
+
+ auto IsBitMap(VoidPtr page_ptr) -> Bool {
+ if (!page_ptr) return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ if (!ptr_bit_set[kBitMapMagIdx] || ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) return No;
+
+ return Yes;
+ }
+
+ auto FreeBitMap(VoidPtr page_ptr) -> Bool {
+ if (this->IsBitMap(page_ptr) == No) return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ kBitMapCursor += ptr_bit_set[kBitMapSizeIdx];
+
+ ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[kBitMapUsedIdx] = No;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ return Yes;
+ }
+
+ UInt32 MakeMMFlags(Bool wr, Bool user) {
+ UInt32 flags = kMMFlagsPresent;
+
+ if (wr) flags |= kMMFlagsWr;
+ if (user) flags |= kMMFlagsUser;
+
+ return flags;
+ }
+
+ /***********************************************************************************/
+ /// @brief Iterate over availables bitmap, until we find a free entry.
+ /// @param base_ptr base pointer to look on.
+ /// @param size the size of the requested data structure.
+ /// @param wr is writable flag?
+ /// @param user is user flag?
+ /// @param pad additional padding added to **size**
+ /// @return The new free address, or nullptr.
+ /***********************************************************************************/
+ auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user, SizeT pad) -> VoidPtr {
+ if (!size) return nullptr;
+
+ if (kBitMapCursor > kKernelBitMpSize) {
+ err_global_get() = kErrorOutOfBitMapMemory;
+
+ (Void)(kout << "Bitmap limit reached, can't allocate more bitmaps." << kendl);
+ return nullptr;
+ }
+
+ VoidPtr base = reinterpret_cast<VoidPtr>((UIntPtr) base_ptr);
+ MUST_PASS(base);
+
+ if (!base) return nullptr;
+
+ STATIC SizeT biggest = 0UL;
+
+ while (YES) {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
+
+ if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic &&
+ ptr_bit_set[kBitMapSizeIdx] == (size + pad)) {
+ if (ptr_bit_set[kBitMapUsedIdx] == No) {
+ ptr_bit_set[kBitMapSizeIdx] = size + pad;
+ ptr_bit_set[kBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeMMFlags(wr, user);
+ mm_map_page(ptr_bit_set, (VoidPtr)mm_get_page_addr(ptr_bit_set), flags);
+
+ if (biggest < (size + pad)) biggest = size + pad;
+
+ kBitMapCursor += size + pad;
+
+ return (VoidPtr) ptr_bit_set;
+ }
+ } else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) {
+ ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[kBitMapSizeIdx] = (size + pad);
+ ptr_bit_set[kBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeMMFlags(wr, user);
+ mm_map_page(ptr_bit_set, (VoidPtr)mm_get_page_addr(ptr_bit_set), flags);
+
+ if (biggest < (size + pad)) biggest = (size + pad);
+
+ kBitMapCursor += size + pad;
+
+ return (VoidPtr) ptr_bit_set;
+ }
+
+ UIntPtr raw_base = reinterpret_cast<UIntPtr>(base);
+ UIntPtr offset = (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
+ ? (size + pad)
+ : ptr_bit_set[kBitMapSizeIdx];
+
+ base = reinterpret_cast<VoidPtr>(raw_base + offset);
+ if (base == nullptr) return nullptr;
+ }
+
+ return nullptr;
+ }
+
+ /// @brief Print Bitmap status
+ auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void {
+ if (!this->IsBitMap(ptr_bit_set)) {
+ (Void)(kout << "Not a BitMap: " << hex_number((UIntPtr) ptr_bit_set) << kendl);
+ return;
+ }
+
+ (Void)(kout << "Magic: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << kendl);
+ (Void)(kout << "Is Allocated? " << (ptr_bit_set[kBitMapUsedIdx] ? "YES" : "NO") << kendl);
+ (Void)(kout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << kendl);
+ (Void)(kout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx]))
+ << kendl);
+ (Void)(kout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx]))
+ << kendl);
+ (Void)(kout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx]))
+ << kendl);
+ (Void)(kout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx]))
+ << kendl);
+ (Void)(kout << "BitMap Address: " << hex_number((UIntPtr) ptr_bit_set) << kendl);
+ }
+ };
+ } // namespace Detail
+
+ STATIC Detail::IBitMapProxy kBitMapMgr;
+
+ auto mm_is_bitmap(VoidPtr ptr) -> BOOL {
+ return kBitMapMgr.IsBitMap(ptr);
+ }
+
+ /***********************************************************************************/
+ /// @brief Allocate a new page to be used by the OS.
+ /// @param wr read/write bit.
+ /// @param user user bit.
+ /// @return a new bitmap allocated pointer.
+ /***********************************************************************************/
+ auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad) -> VoidPtr {
+ VoidPtr ptr_new = nullptr;
+ if (is_page) return nullptr;
+
+ ptr_new = kBitMapMgr.FindBitMap(kKernelBitMpStart, size, wr, user, pad);
+
+ if (!ptr_new) {
+ ke_panic(RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM, "Out of memory bitmap");
+ return nullptr;
+ }
+
+ return ptr_new;
+ }
+
+ /***********************************************************************************/
+ /// @brief Free Bitmap, and mark it as absent.
+ /// @param ptr the pointer to free.
+ /***********************************************************************************/
+ auto mm_free_bitmap(VoidPtr ptr) -> Bool {
+ if (!ptr) return No;
+
+ Bool ret = kBitMapMgr.FreeBitMap(ptr);
+ return ret;
+ }
+} // namespace HAL
+} // namespace Kernel
diff --git a/src/kernel/src/CRuntimeOverrides.cc b/src/kernel/src/CRuntimeOverrides.cc
new file mode 100644
index 00000000..a773d4f9
--- /dev/null
+++ b/src/kernel/src/CRuntimeOverrides.cc
@@ -0,0 +1,27 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Utils.h>
+
+using namespace Kernel;
+
+/// =========================================================== ///
+/// @brief C Standard Library overrides. ///
+/// =========================================================== ///
+
+EXTERN_C void* memset(void* dst, int c, long long unsigned int len) {
+ return Kernel::rt_set_memory_safe(dst, c, static_cast<Size>(len), static_cast<Size>(len));
+}
+
+EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) {
+ Kernel::rt_copy_memory_safe(const_cast<void*>(src), dst, static_cast<Size>(len),
+ static_cast<Size>(len));
+ return dst;
+}
+
+EXTERN_C Int32 strcmp(const char* a, const char* b) {
+ return Kernel::rt_string_cmp(a, b, rt_string_len(a));
+}
diff --git a/src/kernel/src/CodeMgr.cc b/src/kernel/src/CodeMgr.cc
new file mode 100644
index 00000000..7b7add6d
--- /dev/null
+++ b/src/kernel/src/CodeMgr.cc
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/CodeMgr.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+
+/// @brief Executes a new process from a function. Kernel code only.
+/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be
+/// accessible.
+/// @param main the start of the process.
+/// @return The team's process id.
+BOOL rtl_create_kernel_task(HAL::StackFramePtr task, const KID kid) noexcept {
+ if (!kid || task == nullptr) return FALSE;
+ return KernelTaskHelper::Add(task, kid);
+}
+
+/***********************************************************************************/
+/// @brief Executes a new process from a function. Kernel code only.
+/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be
+/// accessible.
+/// @param main the start of the process.
+/// @return if the process was started or not.
+/***********************************************************************************/
+
+ProcessID rtl_create_user_process(rtl_main_kind main, const Char* process_name) noexcept {
+ if (!process_name || *process_name == 0) return kSchedInvalidPID;
+ return UserProcessScheduler::The().Spawn(process_name, reinterpret_cast<VoidPtr>(main), nullptr);
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Crc32.cc b/src/kernel/src/Crc32.cc
new file mode 100644
index 00000000..88a9b73a
--- /dev/null
+++ b/src/kernel/src/Crc32.cc
@@ -0,0 +1,65 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Crc32.h>
+
+#define kCrcCnt (256)
+
+// @file CRC32.cc
+// @brief Check sequence implementation.
+
+namespace Kernel {
+/// @brief The CRC32 seed table.
+UInt32 kChecksumPolys[kCrcCnt] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
+
+/// @brief Calculate CRC32 of p
+/// @param in the data to compute.
+/// @param len the length of the data.
+/// @return CRC32 of **in**.
+UInt32 ke_calculate_crc32(const VoidPtr inp, Int32 len) noexcept {
+ if (!inp) return ~0;
+
+ UInt32 crc = 0xffffffff;
+
+ Char* in = static_cast<Char*>(inp);
+
+ while ((len--) > 0) crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF];
+
+ return ~crc;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Defines.cc b/src/kernel/src/Defines.cc
new file mode 100644
index 00000000..1ae6f12f
--- /dev/null
+++ b/src/kernel/src/Defines.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Defines.h>
diff --git a/src/kernel/src/DeviceMgr.cc b/src/kernel/src/DeviceMgr.cc
new file mode 100644
index 00000000..b392a4ee
--- /dev/null
+++ b/src/kernel/src/DeviceMgr.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/DeviceMgr.h>
+
+namespace Kernel {} // namespace Kernel
diff --git a/src/kernel/src/DriveMgr.cc b/src/kernel/src/DriveMgr.cc
new file mode 100644
index 00000000..8f2611a4
--- /dev/null
+++ b/src/kernel/src/DriveMgr.cc
@@ -0,0 +1,254 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <FirmwareKit/GPT.h>
+#include <FirmwareKit/VEPM.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/DriveMgr.h>
+#include <NeKit/Utils.h>
+#include <modules/AHCI/AHCI.h>
+#include <modules/ATA/ATA.h>
+#include <modules/NVME/NVME.h>
+
+/***********************************************************************************/
+/// @file DriveMgr.cc
+/// @brief Drive Manager of NeKernel.
+///! @author Amlal El Mahrouss (amlal@nekernel.org)
+/***********************************************************************************/
+
+namespace Kernel {
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+STATIC UInt16 kATAIO = 0U;
+STATIC UInt8 kATAMaster = 0U;
+#endif
+
+#if defined(__AHCI__)
+STATIC UInt16 kAHCIPortsImplemented [[maybe_unused]] = 0UL;
+#endif
+
+/// @brief reads from an ATA drive.
+/// @param pckt Packet structure (fPacketContent must be non null)
+/// @return
+Void io_drv_input(DriveTrait::DrivePacket& pckt) {
+#ifdef __AHCI__
+ drv_std_read(pckt.fPacketLba, (Char*) pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize);
+
+ if (err_global_get() != kErrorSuccess) pckt.fPacketGood = NO;
+#elif defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ drv_std_read(pckt.fPacketLba, kATAIO, kATAMaster, (Char*) pckt.fPacketContent, kATASectorSize,
+ pckt.fPacketSize);
+#endif
+}
+
+/// @brief Writes to an ATA drive.
+/// @param pckt the packet to write.
+/// @return
+Void io_drv_output(DriveTrait::DrivePacket& pckt) {
+ if (pckt.fPacketReadOnly) {
+ pckt.fPacketGood = NO;
+ return;
+ }
+
+ // nothing starts before 512 anyways, even an EPM partition.
+ if (!pckt.fPacketReadOnly && pckt.fPacketLba == 0) {
+ pckt.fPacketGood = NO;
+ return;
+ }
+
+#ifdef __AHCI__
+ drv_std_write(pckt.fPacketLba, (Char*) pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize);
+
+ if (err_global_get() != kErrorSuccess) pckt.fPacketGood = NO;
+#elif defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ drv_std_write(pckt.fPacketLba, kATAIO, kATAMaster, (Char*) pckt.fPacketContent, kATASectorSize,
+ pckt.fPacketSize);
+#endif
+}
+
+/// @brief Executes a disk check on the ATA drive.
+/// @param pckt the packet to read.
+/// @return
+Void io_drv_init(DriveTrait::DrivePacket& pckt) {
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ kATAMaster = 0;
+ kATAIO = 0;
+
+ kATAMaster = YES;
+ kATAIO = ATA_PRIMARY_IO;
+
+ if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) {
+ pckt.fPacketGood = YES;
+ return;
+ }
+
+ kATAMaster = NO;
+ kATAIO = ATA_SECONDARY_IO;
+
+ if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) {
+ pckt.fPacketGood = YES;
+ return;
+ }
+
+ pckt.fPacketGood = YES;
+#elif defined(__AHCI__)
+ kAHCIPortsImplemented = 0;
+ drv_std_init(kAHCIPortsImplemented);
+
+ pckt.fPacketGood = kAHCIPortsImplemented > 0;
+#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__)
+}
+
+/// @brief Gets the drive kind (ATA, SCSI, AHCI...)
+/// @param void no arguments.
+/// @return no arguments.
+#ifdef __ATA_PIO__
+const Char* io_drv_kind(Void) {
+ return "ATA-PIO";
+}
+#elif defined(__ATA_DMA__)
+const Char* io_drv_kind(Void) {
+ return "ATA-DMA";
+}
+#elif defined(__AHCI__)
+const Char* io_drv_kind(Void) {
+ return "AHCI";
+}
+#else
+const Char* io_drv_kind(Void) {
+ return "null";
+}
+#endif
+
+/// @brief Unimplemented drive function.
+/// @param pckt the packet to read.
+Void io_drv_unimplemented(DriveTrait::DrivePacket& pckt) noexcept {
+ NE_UNUSED(pckt);
+}
+
+/// @brief Makes a new drive.
+/// @return the new blank drive.
+DriveTrait io_construct_blank_drive() noexcept {
+ DriveTrait trait;
+
+ constexpr auto kBlankDrive = "/media/blank/";
+
+ rt_copy_memory((VoidPtr) kBlankDrive, trait.fName, rt_string_len(kBlankDrive));
+ trait.fKind = kInvalidDrive;
+
+ trait.fInput = io_drv_unimplemented;
+ trait.fOutput = io_drv_unimplemented;
+ trait.fVerify = io_drv_unimplemented;
+ trait.fInit = io_drv_unimplemented;
+ trait.fProtocol = io_drv_kind;
+
+ kout << "DriveMgr: Construct: " << trait.fName << "\r";
+
+ return trait;
+}
+
+namespace Probe {
+ Void io_detect_drive(DriveTrait& trait) {
+ trait.fInit(trait.fPacket);
+
+ EPM_PART_BLOCK block_struct;
+
+ trait.fPacket.fPacketLba = kEPMBootBlockLba;
+ trait.fPacket.fPacketSize = sizeof(EPM_PART_BLOCK);
+ trait.fPacket.fPacketContent = &block_struct;
+
+ rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime,
+ rt_string_len("fs/detect-packet"));
+
+ trait.fInput(trait.fPacket);
+
+ if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0) {
+ trait.fPacket.fPacketReadOnly = NO;
+ trait.fKind = kMassStorageDrive | kEPMDrive;
+
+ kout << "DriveMgr: Disk is EPM formatted.\r";
+
+ trait.fSectorSz = block_struct.SectorSz;
+ trait.fLbaEnd = block_struct.LbaEnd;
+ trait.fLbaStart = block_struct.LbaStart;
+ } else {
+ GPT_PARTITION_TABLE gpt_struct;
+
+ trait.fPacket.fPacketLba = kEPMBootBlockLba;
+ trait.fPacket.fPacketSize = sizeof(GPT_PARTITION_TABLE);
+ trait.fPacket.fPacketContent = &gpt_struct;
+
+ rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime,
+ rt_string_len("fs/detect-packet"));
+
+ trait.fInput(trait.fPacket);
+
+ if (rt_string_cmp(gpt_struct.Signature, kMagicGPT, kMagicLenGPT) == 0) {
+ trait.fPacket.fPacketReadOnly = NO;
+ trait.fKind = kMassStorageDrive | kGPTDrive;
+
+ kout << "DriveMgr: Disk is GPT formatted.\r";
+
+ trait.fSectorSz = gpt_struct.SizeOfEntries;
+ trait.fLbaEnd = gpt_struct.LastGPTEntry;
+ trait.fLbaStart = gpt_struct.FirstGPTEntry;
+ } else {
+ kout << "DriveMgr: Disk is unformatted.\r";
+
+ trait.fPacket.fPacketReadOnly = YES;
+ trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive;
+
+ trait.fSectorSz = 512;
+ trait.fLbaEnd = drv_std_get_sector_count() - 1;
+ trait.fLbaStart = 0x400;
+ }
+ }
+
+ rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime, rt_string_len("*/*"));
+
+ trait.fPacket.fPacketLba = 0;
+ trait.fPacket.fPacketSize = 0UL;
+ trait.fPacket.fPacketContent = nullptr;
+ }
+} // namespace Probe
+
+/// @brief Fetches the main drive.
+/// @return the new drive. (returns kEPMDrive if EPM formatted)
+DriveTrait io_construct_main_drive() noexcept {
+ constexpr auto kMainDrive = "/media/main/";
+
+ DriveTrait trait;
+
+ rt_copy_memory((VoidPtr) kMainDrive, trait.fName, rt_string_len(kMainDrive));
+ MUST_PASS(trait.fName[0] != 0);
+
+ trait.fVerify = io_drv_unimplemented;
+ trait.fOutput = io_drv_output;
+ trait.fInput = io_drv_input;
+ trait.fInit = io_drv_init;
+ trait.fProtocol = io_drv_kind;
+
+ Probe::io_detect_drive(trait);
+
+ return trait;
+}
+
+/// @brief Replacement for io_construct_main_drive that works with IMountpoint.
+/// @return the new drive. (returns kEPMDrive if EPM formatted)
+Void io_construct_main_drive(DriveTrait& trait) noexcept {
+ constexpr auto kMainDrive = "/media/main/";
+
+ rt_copy_memory((VoidPtr) kMainDrive, trait.fName, rt_string_len(kMainDrive));
+ MUST_PASS(trait.fName[0] != 0);
+
+ trait.fVerify = io_drv_unimplemented;
+ trait.fOutput = io_drv_output;
+ trait.fInput = io_drv_input;
+ trait.fInit = io_drv_init;
+ trait.fProtocol = io_drv_kind;
+
+ Probe::io_detect_drive(trait);
+}
+} // namespace Kernel
diff --git a/src/kernel/src/ErrorOr.cc b/src/kernel/src/ErrorOr.cc
new file mode 100644
index 00000000..9f1b550b
--- /dev/null
+++ b/src/kernel/src/ErrorOr.cc
@@ -0,0 +1,12 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/ErrorOr.h>
+
+/***********************************************************************************/
+/// @file ErrorOr.cc ///
+/// @brief ErrorOr container class. ///
+/***********************************************************************************/
diff --git a/src/kernel/src/FS/Ext2+IFS.cc b/src/kernel/src/FS/Ext2+IFS.cc
new file mode 100644
index 00000000..106229f7
--- /dev/null
+++ b/src/kernel/src/FS/Ext2+IFS.cc
@@ -0,0 +1,1555 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __NE_MINIMAL_OS__
+#ifdef __FSKIT_INCLUDES_EXT2__
+
+#include <FSKit/Ext2+IFS.h>
+#include <FSKit/Ext2.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/HeapMgr.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+
+constexpr static UInt32 EXT2_DIRECT_BLOCKS = 12;
+constexpr static UInt32 EXT2_SINGLE_INDIRECT_INDEX = 12;
+constexpr static UInt32 EXT2_DOUBLE_INDIRECT_INDEX = 13;
+constexpr ATTRIBUTE(unused) static UInt32 EXT2_TRIPLE_INDIRECT_INDEX = 14;
+constexpr static UInt32 EXT2_ROOT_INODE = 2;
+constexpr ATTRIBUTE(unused) static UInt32 EXT2_SUPERBLOCK_BLOCK = 1;
+constexpr static UInt32 EXT2_GROUP_DESC_BLOCK_SMALL = 2;
+constexpr static UInt32 EXT2_GROUP_DESC_BLOCK_LARGE = 1;
+
+static inline SizeT ext2_min(SizeT a, SizeT b) {
+ return a < b ? a : b;
+}
+
+struct Ext2GroupInfo {
+ EXT2_GROUP_DESCRIPTOR* groupDesc;
+ UInt32 groupDescriptorBlock;
+ UInt32 offsetInGroupDescBlock;
+ UInt8* blockBuffer;
+};
+
+// Convert EXT2 block number -> LBA (sector index) for Drive I/O.
+static inline UInt32 ext2_block_to_lba(Ext2Context* ctx, UInt32 blockNumber) {
+ if (!ctx || !ctx->drive) return 0;
+ UInt32 blockSize = ctx->BlockSize();
+ UInt32 sectorSize = ctx->drive->fSectorSz;
+ UInt32 sectorsPerBlock = blockSize / sectorSize;
+ return blockNumber * sectorsPerBlock;
+}
+
+// Read a block and return a pointer to its content
+static ErrorOr<UInt32*> ext2_read_block_ptr(Ext2Context* ctx, UInt32 blockNumber) {
+ if (!ctx || !ctx->drive || !ctx->superblock) return ErrorOr<UInt32*>(kErrorInvalidData);
+
+ UInt32 blockSize = ctx->BlockSize();
+ auto buf = (UInt32*) mm_alloc_ptr(blockSize, true, false);
+ if (!buf) return ErrorOr<UInt32*>(kErrorHeapOutOfMemory);
+
+ UInt32 lba = ext2_block_to_lba(ctx, blockNumber);
+ if (!ext2_read_block(ctx->drive, lba, buf, blockSize)) {
+ mm_free_ptr(buf);
+ return ErrorOr<UInt32*>(kErrorDisk);
+ }
+ return ErrorOr<UInt32*>(buf);
+}
+
+// Get the block address for a given logical block index
+static ErrorOr<UInt32> ext2_get_block_address(Ext2Context* ctx, Ext2Node* node,
+ UInt32 logicalIndex) {
+ if (!ctx || !node || !ctx->drive) return ErrorOr<UInt32>(kErrorInvalidData);
+
+ UInt32 blockSize = ctx->BlockSize();
+ UInt32 pointersPerBlock = blockSize / sizeof(UInt32);
+
+ // Direct blocks
+ if (logicalIndex < EXT2_DIRECT_BLOCKS) {
+ UInt32 bn = node->inode.fBlock[logicalIndex];
+ if (bn == 0) return ErrorOr<UInt32>(kErrorInvalidData);
+ return ErrorOr<UInt32>(bn);
+ }
+
+ // Single indirect blocks
+ if (logicalIndex < (EXT2_DIRECT_BLOCKS + pointersPerBlock)) {
+ UInt32 iblock = node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX];
+ if (iblock == 0) return ErrorOr<UInt32>(kErrorInvalidData);
+
+ auto res = ext2_read_block_ptr(ctx, iblock);
+ if (!res) return ErrorOr<UInt32>(res.Error());
+
+ // Using dereference operator
+ UInt32* ptr = *res.Leak(); // operator* returns T (UInt32*)
+
+ UInt32 val = ptr[logicalIndex - EXT2_DIRECT_BLOCKS];
+ mm_free_ptr(ptr);
+
+ if (val == 0) return ErrorOr<UInt32>(kErrorInvalidData);
+ return ErrorOr<UInt32>(val);
+ }
+
+ // Double indirect blocks
+ UInt32 doubleStart = EXT2_DIRECT_BLOCKS + pointersPerBlock;
+ UInt32 doubleSpan = pointersPerBlock * pointersPerBlock;
+ if (logicalIndex < (doubleStart + doubleSpan)) {
+ UInt32 db = node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX];
+ if (db == 0) return ErrorOr<UInt32>(kErrorInvalidData);
+
+ auto dblRes = ext2_read_block_ptr(ctx, db);
+ if (!dblRes) return ErrorOr<UInt32>(dblRes.Error());
+
+ UInt32* dblPtr = *dblRes.Leak();
+
+ UInt32 idxWithin = logicalIndex - doubleStart;
+ UInt32 firstIdx = idxWithin / pointersPerBlock;
+ UInt32 secondIdx = idxWithin % pointersPerBlock;
+ UInt32 singleBlockNum = dblPtr[firstIdx];
+
+ mm_free_ptr(dblPtr);
+ if (singleBlockNum == 0) return ErrorOr<UInt32>(kErrorInvalidData);
+
+ auto singleRes = ext2_read_block_ptr(ctx, singleBlockNum);
+ if (!singleRes) return ErrorOr<UInt32>(singleRes.Error());
+
+ UInt32* singlePtr = *singleRes.Leak();
+ UInt32 val = singlePtr[secondIdx];
+ mm_free_ptr(singlePtr);
+
+ if (val == 0) return ErrorOr<UInt32>(kErrorInvalidData);
+ return ErrorOr<UInt32>(val);
+ }
+
+ return ErrorOr<UInt32>(kErrorUnimplemented);
+}
+
+static ErrorOr<voidPtr> ext2_read_inode_data(Ext2Context* ctx, Ext2Node* node, SizeT size) {
+ if (!ctx || !ctx->drive || !node || size == 0) return ErrorOr<voidPtr>(1);
+
+ auto blockSize = ctx->BlockSize();
+ SizeT available = (node->inode.fSize > node->cursor) ? (node->inode.fSize - node->cursor) : 0;
+ SizeT bytesToRead = (size < available) ? size : available;
+ if (bytesToRead == 0) return ErrorOr<voidPtr>(2); // nothing to read
+
+ auto buffer = mm_alloc_ptr(bytesToRead, true, false);
+ if (!buffer) return ErrorOr<voidPtr>(3); // allocation failed
+
+ UInt32 currentOffset = node->cursor;
+ SizeT remaining = bytesToRead;
+ UInt8* dest = reinterpret_cast<UInt8*>(buffer);
+
+ while (remaining > 0) {
+ UInt32 logicalIndex = currentOffset / blockSize;
+ UInt32 offsetInBlock = currentOffset % blockSize;
+
+ auto phys = ext2_get_block_address(ctx, node, logicalIndex);
+ if (phys.HasError()) {
+ mm_free_ptr(buffer);
+ return ErrorOr<voidPtr>(phys.Error());
+ }
+
+ auto blockNumber = phys.Value();
+ UInt32 lba = ext2_block_to_lba(ctx, blockNumber);
+
+ auto blockBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!blockBuf) {
+ mm_free_ptr(buffer);
+ return ErrorOr<voidPtr>(4); // block buffer allocation failed
+ }
+
+ if (!ext2_read_block(ctx->drive, lba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ mm_free_ptr(buffer);
+ return ErrorOr<voidPtr>(5); // block read failed
+ }
+
+ SizeT chunk = ext2_min(remaining, blockSize - offsetInBlock);
+ rt_copy_memory_safe(static_cast<void*>(static_cast<UInt8*>(blockBuf) + offsetInBlock),
+ static_cast<void*>(dest), chunk, chunk);
+
+ mm_free_ptr(blockBuf);
+
+ currentOffset += static_cast<UInt32>(chunk);
+ dest += chunk;
+ remaining -= chunk;
+ }
+
+ node->cursor += static_cast<UInt32>(bytesToRead);
+ return ErrorOr<voidPtr>(buffer);
+}
+
+// Get group descriptor information for a given block/inode number
+static ErrorOr<Ext2GroupInfo*> ext2_get_group_descriptor_info(Ext2Context* ctx,
+ UInt32 targetBlockOrInode) {
+ if (!ctx || !ctx->superblock || !ctx->drive) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData);
+
+ UInt32 blockSize = ctx->BlockSize();
+ UInt32 blocksPerGroup = ctx->superblock->fBlocksPerGroup;
+ UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup;
+ UInt32 totalBlocks = ctx->superblock->fBlockCount;
+ UInt32 totalInodes = ctx->superblock->fInodeCount;
+
+ if (blocksPerGroup == 0 || inodesPerGroup == 0) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData);
+
+ // block group index
+ UInt32 groupIndex = 0;
+ if (targetBlockOrInode == 0) {
+ groupIndex = 0;
+ } else if (targetBlockOrInode <= totalInodes) {
+ // 1-based
+ groupIndex = (targetBlockOrInode - 1) / inodesPerGroup;
+ } else {
+ // EXT2 block number
+ if (targetBlockOrInode < ctx->superblock->fFirstDataBlock) {
+ groupIndex = 0;
+ } else {
+ groupIndex = (targetBlockOrInode - ctx->superblock->fFirstDataBlock) / blocksPerGroup;
+ }
+ }
+
+ // Calculate number of block groups
+ UInt32 groupsCount = static_cast<UInt32>((totalBlocks + blocksPerGroup - 1) / blocksPerGroup);
+ if (groupIndex >= groupsCount) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData);
+
+ // Determine GDT start block
+ UInt32 gdtStartBlock =
+ (blockSize == 1024) ? EXT2_GROUP_DESC_BLOCK_SMALL : EXT2_GROUP_DESC_BLOCK_LARGE;
+
+ // Compute byte offset of descriptor within the GDT
+ const UInt32 descSize = sizeof(EXT2_GROUP_DESCRIPTOR);
+ UInt64 descByteOffset = static_cast<UInt64>(groupIndex) * descSize;
+
+ // Which EXT2 block contains that descriptor?
+ UInt32 blockOffsetWithinGdt = static_cast<UInt32>(descByteOffset / blockSize);
+ UInt32 offsetInGroupDescBlock = static_cast<UInt32>(descByteOffset % blockSize);
+ UInt32 groupDescriptorBlock = gdtStartBlock + blockOffsetWithinGdt;
+
+ // Allocate buffer and read the block containing the descriptor
+ auto blockBuffer = mm_alloc_ptr(blockSize, true, false);
+ if (!blockBuffer) return ErrorOr<Ext2GroupInfo*>(kErrorHeapOutOfMemory);
+
+ UInt32 groupDescriptorLba = ext2_block_to_lba(ctx, groupDescriptorBlock);
+ if (!ext2_read_block(ctx->drive, groupDescriptorLba, blockBuffer, blockSize)) {
+ mm_free_ptr(blockBuffer);
+ return ErrorOr<Ext2GroupInfo*>(kErrorDisk);
+ }
+
+ auto groupInfo = (Ext2GroupInfo*) mm_alloc_ptr(sizeof(Ext2GroupInfo), true, false);
+ if (!groupInfo) {
+ mm_free_ptr(blockBuffer);
+ return ErrorOr<Ext2GroupInfo*>(kErrorHeapOutOfMemory);
+ }
+
+ groupInfo->groupDesc = reinterpret_cast<EXT2_GROUP_DESCRIPTOR*>(
+ reinterpret_cast<UInt8*>(blockBuffer) + offsetInGroupDescBlock);
+ groupInfo->groupDescriptorBlock = groupDescriptorBlock;
+ groupInfo->offsetInGroupDescBlock = offsetInGroupDescBlock;
+ groupInfo->blockBuffer = reinterpret_cast<UInt8*>(blockBuffer);
+
+ return ErrorOr<Ext2GroupInfo*>(groupInfo);
+}
+
+// Allocate a new block
+inline ErrorOr<UInt32> ext2_alloc_block(Ext2Context* ctx, EXT2_GROUP_DESCRIPTOR* groupDesc) {
+ if (!ctx || !ctx->superblock || !groupDesc) return ErrorOr<UInt32>(kErrorInvalidData);
+
+ UInt32 blockSize = ctx->BlockSize();
+
+ // for the bitmap
+ auto bitmap = mm_alloc_ptr(blockSize, true, false);
+ if (!bitmap) return ErrorOr<UInt32>(kErrorHeapOutOfMemory);
+
+ // Read block bitmap
+ if (!ext2_read_block(ctx->drive, groupDesc->fBlockBitmap, bitmap, blockSize)) {
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(kErrorDisk);
+ }
+
+ // bit = 0
+ for (UInt32 byteIdx = 0; byteIdx < blockSize; ++byteIdx) {
+ auto byte = reinterpret_cast<unsigned char*>(bitmap)[byteIdx];
+ if (byte != 0xFF) {
+ for (int bit = 0; bit < 8; ++bit) {
+ if (!(byte & (1 << bit))) {
+ // Mark bit as used
+ reinterpret_cast<unsigned char*>(bitmap)[byteIdx] |= (1 << bit);
+
+ // Compute block number
+ UInt32 blockNumber = byteIdx * 8 + bit;
+
+ // Write bitmap back
+ if (!ext2_write_block(ctx->drive, groupDesc->fBlockBitmap, bitmap, blockSize)) {
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(kErrorDisk);
+ }
+
+ // Update group descriptor free count
+ groupDesc->fFreeBlocksCount--;
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(blockNumber);
+ }
+ }
+ }
+ }
+
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(kErrorDiskIsFull);
+}
+
+// Indirect blocks
+static ErrorOr<Void*> ext2_set_block_address(Ext2Context* ctx, Ext2Node* node,
+ UInt32 logicalBlockIndex, UInt32 physicalBlockNumber) {
+ using namespace Kernel;
+
+ if (!ctx || !ctx->drive || !node) return ErrorOr<Void*>(kErrorInvalidData);
+
+ auto blockSize = ctx->BlockSize();
+ UInt32 blocksPerPointerBlock = blockSize / sizeof(UInt32);
+
+ // Direct blocks
+ if (logicalBlockIndex < EXT2_DIRECT_BLOCKS) {
+ node->inode.fBlock[logicalBlockIndex] = physicalBlockNumber;
+ return ErrorOr<Void*>(nullptr);
+ }
+
+ // Single indirect blocks
+ if (logicalBlockIndex < EXT2_DIRECT_BLOCKS + blocksPerPointerBlock) {
+ if (node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX] == 0) {
+ auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
+ if (groupInfoRes.HasError()) return ErrorOr<Void*>(groupInfoRes.Error());
+
+ auto groupInfo = groupInfoRes.Leak().Leak(); // Ref<Ext2GroupInfo*>
+ auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
+ if (newBlockRes.HasError()) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(newBlockRes.Error());
+ }
+
+ node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX] = newBlockRes.Leak();
+
+ UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
+ if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ // Zero out new indirect block
+ auto zeroBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!zeroBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory);
+
+ rt_zero_memory(zeroBuf, blockSize);
+ UInt32 indirectLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]);
+ if (!ext2_write_block(ctx->drive, indirectLba, zeroBuf, blockSize)) {
+ mm_free_ptr(zeroBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(zeroBuf);
+ }
+
+ // Read, modify, and write single indirect block
+ auto indirectRes = ext2_read_block_ptr(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]);
+ if (indirectRes.HasError()) return ErrorOr<Void*>(indirectRes.Error());
+
+ UInt32* indirectPtr = indirectRes.Leak().Leak(); // Ref<UInt32*>
+ indirectPtr[logicalBlockIndex - EXT2_DIRECT_BLOCKS] = physicalBlockNumber;
+
+ UInt32 indirectLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]);
+ if (!ext2_write_block(ctx->drive, indirectLba, indirectPtr, blockSize)) {
+ mm_free_ptr(indirectPtr);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(indirectPtr);
+ return ErrorOr<Void*>(nullptr);
+ }
+
+ // Double
+ UInt32 doubleStart = EXT2_DIRECT_BLOCKS + blocksPerPointerBlock;
+ UInt32 doubleSpan = blocksPerPointerBlock * blocksPerPointerBlock;
+ if (logicalBlockIndex < doubleStart + doubleSpan) {
+ if (node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX] == 0) {
+ auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
+ if (groupInfoRes.HasError()) return ErrorOr<Void*>(groupInfoRes.Error());
+
+ auto groupInfo = groupInfoRes.Leak().Leak();
+ auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
+ if (newBlockRes.HasError()) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(newBlockRes.Error());
+ }
+
+ node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX] = newBlockRes.Leak();
+
+ UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
+ if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ // Zero new double-indirect block
+ auto zeroBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!zeroBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory);
+
+ rt_zero_memory(zeroBuf, blockSize);
+ UInt32 dblLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]);
+ if (!ext2_write_block(ctx->drive, dblLba, zeroBuf, blockSize)) {
+ mm_free_ptr(zeroBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(zeroBuf);
+ }
+
+ // Compute indices
+ UInt32 idxWithin = logicalBlockIndex - doubleStart;
+ UInt32 firstIdx = idxWithin / blocksPerPointerBlock;
+ UInt32 secondIdx = idxWithin % blocksPerPointerBlock;
+
+ auto doubleRes = ext2_read_block_ptr(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]);
+ if (doubleRes.HasError()) return ErrorOr<Void*>(doubleRes.Error());
+
+ UInt32* doublePtr = doubleRes.Leak().Leak();
+ UInt32 singleIndirectBlock = doublePtr[firstIdx];
+
+ // Allocate single-indirect if missing
+ if (singleIndirectBlock == 0) {
+ auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
+ if (groupInfoRes.HasError()) {
+ mm_free_ptr(doublePtr);
+ return ErrorOr<Void*>(groupInfoRes.Error());
+ }
+
+ auto groupInfo = groupInfoRes.Leak().Leak();
+ auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
+ if (newBlockRes.HasError()) {
+ mm_free_ptr(doublePtr);
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(newBlockRes.Error());
+ }
+
+ singleIndirectBlock = newBlockRes.Leak();
+ doublePtr[firstIdx] = singleIndirectBlock;
+
+ // Write back GDT
+ UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
+ if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
+ mm_free_ptr(doublePtr);
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ // Zero single-indirect block
+ auto zeroBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!zeroBuf) {
+ mm_free_ptr(doublePtr);
+ return ErrorOr<Void*>(kErrorHeapOutOfMemory);
+ }
+
+ rt_zero_memory(zeroBuf, blockSize);
+ UInt32 singleLba = ext2_block_to_lba(ctx, singleIndirectBlock);
+ if (!ext2_write_block(ctx->drive, singleLba, zeroBuf, blockSize)) {
+ mm_free_ptr(zeroBuf);
+ mm_free_ptr(doublePtr);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(zeroBuf);
+
+ // Write double-indirect back to disk
+ UInt32 dblLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]);
+ if (!ext2_write_block(ctx->drive, dblLba, doublePtr, blockSize)) {
+ mm_free_ptr(doublePtr);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+ }
+
+ mm_free_ptr(doublePtr);
+
+ // Write to single-indirect block
+ auto singleRes = ext2_read_block_ptr(ctx, singleIndirectBlock);
+ if (singleRes.HasError()) return ErrorOr<Void*>(singleRes.Error());
+
+ UInt32* singlePtr = singleRes.Leak().Leak();
+ singlePtr[secondIdx] = physicalBlockNumber;
+
+ UInt32 singleLba = ext2_block_to_lba(ctx, singleIndirectBlock);
+ if (!ext2_write_block(ctx->drive, singleLba, singlePtr, blockSize)) {
+ mm_free_ptr(singlePtr);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(singlePtr);
+ return ErrorOr<Void*>(nullptr);
+ }
+
+ // Triple indirect blocks not implemented
+ return ErrorOr<Void*>(kErrorUnimplemented);
+}
+
+// Find a directory entry by name within a directory inode
+static ErrorOr<EXT2_DIR_ENTRY*> ext2_find_dir_entry(Ext2Context* ctx, Ext2Node* dirNode,
+ const char* name) {
+ if (!ctx || !ctx->drive || !dirNode || !name) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorInvalidData);
+
+ // Check directory type
+ auto type = (dirNode->inode.fMode >> 12) & 0xF;
+ if (type != kExt2FileTypeDirectory) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorInvalidData);
+
+ UInt32 blockSize = ctx->BlockSize();
+ auto blockBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!blockBuf) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorHeapOutOfMemory);
+
+ SizeT nameLen = rt_string_len(name);
+ for (UInt32 i = 0; i < EXT2_DIRECT_BLOCKS; ++i) {
+ UInt32 blockNum = dirNode->inode.fBlock[i];
+ if (blockNum == 0) continue;
+
+ UInt32 lba = ext2_block_to_lba(ctx, blockNum);
+ if (!ext2_read_block(ctx->drive, lba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<EXT2_DIR_ENTRY*>(kErrorDisk);
+ }
+
+ UInt32 offset = 0;
+ while (offset + sizeof(UInt32) + sizeof(UInt16) <= blockSize) {
+ auto onDiskEntry = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + offset);
+ if (onDiskEntry->fRecordLength == 0) break; // corrupted
+
+ if (onDiskEntry->fInode != 0 && onDiskEntry->fNameLength == nameLen) {
+ // Compare names
+ if (rt_string_cmp(name, onDiskEntry->fName, nameLen) == 0) {
+ // Allocate a result sized to hold the name + metadata
+ SizeT recSize = sizeof(EXT2_DIR_ENTRY);
+ auto found = (EXT2_DIR_ENTRY*) mm_alloc_ptr(recSize, true, false);
+ if (!found) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<EXT2_DIR_ENTRY*>(kErrorHeapOutOfMemory);
+ }
+
+ // Copy only record-length bytes
+ rt_copy_memory_safe(onDiskEntry, found, onDiskEntry->fRecordLength, recSize);
+ mm_free_ptr(blockBuf);
+ return ErrorOr<EXT2_DIR_ENTRY*>(found);
+ }
+ }
+ offset += onDiskEntry->fRecordLength;
+ }
+ }
+
+ mm_free_ptr(blockBuf);
+ return ErrorOr<EXT2_DIR_ENTRY*>(kErrorFileNotFound);
+}
+
+// Compute ideal record length for a directory name
+static inline UInt16 ext2_dir_entry_ideal_len(UInt8 nameLen) {
+ UInt16 raw =
+ static_cast<UInt16>(8 + nameLen); // 8 = inode(4)+rec_len(2)+name_len(1)+file_type(1)
+ return static_cast<UInt16>((raw + 3) & ~3u); // align up to 4
+}
+
+static ErrorOr<Void*> ext2_add_dir_entry(Ext2Context* ctx, Ext2Node* parentDirNode,
+ const char* name, UInt32 inodeNumber, UInt8 fileType) {
+ using namespace Kernel;
+
+ if (!ctx || !ctx->drive || !parentDirNode || !name) return ErrorOr<Void*>(kErrorInvalidData);
+
+ UInt32 blockSize = ctx->BlockSize();
+ SizeT nameLen = rt_string_len(name);
+ if (nameLen == 0 || nameLen > 255) return ErrorOr<Void*>(kErrorInvalidData);
+
+ UInt16 newRecIdeal = ext2_dir_entry_ideal_len(static_cast<UInt8>(nameLen));
+
+ auto blockBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!blockBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory);
+
+ for (UInt32 bi = 0; bi < EXT2_DIRECT_BLOCKS; ++bi) {
+ UInt32 blockNum = parentDirNode->inode.fBlock[bi];
+
+ if (blockNum == 0) {
+ // Allocate new block
+ auto groupInfoRes = ext2_get_group_descriptor_info(ctx, parentDirNode->inodeNumber);
+ if (!groupInfoRes) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(groupInfoRes.Error());
+ }
+
+ auto groupInfo = *groupInfoRes.Leak(); // Dereference to get Ext2GroupInfo*
+ auto allocBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
+ if (!allocBlockRes) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(allocBlockRes.Error());
+ }
+
+ UInt32 newBlock = *allocBlockRes.Leak(); // Dereference to get UInt32
+ UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
+
+ if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ // Zero block & insert entry
+ rt_zero_memory(blockBuf, blockSize);
+ auto entry = reinterpret_cast<EXT2_DIR_ENTRY*>(blockBuf);
+ entry->fInode = inodeNumber;
+ entry->fNameLength = static_cast<UInt8>(nameLen);
+ entry->fFileType = fileType;
+ entry->fRecordLength = static_cast<UInt16>(blockSize);
+ rt_copy_memory_safe(const_cast<char*>(name), entry->fName, nameLen, blockSize);
+
+ UInt32 blockLba = ext2_block_to_lba(ctx, newBlock);
+ if (!ext2_write_block(ctx->drive, blockLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ auto setRes = ext2_set_block_address(ctx, parentDirNode, bi, newBlock);
+ if (!setRes) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(setRes.Error());
+ }
+
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(nullptr);
+ }
+
+ // read it
+ UInt32 blockLba = ext2_block_to_lba(ctx, blockNum);
+ if (!ext2_read_block(ctx->drive, blockLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ UInt32 offset = 0;
+ EXT2_DIR_ENTRY* lastEntry = nullptr;
+ UInt32 lastOffset = 0;
+
+ while (offset < blockSize) {
+ if (offset + 8 > blockSize) break;
+ auto e = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + offset);
+ if (e->fRecordLength == 0) break;
+ lastEntry = e;
+ lastOffset = offset;
+ offset += e->fRecordLength;
+ }
+
+ if (!lastEntry) continue;
+
+ UInt16 lastIdeal = ext2_dir_entry_ideal_len(lastEntry->fNameLength);
+
+ if (lastEntry->fRecordLength >= (UInt16) (lastIdeal + newRecIdeal)) {
+ UInt16 origRec = lastEntry->fRecordLength;
+ lastEntry->fRecordLength = lastIdeal;
+
+ UInt32 newOffset = lastOffset + lastIdeal;
+ auto newEntry = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + newOffset);
+ newEntry->fInode = inodeNumber;
+ newEntry->fNameLength = static_cast<UInt8>(nameLen);
+ newEntry->fFileType = fileType;
+ newEntry->fRecordLength = static_cast<UInt16>(origRec - lastIdeal);
+ rt_copy_memory_safe(const_cast<char*>(name), newEntry->fName, nameLen,
+ newEntry->fRecordLength);
+
+ if (!ext2_write_block(ctx->drive, blockLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(nullptr);
+ }
+ }
+
+ // No space in direct blocks -> allocate new block
+ int targetIndex = -1;
+ for (UInt32 i = 0; i < EXT2_DIRECT_BLOCKS; ++i) {
+ if (parentDirNode->inode.fBlock[i] == 0) {
+ targetIndex = i;
+ break;
+ }
+ }
+ if (targetIndex == -1) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(kErrorUnimplemented);
+ }
+
+ auto groupInfoResult = ext2_get_group_descriptor_info(ctx, parentDirNode->inodeNumber);
+ if (!groupInfoResult) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(groupInfoResult.Error());
+ }
+
+ auto groupInfo = *groupInfoResult.Leak(); // Dereference to get Ext2GroupInfo*
+ auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc);
+ if (!newBlockRes) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(newBlockRes.Error());
+ }
+
+ UInt32 newBlockNum = *newBlockRes.Leak(); // Dereference to get UInt32
+ UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock);
+ if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ rt_zero_memory(blockBuf, blockSize);
+ auto entry = reinterpret_cast<EXT2_DIR_ENTRY*>(blockBuf);
+ entry->fInode = inodeNumber;
+ entry->fNameLength = static_cast<UInt8>(nameLen);
+ entry->fFileType = fileType;
+ entry->fRecordLength = static_cast<UInt16>(blockSize);
+ rt_copy_memory_safe(const_cast<char*>(name), entry->fName, nameLen, blockSize);
+
+ UInt32 newBlockLba = ext2_block_to_lba(ctx, newBlockNum);
+ if (!ext2_write_block(ctx->drive, newBlockLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ auto setRes = ext2_set_block_address(ctx, parentDirNode, targetIndex, newBlockNum);
+ if (!setRes) {
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(setRes.Error());
+ }
+
+ mm_free_ptr(blockBuf);
+ return ErrorOr<Void*>(nullptr);
+}
+
+// Soon
+static ErrorOr<UInt32> ext2_alloc_inode(Ext2Context* ctx, EXT2_GROUP_DESCRIPTOR* groupDesc) {
+ if (!ctx || !ctx->superblock || !groupDesc) return ErrorOr<UInt32>(kErrorInvalidData);
+
+ UInt32 blockSize = ctx->BlockSize();
+
+ // buffer for the inode bitmap
+ auto bitmap = mm_alloc_ptr(blockSize, true, false);
+ if (!bitmap) return ErrorOr<UInt32>(kErrorHeapOutOfMemory);
+
+ // Read inode bitmap
+ if (!ext2_read_block(ctx->drive, groupDesc->fInodeBitmap, bitmap, blockSize)) {
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(kErrorDisk);
+ }
+
+ // Find first free inode (bit = 0)
+ for (UInt32 byteIdx = 0; byteIdx < blockSize; ++byteIdx) {
+ auto byte = reinterpret_cast<unsigned char*>(bitmap)[byteIdx];
+ if (byte != 0xFF) {
+ for (int bit = 0; bit < 8; ++bit) {
+ if (!(byte & (1 << bit))) {
+ // Mark bit as used
+ reinterpret_cast<unsigned char*>(bitmap)[byteIdx] |= (1 << bit);
+
+ // Compute inode number
+ UInt32 inodeNumber = byteIdx * 8 + bit + 1; // Inodes are 1-based
+
+ // Write bitmap back
+ if (!ext2_write_block(ctx->drive, groupDesc->fInodeBitmap, bitmap, blockSize)) {
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(kErrorDisk);
+ }
+
+ // Update group descriptor free count
+ groupDesc->fFreeInodesCount--;
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(inodeNumber);
+ }
+ }
+ }
+ }
+
+ mm_free_ptr(bitmap);
+ return ErrorOr<UInt32>(kErrorDiskIsFull);
+}
+
+// to write an inode to its correct location on disk
+static ErrorOr<Void*> ext2_write_inode(Ext2Context* ctx, Ext2Node* node) {
+ using namespace Kernel;
+
+ if (!ctx || !ctx->superblock || !ctx->drive || !node) return ErrorOr<Void*>(kErrorInvalidData);
+
+ auto blockSize = ctx->BlockSize();
+ UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup;
+
+ if (inodesPerGroup == 0) return ErrorOr<Void*>(kErrorInvalidData);
+
+ // Calculate which group this inode belongs to
+ UInt32 groupIndex = (node->inodeNumber - 1) / inodesPerGroup;
+ NE_UNUSED(groupIndex);
+ UInt32 inodeIndexInGroup = (node->inodeNumber - 1) % inodesPerGroup;
+
+ // Get group descriptor
+ auto groupInfoResult = ext2_get_group_descriptor_info(ctx, node->inodeNumber);
+ if (!groupInfoResult) return ErrorOr<Void*>(groupInfoResult.Error());
+
+ auto groupInfo = *groupInfoResult.Leak(); // Dereference to get Ext2GroupInfo*
+
+ // Calculate inode table position
+ UInt32 inodeTableBlock = groupInfo->groupDesc->fInodeTable;
+ UInt32 inodeSize = ctx->superblock->fInodeSize;
+ UInt32 inodesPerBlock = blockSize / inodeSize;
+
+ UInt32 blockOffset = inodeIndexInGroup / inodesPerBlock;
+ UInt32 offsetInBlock = (inodeIndexInGroup % inodesPerBlock) * inodeSize;
+
+ UInt32 inodeBlock = inodeTableBlock + blockOffset;
+ UInt32 inodeLba = ext2_block_to_lba(ctx, inodeBlock);
+
+ // Read the block containing the inode
+ auto blockBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!blockBuf) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(kErrorHeapOutOfMemory);
+ }
+
+ if (!ext2_read_block(ctx->drive, inodeLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ // Copy the updated inode into the block buffer
+ rt_copy_memory_safe(&node->inode, static_cast<void*>((UInt8*) blockBuf + offsetInBlock),
+ sizeof(EXT2_INODE), blockSize - offsetInBlock);
+
+ // Write the block back
+ if (!ext2_write_block(ctx->drive, inodeLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return ErrorOr<Void*>(kErrorDisk);
+ }
+
+ mm_free_ptr(blockBuf);
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ return ErrorOr<Void*>(nullptr);
+}
+
+namespace {
+// new
+struct PathComponents {
+ const char** components;
+ int count;
+ Char* buffer;
+
+ PathComponents(const char* path) : components(nullptr), count(0), buffer(nullptr) {
+ if (!path || *path == '\0') return;
+
+ SizeT pathLen = rt_string_len(path);
+ buffer = (Char*) mm_alloc_ptr(pathLen + 1, true, false);
+ if (!buffer) return;
+
+ rt_copy_memory_safe((void*) path, buffer, pathLen, pathLen + 1);
+ buffer[pathLen] = '\0';
+
+ // temp array
+ const char** temp = (const char**) mm_alloc_ptr(sizeof(char*) * (pathLen + 1), true, false);
+ if (!temp) {
+ mm_free_ptr(buffer);
+ buffer = nullptr;
+ return;
+ }
+
+ UInt32 compCount = 0;
+ Char* p = buffer;
+
+ while (*p != '\0') {
+ // skip slashes
+ while (*p == '/') p++;
+ if (*p == '\0') break;
+
+ Char* start = p;
+ while (*p != '/' && *p != '\0') p++;
+ Char saved = *p;
+ *p = '\0';
+
+ // handle ".", "..", or normal
+ if (rt_string_cmp(start, ".", 1) == 0) {
+ // ignore
+ } else if (rt_string_cmp(start, "..", 2) == 0) {
+ if (compCount > 0) compCount--; // go up one level
+ } else {
+ temp[compCount++] = start;
+ }
+
+ *p = saved;
+ }
+
+ if (compCount == 0) {
+ mm_free_ptr(temp);
+ return;
+ }
+
+ components = (const char**) mm_alloc_ptr(sizeof(char*) * compCount, true, false);
+ if (!components) {
+ mm_free_ptr(temp);
+ return;
+ }
+
+ for (UInt32 i = 0; i < compCount; i++) components[i] = temp[i];
+ count = compCount;
+
+ mm_free_ptr(temp);
+ }
+
+ ~PathComponents() {
+ if (components) mm_free_ptr(components);
+ if (buffer) mm_free_ptr(buffer);
+ }
+};
+} // anonymous namespace
+
+// The Ext2FileSystemParser (not manager!)
+Ext2FileSystemParser::Ext2FileSystemParser(DriveTrait* drive) : fCtx(drive) {
+ MUST_PASS(fCtx);
+}
+
+NodePtr Ext2FileSystemParser::Open(const char* path, const char* restrict_type) {
+ NE_UNUSED(restrict_type);
+ if (!path || *path == '\0' || !this->fCtx.drive) {
+ return nullptr;
+ }
+
+ // Root ("/")
+ if (rt_string_len(path) == 1 && rt_string_cmp(path, "/", 1) == 0) {
+ auto inodeResult = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE);
+ if (!inodeResult) {
+ return nullptr;
+ }
+
+ auto heapNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false);
+ if (!heapNode) return nullptr;
+
+ *heapNode = *inodeResult.Leak().Leak();
+ heapNode->cursor = 0;
+ return reinterpret_cast<NodePtr>(heapNode);
+ }
+
+ PathComponents pathComponents(path);
+ if (pathComponents.count == 0) {
+ return nullptr;
+ }
+
+ UInt32 currentInodeNumber = EXT2_ROOT_INODE;
+ Ext2Node* currentDirNode = nullptr;
+
+ for (UInt32 i = 0; i < (UInt32) pathComponents.count; ++i) {
+ auto inodeResult = ext2_load_inode(&this->fCtx, currentInodeNumber);
+ if (!inodeResult) {
+ if (currentDirNode) mm_free_ptr(currentDirNode);
+ return nullptr;
+ }
+
+ if (currentDirNode) {
+ mm_free_ptr(currentDirNode);
+ currentDirNode = nullptr;
+ }
+
+ currentDirNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false);
+ if (!currentDirNode) {
+ return nullptr;
+ }
+
+ *currentDirNode = *inodeResult.Leak().Leak();
+ currentDirNode->cursor = 0;
+
+ if (i < pathComponents.count - 1U) {
+ UInt32 type = (currentDirNode->inode.fMode >> 12) & 0xF;
+ if (type != kExt2FileTypeDirectory) {
+ mm_free_ptr(currentDirNode);
+ return nullptr;
+ }
+ }
+
+ auto dirEntryResult =
+ ext2_find_dir_entry(&this->fCtx, currentDirNode, pathComponents.components[i]);
+ if (!dirEntryResult) {
+ mm_free_ptr(currentDirNode);
+ return nullptr;
+ }
+
+ EXT2_DIR_ENTRY* entryPtr = *dirEntryResult.Leak();
+ currentInodeNumber = entryPtr->fInode;
+ mm_free_ptr(entryPtr);
+ }
+
+ auto finalInodeResult = ext2_load_inode(&this->fCtx, currentInodeNumber);
+ if (!finalInodeResult) {
+ if (currentDirNode) mm_free_ptr(currentDirNode);
+ return nullptr;
+ }
+
+ if (currentDirNode) {
+ mm_free_ptr(currentDirNode);
+ }
+
+ auto resultNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false);
+ if (!resultNode) {
+ return nullptr;
+ }
+
+ *resultNode = *finalInodeResult.Leak().Leak();
+ resultNode->cursor = 0;
+ return reinterpret_cast<NodePtr>(resultNode);
+}
+
+void* Ext2FileSystemParser::Read(NodePtr node, Int32 flags, SizeT size) {
+ if (!node) return nullptr;
+
+ NE_UNUSED(flags);
+
+ auto extNode = reinterpret_cast<Ext2Node*>(node);
+ auto dataResult = ext2_read_inode_data(&this->fCtx, extNode, size);
+
+ if (!dataResult) {
+ return nullptr; // error, nothing to return
+ }
+
+ void* data = *dataResult.Leak();
+ if (data) {
+ extNode->cursor += static_cast<UInt32>(size);
+ }
+
+ return data;
+}
+
+void Ext2FileSystemParser::Write(NodePtr node, void* data, Int32 flags, SizeT size) {
+ if (!node || !data || size == 0) return;
+
+ NE_UNUSED(flags);
+
+ auto extNode = reinterpret_cast<Ext2Node*>(node);
+ auto blockSize = this->fCtx.BlockSize();
+ SizeT bytesWritten = 0;
+
+ UInt32 currentOffset = extNode->cursor;
+ UInt8* src = reinterpret_cast<UInt8*>(data);
+
+ while (bytesWritten < size) {
+ UInt32 logicalBlockIndex = currentOffset / blockSize;
+ UInt32 offsetInBlock = currentOffset % blockSize;
+
+ auto physBlockResult = ext2_get_block_address(&this->fCtx, extNode, logicalBlockIndex);
+ UInt32 physicalBlock = 0;
+
+ if (!physBlockResult) {
+ auto err = physBlockResult.Error();
+ if (err == kErrorInvalidData || err == kErrorUnimplemented) {
+ auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, extNode->inodeNumber);
+ if (!groupInfoResult) {
+ return;
+ }
+
+ auto groupInfo = *groupInfoResult.Leak();
+ auto allocResult = ext2_alloc_block(&this->fCtx, groupInfo->groupDesc);
+ if (!allocResult) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return;
+ }
+
+ physicalBlock = *allocResult.Leak();
+
+ auto setRes =
+ ext2_set_block_address(&this->fCtx, extNode, logicalBlockIndex, physicalBlock);
+ if (!setRes) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return;
+ }
+
+ UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock);
+ if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, blockSize)) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ return;
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ } else {
+ return;
+ }
+ } else {
+ physicalBlock = physBlockResult.Value();
+ }
+
+ UInt32 physicalLba = ext2_block_to_lba(&this->fCtx, physicalBlock);
+
+ auto blockBuf = mm_alloc_ptr(blockSize, true, false);
+ if (!blockBuf) return;
+
+ if (offsetInBlock > 0 || (size - bytesWritten) < blockSize) {
+ if (!ext2_read_block(this->fCtx.drive, physicalLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ return;
+ }
+ } else {
+ rt_zero_memory(blockBuf, blockSize);
+ }
+
+ UInt32 bytesInCurrentBlock =
+ static_cast<UInt32>(ext2_min(size - bytesWritten, blockSize - offsetInBlock));
+ rt_copy_memory_safe(src, static_cast<void*>((UInt8*) blockBuf + offsetInBlock),
+ bytesInCurrentBlock, blockSize - offsetInBlock);
+
+ if (!ext2_write_block(this->fCtx.drive, physicalLba, blockBuf, blockSize)) {
+ mm_free_ptr(blockBuf);
+ return;
+ }
+
+ mm_free_ptr(blockBuf);
+
+ currentOffset += bytesInCurrentBlock;
+ src += bytesInCurrentBlock;
+ bytesWritten += bytesInCurrentBlock;
+ }
+
+ if (currentOffset > extNode->inode.fSize) {
+ extNode->inode.fSize = currentOffset;
+ }
+
+ extNode->inode.fBlocks = (extNode->inode.fSize + blockSize - 1) / blockSize;
+ extNode->inode.fModifyTime = 0;
+
+ auto writeInodeRes = ext2_write_inode(&this->fCtx, extNode);
+ if (!writeInodeRes) {
+ // Failed to persist inode
+ }
+
+ extNode->cursor = currentOffset;
+}
+
+bool Ext2FileSystemParser::Seek(NodePtr node, SizeT offset) {
+ if (!node) return false;
+ auto extNode = reinterpret_cast<Ext2Node*>(node);
+ extNode->cursor = static_cast<UInt32>(offset);
+ return true;
+}
+
+SizeT Ext2FileSystemParser::Tell(NodePtr node) {
+ if (!node) return 0;
+ auto extNode = reinterpret_cast<Ext2Node*>(node);
+ return extNode->cursor;
+}
+
+bool Ext2FileSystemParser::Rewind(NodePtr node) {
+ if (!node) return false;
+ auto extNode = reinterpret_cast<Ext2Node*>(node);
+ extNode->cursor = 0;
+ return true;
+}
+
+void* Ext2FileSystemParser::Read(const char* name, NodePtr node, Int32 flags, SizeT size) {
+ NE_UNUSED(name);
+ return Read(node, flags, size);
+}
+
+void Ext2FileSystemParser::Write(const char* name, NodePtr node, void* data, Int32 flags,
+ SizeT size) {
+ NE_UNUSED(name);
+ Write(node, data, flags, size);
+}
+
+NodePtr Ext2FileSystemParser::Create(const char* path) {
+ if (!path || *path == '\0') return nullptr;
+
+ PathComponents pathComponents(path);
+ if (pathComponents.count == 0) return nullptr;
+
+ const char* filename = pathComponents.components[pathComponents.count - 1];
+ if (rt_string_len(filename) > kExt2FSMaxFileNameLen) return nullptr;
+
+ // Build parent path
+ Char parentPathBuf[256] = {0};
+ SizeT currentPathLen = 0;
+ for (UInt32 i = 0; (i < pathComponents.count - 1U); ++i) {
+ SizeT componentLen = rt_string_len(pathComponents.components[i]);
+ if (currentPathLen + componentLen + 1 >= sizeof(parentPathBuf)) return nullptr;
+ if (i > 0) parentPathBuf[currentPathLen++] = '/';
+ rt_copy_memory_safe(const_cast<char*>(pathComponents.components[i]),
+ parentPathBuf + currentPathLen, componentLen,
+ sizeof(parentPathBuf) - currentPathLen);
+ currentPathLen += componentLen;
+ }
+ parentPathBuf[currentPathLen] = '\0';
+
+ // Open parent directory
+ NodePtr parentDirNodePtr = nullptr;
+ if (currentPathLen == 0) {
+ // root
+ auto inodeRes = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE);
+ if (!inodeRes) return nullptr;
+ parentDirNodePtr = mm_alloc_ptr(sizeof(Ext2Node), true, false);
+ if (!parentDirNodePtr) return nullptr;
+ *reinterpret_cast<Ext2Node*>(parentDirNodePtr) = *inodeRes.Leak().Leak();
+ reinterpret_cast<Ext2Node*>(parentDirNodePtr)->cursor = 0;
+ } else {
+ parentDirNodePtr = Open(parentPathBuf, "r");
+ }
+
+ if (!parentDirNodePtr) return nullptr;
+
+ auto parentDirNode = reinterpret_cast<Ext2Node*>(parentDirNodePtr);
+
+ // Ensure parent is a directory
+ UInt32 type = (parentDirNode->inode.fMode >> 12) & 0xF;
+ if (type != kExt2FileTypeDirectory) {
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ // Get group info for allocation
+ auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, parentDirNode->inodeNumber);
+ if (!groupInfoResult) {
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+ auto groupInfo = *groupInfoResult.Leak();
+
+ // Allocate new inode
+ auto newInodeRes = ext2_alloc_inode(&this->fCtx, groupInfo->groupDesc);
+ if (!newInodeRes) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo); // so this works
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+ UInt32 newInodeNumber = newInodeRes.Value();
+
+ UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock);
+ if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, this->fCtx.BlockSize())) {
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ // Create new Ext2Node
+ Ext2Node* newFileNode = reinterpret_cast<Ext2Node*>(mm_alloc_ptr(sizeof(Ext2Node), true, false));
+ if (!newFileNode) {
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ newFileNode->inodeNumber = newInodeNumber;
+ rt_zero_memory(&newFileNode->inode, sizeof(EXT2_INODE));
+
+ newFileNode->inode.fMode = (kExt2FileTypeRegular << 12);
+ newFileNode->inode.fUID = 0;
+ newFileNode->inode.fGID = 0;
+ newFileNode->inode.fLinksCount = 1;
+ newFileNode->inode.fSize = 0;
+ newFileNode->inode.fBlocks = 0;
+ newFileNode->inode.fCreateTime = 0;
+ newFileNode->inode.fModifyTime = 0;
+
+ // Persist new inode
+ auto writeInodeRes = ext2_write_inode(&this->fCtx, newFileNode);
+ if (!writeInodeRes) {
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newFileNode);
+ return nullptr;
+ }
+
+ // Add directory entry
+ auto addRes = ext2_add_dir_entry(&this->fCtx, parentDirNode, filename, newInodeNumber,
+ kExt2FileTypeRegular);
+ if (!addRes) {
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newFileNode);
+ return nullptr;
+ }
+
+ // Update parent inode
+ auto parentWriteRes = ext2_write_inode(&this->fCtx, parentDirNode);
+ // ignore failure
+
+ NE_UNUSED(parentWriteRes);
+
+ mm_free_ptr(parentDirNode);
+ return reinterpret_cast<NodePtr>(newFileNode);
+}
+
+NodePtr Ext2FileSystemParser::CreateDirectory(const char* path) {
+ if (!path || *path == '\0') return nullptr;
+
+ PathComponents pathComponents(path);
+ if (pathComponents.count == 0) {
+ kout << "EXT2: Failed to parse path for CreateDirectory.\n";
+ return nullptr;
+ }
+
+ const char* dirname = pathComponents.components[pathComponents.count - 1];
+ if (rt_string_len(dirname) > kExt2FSMaxFileNameLen) {
+ kout << "EXT2: Directory name too long: " << dirname << ".\n";
+ return nullptr;
+ }
+
+ // Build parent path
+ Char parentPathBuf[256];
+ SizeT currentPathLen = 0;
+ for (UInt32 i = 0; (i < pathComponents.count - 1U); ++i) {
+ SizeT componentLen = rt_string_len(pathComponents.components[i]);
+ if (currentPathLen + componentLen + 1 >= sizeof(parentPathBuf)) {
+ kout << "EXT2: Parent path too long for CreateDirectory.\n";
+ return nullptr;
+ }
+
+ if (i > 0) parentPathBuf[currentPathLen++] = '/';
+
+ rt_copy_memory_safe(static_cast<void*>(const_cast<char*>(pathComponents.components[i])),
+ static_cast<void*>(parentPathBuf + currentPathLen), componentLen,
+ sizeof(parentPathBuf) - currentPathLen);
+ currentPathLen += componentLen;
+ }
+
+ parentPathBuf[currentPathLen] = '\0';
+
+ // Open parent directory node
+ NodePtr parentDirNodePtr = nullptr;
+ if (currentPathLen == 0) {
+ auto inodeRes = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE);
+ if (!inodeRes) {
+ return nullptr;
+ }
+
+ parentDirNodePtr = reinterpret_cast<NodePtr>(mm_alloc_ptr(sizeof(Ext2Node), true, false));
+ if (!parentDirNodePtr) return nullptr;
+
+ *reinterpret_cast<Ext2Node*>(parentDirNodePtr) = *inodeRes.Leak().Leak();
+ reinterpret_cast<Ext2Node*>(parentDirNodePtr)->cursor = 0;
+ } else {
+ parentDirNodePtr = Open(parentPathBuf, "r");
+ }
+
+ if (!parentDirNodePtr) {
+ kout << "EXT2: Failed to open parent directory for CreateDirectory: " << parentPathBuf << ".\n";
+ return nullptr;
+ }
+
+ auto parentDirNode = reinterpret_cast<Ext2Node*>(parentDirNodePtr);
+
+ // Check parent is a directory
+ UInt32 parentType = (parentDirNode->inode.fMode >> 12) & 0xF;
+ if (parentType != kExt2FileTypeDirectory) {
+ kout << "EXT2: Parent is not a directory: " << parentPathBuf << ".\n";
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ // Allocate inode
+ auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, parentDirNode->inodeNumber);
+ if (!groupInfoResult) {
+ kout << "EXT2: Failed to get group descriptor info for new dir inode.\n";
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ auto groupInfo = *groupInfoResult.Leak();
+ auto newInodeRes = ext2_alloc_inode(&this->fCtx, groupInfo->groupDesc);
+ if (!newInodeRes) {
+ kout << "EXT2: Failed to allocate inode for new directory.\n";
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ UInt32 newInodeNumber = *newInodeRes.Leak();
+
+ // Write back group descriptor block
+ UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock);
+ if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, this->fCtx.BlockSize())) {
+ kout << "EXT2: Failed to write group descriptor after inode allocation.\n";
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer));
+ mm_free_ptr(groupInfo);
+
+ // Create new Ext2Node and initialize inode fields
+ Ext2Node* newDirNode = reinterpret_cast<Ext2Node*>(mm_alloc_ptr(sizeof(Ext2Node), true, false));
+ if (!newDirNode) {
+ kout << "EXT2: Out of memory for new directory node.\n";
+ mm_free_ptr(parentDirNode);
+ return nullptr;
+ }
+
+ newDirNode->inodeNumber = newInodeNumber;
+ rt_zero_memory(&newDirNode->inode, sizeof(EXT2_INODE));
+ newDirNode->inode.fMode = (kExt2FileTypeDirectory << 12);
+ newDirNode->inode.fUID = 0;
+ newDirNode->inode.fGID = 0;
+ newDirNode->inode.fLinksCount = 2; // . and ..
+ newDirNode->inode.fSize = this->fCtx.BlockSize();
+ newDirNode->inode.fBlocks = 1;
+ newDirNode->inode.fCreateTime = 0;
+ newDirNode->inode.fModifyTime = 0;
+
+ // Allocate a data block for the new directory
+ auto groupForBlockRes = ext2_get_group_descriptor_info(&this->fCtx, newDirNode->inodeNumber);
+ if (!groupForBlockRes) {
+ kout << "EXT2: Failed to get group info for directory block allocation.\n";
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ auto groupForBlock = *groupForBlockRes.Leak();
+ auto newBlockRes = ext2_alloc_block(&this->fCtx, groupForBlock->groupDesc);
+ if (!newBlockRes) {
+ kout << "EXT2: Failed to allocate block for new directory contents.\n";
+ mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer));
+ mm_free_ptr(groupForBlock);
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ UInt32 newDirBlockNum = *newBlockRes.Leak();
+
+ // Write back GDT
+ UInt32 gdtLba2 = ext2_block_to_lba(&this->fCtx, groupForBlock->groupDescriptorBlock);
+ if (!ext2_write_block(this->fCtx.drive, gdtLba2, groupForBlock->blockBuffer,
+ this->fCtx.BlockSize())) {
+ kout << "EXT2: Failed to write GDT after directory block allocation.\n";
+ mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer));
+ mm_free_ptr(groupForBlock);
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer));
+ mm_free_ptr(groupForBlock);
+
+ // Set the block in newDirNode
+ auto setBlkRes = ext2_set_block_address(&this->fCtx, newDirNode, 0, newDirBlockNum);
+ if (!setBlkRes) {
+ kout << "EXT2: Failed to set data block for new directory.\n";
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ // Prepare block with '.' and '..'
+ auto dirBlockBuf = mm_alloc_ptr(this->fCtx.BlockSize(), true, false);
+ if (!dirBlockBuf) {
+ kout << "EXT2: Out of memory preparing directory block.\n";
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ rt_zero_memory(dirBlockBuf, this->fCtx.BlockSize());
+
+ // '.' entry
+ auto dot = reinterpret_cast<EXT2_DIR_ENTRY*>(dirBlockBuf);
+ dot->fInode = newInodeNumber;
+ dot->fNameLength = 1;
+ dot->fFileType = kExt2FileTypeDirectory;
+ dot->fRecordLength = ext2_dir_entry_ideal_len(dot->fNameLength);
+ dot->fName[0] = '.';
+
+ // '..' entry occupies rest of block
+ auto dotdot = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) dirBlockBuf + dot->fRecordLength);
+ dotdot->fInode = parentDirNode->inodeNumber;
+ dotdot->fNameLength = 2;
+ dotdot->fFileType = kExt2FileTypeDirectory;
+ dotdot->fRecordLength = static_cast<UInt16>(this->fCtx.BlockSize() - dot->fRecordLength);
+ dotdot->fName[0] = '.';
+ dotdot->fName[1] = '.';
+
+ // Write dir block to disk
+ UInt32 newDirBlockLba = ext2_block_to_lba(&this->fCtx, newDirBlockNum);
+ if (!ext2_write_block(this->fCtx.drive, newDirBlockLba, dirBlockBuf, this->fCtx.BlockSize())) {
+ kout << "EXT2: Failed to write directory block to disk.\n";
+ mm_free_ptr(dirBlockBuf);
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ mm_free_ptr(dirBlockBuf);
+
+ // Persist new directory inode
+ auto writeInodeRes = ext2_write_inode(&this->fCtx, newDirNode);
+ if (!writeInodeRes) {
+ kout << "EXT2: Failed to write new directory inode to disk.\n";
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ // Add directory entry into parent
+ auto addRes = ext2_add_dir_entry(&this->fCtx, parentDirNode, dirname, newInodeNumber,
+ kExt2FileTypeDirectory);
+ if (!addRes) {
+ kout << "EXT2: Failed to add directory entry for '" << dirname << "' to parent.\n";
+ mm_free_ptr(parentDirNode);
+ mm_free_ptr(newDirNode);
+ return nullptr;
+ }
+
+ // Increment parent link count and persist parent inode
+ parentDirNode->inode.fLinksCount += 1;
+ auto parentWriteRes = ext2_write_inode(&this->fCtx, parentDirNode);
+ if (!parentWriteRes) {
+ kout << "EXT2: Warning: failed to update parent inode after directory creation.\n";
+ }
+
+ mm_free_ptr(parentDirNode);
+ return reinterpret_cast<NodePtr>(newDirNode);
+}
+
+#endif
+#endif
diff --git a/src/kernel/src/FS/NeFS+FileMgr.cc b/src/kernel/src/FS/NeFS+FileMgr.cc
new file mode 100644
index 00000000..0fdabd6f
--- /dev/null
+++ b/src/kernel/src/FS/NeFS+FileMgr.cc
@@ -0,0 +1,276 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __NE_MINIMAL_OS__
+#ifdef __FSKIT_INCLUDES_NEFS__
+
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/HeapMgr.h>
+
+/// @brief NeFS File System Manager.
+/// BUGS: 0
+
+namespace Kernel {
+static inline bool is_valid_nefs_catalog(NodePtr node);
+
+/// @brief C++ constructor
+NeFileSystemMgr::NeFileSystemMgr() {
+ mParser = new NeFileSystemParser();
+ MUST_PASS(mParser);
+
+ kout << "We are done allocating NeFileSystemParser...\n";
+}
+
+NeFileSystemMgr::~NeFileSystemMgr() {
+ if (mParser) {
+ kout << "Destroying NeFileSystemParser...\n";
+ delete mParser;
+ mParser = nullptr;
+ }
+}
+
+/// @brief Removes a node from the filesystem.
+/// @param path The filename
+/// @return If it was deleted or not.
+bool NeFileSystemMgr::Remove(_Input const Char* path) {
+ if (path == nullptr || *path == 0) {
+ kout << "NeFS: Remove called with null or empty path\n";
+ return false;
+ }
+ return mParser->RemoveCatalog(path);
+}
+
+/// @brief Creates a node with the specified.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr NeFileSystemMgr::Create(_Input const Char* path) {
+ if (!path || *path == 0) {
+ kout << "NeFS: Create called with null or empty path\n";
+ return nullptr;
+ }
+ return rtl_node_cast(mParser->CreateCatalog(path));
+}
+
+/// @brief Creates a node which is a directory.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) {
+ if (!path || *path == 0) {
+ kout << "NeFS: CreateDirectory called with null or empty path\n";
+ return nullptr;
+ }
+ return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindDir));
+}
+
+/// @brief Creates a node which is an alias.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr NeFileSystemMgr::CreateAlias(const Char* path) {
+ if (!path || *path == 0) {
+ kout << "NeFS: CreateAlias called with null or empty path\n";
+ return nullptr;
+ }
+ return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindAlias));
+}
+
+NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) {
+ if (!path || *path == 0) {
+ kout << "NeFS: CreateSwapFile called with null or empty path\n";
+ return nullptr;
+ }
+ return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindPage));
+}
+
+/// @brief Gets the root directory.
+/// @return
+const Char* NeFileSystemHelper::Root() {
+ return kNeFSRoot;
+}
+
+/// @brief Gets the up-dir directory.
+/// @return
+const Char* NeFileSystemHelper::UpDir() {
+ return kNeFSUpDir;
+}
+
+/// @brief Gets the separator character.
+/// @return
+Char NeFileSystemHelper::Separator() {
+ return kNeFSSeparator;
+}
+
+/// @brief Gets the metafile character.
+/// @return
+Char NeFileSystemHelper::MetaFile() {
+ return kNeFSMetaFilePrefix;
+}
+
+/// @brief Opens a new file.
+/// @param path
+/// @param r
+/// @return
+_Output NodePtr NeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) {
+ if (!path || *path == 0) {
+ kout << "NeFS: Open called with null or empty path\n";
+ return nullptr;
+ }
+ if (!r || *r == 0) {
+ kout << "NeFS: Open called with null or empty mode string\n";
+ return nullptr;
+ }
+ auto catalog = mParser->GetCatalog(path);
+ if (!catalog) {
+ kout << "NeFS: Open could not find catalog for path\n";
+ return nullptr;
+ }
+ return rtl_node_cast(catalog);
+}
+
+Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) {
+ if (!is_valid_nefs_catalog(node)) {
+ kout << "NeFS: Write called with invalid node pointer\n";
+ return;
+ }
+ if (!data) {
+ kout << "NeFS: Write called with null data pointer\n";
+ return;
+ }
+ if (!size || size > kNeFSForkSize) {
+ (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size));
+ kout << "\n";
+ return;
+ }
+ constexpr auto kDataForkName = kNeFSDataFork;
+ this->Write(kDataForkName, node, data, flags, size);
+}
+
+_Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) {
+ if (!is_valid_nefs_catalog(node)) {
+ kout << "NeFS: Read called with invalid node pointer\n";
+ return nullptr;
+ }
+ if (!size || size > kNeFSForkSize) {
+ (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size));
+ kout << "\n";
+ return nullptr;
+ }
+ constexpr auto kDataForkName = kNeFSDataFork;
+ return this->Read(kDataForkName, node, flags, size);
+}
+
+Void NeFileSystemMgr::Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data,
+ _Input Int32 flags, _Input SizeT size) {
+ if (!is_valid_nefs_catalog(node)) {
+ kout << "NeFS: Write(fork) called with invalid node pointer\n";
+ return;
+ }
+ if (!name || *name == 0) {
+ kout << "NeFS: Write(fork) called with null or empty fork name\n";
+ return;
+ }
+ if (!data) {
+ kout << "NeFS: Write(fork) called with null data pointer\n";
+ return;
+ }
+ if (!size || size > kNeFSForkSize) {
+ (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size));
+ kout << "\n";
+ return;
+ }
+ NE_UNUSED(flags);
+ auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node);
+ if (cat->Kind == kNeFSCatalogKindFile) {
+ mParser->WriteCatalog(cat->Name, (flags & kFileFlagRsrc ? true : false), data, size, name);
+ }
+}
+
+_Output VoidPtr NeFileSystemMgr::Read(_Input const Char* name, _Input NodePtr node,
+ _Input Int32 flags, _Input SizeT sz) {
+ if (!is_valid_nefs_catalog(node)) {
+ kout << "NeFS: Read(fork) called with invalid node pointer\n";
+ return nullptr;
+ }
+ if (!name || *name == 0) {
+ kout << "NeFS: Read(fork) called with null or empty fork name\n";
+ return nullptr;
+ }
+ if (!sz || sz > kNeFSForkSize) {
+ (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(sz));
+ kout << "\n";
+ return nullptr;
+ }
+ NE_UNUSED(flags);
+ auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node);
+ if (cat->Kind == kNeFSCatalogKindFile) {
+ return mParser->ReadCatalog(cat, (flags & kFileFlagRsrc ? true : false), sz, name);
+ }
+ return nullptr;
+}
+
+_Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) {
+ if (!is_valid_nefs_catalog(node)) {
+ kout << "NeFS: Seek called with invalid node pointer\n";
+ return false;
+ }
+ // Allow off == 0
+ return mParser->Seek(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node), off);
+}
+
+/// @brief Tell current offset within catalog.
+/// @param node
+/// @return kFileMgrNPos if invalid, else current offset.
+_Output SizeT NeFileSystemMgr::Tell(NodePtr node) {
+ if (!is_valid_nefs_catalog(node)) {
+ kout << "NeFS: Tell called with invalid node pointer\n";
+ return kFileMgrNPos;
+ }
+ return mParser->Tell(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node));
+}
+
+/// @brief Rewinds the catalog
+/// @param node
+/// @return False if invalid, nah? calls Seek(node, 0).
+_Output Bool NeFileSystemMgr::Rewind(NodePtr node) {
+ if (!is_valid_nefs_catalog(node)) {
+ kout << "NeFS: Rewind called with invalid node pointer\n";
+ return false;
+ }
+ return this->Seek(node, 0);
+}
+
+/// @brief Returns the parser of NeFS.
+_Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept {
+ return mParser;
+}
+
+static inline bool is_valid_nefs_catalog(NodePtr node) {
+ if (!node) return false;
+ auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node);
+ switch (cat->Kind) {
+ case kNeFSCatalogKindFile:
+ case kNeFSCatalogKindDir:
+ case kNeFSCatalogKindAlias:
+ case kNeFSCatalogKindPage:
+ break;
+ default:
+ return false;
+ }
+ bool null_found = false;
+ for (int i = 0; i < kNeFSCatalogNameLen; ++i) {
+ if (cat->Name[i] == 0) {
+ null_found = true;
+ break;
+ }
+ }
+ if (!null_found) return false;
+ return true;
+}
+
+} // namespace Kernel
+
+#endif // ifdef __FSKIT_INCLUDES_NEFS__
+#endif // ifndef __NE_MINIMAL_OS__
diff --git a/src/kernel/src/FS/NeFS+FileSystemParser.cc b/src/kernel/src/FS/NeFS+FileSystemParser.cc
new file mode 100644
index 00000000..bfb8d63a
--- /dev/null
+++ b/src/kernel/src/FS/NeFS+FileSystemParser.cc
@@ -0,0 +1,870 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifdef __FSKIT_INCLUDES_NEFS__
+
+#include <FSKit/NeFS.h>
+#include <FirmwareKit/EPM.h>
+
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/IFS.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/Crc32.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+#include <modules/AHCI/AHCI.h>
+#include <modules/ATA/ATA.h>
+
+using namespace Kernel;
+
+#ifdef __NE_NO_BUILTIN__
+/***********************************************************************************/
+/**
+ Define those external symbols, to make the editor shutup
+*/
+/***********************************************************************************/
+
+/***********************************************************************************/
+/// @brief get sector count.
+/***********************************************************************************/
+Kernel::SizeT drv_std_get_sector_count();
+
+/***********************************************************************************/
+/// @brief get device size.
+/***********************************************************************************/
+Kernel::SizeT drv_std_get_size();
+
+#endif
+
+///! BUGS: 0
+
+/***********************************************************************************/
+/// This file implements the New extended File System.
+/// New extended File System implements a flat linked-list based algorithm.
+/// /
+/// /Path1/ /Path2/
+/// /readme.rtf /ListContents.pef /readme.lnk <-- symlink.
+/// /Path1/readme.rtf
+/***********************************************************************************/
+static inline bool is_valid_size(SizeT size, SizeT max_size) {
+ return size > 0 && size <= max_size;
+}
+
+static inline bool is_valid_lba(Lba lba, DriveTrait& drive) {
+ NEFS_ROOT_PARTITION_BLOCK part_block;
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part_block);
+ drive.fInput(drive.fPacket);
+
+ if (!drive.fPacket.fPacketGood) {
+ return false;
+ }
+
+ // Compute the maximum LBA (DiskSize / sector size)
+ SizeT sectorSize = drive.fSectorSz;
+ Lba maxLba = part_block.DiskSize / sectorSize;
+
+ return (lba >= part_block.StartCatalog) && (lba < maxLba);
+}
+
+STATIC IMountpoint kMountpoint;
+/***********************************************************************************/
+/// @brief Creates a new fork inside the New filesystem partition.
+/// @param catalog it's catalog
+/// @param the_fork the fork itself.
+/// @return the fork
+/***********************************************************************************/
+_Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) {
+ if (the_fork.ForkName[0] == 0 || the_fork.CatalogName[0] == 0 || the_fork.DataSize == 0) {
+ return NO;
+ }
+
+ auto catalog = this->GetCatalog(the_fork.CatalogName);
+ if (!catalog) return NO;
+
+ Lba lba = catalog->DataFork;
+ if (lba < kNeFSCatalogStartAddress) {
+ delete catalog;
+ return NO;
+ }
+
+ auto& drv = kMountpoint.A();
+ Lba lba_prev = lba;
+ NEFS_FORK_STRUCT prev_fork{};
+ NEFS_FORK_STRUCT cur_fork{};
+
+ while (true) {
+ drv.fPacket.fPacketLba = lba;
+ drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&cur_fork);
+ drv.fInput(drv.fPacket);
+ if (!drv.fPacket.fPacketGood) {
+ delete catalog;
+ return NO;
+ }
+
+ if (cur_fork.Flags & kNeFSFlagCreated) {
+ if (KStringBuilder::Equals(cur_fork.ForkName, the_fork.ForkName) &&
+ KStringBuilder::Equals(cur_fork.CatalogName, the_fork.CatalogName)) {
+ break;
+ }
+ lba_prev = lba;
+ lba = cur_fork.NextSibling;
+ prev_fork = cur_fork;
+ } else {
+ if (lba >= kNeFSCatalogStartAddress) {
+ prev_fork.NextSibling = lba;
+ drv.fPacket.fPacketLba = lba_prev;
+ drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&prev_fork);
+ drv.fOutput(drv.fPacket);
+ }
+ break;
+ }
+ }
+
+ SizeT sectorCount = (the_fork.DataSize + kNeFSSectorSz - 1) / kNeFSSectorSz;
+ the_fork.DataOffset = lba + 1;
+ the_fork.PreviousSibling = lba_prev;
+ the_fork.NextSibling = lba + 1 + sectorCount;
+ the_fork.Flags |= kNeFSFlagCreated;
+
+ drv.fPacket.fPacketLba = lba;
+ drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&the_fork);
+ drv.fOutput(drv.fPacket);
+
+ fs_ifs_write(&kMountpoint, drv, IMountpoint::kDriveIndexA);
+
+ delete catalog;
+ return YES;
+}
+
+/***********************************************************************************/
+/// @brief Find fork inside filesystem.
+/// @param catalog the catalog.
+/// @param name the fork name.
+/// @return the newly found fork.
+/***********************************************************************************/
+_Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUCT* catalog,
+ _Input const Char* name,
+ _Input Boolean is_data) {
+ if (!catalog || !name) return nullptr;
+
+ auto& drive = kMountpoint.A();
+ Lba lba = is_data ? catalog->DataFork : catalog->ResourceFork;
+ NEFS_FORK_STRUCT local_buf{};
+
+ while (lba >= kNeFSCatalogStartAddress) {
+ drive.fPacket.fPacketLba = lba;
+ drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&local_buf);
+
+ rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
+
+ if (auto res = fs_ifs_read(&kMountpoint, drive, this->mDriveIndex); res) {
+ switch (res) {
+ case 1:
+ err_global_get() = kErrorDiskReadOnly;
+ break;
+ case 2:
+ err_global_get() = kErrorDiskIsFull;
+ break;
+ case 3:
+ err_global_get() = kErrorNoSuchDisk;
+ break;
+ default:
+ break;
+ }
+ return nullptr;
+ }
+
+ if (KStringBuilder::Equals(local_buf.ForkName, name) &&
+ KStringBuilder::Equals(local_buf.CatalogName, catalog->Name)) {
+ auto result = new NEFS_FORK_STRUCT();
+ rt_copy_memory_safe(&local_buf, result, sizeof(NEFS_FORK_STRUCT), sizeof(NEFS_FORK_STRUCT));
+ return result;
+ }
+
+ lba = local_buf.NextSibling;
+ }
+
+ return nullptr;
+}
+
+/***********************************************************************************/
+/// @brief Simpler factory to create a catalog (assumes you want to create a
+/// file.)
+/// @param name
+/// @return catalog pointer.
+/***********************************************************************************/
+_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) {
+ return this->CreateCatalog(name, 0, kNeFSCatalogKindFile);
+}
+
+/***********************************************************************************/
+/// @brief Creates a new catalog into the disk.
+/// @param name the catalog name.
+/// @param flags the flags of the catalog.
+/// @param kind the catalog kind.
+/// @return catalog pointer.
+/***********************************************************************************/
+_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name,
+ _Input const Int32& flags,
+ _Input const Int32& kind) {
+ kout << "CreateCatalog(*...*)\r";
+
+ if (!name) return nullptr;
+ SizeT nameLen = rt_string_len(name);
+ if (nameLen == 0) return nullptr;
+
+ Lba out_lba = 0UL;
+
+ kout << "Checking for path separator...\r";
+
+ /// a directory should have a slash in the end.
+ if (kind == kNeFSCatalogKindDir && name[nameLen - 1] != NeFileSystemHelper::Separator())
+ return nullptr;
+
+ /// a file shouldn't have a slash in the end.
+ if (kind != kNeFSCatalogKindDir && name[nameLen - 1] == NeFileSystemHelper::Separator())
+ return nullptr;
+
+ NEFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba);
+
+ if (catalog_copy) {
+ kout << "Catalog already exists: " << name << ".\r";
+ err_global_get() = kErrorFileExists;
+ delete catalog_copy;
+ catalog_copy = nullptr;
+ return nullptr;
+ }
+
+ Char* parent_name = (Char*) mm_alloc_ptr(nameLen + 1, Yes, No);
+ rt_copy_memory_safe(const_cast<Char*>(name), parent_name, nameLen + 1, nameLen + 1);
+
+ if (nameLen < 2) {
+ mm_free_ptr(parent_name);
+ err_global_get() = kErrorFileNotFound;
+ return nullptr;
+ }
+
+ SizeT index_reverse_copy = nameLen - 1;
+ if (parent_name[index_reverse_copy] == NeFileSystemHelper::Separator()) {
+ parent_name[index_reverse_copy] = 0;
+ --index_reverse_copy;
+ }
+ while (index_reverse_copy > 0 &&
+ parent_name[index_reverse_copy] != NeFileSystemHelper::Separator()) {
+ parent_name[index_reverse_copy] = 0;
+ --index_reverse_copy;
+ }
+ if (index_reverse_copy == 0 && parent_name[0] != NeFileSystemHelper::Separator()) {
+ mm_free_ptr(parent_name);
+ err_global_get() = kErrorFileNotFound;
+ return nullptr;
+ }
+
+ NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba);
+ mm_free_ptr(parent_name);
+
+ auto& drive = kMountpoint.A();
+ if (catalog && catalog->Kind == kNeFSCatalogKindFile) {
+ kout << "Parent is a file.\r";
+ delete catalog;
+ return nullptr;
+ } else if (!catalog) {
+ Char part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block);
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fInput(drive.fPacket);
+
+ NEFS_ROOT_PARTITION_BLOCK* blk_nefs = (NEFS_ROOT_PARTITION_BLOCK*) part_block;
+ out_lba = blk_nefs->StartCatalog;
+ }
+
+ if (drive.fPacket.fPacketReadOnly) {
+ delete catalog;
+ return nullptr;
+ }
+
+ NEFS_CATALOG_STRUCT* child_catalog = new NEFS_CATALOG_STRUCT();
+ child_catalog->Checksum = 0;
+ child_catalog->ResourceForkSize = 0UL;
+ child_catalog->DataForkSize = 0UL;
+ child_catalog->CatalogFlags = kNeFSStatusUnlocked;
+ child_catalog->NextSibling = out_lba;
+ child_catalog->PrevSibling = out_lba;
+ child_catalog->Kind = kind;
+ child_catalog->Flags |= kNeFSFlagCreated;
+ child_catalog->CatalogFlags = flags;
+
+ SizeT i = nameLen;
+ --i;
+ if (kind == kNeFSCatalogKindDir) --i;
+ while (name[i] != '/') --i;
+ rt_copy_memory_safe((VoidPtr) (name + i), (VoidPtr) child_catalog->Name, rt_string_len(name) - i,
+ kNeFSCatalogNameLen);
+
+ NEFS_CATALOG_STRUCT temporary_catalog{};
+ Lba start_free = out_lba;
+
+ rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
+
+ Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf_part_block);
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fInput(drive.fPacket);
+
+ NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) buf_part_block;
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&temporary_catalog);
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
+ drive.fInput(drive.fPacket);
+
+ if (part_block->FreeCatalog < 1) {
+ delete child_catalog;
+ delete catalog;
+ return nullptr;
+ }
+
+ kout << "Start finding catalog to allocate or empty space...\r";
+
+ SizeT catalogSectors = (sizeof(NEFS_CATALOG_STRUCT) + drive.fSectorSz - 1) / drive.fSectorSz;
+ while (start_free < part_block->StartCatalog + (part_block->CatalogCount * catalogSectors)) {
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&temporary_catalog);
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
+ drive.fInput(drive.fPacket);
+
+ if ((temporary_catalog.Flags & kNeFSFlagCreated) == 0) {
+ child_catalog->NextSibling = start_free + catalogSectors;
+
+ NEFS_CATALOG_STRUCT placeholder{};
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&placeholder);
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
+ drive.fOutput(drive.fPacket);
+
+ child_catalog->DataFork = part_block->DiskSize - start_free;
+ child_catalog->ResourceFork = child_catalog->DataFork;
+
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(child_catalog);
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketLba = start_free;
+ drive.fOutput(drive.fPacket);
+
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf_part_block);
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fInput(drive.fPacket);
+
+ part_block->FreeSectors -= catalogSectors;
+ part_block->CatalogCount += 1;
+ part_block->FreeCatalog -= 1;
+
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block);
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fOutput(drive.fPacket);
+
+ delete catalog;
+ NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT();
+ rt_copy_memory_safe(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT),
+ sizeof(NEFS_CATALOG_STRUCT));
+
+ delete child_catalog;
+ return found_catalog;
+ } else if ((temporary_catalog.Flags & kNeFSFlagCreated) &&
+ KStringBuilder::Equals(temporary_catalog.Name, name)) {
+ rt_copy_memory_safe(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT),
+ sizeof(NEFS_CATALOG_STRUCT));
+ delete catalog;
+ return child_catalog;
+ }
+
+ start_free += catalogSectors;
+ }
+
+ delete child_catalog;
+ delete catalog;
+ return nullptr;
+}
+
+/***********************************************************************************/
+/// @brief Make a EPM+NeFS drive out of the disk.
+/// @param drive The drive to write on.
+/// @return If it was sucessful, see err_global_get().
+/***********************************************************************************/
+bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
+ const Char* part_name) {
+ if (!part_name || *part_name == 0) return false;
+ NE_UNUSED(flags);
+
+ // verify disk.
+ drive->fVerify(drive->fPacket);
+ rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"), sizeof(drive->fPacket.fPacketMime));
+ if (!drive->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return false;
+ }
+
+ Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
+ Lba start = drive->fLbaStart;
+
+ drive->fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf);
+ drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive->fPacket.fPacketLba = start;
+ drive->fInput(drive->fPacket);
+
+ NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf;
+ if (rt_string_cmp(kNeFSIdent, part_block->Ident, kNeFSIdentLen) == 0) return true;
+
+ const auto kNeFSUntitledHD = part_name;
+ rt_copy_memory_safe((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen,
+ sizeof(part_block->Ident));
+ rt_copy_memory_safe((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName,
+ rt_string_len(kNeFSUntitledHD), sizeof(part_block->PartitionName));
+
+ SizeT sectorCount = drv_std_get_sector_count();
+ SizeT sectorSize = drive->fSectorSz;
+ SizeT totalBytes = sectorCount * sectorSize;
+ SizeT catalogEntries = totalBytes / sizeof(NEFS_CATALOG_STRUCT);
+ SizeT catalogSectors = (sizeof(NEFS_CATALOG_STRUCT) + sectorSize - 1) / sectorSize;
+
+ part_block->Version = kNeFSVersionInteger;
+ part_block->Kind = kNeFSPartitionTypeStandard;
+ part_block->StartCatalog = start + catalogSectors;
+ part_block->Flags = 0UL;
+ part_block->CatalogCount = catalogEntries;
+ part_block->FreeCatalog = catalogEntries - 1;
+ part_block->SectorCount = sectorCount;
+ part_block->DiskSize = totalBytes;
+ part_block->SectorSize = sectorSize;
+ part_block->FreeSectors = sectorCount - catalogSectors;
+
+ drive->fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf);
+ drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive->fPacket.fPacketLba = start;
+ drive->fOutput(drive->fPacket);
+
+ (Void)(kout << "Drive kind: " << drive->fProtocol() << kendl);
+ (Void)(kout << "Partition name: " << part_block->PartitionName << kendl);
+ (Void)(kout << "Start catalog: " << hex_number(part_block->StartCatalog) << kendl);
+ (Void)(kout << "Number of catalogs: " << hex_number(part_block->CatalogCount) << kendl);
+ (Void)(kout << "Free catalog: " << hex_number(part_block->FreeCatalog) << kendl);
+ (Void)(kout << "Free sectors: " << hex_number(part_block->FreeSectors) << kendl);
+ (Void)(kout << "Sector size: " << hex_number(part_block->SectorSize) << kendl);
+
+ return true;
+}
+
+/***********************************************************************************/
+/// @brief Writes the data fork into a specific catalog.
+/// @param catalog the catalog itself
+/// @param data the data.
+/// @return if the catalog wrote the contents successfully.
+/***********************************************************************************/
+bool NeFileSystemParser::WriteCatalog(_Input const Char* catalog_name, Bool is_rsrc_fork,
+ _Input VoidPtr data, _Input SizeT size_of_data,
+ _Input const Char* fork_name) {
+ if (size_of_data < 1) return NO;
+
+ auto catalog = this->GetCatalog(catalog_name);
+ if (!catalog) {
+ kout << "NeFS: WriteCatalog failed to find catalog: " << catalog_name << "\n";
+ return false;
+ }
+
+ SizeT maxSize = is_rsrc_fork ? catalog->ResourceForkSize : catalog->DataForkSize;
+
+ if (!is_valid_size(size_of_data, maxSize)) {
+ (Void)(kout << "NeFS: WriteCatalog called with invalid size: " << hex_number(size_of_data));
+ kout << "\n";
+
+ delete catalog;
+ return false;
+ }
+
+ Lba startFork = is_rsrc_fork ? catalog->ResourceFork : catalog->DataFork;
+ auto& drive = kMountpoint.A();
+
+ if (!is_valid_lba(startFork, drive)) {
+ (Void)(kout << "NeFS: WriteCatalog called with invalid LBA: " << hex_number(startFork));
+ kout << "\n";
+
+ delete catalog;
+ return false;
+ }
+
+ NEFS_ROOT_PARTITION_BLOCK part_block;
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fPacket.fPacketSize = sizeof(part_block);
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part_block);
+ drive.fInput(drive.fPacket);
+
+ auto buf = new UInt8[size_of_data];
+ rt_set_memory(buf, 0, size_of_data);
+ rt_copy_memory_safe(data, buf, size_of_data, size_of_data);
+ rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
+
+ NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT();
+ NEFS_FORK_STRUCT prev_fork{};
+
+ while (startFork >= part_block.StartCatalog && drive.fPacket.fPacketGood) {
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fork_data_input);
+ drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drive.fPacket.fPacketLba = startFork;
+ drive.fInput(drive.fPacket);
+
+ if (!drive.fPacket.fPacketGood) {
+ break;
+ }
+
+ if ((fork_data_input->Flags & kNeFSFlagCreated) &&
+ KStringBuilder::Equals(fork_data_input->ForkName, fork_name) &&
+ KStringBuilder::Equals(fork_data_input->CatalogName, catalog_name) &&
+ fork_data_input->DataSize == size_of_data) {
+ SizeT bytes_left = size_of_data;
+ SizeT offset = 0;
+ Lba base_lba = fork_data_input->DataOffset;
+
+ while (bytes_left > 0) {
+ SizeT chunk = (bytes_left > kNeFSSectorSz) ? kNeFSSectorSz : bytes_left;
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf + offset);
+ drive.fPacket.fPacketSize = chunk;
+ drive.fPacket.fPacketLba = base_lba + (offset / kNeFSSectorSz);
+ drive.fOutput(drive.fPacket);
+ offset += chunk;
+ bytes_left -= chunk;
+ }
+
+ delete fork_data_input;
+ delete[] buf;
+ delete catalog;
+ return true;
+ }
+
+ prev_fork = *fork_data_input;
+ startFork = fork_data_input->NextSibling;
+ }
+
+ delete fork_data_input;
+ delete[] buf;
+ delete catalog;
+ return false;
+}
+
+/***********************************************************************************/
+/// @brief
+/// @param catalog_name the catalog name.
+/// @return the newly found catalog.
+/***********************************************************************************/
+_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* catalog_name,
+ Lba& out_lba, Bool search_hidden,
+ Bool local_search) {
+ if (!catalog_name || *catalog_name == 0) return nullptr;
+
+ NEFS_ROOT_PARTITION_BLOCK part{};
+ auto& drive = kMountpoint.A();
+
+ rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part);
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fInput(drive.fPacket);
+
+ auto start_catalog_lba = kNeFSCatalogStartAddress;
+
+ // Helper lambda to scan from a given LBA
+ auto scan_from = [&](Lba lba_start, Bool allow_hidden) -> NEFS_CATALOG_STRUCT* {
+ Lba cursor = lba_start;
+ NEFS_CATALOG_STRUCT tmp{};
+ while (cursor >= part.StartCatalog && drive.fPacket.fPacketGood) {
+ drive.fPacket.fPacketLba = cursor;
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&tmp);
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fInput(drive.fPacket);
+
+ if (KStringBuilder::Equals(
+ tmp.Name, catalog_name + (rt_string_len(catalog_name) - rt_string_len(tmp.Name)))) {
+ if (tmp.Status == kNeFSStatusLocked && !allow_hidden) {
+ err_global_get() = kErrorFileLocked;
+ return nullptr;
+ }
+ if (!(tmp.Flags & kNeFSFlagCreated)) {
+ err_global_get() = kErrorFileNotFound;
+ return nullptr;
+ }
+ NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT();
+ rt_copy_memory_safe(&tmp, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT),
+ sizeof(NEFS_CATALOG_STRUCT));
+ out_lba = cursor;
+ return catalog_ptr;
+ }
+ cursor = tmp.NextSibling;
+ }
+ return nullptr;
+ };
+
+ if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search) {
+ Char parent_name[kNeFSCatalogNameLen] = {0};
+ SizeT nameLen = rt_string_len(catalog_name);
+ rt_copy_memory_safe(const_cast<Char*>(catalog_name), parent_name, nameLen + 1,
+ kNeFSCatalogNameLen);
+
+ SizeT indexReverseCopy = nameLen - 1;
+ if (parent_name[indexReverseCopy] == NeFileSystemHelper::Separator()) {
+ parent_name[indexReverseCopy] = 0;
+ --indexReverseCopy;
+ }
+ while (indexReverseCopy > 0 &&
+ parent_name[indexReverseCopy] != NeFileSystemHelper::Separator()) {
+ parent_name[indexReverseCopy] = 0;
+ --indexReverseCopy;
+ }
+ if (indexReverseCopy == 0 && parent_name[0] != NeFileSystemHelper::Separator()) {
+ return nullptr;
+ }
+
+ NEFS_CATALOG_STRUCT* parent_catalog =
+ this->FindCatalog(parent_name, out_lba, search_hidden, NO);
+ if (parent_catalog) {
+ start_catalog_lba = parent_catalog->NextSibling;
+ delete parent_catalog;
+ NEFS_CATALOG_STRUCT* found = scan_from(start_catalog_lba, search_hidden);
+ if (found) return found;
+ }
+ }
+
+ return scan_from(part.StartCatalog, search_hidden);
+}
+
+/***********************************************************************************/
+/// @brief Get catalog from filesystem.
+/// @param name the catalog's name/
+/// @return
+/***********************************************************************************/
+_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::GetCatalog(_Input const Char* name) {
+ Lba unused = 0;
+ return this->FindCatalog(name, unused, YES, YES);
+}
+
+/***********************************************************************************/
+/// @brief Closes a catalog, (frees it).
+/// @param catalog the catalog to close.
+/// @return
+/***********************************************************************************/
+_Output Boolean NeFileSystemParser::CloseCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog) {
+ if (!catalog) return false;
+ delete catalog;
+ catalog = nullptr;
+ return true;
+}
+
+/***********************************************************************************/
+/// @brief Mark catalog as removed.
+/// @param catalog The catalog structure.
+/// @return if the catalog was removed or not.
+/***********************************************************************************/
+_Output Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_name) {
+ if (!catalog_name || KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root())) {
+ err_global_get() = kErrorInternal;
+ return false;
+ }
+
+ Lba out_lba = 0;
+ auto catalog = this->FindCatalog(catalog_name, out_lba, YES, YES);
+ if (!catalog) return false;
+
+ auto& drive = kMountpoint.A();
+ NEFS_FORK_STRUCT fork_buf{};
+ Lba fork_lba = catalog->DataFork;
+ while (fork_lba >= kNeFSCatalogStartAddress) {
+ drive.fPacket.fPacketLba = fork_lba;
+ drive.fPacket.fPacketSize = sizeof(fork_buf);
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
+ drive.fInput(drive.fPacket);
+
+ fork_buf.Flags &= (~kNeFSFlagCreated);
+ fork_buf.Flags |= kNeFSFlagDeleted;
+
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
+ drive.fPacket.fPacketSize = sizeof(fork_buf);
+ drive.fPacket.fPacketLba = fork_lba;
+ drive.fOutput(drive.fPacket);
+
+ fork_lba = fork_buf.NextSibling;
+ }
+
+ fork_lba = catalog->ResourceFork;
+ while (fork_lba >= kNeFSCatalogStartAddress) {
+ drive.fPacket.fPacketLba = fork_lba;
+ drive.fPacket.fPacketSize = sizeof(fork_buf);
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
+ drive.fInput(drive.fPacket);
+
+ fork_buf.Flags &= (~kNeFSFlagCreated);
+ fork_buf.Flags |= kNeFSFlagDeleted;
+
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf);
+ drive.fPacket.fPacketSize = sizeof(fork_buf);
+ drive.fPacket.fPacketLba = fork_lba;
+ drive.fOutput(drive.fPacket);
+
+ fork_lba = fork_buf.NextSibling;
+ }
+
+ if (out_lba >= kNeFSCatalogStartAddress || (catalog->Flags & kNeFSFlagCreated)) {
+ catalog->Flags &= (~kNeFSFlagCreated);
+ catalog->Flags |= kNeFSFlagDeleted;
+
+ rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
+ drive.fPacket.fPacketLba = out_lba;
+ drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT);
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(catalog);
+ drive.fOutput(drive.fPacket);
+
+ Char partitionBlockBuf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0};
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(partitionBlockBuf);
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fInput(drive.fPacket);
+
+ NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) partitionBlockBuf;
+ if (part_block->CatalogCount > 0) --part_block->CatalogCount;
+ ++part_block->FreeSectors;
+
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block);
+ drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK);
+ drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress;
+ drive.fOutput(drive.fPacket);
+
+ delete catalog;
+ catalog = nullptr;
+ return true;
+ }
+
+ delete catalog;
+ catalog = nullptr;
+ return false;
+}
+
+/// ***************************************************************** ///
+/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead.
+/// ***************************************************************** ///
+
+/***********************************************************************************/
+/// @brief Read the catalog data fork.
+/// @param catalog
+/// @param dataSz
+/// @return
+/***********************************************************************************/
+VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog,
+ _Input Bool is_rsrc_fork, _Input SizeT dataSz,
+ _Input const Char* forkName) {
+ if (!catalog) {
+ err_global_get() = kErrorInvalidData;
+ return nullptr;
+ }
+ // Validate size against fork size
+ SizeT maxSize = is_rsrc_fork ? catalog->ResourceForkSize : catalog->DataForkSize;
+ if (!is_valid_size(dataSz, maxSize)) {
+ kout << "NeFS: ReadCatalog called with invalid size: ";
+ hex_number(dataSz);
+ kout << "\n";
+ return nullptr;
+ }
+
+ Lba dataForkLba = is_rsrc_fork ? catalog->ResourceFork : catalog->DataFork;
+ auto& drive = kMountpoint.A();
+ if (!is_valid_lba(dataForkLba, drive)) {
+ kout << "NeFS: ReadCatalog called with invalid LBA: ";
+ hex_number(dataForkLba);
+ kout << "\n";
+ return nullptr;
+ }
+
+ auto* fs_buf = new NEFS_FORK_STRUCT();
+ rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime,
+ rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime));
+
+ NEFS_FORK_STRUCT* fs_fork_data = nullptr;
+ while (dataForkLba >= kNeFSCatalogStartAddress) {
+ drive.fPacket.fPacketLba = dataForkLba;
+ drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT);
+ drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf);
+ drive.fInput(drive.fPacket);
+
+ fs_fork_data = fs_buf;
+ (Void)(kout << "ForkName: " << fs_fork_data->ForkName << kendl);
+ (Void)(kout << "CatalogName: " << fs_fork_data->CatalogName << kendl);
+
+ if (KStringBuilder::Equals(forkName, fs_fork_data->ForkName) &&
+ KStringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) {
+ break;
+ }
+ dataForkLba = fs_fork_data->NextSibling;
+ }
+
+ if (dataForkLba < kNeFSCatalogStartAddress) {
+ delete fs_buf;
+ return nullptr;
+ }
+ return fs_fork_data;
+}
+
+/***********************************************************************************/
+/// @brief Seek in the data fork.
+/// @param catalog the catalog offset.
+/// @param off where to seek.
+/// @return if the seeking was successful.
+/***********************************************************************************/
+bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off) {
+ NE_UNUSED(catalog);
+ NE_UNUSED(off);
+ err_global_get() = kErrorUnimplemented;
+ return false;
+}
+
+/***********************************************************************************/
+/// @brief Tell where we are inside the data fork.
+/// @param catalog
+/// @return The position on the file.
+/***********************************************************************************/
+SizeT NeFileSystemParser::Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog) {
+ NE_UNUSED(catalog);
+ err_global_get() = kErrorUnimplemented;
+ return 0;
+}
+
+namespace Kernel::NeFS {
+/***********************************************************************************/
+/// @brief Construct NeFS drives.
+/***********************************************************************************/
+Boolean fs_init_nefs(Void) noexcept {
+ kout << "Creating OpenHeFS disk...\r";
+ kMountpoint.A() = io_construct_main_drive();
+ if (kMountpoint.A().fPacket.fPacketReadOnly == YES)
+ ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main disk cannot be mounted.");
+ NeFileSystemParser parser;
+ return parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName);
+}
+} // namespace Kernel::NeFS
+
+#endif // ifdef __FSKIT_INCLUDES_NEFS__
diff --git a/src/kernel/src/FS/OpenHeFS+FileMgr.cc b/src/kernel/src/FS/OpenHeFS+FileMgr.cc
new file mode 100644
index 00000000..7340514a
--- /dev/null
+++ b/src/kernel/src/FS/OpenHeFS+FileMgr.cc
@@ -0,0 +1,191 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __NE_MINIMAL_OS__
+#ifdef __FSKIT_INCLUDES_OPENHEFS__
+
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/HeapMgr.h>
+
+/// @brief OpenHeFS File System Manager.
+/// BUGS: 0
+
+namespace Kernel {
+/// @brief C++ constructor
+HeFileSystemMgr::HeFileSystemMgr() {
+ mParser = new HeFileSystemParser();
+ MUST_PASS(mParser);
+
+ kout << "We are done allocating HeFileSystemParser...\n";
+}
+
+HeFileSystemMgr::~HeFileSystemMgr() {
+ if (mParser) {
+ kout << "Destroying HeFileSystemParser...\n";
+ delete mParser;
+ mParser = nullptr;
+ }
+}
+
+/// @brief Removes a node from the filesystem.
+/// @param path The filename
+/// @return If it was deleted or not.
+bool HeFileSystemMgr::Remove(_Input const Char* path) {
+ if (path == nullptr || *path == 0) {
+ kout << "OpenHeFS: Remove called with null or empty path\n";
+ return false;
+ }
+
+ return NO;
+}
+
+/// @brief Creates a node with the specified.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr HeFileSystemMgr::Create(_Input const Char* path) {
+ if (!path || *path == 0) {
+ kout << "OpenHeFS: Create called with null or empty path\n";
+ return nullptr;
+ }
+ return nullptr;
+}
+
+/// @brief Creates a node which is a directory.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr HeFileSystemMgr::CreateDirectory(const Char* path) {
+ if (!path || *path == 0) {
+ kout << "OpenHeFS: CreateDirectory called with null or empty path\n";
+ return nullptr;
+ }
+ return nullptr;
+}
+
+/// @brief Creates a node which is an alias.
+/// @param path The filename path.
+/// @return The Node pointer.
+NodePtr HeFileSystemMgr::CreateAlias(const Char* path) {
+ if (!path || *path == 0) {
+ kout << "OpenHeFS: CreateAlias called with null or empty path\n";
+ return nullptr;
+ }
+ return nullptr;
+}
+
+NodePtr HeFileSystemMgr::CreateSwapFile(const Char* path) {
+ if (!path || *path == 0) {
+ kout << "OpenHeFS: CreateSwapFile called with null or empty path\n";
+ return nullptr;
+ }
+ return nullptr;
+}
+
+/// @brief Gets the root directory.
+/// @return
+const Char* NeFileSystemHelper::Root() {
+ return kOpenHeFSRootDirectory;
+}
+
+/// @brief Gets the up-dir directory.
+/// @return
+const Char* NeFileSystemHelper::UpDir() {
+ return kOpenHeFSUpDir;
+}
+
+/// @brief Gets the separator character.
+/// @return
+Char NeFileSystemHelper::Separator() {
+ return kOpenHeFSSeparator;
+}
+
+/// @brief Gets the metafile character.
+/// @return
+Char NeFileSystemHelper::MetaFile() {
+ return '\0';
+}
+
+/// @brief Opens a new file.
+/// @param path
+/// @param r
+/// @return
+_Output NodePtr HeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) {
+ if (!path || *path == 0) {
+ kout << "OpenHeFS: Open called with null or empty path\n";
+ return nullptr;
+ }
+ if (!r || *r == 0) {
+ kout << "OpenHeFS: Open called with null or empty mode string\n";
+ return nullptr;
+ }
+ return nullptr;
+}
+
+Void HeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags,
+ _Input SizeT size) {
+ NE_UNUSED(node);
+ NE_UNUSED(flags);
+ NE_UNUSED(size);
+ NE_UNUSED(data);
+}
+
+_Output VoidPtr HeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) {
+ NE_UNUSED(node);
+ NE_UNUSED(flags);
+ NE_UNUSED(size);
+
+ return nullptr;
+}
+
+Void HeFileSystemMgr::Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data,
+ _Input Int32 flags, _Input SizeT size) {
+ NE_UNUSED(node);
+ NE_UNUSED(flags);
+ NE_UNUSED(size);
+ NE_UNUSED(name);
+ NE_UNUSED(data);
+}
+
+_Output VoidPtr HeFileSystemMgr::Read(_Input const Char* name, _Input NodePtr node,
+ _Input Int32 flags, _Input SizeT sz) {
+ NE_UNUSED(node);
+ NE_UNUSED(flags);
+ NE_UNUSED(sz);
+ NE_UNUSED(name);
+
+ return nullptr;
+}
+
+_Output Bool HeFileSystemMgr::Seek(NodePtr node, SizeT off) {
+ NE_UNUSED(node);
+ NE_UNUSED(off);
+
+ return false;
+}
+
+/// @brief Tell current offset within catalog.
+/// @param node
+/// @return kFileMgrNPos if invalid, else current offset.
+_Output SizeT HeFileSystemMgr::Tell(NodePtr node) {
+ NE_UNUSED(node);
+ return kFileMgrNPos;
+}
+
+/// @brief Rewinds the catalog
+/// @param node
+/// @return False if invalid, nah? calls Seek(node, 0).
+_Output Bool HeFileSystemMgr::Rewind(NodePtr node) {
+ NE_UNUSED(node);
+ return kFileMgrNPos;
+}
+
+/// @brief Returns the parser of OpenHeFS.
+_Output HeFileSystemParser* HeFileSystemMgr::GetParser() noexcept {
+ return mParser;
+}
+} // namespace Kernel
+
+#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__
+#endif // ifndef __NE_MINIMAL_OS__
diff --git a/src/kernel/src/FS/OpenHeFS+FileSystemParser.cc b/src/kernel/src/FS/OpenHeFS+FileSystemParser.cc
new file mode 100644
index 00000000..d6aeb992
--- /dev/null
+++ b/src/kernel/src/FS/OpenHeFS+FileSystemParser.cc
@@ -0,0 +1,1160 @@
+/* ========================================
+
+ Copyright (C) 2024-2025 Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifdef __FSKIT_INCLUDES_OPENHEFS__
+
+#include <FSKit/OpenHeFS.h>
+#include <FirmwareKit/EPM.h>
+#include <FirmwareKit/GPT.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/Crc32.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+#include <modules/AHCI/AHCI.h>
+#include <modules/ATA/ATA.h>
+
+namespace Kernel {
+namespace Detail {
+ /// @brief Forward declarations of internal functions.
+
+ /***********************************************************************************/
+ /// @brief Traverse the RB-Tree of the filesystem.
+ /// @param dir The directory to traverse.
+ /// @param start The starting point of the traversal.
+ /// @note This function is used to traverse the RB-Tree of the filesystem.
+ /// @internal Internal filesystem use only.
+ /***********************************************************************************/
+ STATIC ATTRIBUTE(unused) _Output Void
+ hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& start_ind,
+ Lba& start);
+
+ /***********************************************************************************/
+ /// @brief Get the index node of a file or directory.
+ /// @param boot The boot node of the filesystem.
+ /// @param mnt The mnt to read from.
+ /// @param dir_name The name of the directory.
+ /// @param file_name The name of the file.
+ /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic
+ /// link, unknown).
+ /***********************************************************************************/
+ STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefsi_fetch_in(HEFS_BOOT_NODE* boot,
+ DriveTrait* mnt,
+ const Utf8Char* dir_name,
+ const Utf8Char* file_name,
+ UInt8 kind);
+
+ /***********************************************************************************/
+ /// @brief Allocate a new index node->
+ /// @param boot The boot node of the filesystem.
+ /// @param mnt The mnt to read/write from.
+ /// @param dir_name The name of the parent directory.
+ /// @return Status, see err_global_get().
+ /***********************************************************************************/
+ STATIC ATTRIBUTE(unused) _Output BOOL
+ hefsi_update_in_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, const Utf8Char* dir_name,
+ HEFS_INDEX_NODE* node, const BOOL create_or_delete);
+
+ /***********************************************************************************/
+ /// @brief Balance RB-Tree of the filesystem.
+ /// @param boot The boot node of the filesystem.
+ /// @param mnt The mnt to read/write from.
+ /// @return Status, see err_global_get().
+ /***********************************************************************************/
+ STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* boot, DriveTrait* mnt);
+
+ /// @brief Alllocate IND from boot node.
+ /// @param boot The boot node of the filesystem.
+ /// @param mnt The mnt to read from.
+ /// @param dir_name The name of the directory.
+ /// @param dir_name The parent of the directory.
+ /// @param flags Directory flags.
+ /// @param delete_or_create Delete or create directory.
+ STATIC _Output BOOL hefsi_update_ind_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt,
+ const Utf8Char* dir_name, UInt16 flags,
+ const BOOL delete_or_create);
+
+ /// @brief This helper makes it easier for other machines to understand OpenHeFS encoded hashes.
+ STATIC UInt64 hefsi_to_big_endian_64(UInt64 val) {
+ return ((val >> 56) & 0x00000000000000FFULL) | ((val >> 40) & 0x000000000000FF00ULL) |
+ ((val >> 24) & 0x0000000000FF0000ULL) | ((val >> 8) & 0x00000000FF000000ULL) |
+ ((val << 8) & 0x000000FF00000000ULL) | ((val << 24) & 0x0000FF0000000000ULL) |
+ ((val << 40) & 0x00FF000000000000ULL) | ((val << 56) & 0xFF00000000000000ULL);
+ }
+
+ /// @brief Simple algorithm to hash directory entries for INDs.
+ /// @param path the directory path.
+ /// @return The hashed path.
+ template <typename CharT = Utf8Char>
+ STATIC UInt64 hefsi_hash_64(const CharT* path) {
+ if (!path || *path == 0) return 0;
+
+ const UInt64 kFnvBaseOffset = 0xcbf29ce484222325ULL;
+ const UInt64 kFnvPrimeNumber = 0x100000001b3ULL;
+
+ UInt64 hash = kFnvBaseOffset;
+
+ while (*path) {
+ hash ^= (CharT) (*path++);
+ hash *= kFnvPrimeNumber;
+ }
+
+ return hefsi_to_big_endian_64(hash);
+ }
+
+ /// @brief Traverse the RB-Tree of the filesystem.
+ /// @param dir The directory to traverse.
+ /// @param start The starting point of the traversal.
+ /// @note This function is used to traverse the RB-Tree of the filesystem.
+ /// @internal Internal filesystem use only.
+ STATIC ATTRIBUTE(unused) Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt,
+ const Lba& ind_start, Lba& start) {
+ if (!mnt || !dir) return;
+
+ BOOL check_is_good = NO;
+ HEFS_INDEX_NODE_DIRECTORY* dir_tmp = new HEFS_INDEX_NODE_DIRECTORY();
+
+ while (YES) {
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir_tmp;
+ mnt->fInput(mnt->fPacket);
+
+ if (!mnt->fPacket.fPacketGood) break;
+
+ if (dir_tmp->fNext != 0) {
+ if (check_is_good) break;
+
+ start = dir_tmp->fNext;
+
+ check_is_good = YES;
+ continue;
+ } else if (dir_tmp->fPrev != 0) {
+ if (check_is_good) break;
+
+ start = dir_tmp->fPrev;
+ check_is_good = YES;
+ continue;
+ } else {
+ if (dir_tmp->fParent != 0) {
+ if (check_is_good) break;
+
+ start = dir_tmp->fParent;
+ check_is_good = YES;
+ continue;
+ } else if (dir_tmp->fPrev != 0) {
+ if (check_is_good) break;
+
+ start = dir_tmp->fPrev;
+ check_is_good = YES;
+ continue;
+ } else {
+ if (start == 0) {
+ start = ind_start;
+ continue;
+ }
+
+ start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ break;
+ }
+ }
+ }
+
+ delete dir_tmp;
+
+ start += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ if (start == 0) start = ind_start;
+ }
+
+ /***********************************************************************************/
+ /// @brief Rotate the RB-Tree to the left or right.
+ /// @internal
+ /***********************************************************************************/
+ STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_tree(Lba& start, DriveTrait* mnt) {
+ if (!start || !mnt) return;
+
+ HEFS_INDEX_NODE_DIRECTORY* cur =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = cur;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (cur->fHashPath == 0) return;
+
+ HEFS_INDEX_NODE_DIRECTORY* sibling =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = cur->fPrev;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = sibling;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (sibling->fHashPath == 0) return;
+
+ auto child_sibling = sibling->fChild;
+ auto child_cur = cur->fChild;
+
+ cur->fChild = child_sibling;
+ sibling->fChild = child_cur;
+
+ sibling->fChecksum = ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+ cur->fChecksum = ke_calculate_crc32((Char*) cur, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = cur->fParent;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = sibling;
+
+ mnt->fOutput(mnt->fPacket);
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = cur;
+
+ mnt->fOutput(mnt->fPacket);
+
+ HEFS_INDEX_NODE_DIRECTORY* sibling_child =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = child_sibling;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = sibling_child;
+
+ mnt->fInput(mnt->fPacket);
+
+ sibling_child->fParent = cur->fParent;
+
+ sibling_child->fChecksum =
+ ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fOutput(mnt->fPacket);
+
+ HEFS_INDEX_NODE_DIRECTORY* cur_child =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = child_cur;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = cur_child;
+
+ mnt->fInput(mnt->fPacket);
+
+ cur_child->fParent = start;
+
+ cur_child->fChecksum = ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fOutput(mnt->fPacket);
+
+ kout << "RB-Tree has been rotated.\r";
+ }
+
+ /// @brief Alllocate IND from boot node.
+ /// @param boot The boot node of the filesystem.
+ /// @param mnt The mnt to read from.
+ /// @param dir_name The name of the directory.
+ /// @param dir_name The parent of the directory.
+ /// @param flags Directory flags.
+ /// @param delete_or_create Delete or create directory.
+ STATIC _Output BOOL hefsi_update_ind_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt,
+ const Utf8Char* dir_name, UInt16 flags,
+ const BOOL delete_or_create) {
+ if (mnt) {
+ HEFS_INDEX_NODE_DIRECTORY* tmpdir =
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
+
+ auto start = boot->fStartIND;
+ auto prev_location = start;
+ auto parent_location = 0UL;
+
+ MUST_PASS(boot->fStartIND > mnt->fLbaStart);
+
+ while (YES) {
+ auto prev_start = start;
+
+ if (start)
+ mnt->fPacket.fPacketLba = start;
+ else
+ mnt->fPacket.fPacketLba = prev_location + sizeof(HEFS_INDEX_NODE_DIRECTORY);
+
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = tmpdir;
+
+ mnt->fInput(mnt->fPacket);
+
+ BOOL expr = NO;
+
+ if (!delete_or_create) {
+ expr = (!tmpdir->fCreated && tmpdir->fDeleted) || tmpdir->fHashPath == 0;
+ } else {
+ expr =
+ tmpdir->fCreated && !tmpdir->fDeleted && hefsi_hash_64(dir_name) == tmpdir->fHashPath;
+ }
+
+ if (expr) {
+ HEFS_INDEX_NODE_DIRECTORY* dirent =
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
+
+ rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ dirent->fHashPath = delete_or_create ? 0UL : hefsi_hash_64(dir_name);
+ dirent->fAccessed = 0UL;
+ dirent->fCreated = delete_or_create ? 0UL : 1UL;
+ dirent->fDeleted = delete_or_create ? 1UL : 0UL;
+ dirent->fModified = 0UL;
+ dirent->fEntryCount = 0UL;
+
+ dirent->fReserved = 0;
+ dirent->fFlags = flags;
+ dirent->fChecksum = 0;
+
+ dirent->fEntryCount = 0;
+
+ if (parent_location) {
+ HEFS_INDEX_NODE_DIRECTORY* tmpend =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = parent_location;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = tmpend;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (tmpend->fChecksum !=
+ ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY)))
+ ke_panic(RUNTIME_CHECK_FILESYSTEM, "Bad CRC32 value, aborting.");
+
+ if (delete_or_create)
+ --tmpend->fEntryCount;
+ else
+ ++tmpend->fEntryCount;
+
+ tmpend->fChecksum =
+ ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fOutput(mnt->fPacket);
+
+ auto child_first = tmpend->fChild;
+
+ while (YES) {
+ mnt->fPacket.fPacketLba = child_first;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = tmpend;
+
+ mnt->fInput(mnt->fPacket);
+
+ if ((!tmpend->fCreated && tmpend->fDeleted) || tmpend->fHashPath == 0) {
+ start = child_first;
+ break;
+ }
+
+ hefsi_traverse_tree(tmpend, mnt, boot->fStartIND, child_first);
+ }
+ }
+
+ dirent->fNext = tmpdir->fNext;
+ dirent->fPrev = tmpdir->fPrev;
+ dirent->fParent = tmpdir->fParent;
+ dirent->fChild = tmpdir->fChild;
+ dirent->fColor = tmpdir->fColor;
+
+ if (dirent->fColor == 0) {
+ dirent->fColor = dirent->fNext ? kOpenHeFSRed : kOpenHeFSBlack;
+ }
+
+ if (dirent->fPrev == 0) {
+ dirent->fPrev = boot->fStartIND;
+ }
+
+ if (dirent->fParent == 0) {
+ dirent->fParent = boot->fStartIND;
+ }
+
+ if (tmpdir->fChild == 0) {
+ auto child = dirent->fNext + sizeof(HEFS_INDEX_NODE_DIRECTORY);
+
+ HEFS_INDEX_NODE_DIRECTORY* tmpend =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ while (YES) {
+ mnt->fPacket.fPacketLba = child;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = tmpend;
+
+ mnt->fInput(mnt->fPacket);
+
+ if ((!tmpend->fCreated && tmpend->fDeleted) || tmpdir->fHashPath == 0) {
+ break;
+ }
+
+ child += sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ if (child > boot->fEndIND) break;
+ }
+
+ dirent->fColor = kOpenHeFSRed;
+ dirent->fChild = child;
+
+ if (child > boot->fEndIND) dirent->fChild = boot->fStartIND;
+ }
+
+ for (SizeT index = 0UL; index < kOpenHeFSSliceCount; ++index) {
+ dirent->fINSlices[index] = 0UL;
+ }
+
+ dirent->fChecksum = ke_calculate_crc32((Char*) dirent, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = prev_start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dirent;
+
+ mnt->fOutput(mnt->fPacket);
+
+ err_global_get() = kErrorSuccess;
+
+ mm_free_ptr(dirent);
+ mm_free_ptr(tmpdir);
+
+ if (!delete_or_create)
+ ++boot->fINDCount;
+ else
+ --boot->fINDCount;
+
+ boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fOutput(mnt->fPacket);
+
+ return YES;
+ }
+
+ prev_location = start;
+
+ hefsi_traverse_tree(tmpdir, mnt, boot->fStartIND, start);
+ if (start > boot->fEndIND || start == 0) break;
+ }
+
+ err_global_get() = kErrorDisk;
+ mm_free_ptr(tmpdir);
+
+ return NO;
+ }
+
+ err_global_get() = kErrorDiskIsFull;
+ return NO;
+ }
+
+ /// @brief Get the index node of a file or directory.
+ /// @param boot The boot node of the filesystem.
+ /// @param mnt The mnt to read from.
+ /// @param dir_name The name of the directory.
+ /// @param file_name The name of the file.
+ /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic
+ /// link, unknown).
+ STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefsi_fetch_in(HEFS_BOOT_NODE* boot,
+ DriveTrait* mnt,
+ const Utf8Char* dir_name,
+ const Utf8Char* file_name,
+ UInt8 kind) {
+ if (mnt) {
+ if (boot->fStartIND > boot->fEndIND) return nullptr;
+ if (boot->fStartIN > boot->fEndIN) return nullptr;
+
+ auto start = boot->fStartIND;
+ HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE();
+
+ HEFS_INDEX_NODE_DIRECTORY* dir =
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
+
+ while (YES) {
+ if (err_global_get() == kErrorDiskIsCorrupted) {
+ delete dir;
+ dir = nullptr;
+
+ delete node;
+ node = nullptr;
+
+ return nullptr;
+ }
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fInput(mnt->fPacket);
+
+ (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl);
+ (Void)(kout << hex_number(dir->fHashPath) << kendl);
+
+ if (dir->fHashPath == 0) break;
+
+ if (hefsi_hash_64(dir_name) == dir->fHashPath) {
+ for (SizeT inode_index = 0UL; inode_index < kOpenHeFSSliceCount; ++inode_index) {
+ mnt->fPacket.fPacketLba = dir->fINSlices[inode_index];
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = node;
+
+ mnt->fInput(mnt->fPacket);
+
+ (Void)(kout << hex_number(hefsi_hash_64(file_name)) << kendl);
+ (Void)(kout << hex_number(node->fHashPath) << kendl);
+
+ if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) {
+ delete dir;
+ dir = nullptr;
+
+ return node;
+ }
+ }
+ }
+
+ hefsi_traverse_tree(dir, mnt, boot->fStartIND, start);
+ if (start == boot->fStartIND || start == boot->fStartIND) break;
+ }
+
+ delete node;
+ node = nullptr;
+
+ delete dir;
+ dir = nullptr;
+ }
+
+ kout << "Error: Failed to find IN.\r";
+
+ err_global_get() = kErrorFileNotFound;
+
+ return nullptr;
+ }
+
+ STATIC ATTRIBUTE(unused) _Output BOOL
+ hefsi_update_in_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, const Utf8Char* dir_name,
+ HEFS_INDEX_NODE* node, BOOL delete_or_create) {
+ if (!boot || !mnt) return NO;
+
+ auto start = boot->fStartIND;
+
+ if (start > boot->fEndIND) return NO;
+ if (boot->fStartIN > boot->fEndIN) return NO;
+ ;
+ if (boot->fStartBlock > boot->fEndBlock) return NO;
+
+ if (mnt) {
+ HEFS_INDEX_NODE_DIRECTORY* dir =
+ (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No);
+
+ auto hash_file = node->fHashPath;
+
+ while (YES) {
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fInput(mnt->fPacket);
+
+ (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl);
+ (Void)(kout << hex_number(dir->fHashPath) << kendl);
+
+ if (hefsi_hash_64(dir_name) == dir->fHashPath) {
+ for (SizeT inode_index = 0UL; inode_index < kOpenHeFSSliceCount; ++inode_index) {
+ if (dir->fINSlices[inode_index] == 0 && !delete_or_create) {
+ dir->fINSlices[inode_index] = boot->fStartIN;
+
+ ++dir->fEntryCount;
+
+ dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fOutput(mnt->fPacket);
+
+ auto lba = dir->fINSlices[inode_index];
+
+ node->fOffsetSliceLow = (UInt32) (boot->fStartBlock);
+ node->fOffsetSliceHigh = (UInt32) (boot->fStartBlock >> 32);
+
+ node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE));
+
+ mnt->fPacket.fPacketLba = lba;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = node;
+
+ mnt->fOutput(mnt->fPacket);
+
+ boot->fStartIN += sizeof(HEFS_INDEX_NODE);
+ boot->fStartBlock += kOpenHeFSBlockLen;
+
+ boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fOutput(mnt->fPacket);
+
+ mm_free_ptr(dir);
+
+ return YES;
+ } else if (dir->fINSlices[inode_index] != 0 && delete_or_create) {
+ auto lba = dir->fINSlices[inode_index];
+
+ HEFS_INDEX_NODE tmp_node{};
+
+ mnt->fPacket.fPacketLba = lba;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = &tmp_node;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (tmp_node.fHashPath != hash_file) {
+ continue;
+ }
+
+ node->fOffsetSliceLow = 0;
+ node->fOffsetSliceHigh = 0;
+
+ boot->fStartIN -= sizeof(HEFS_INDEX_NODE);
+ boot->fStartBlock -= kOpenHeFSBlockLen;
+
+ boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fOutput(mnt->fPacket);
+
+ mnt->fPacket.fPacketLba = lba;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE);
+ mnt->fPacket.fPacketContent = node;
+
+ mnt->fOutput(mnt->fPacket);
+
+ dir->fINSlices[inode_index] = 0;
+
+ if (dir->fEntryCount) --dir->fEntryCount;
+
+ dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fOutput(mnt->fPacket);
+
+ mm_free_ptr(dir);
+
+ return YES;
+ }
+ }
+ }
+
+ hefsi_traverse_tree(dir, mnt, boot->fStartIND, start);
+ if (start > boot->fEndIND || start == 0) break;
+ }
+
+ mm_free_ptr(dir);
+ err_global_get() = kErrorFileNotFound;
+ return NO;
+ }
+
+ err_global_get() = kErrorDiskIsFull;
+ return NO;
+ }
+
+ /// @brief Balance RB-Tree of the filesystem.
+ /// @param boot The boot node of the filesystem.
+ /// @param mnt The mnt to read/write from.
+ /// @return Status, see err_global_get().
+ STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* boot, DriveTrait* mnt) {
+ if (mnt) {
+ HEFS_INDEX_NODE_DIRECTORY* dir =
+ (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ auto start = boot->fStartIND;
+
+ while (YES) {
+ if (start == 0UL || start > boot->fEndIND) break;
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!mnt->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ if (start == boot->fStartIND) {
+ dir->fColor = kOpenHeFSBlack;
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fOutput(mnt->fPacket);
+ }
+
+ if (dir->fColor == kOpenHeFSBlack && dir->fChild != 0UL) {
+ dir->fColor = kOpenHeFSRed;
+ hefsi_rotate_tree(start, mnt);
+ } else if (dir->fColor == kOpenHeFSBlack && dir->fChild == 0UL) {
+ dir->fColor = kOpenHeFSBlack;
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fOutput(mnt->fPacket);
+ }
+
+ if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != dir->fChecksum) {
+ dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY));
+
+ mnt->fPacket.fPacketLba = start;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY);
+ mnt->fPacket.fPacketContent = dir;
+
+ mnt->fOutput(mnt->fPacket);
+ }
+
+ hefsi_traverse_tree(dir, mnt, boot->fStartIND, start);
+ }
+
+ err_global_get() = kErrorSuccess;
+ return YES;
+ }
+
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+} // namespace Detail
+} // namespace Kernel
+
+/// @note OpenHeFS will allocate inodes and ind in advance, to avoid having to allocate them in
+/// real-time.
+/// @note This is certainly take longer to format a disk with it, but worth-it in the long run.
+
+namespace Kernel {
+/// @brief Make a EPM+OpenHeFS mnt out of the disk.
+/// @param mnt The mnt to write on.
+/// @return If it was sucessful, see err_local_get().
+_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input const Int32 flags,
+ _Input const Utf8Char* vol_name) {
+ // Verify Disk.
+ mnt->fVerify(mnt->fPacket);
+
+ // if disk isn't good, then error out.
+ if (false == mnt->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return NO;
+ }
+
+ if (drv_std_get_size() < kOpenHeFSMinimumDiskSize) {
+ (Void)(kout << "OpenHeFS recommends at least 128 GiB of free space." << kendl);
+ }
+
+ HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!mnt->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ // Check if the disk is already formatted.
+
+ if (KStringBuilder::Equals(boot->fMagic, kOpenHeFSMagic) && boot->fVersion == kOpenHeFSVersion) {
+ if (ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)) != boot->fChecksum &&
+ boot->fChecksum > 0) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return NO;
+ }
+
+ err_global_get() = kErrorSuccess;
+ return YES;
+ }
+
+ if (ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)) != boot->fChecksum &&
+ boot->fChecksum > 0) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return NO;
+ }
+
+ rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
+
+ urt_copy_memory((VoidPtr) vol_name, boot->fVolName, urt_string_len(vol_name) + 1);
+ rt_copy_memory_safe((VoidPtr) kOpenHeFSMagic, boot->fMagic, kOpenHeFSMagicLen - 1, sizeof(boot->fMagic));
+
+ if (mnt->fLbaStart > mnt->fLbaEnd) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ return NO;
+ }
+
+ boot->fBadSectors = 0;
+
+ boot->fSectorCount = drv_std_get_sector_count();
+ boot->fSectorSize = mnt->fSectorSz;
+
+ MUST_PASS(boot->fSectorSize);
+
+ /// @note all OpenHeFS strucutres are equal to 512, so here it's fine, unless fSectoSize is 2048.
+ const SizeT max_lba = (drv_std_get_size()) / boot->fSectorSize;
+
+ const SizeT dir_max = max_lba / 300; // 5% for directory inodes
+ const SizeT inode_max = max_lba / 400; // 5% for inodes
+
+ boot->fStartIND = mnt->fLbaStart + kOpenHeFSINDStartOffset;
+ boot->fEndIND = boot->fStartIND + dir_max;
+
+ boot->fStartIN = boot->fEndIND;
+ boot->fEndIN = boot->fStartIN + inode_max;
+
+ boot->fStartBlock = boot->fEndIN;
+ boot->fEndBlock = drv_std_get_size();
+
+ boot->fINDCount = 0;
+
+ boot->fDiskSize = drv_std_get_size();
+ boot->fDiskStatus = kOpenHeFSStatusUnlocked;
+
+ boot->fDiskFlags = flags;
+
+ if (mnt->fKind & kMassStorageDrive) {
+ boot->fDiskKind = kOpenHeFSMassStorageDevice;
+ } else if (mnt->fKind & kOpenHeFSOpticalDrive) {
+ boot->fDiskKind = kOpenHeFSOpticalDrive;
+ } else {
+ boot->fDiskKind = kOpenHeFSUnknown;
+ }
+
+ boot->fVersion = kOpenHeFSVersion;
+
+ boot->fVID = kOpenHeFSInvalidVID;
+
+ boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fOutput(mnt->fPacket);
+
+ (Void)(kout << "Protocol: " << mnt->fProtocol() << kendl);
+ (Void)(kout8 << u8"Volume Name: " << boot->fVolName << kendl8);
+ (Void)(kout << "Start IND: " << hex_number(boot->fStartIND) << kendl);
+ (Void)(kout << "End IND: " << hex_number(boot->fEndIND) << kendl);
+ (Void)(kout << "Start IN: " << hex_number(boot->fStartIN) << kendl);
+ (Void)(kout << "End IN: " << hex_number(boot->fEndIN) << kendl);
+ (Void)(kout << "Start Block: " << hex_number(boot->fStartBlock) << kendl);
+ (Void)(kout << "End Block: " << hex_number(boot->fEndBlock) << kendl);
+ (Void)(kout << "Number of IND: " << hex_number(boot->fINDCount) << kendl);
+ (Void)(kout << "Sector Size: " << hex_number(boot->fSectorSize) << kendl);
+ (Void)(kout << "Drive Kind: " << Detail::hefs_drive_kind_to_string(boot->fDiskKind) << kendl);
+
+ if (!mnt->fPacket.fPacketGood) {
+ err_global_get() = kErrorDiskIsCorrupted;
+ return NO;
+ }
+
+ /// AMLALE: Better way to create default directories than before.
+ const Utf8Char* kFileMap[] = {u8"/", u8"/boot", u8"/system", u8"/network",
+ u8"/devices", u8"/media", u8"/dev", (Utf8Char*) nullptr};
+
+ SizeT i = 0;
+ while (kFileMap[++i] != nullptr) {
+ this->CreateINodeDirectory(mnt, kOpenHeFSEncodingFlagsUTF8, kFileMap[i]);
+ }
+
+ err_global_get() = kErrorSuccess;
+
+ return YES;
+}
+
+/// @brief Create a new directory on the disk.
+/// @param mnt The mnt to write on.
+/// @param flags The flags to use.
+/// @param dir The directory to create the file in.
+/// @return If it was sucessful, see err_local_get().
+_Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt,
+ _Input const Int32 flags,
+ const Utf8Char* dir,
+ const BOOL delete_or_create) {
+ if (urt_string_len(dir) > kOpenHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) mm_alloc_ptr(sizeof(HEFS_BOOT_NODE), Yes, No);
+
+ rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!KStringBuilder::Equals(boot->fMagic, kOpenHeFSMagic) || boot->fVersion != kOpenHeFSVersion) {
+ err_global_get() = kErrorDisk;
+ return YES;
+ }
+
+ if (!KStringBuilder::Equals(boot->fMagic, kOpenHeFSMagic) || boot->fVersion != kOpenHeFSVersion) {
+ err_global_get() = kErrorDiskIsCorrupted;
+
+ kout << "Invalid Boot Node, this can't continue!\r";
+
+ return NO;
+ }
+
+ if (KStringBuilder::Equals(dir, kOpenHeFSSearchAllStr)) {
+ kout << "Error: Invalid directory name.\r";
+
+ err_global_get() = kErrorInvalidData;
+
+ return NO;
+ }
+
+ if (Detail::hefsi_update_ind_status(boot, mnt, dir, flags, delete_or_create)) {
+ // todo: make it smarter for high-throughput.
+ Detail::hefsi_balance_ind(boot, mnt);
+
+ mm_free_ptr((VoidPtr) boot);
+ return YES;
+ }
+
+ mm_free_ptr((VoidPtr) boot);
+ return NO;
+}
+
+_Output Bool HeFileSystemParser::RemoveINodeDirectory(_Input DriveTrait* mnt,
+ _Input const Int32 flags,
+ const Utf8Char* dir) {
+ return this->INodeDirectoryCtlManip(mnt, flags, dir, YES);
+}
+
+_Output Bool HeFileSystemParser::CreateINodeDirectory(_Input DriveTrait* mnt,
+ _Input const Int32 flags,
+ const Utf8Char* dir) {
+ return this->INodeDirectoryCtlManip(mnt, flags, dir, NO);
+}
+
+_Output Bool HeFileSystemParser::DeleteINode(_Input DriveTrait* mnt, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name,
+ const UInt8 kind) {
+ return this->INodeCtlManip(mnt, flags, dir, name, YES, kind);
+}
+
+_Output Bool HeFileSystemParser::CreateINode(_Input DriveTrait* mnt, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name,
+ const UInt8 kind) {
+ return this->INodeCtlManip(mnt, flags, dir, name, NO, kind);
+}
+
+_Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr block, SizeT block_sz,
+ const Utf8Char* dir, const Utf8Char* name,
+ const UInt8 kind, const BOOL is_input) {
+ if (urt_string_len(dir) > kOpenHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ if (urt_string_len(name) > kOpenHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) mm_alloc_ptr(sizeof(HEFS_BOOT_NODE), Yes, No);
+
+ if (!boot) {
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+
+ rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!KStringBuilder::Equals(boot->fMagic, kOpenHeFSMagic) || boot->fVersion != kOpenHeFSVersion) {
+ (Void)(kout << "Invalid Boot Node, OpenHeFS partition is invalid." << kendl);
+ mm_free_ptr((VoidPtr) boot);
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ auto start = Detail::hefsi_fetch_in(boot, mnt, dir, name, kind);
+
+ if (start) {
+ (Void)(kout << hex_number(start->fHashPath) << kendl);
+ (Void)(kout << hex_number(start->fOffsetSliceLow) << kendl);
+
+ if (start->fOffsetSliceLow && start->fHashPath) {
+ mnt->fPacket.fPacketLba = ((UInt64) start->fOffsetSliceHigh << 32) | start->fOffsetSliceLow;
+ mnt->fPacket.fPacketSize = block_sz;
+ mnt->fPacket.fPacketContent = block;
+
+ if (is_input) {
+ mnt->fInput(mnt->fPacket);
+ } else {
+ if (start->fFlags & kOpenHeFSFlagsReadOnly) {
+ mm_free_ptr((VoidPtr) boot);
+ delete start;
+
+ kout << "Error: File is read-only\r";
+
+ return NO;
+ }
+
+ mnt->fOutput(mnt->fPacket);
+ }
+ }
+ }
+
+ mm_free_ptr((VoidPtr) boot);
+ delete start;
+ return YES;
+}
+
+/// @brief Create a new file on the disk.
+/// @param mnt The mnt to write on.
+/// @param flags The flags to use.
+/// @param dir The directory to create the file in.
+/// @param name The name of the file.
+/// @return If it was sucessful, see err_local_get().
+_Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input const Int32 flags,
+ const Utf8Char* dir, const Utf8Char* name,
+ const BOOL delete_or_create, const UInt8 kind) {
+ if (urt_string_len(name) > kOpenHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ if (urt_string_len(dir) > kOpenHeFSFileNameLen) {
+ err_global_get() = kErrorDisk;
+ return NO;
+ }
+
+ HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE), Yes, No);
+
+ if (!node) {
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+
+ rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE));
+
+ HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE));
+
+ if (!boot) {
+ mm_free_ptr((VoidPtr) node);
+ err_global_get() = kErrorInvalidData;
+
+ return NO;
+ }
+
+ rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime,
+ rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime));
+
+ mnt->fPacket.fPacketLba = mnt->fLbaStart;
+ mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE);
+ mnt->fPacket.fPacketContent = boot;
+
+ mnt->fInput(mnt->fPacket);
+
+ if (!KStringBuilder::Equals(boot->fMagic, kOpenHeFSMagic) || boot->fVersion != kOpenHeFSVersion) {
+ err_global_get() = kErrorDisk;
+ return YES;
+ }
+
+ if (KStringBuilder::Equals(dir, kOpenHeFSSearchAllStr)) {
+ kout << "Error: Invalid file name.\r";
+
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+
+ for (SizeT i_name = 0UL; i_name < urt_string_len(name); ++i_name) {
+ if (name[i_name] == u'/') {
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+ }
+
+ if (KStringBuilder::Equals(dir, kOpenHeFSSearchAllStr)) {
+ kout << "Error: Invalid directory name.\r";
+
+ err_global_get() = kErrorInvalidData;
+ return NO;
+ }
+
+ node->fAccessed = 0;
+ node->fCreated = delete_or_create ? NO : YES;
+ node->fDeleted = delete_or_create ? 1UL : NO;
+ node->fModified = 0;
+ node->fSize = 0;
+ node->fKind = kind;
+ node->fFlags = flags;
+ node->fChecksum = 0;
+ node->fGID = 0;
+ node->fUID = 0;
+ node->fHashPath = Detail::hefsi_hash_64(name);
+
+ if (Detail::hefsi_update_in_status(boot, mnt, dir, node, delete_or_create)) {
+ mm_free_ptr((VoidPtr) node);
+
+ Detail::hefsi_balance_ind(boot, mnt);
+
+ err_global_get() = kErrorSuccess;
+ return YES;
+ }
+
+ mm_free_ptr((VoidPtr) node);
+ err_global_get() = kErrorDirectoryNotFound;
+
+ return NO;
+}
+
+STATIC IMountpoint kMountpoint;
+
+/// @brief Initialize the OpenHeFS filesystem.
+/// @return To check its status, see err_local_get().
+Boolean OpenHeFS::fs_init_openhefs(Void) noexcept {
+ io_construct_main_drive(kMountpoint.A());
+
+ if (kMountpoint.A().fPacket.fPacketReadOnly == YES) {
+ kout << "Main disk cannot be mounted (read-only media).\r";
+ return YES;
+ }
+
+ return HeFileSystemParser{}.Format(&kMountpoint.A(), kOpenHeFSEncodingFlagsUTF8, kOpenHeFSDefaultVolumeName);
+}
+} // namespace Kernel
+
+#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__
diff --git a/src/kernel/src/FileMgr.cc b/src/kernel/src/FileMgr.cc
new file mode 100644
index 00000000..88b17470
--- /dev/null
+++ b/src/kernel/src/FileMgr.cc
@@ -0,0 +1,49 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/FileMgr.h>
+#include <NeKit/Utils.h>
+
+/***********************************************************************************/
+/// @file FileMgr.cc
+//! @brief File System Manager API.
+///! @author Amlal El Mahrouss (amlal@nekernel.org)
+/***********************************************************************************/
+
+namespace Kernel {
+STATIC IFilesystemMgr* kMountedFilesystem = nullptr;
+
+/// @brief FilesystemMgr getter.
+/// @return The mounted filesystem.
+_Output IFilesystemMgr* IFilesystemMgr::GetMounted() {
+ return kMountedFilesystem;
+}
+
+/// @brief Unmount filesystem.
+/// @return The unmounted filesystem.
+_Output IFilesystemMgr* IFilesystemMgr::Unmount() {
+ if (kMountedFilesystem) {
+ auto mount = kMountedFilesystem;
+ kMountedFilesystem = nullptr;
+
+ return mount;
+ }
+
+ return nullptr;
+}
+
+/// @brief Mount filesystem.
+/// @param mount_ptr The filesystem to mount.
+/// @return if it succeeded true, otherwise false.
+_Output Bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr) {
+ if (mount_ptr != nullptr) {
+ kMountedFilesystem = mount_ptr;
+ return Yes;
+ }
+
+ return No;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/GUIDWizard.cc b/src/kernel/src/GUIDWizard.cc
new file mode 100644
index 00000000..2d1218ed
--- /dev/null
+++ b/src/kernel/src/GUIDWizard.cc
@@ -0,0 +1,67 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: GUIDWizard.cc
+ Purpose: GUID helper code
+
+ Revision History:
+
+======================================== */
+
+#include <CFKit/GUIDWizard.h>
+#include <NeKit/Ref.h>
+
+// begin of ascii 'readable' characters. (A, C, C, 1, 2)
+#define kGUIDAsciiBegin 47
+// @brief Size of UUID.
+#define kGUIDSize 37
+
+namespace Kernel::CF::XRN::Version1 {
+auto cf_make_sequence(const ArrayList<UInt32>& uuidSeq) -> Ref<GUIDSequence*> {
+ GUIDSequence* seq = new GUIDSequence();
+ MUST_PASS(seq);
+
+ Ref<GUIDSequence*> seq_ref{seq};
+
+ if (!seq) return seq_ref;
+
+ seq_ref.Leak()->fUuid.fMs1 = uuidSeq[0];
+ seq_ref.Leak()->fUuid.fMs2 = uuidSeq[1];
+ seq_ref.Leak()->fUuid.fMs3 = uuidSeq[2];
+ seq_ref.Leak()->fUuid.fMs4[0] = uuidSeq[3];
+ seq_ref.Leak()->fUuid.fMs4[1] = uuidSeq[4];
+ seq_ref.Leak()->fUuid.fMs4[2] = uuidSeq[5];
+ seq_ref.Leak()->fUuid.fMs4[3] = uuidSeq[6];
+ seq_ref.Leak()->fUuid.fMs4[4] = uuidSeq[7];
+ seq_ref.Leak()->fUuid.fMs4[5] = uuidSeq[8];
+ seq_ref.Leak()->fUuid.fMs4[6] = uuidSeq[9];
+ seq_ref.Leak()->fUuid.fMs4[7] = uuidSeq[10];
+
+ return seq_ref;
+}
+
+// @brief Tries to make a guid out of a string.
+// This function is not complete for now
+auto cf_try_guid_to_string(Ref<GUIDSequence*>& seq) -> ErrorOr<Ref<KString>> {
+ Char buf[kGUIDSize];
+
+ for (SizeT index = 0; index < 16; ++index) {
+ buf[index] = seq.Leak()->fU8[index] + kGUIDAsciiBegin;
+ }
+
+ for (SizeT index = 16; index < 24; ++index) {
+ buf[index] = seq.Leak()->fU16[index] + kGUIDAsciiBegin;
+ }
+
+ for (SizeT index = 24; index < 28; ++index) {
+ buf[index] = seq.Leak()->fU32[index] + kGUIDAsciiBegin;
+ }
+
+ auto view = KStringBuilder::Construct(buf);
+
+ if (view) return ErrorOr<Ref<KString>>{view.Leak()};
+
+ return ErrorOr<Ref<KString>>{kErrorInvalidData};
+}
+} // namespace Kernel::CF::XRN::Version1
diff --git a/src/kernel/src/GUIDWrapper.cc b/src/kernel/src/GUIDWrapper.cc
new file mode 100644
index 00000000..ee29f911
--- /dev/null
+++ b/src/kernel/src/GUIDWrapper.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <CFKit/GUIDWrapper.h>
+
+namespace Kernel::CF::XRN {}
diff --git a/src/kernel/src/Gfx/FBDeviceInterface.cc b/src/kernel/src/Gfx/FBDeviceInterface.cc
new file mode 100644
index 00000000..c5fac330
--- /dev/null
+++ b/src/kernel/src/Gfx/FBDeviceInterface.cc
@@ -0,0 +1,50 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <GfxKit/FB.h>
+
+using namespace Kernel;
+
+/// @brief Class constructor
+/// @param Out Drive output
+/// @param In Drive input
+/// @param Cleanup Drive cleanup.
+FBDeviceInterface::FBDeviceInterface(void (*out)(DeviceInterface* self, FBDevicePacket* outpacket),
+ void (*in)(DeviceInterface* self, FBDevicePacket* inpacket))
+ : DeviceInterface(out, in) {}
+
+/// @brief Class desctructor
+FBDeviceInterface::~FBDeviceInterface() = default;
+
+/// @brief Output operator.
+/// @param mnt the disk mountpoint.
+/// @return the class itself after operation.
+FBDeviceInterface& FBDeviceInterface::operator<<(FBDevicePacket* pckt) {
+ if (!pckt) return *this;
+
+ if (pckt->fHeight == 0 || pckt->fWidth == 0) return *this;
+
+ this->fOut(this, pckt);
+
+ return *this;
+}
+
+/// @brief Input operator.
+/// @param mnt the disk mountpoint.
+/// @return the class itself after operation.
+FBDeviceInterface& FBDeviceInterface::operator>>(FBDevicePacket* pckt) {
+ if (!pckt) return *this;
+
+ this->fIn(this, pckt);
+
+ return *this;
+}
+
+/// @brief Returns the name of the device interface.
+/// @return it's name as a string.
+const Char* FBDeviceInterface::Name() const {
+ return "/devices/fb{}";
+} \ No newline at end of file
diff --git a/src/kernel/src/HardwareThreadScheduler.cc b/src/kernel/src/HardwareThreadScheduler.cc
new file mode 100644
index 00000000..41d927f6
--- /dev/null
+++ b/src/kernel/src/HardwareThreadScheduler.cc
@@ -0,0 +1,184 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <CFKit/Property.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/ProcessScheduler.h>
+
+/***********************************************************************************/
+///! @file HardwareThreadScheduler.cc
+///! @brief This file handles multi processing in the Kernel.
+///! @brief Multi processing is needed for multi-tasking operations.
+/***********************************************************************************/
+
+namespace Kernel {
+/***********************************************************************************/
+/// @note Those symbols are needed in order to switch and validate the stack.
+/***********************************************************************************/
+
+EXTERN_C Bool hal_check_task(HAL::StackFramePtr frame);
+EXTERN_C Bool mp_register_task(HAL::StackFramePtr frame, ProcessID pid);
+
+STATIC HardwareThreadScheduler kHardwareThreadScheduler;
+
+///! A HardwareThread class takes care of it's owned hardware thread.
+///! It has a stack for it's core.
+
+/***********************************************************************************/
+///! @brief C++ constructor.
+/***********************************************************************************/
+HardwareThread::HardwareThread() = default;
+
+/***********************************************************************************/
+///! @brief C++ destructor.
+/***********************************************************************************/
+HardwareThread::~HardwareThread() = default;
+
+/***********************************************************************************/
+//! @brief returns the id of the thread.
+/***********************************************************************************/
+ThreadID& HardwareThread::ID() noexcept {
+ return fID;
+}
+
+/***********************************************************************************/
+//! @brief returns the kind of thread we have.
+/***********************************************************************************/
+ThreadKind& HardwareThread::Kind() noexcept {
+ return fKind;
+}
+
+/***********************************************************************************/
+//! @brief is the thread busy?
+//! @return whether the thread is busy or not.
+/***********************************************************************************/
+Bool HardwareThread::IsBusy() noexcept {
+ return fBusy;
+}
+
+/***********************************************************************************/
+/// @brief Get processor stack frame.
+/***********************************************************************************/
+
+HAL::StackFramePtr HardwareThread::StackFrame() noexcept {
+ MUST_PASS(this->fStack);
+ return this->fStack;
+}
+
+Void HardwareThread::Busy(Bool busy) noexcept {
+ this->fBusy = busy;
+}
+
+HardwareThread::operator bool() {
+ return this->fStack && !this->fBusy;
+}
+
+/***********************************************************************************/
+/// @brief Wakeup the processor.
+/***********************************************************************************/
+
+Void HardwareThread::Wake(const bool wakeup) noexcept {
+ this->fWakeup = wakeup;
+}
+
+/***********************************************************************************/
+/// @brief Switch to hardware thread.
+/// @param stack the new hardware thread.
+/// @retval true stack was changed, code is running.
+/// @retval false stack is invalid, previous code is running.
+/***********************************************************************************/
+Bool HardwareThread::Switch(HAL::StackFramePtr frame) {
+ if (!frame) {
+ return NO;
+ }
+
+ if (!hal_check_task(frame)) {
+ return NO;
+ }
+
+ this->fStack = frame;
+ return mp_register_task(fStack, this->fID);
+}
+
+/***********************************************************************************/
+///! @brief Tells if processor is waked up.
+/***********************************************************************************/
+bool HardwareThread::IsWakeup() noexcept {
+ return this->fWakeup;
+}
+
+/***********************************************************************************/
+///! @brief Constructor and destructors.
+///! @brief Default constructor.
+/***********************************************************************************/
+
+HardwareThreadScheduler::HardwareThreadScheduler() = default;
+
+/***********************************************************************************/
+///! @brief Default destructor.
+/***********************************************************************************/
+HardwareThreadScheduler::~HardwareThreadScheduler() = default;
+
+/***********************************************************************************/
+/// @brief Shared singleton function
+/***********************************************************************************/
+HardwareThreadScheduler& HardwareThreadScheduler::The() {
+ return kHardwareThreadScheduler;
+}
+
+/***********************************************************************************/
+/// @brief Get Stack Frame of AP.
+/***********************************************************************************/
+HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept {
+ return fThreadList[fCurrentThreadIdx].fStack;
+}
+
+/***********************************************************************************/
+/**
+ * Get Hardware thread at index.
+ * @param idx the index
+ * @return the reference to the hardware thread.
+ */
+/***********************************************************************************/
+Ref<HardwareThread*> HardwareThreadScheduler::operator[](SizeT idx) {
+ if (idx > kMaxAPInsideSched) {
+ HardwareThread* kFakeThread = nullptr;
+ return {kFakeThread};
+ }
+
+ fCurrentThreadIdx = idx;
+ return &fThreadList[idx];
+}
+
+/***********************************************************************************/
+/**
+ * Check if thread pool isn't empty.
+ * @return
+ */
+/***********************************************************************************/
+HardwareThreadScheduler::operator bool() noexcept {
+ return !fThreadList.Empty();
+}
+
+/***********************************************************************************/
+/**
+ * Reverse operator bool
+ * @return
+ */
+/***********************************************************************************/
+bool HardwareThreadScheduler::operator!() noexcept {
+ return fThreadList.Empty();
+}
+
+/***********************************************************************************/
+/// @brief Returns the amount of core present.
+/// @return the number of APs.
+/***********************************************************************************/
+SizeT HardwareThreadScheduler::Capacity() noexcept {
+ return fThreadList.Count();
+}
+} // namespace Kernel
diff --git a/src/kernel/src/HeapMgr.cc b/src/kernel/src/HeapMgr.cc
new file mode 100644
index 00000000..848a0377
--- /dev/null
+++ b/src/kernel/src/HeapMgr.cc
@@ -0,0 +1,260 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/Crc32.h>
+#include <NeKit/PageMgr.h>
+#include <NeKit/Utils.h>
+
+/* ========================================
+
+ Revision History:
+ 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field.
+ 20/10/24: FIX: Fix mm_new_ and mm_delete_ APIs inside HeapMgr.h header. (amlal)
+ 27/01/25: REFACTOR: Reworked code as the memory manager.
+ 25/03/25: REFACTOR: Refactor HeapMgr code and log freed address location.
+
+ ======================================== */
+
+//! @file HeapMgr.cc
+//! @brief Heap system that serves as the main memory manager.
+
+#define kHeapMgrMagic (0xD4D75)
+#define kHeapMgrAlignSz (4U)
+
+namespace Kernel {
+/// @brief Implementation details.
+namespace Detail {
+ struct PACKED MM_INFORMATION_BLOCK;
+
+ /// @brief Kernel heap information block.
+ /// Located before the address bytes.
+ /// | HIB | CLASS/STRUCT/DATA TYPES... |
+ struct PACKED MM_INFORMATION_BLOCK final {
+ ///! @brief 32-bit value which contains the magic number of the heap.
+ UInt32 fMagic : 24;
+
+ ///! @brief Is the heap present?
+ UInt8 fPresent : 1;
+
+ /// @brief Is this value writable?
+ UInt8 fWriteRead : 1;
+
+ /// @brief Is this value owned by the user?
+ UInt8 fUser : 1;
+
+ /// @brief Is this a page pointer?
+ UInt8 fPage : 1;
+
+ /// @brief 32-bit CRC checksum.
+ UInt32 fCRC32;
+
+ /// @brief 64-bit Allocation flags.
+ UInt16 fFlags;
+
+ /// @brief 64-bit pointer size.
+ SizeT fSize;
+
+ /// @brief 64-bit target offset pointer.
+ UIntPtr fOffset;
+
+ /// @brief Padding.
+ UInt32 fPad;
+
+ /// @brief Padding bytes for header.
+ UInt8 fPadding[kHeapMgrAlignSz];
+ };
+
+ /// @brief Check for heap address validity.
+ /// @param heap_ptr The address_ptr to check.
+ /// @return Bool if the pointer is valid or not.
+ _Output auto mm_check_ptr_address(VoidPtr heap_ptr) -> Bool {
+ if (!heap_ptr) return false;
+
+ IntPtr base_ptr = ((IntPtr) heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK);
+
+ /// Add that check in case we're having an integer underflow. ///
+
+ if (base_ptr < 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR;
+} // namespace Detail
+
+STATIC PageMgr kPageMgr;
+
+/// @brief Allocate chunk of memory.
+/// @param sz Size of pointer
+/// @param wr Read Write bit.
+/// @param user User enable bit.
+/// @return The newly allocated pointer.
+_Output VoidPtr mm_alloc_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount) {
+ auto sz_fix = sz;
+
+ if (sz_fix == 0) return nullptr;
+
+ sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK);
+
+ auto wrapper = kPageMgr.Request(wr, user, No, sz_fix, pad_amount);
+
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>(wrapper.VirtualAddress() +
+ sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ heap_info_ptr->fSize = sz_fix;
+ heap_info_ptr->fMagic = kHeapMgrMagic;
+ heap_info_ptr->fCRC32 = 0U; // dont fill it for now.
+ heap_info_ptr->fOffset =
+ reinterpret_cast<UIntPtr>(heap_info_ptr) + sizeof(Detail::MM_INFORMATION_BLOCK);
+ heap_info_ptr->fPage = No;
+ heap_info_ptr->fWriteRead = wr;
+ heap_info_ptr->fUser = user;
+ heap_info_ptr->fPresent = Yes;
+ heap_info_ptr->fPad = pad_amount;
+
+ rt_set_memory(heap_info_ptr->fPadding, 0, kHeapMgrAlignSz);
+
+ auto result = reinterpret_cast<VoidPtr>(heap_info_ptr->fOffset);
+
+ (Void)(kout << "HeapMgr: Registered heap address: "
+ << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl);
+
+ return result;
+}
+
+/// @brief Makes a page heap.
+/// @param heap_ptr the pointer to make a page heap.
+/// @return kErrorSuccess if successful, otherwise an error code.
+_Output Int32 mm_make_page(VoidPtr heap_ptr) {
+ if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent;
+
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr) return kErrorHeapNotPresent;
+
+ heap_info_ptr->fPage = true;
+
+ (Void)(kout << "HeapMgr: Registered page from heap address: "
+ << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl);
+
+ return kErrorSuccess;
+}
+
+/// @brief Overwrites and set the flags of a heap header.
+/// @param heap_ptr the pointer to update.
+/// @param flags the flags to set.
+_Output Int32 mm_set_ptr_flags(VoidPtr heap_ptr, UInt64 flags) {
+ if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent;
+
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr) return kErrorHeapNotPresent;
+
+ heap_info_ptr->fFlags = flags;
+
+ return kErrorSuccess;
+}
+
+/// @brief Gets the flags of a heap header.
+/// @param heap_ptr the pointer to get.
+_Output UInt64 mm_get_ptr_flags(VoidPtr heap_ptr) {
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr) return kErrorHeapNotPresent;
+
+ return heap_info_ptr->fFlags;
+}
+
+/// @brief Declare pointer as free.
+/// @param heap_ptr the pointer.
+/// @return
+_Output Int32 mm_free_ptr(VoidPtr heap_ptr) {
+ if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent;
+
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) (heap_ptr) -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ if (heap_info_ptr && heap_info_ptr->fMagic == kHeapMgrMagic) {
+ if (!heap_info_ptr->fPresent) {
+ return kErrorHeapNotPresent;
+ }
+
+ heap_info_ptr->fSize = 0UL;
+ heap_info_ptr->fPresent = No;
+ heap_info_ptr->fOffset = 0;
+ heap_info_ptr->fCRC32 = 0;
+ heap_info_ptr->fWriteRead = No;
+ heap_info_ptr->fUser = No;
+ heap_info_ptr->fMagic = 0;
+ heap_info_ptr->fPad = 0;
+
+ (Void)(kout << "HeapMgr: Freed heap address: "
+ << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl);
+
+ PTEWrapper page_wrapper(
+ No, No, No,
+ reinterpret_cast<UIntPtr>(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ Ref<PTEWrapper> pte_address{page_wrapper};
+
+ kPageMgr.Free(pte_address);
+
+ return kErrorSuccess;
+ }
+
+ return kErrorInternal;
+}
+
+/// @brief Check if pointer is a valid Kernel pointer.
+/// @param heap_ptr the pointer
+/// @return if it exists.
+_Output Boolean mm_is_valid_ptr(VoidPtr heap_ptr) {
+ if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) {
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) (heap_ptr) -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ return (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kHeapMgrMagic);
+ }
+
+ return No;
+}
+
+/// @brief Protect the heap with a CRC value.
+/// @param heap_ptr HIB pointer.
+/// @return if it valid: point has crc now., otherwise fail.
+_Output Boolean mm_protect_ptr(VoidPtr heap_ptr) {
+ if (heap_ptr) {
+ Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr -
+ sizeof(Detail::MM_INFORMATION_BLOCK));
+
+ /// if valid, present and is heap header, then compute crc32
+ if (heap_info_ptr && heap_info_ptr->fPresent && kHeapMgrMagic == heap_info_ptr->fMagic) {
+ heap_info_ptr->fCRC32 =
+ ke_calculate_crc32((Char*) heap_info_ptr->fOffset, heap_info_ptr->fSize);
+
+ return Yes;
+ }
+ }
+
+ return No;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/IDylibObject.cc b/src/kernel/src/IDylibObject.cc
new file mode 100644
index 00000000..61191af1
--- /dev/null
+++ b/src/kernel/src/IDylibObject.cc
@@ -0,0 +1,13 @@
+/*
+ * ========================================================
+ *
+ * NeKernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/IDylibObject.h>
+
+using namespace Kernel;
diff --git a/src/kernel/src/IFS.cc b/src/kernel/src/IFS.cc
new file mode 100644
index 00000000..4679b8a3
--- /dev/null
+++ b/src/kernel/src/IFS.cc
@@ -0,0 +1,89 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/FileMgr.h>
+
+/*************************************************************
+ *
+ * File: IFS.cc
+ * Purpose: Filesystem to mountpoint interface.
+ * Date: 05/26/2025
+ *
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ *************************************************************/
+
+/// Useful macros regarding the IFS.
+
+#define fsi_ifs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS)
+#define fsi_ifs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS)
+
+namespace Kernel {
+/// @brief Read from fs disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_read(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) {
+ if (!Mnt) return kErrorDisk;
+
+ DrvTrait.fPacket.fPacketGood = false;
+
+ switch (DrvIndex) {
+ case IMountpoint::kDriveIndexA: {
+ fsi_ifs_read(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case IMountpoint::kDriveIndexB: {
+ fsi_ifs_read(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case IMountpoint::kDriveIndexC: {
+ fsi_ifs_read(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case IMountpoint::kDriveIndexD: {
+ fsi_ifs_read(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
+
+ return DrvTrait.fPacket.fPacketGood ? kErrorSuccess : kErrorDisk;
+}
+
+/// @brief Write to fs disk.
+/// @param Mnt mounted interface.
+/// @param DrvTrait drive info
+/// @param DrvIndex drive index.
+/// @return
+Int32 fs_ifs_write(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) {
+ if (!Mnt) return kErrorDisk;
+
+ DrvTrait.fPacket.fPacketGood = false;
+
+ switch (DrvIndex) {
+ case IMountpoint::kDriveIndexA: {
+ fsi_ifs_write(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case IMountpoint::kDriveIndexB: {
+ fsi_ifs_write(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case IMountpoint::kDriveIndexC: {
+ fsi_ifs_write(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case IMountpoint::kDriveIndexD: {
+ fsi_ifs_write(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
+
+ return DrvTrait.fPacket.fPacketGood ? kErrorSuccess : kErrorDisk;
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/src/IPEFDylibObject.cc b/src/kernel/src/IPEFDylibObject.cc
new file mode 100644
index 00000000..4ba9278d
--- /dev/null
+++ b/src/kernel/src/IPEFDylibObject.cc
@@ -0,0 +1,109 @@
+/*
+ * ========================================================
+ *
+ * NeKernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <KernelKit/PEF.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/ThreadLocalStorage.h>
+#include <NeKit/Defines.h>
+
+/* ========================================
+
+ Revision History:
+
+ 01/02/24: Reworked dll ABI, expect a rtl_init_dylib_pef and
+ rtl_fini_dylib_pef (amlel)
+
+ 15/02/24: Breaking changes, changed the name of the
+ routines. (amlel)
+
+ 07/28/24: Replace rt_library_free with rtl_fini_dylib_pef
+
+ 10/8/24: FIX: Fix log comment.
+
+ ======================================== */
+
+using namespace Kernel;
+
+/***********************************************************************************/
+/// @file IPEFDylibObject.cc
+/// @brief PEF's Dylib runtime.
+///! @author Amlal El Mahrouss (amlal@nekernel.org)
+/***********************************************************************************/
+
+/***********************************************************************************/
+/** @brief Library initializer. */
+/***********************************************************************************/
+
+EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) {
+ IDylibRef dll_obj = tls_new_class<IPEFDylibObject>();
+
+ if (!dll_obj) {
+ process.Crash();
+ return nullptr;
+ }
+
+ dll_obj->Mount(new IPEFDylibObject::DylibTraits());
+
+ if (!dll_obj->Get()) {
+ tls_delete_class(dll_obj);
+ dll_obj = nullptr;
+
+ process.Crash();
+
+ return nullptr;
+ }
+
+ dll_obj->Get()->ImageObject = process.Image.LeakBlob().Leak().Leak();
+
+ if (!dll_obj->Get()->ImageObject) {
+ delete dll_obj->Get();
+
+ tls_delete_class(dll_obj);
+ dll_obj = nullptr;
+
+ process.Crash();
+
+ return nullptr;
+ }
+
+ dll_obj->Get()->ImageEntrypointOffset =
+ dll_obj->Load<VoidPtr>(kPefStart, rt_string_len(kPefStart, 0), kPefCode);
+
+ return dll_obj;
+}
+
+/***********************************************************************************/
+/** @brief Frees the dll_obj. */
+/** @note Please check if the dll_obj got freed! */
+/** @param dll_obj The dll_obj to free. */
+/** @param successful Reports if successful or not. */
+/***********************************************************************************/
+
+EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) {
+ MUST_PASS(successful);
+
+ if (!successful) {
+ return;
+ }
+
+ // sanity check (will also trigger a bug check if this fails)
+ if (dll_obj == nullptr) {
+ *successful = false;
+ process.Crash();
+ }
+
+ delete dll_obj->Get();
+ delete dll_obj;
+
+ dll_obj = nullptr;
+
+ *successful = true;
+}
diff --git a/src/kernel/src/IndexableProperty.cc b/src/kernel/src/IndexableProperty.cc
new file mode 100644
index 00000000..85207d4b
--- /dev/null
+++ b/src/kernel/src/IndexableProperty.cc
@@ -0,0 +1,45 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <CompilerKit/CompilerKit.h>
+#include <FSKit/IndexableProperty.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/MutableArray.h>
+#include <NeKit/Utils.h>
+
+/// @brief File indexer API for fast path access.
+/// BUGS: 0
+
+#define kMaxLenIndexer (256U)
+
+namespace Kernel {
+namespace Indexer {
+ Index& IndexableProperty::Leak() noexcept { return fIndex; }
+
+ Void IndexableProperty::AddFlag(UInt16 flag) { fFlags |= flag; }
+
+ Void IndexableProperty::RemoveFlag(UInt16 flag) { fFlags &= ~(flag); }
+
+ UInt16 IndexableProperty::HasFlag(UInt16 flag) { return fFlags & flag; }
+
+ /// @brief Index a file into the indexer instance.
+ /// @param filename filesystem path to access.
+ /// @param filenameLen used bytes in path.
+ /// @param indexer the filesystem indexer.
+ /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)).
+ Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) {
+ if (!indexer.HasFlag(kIndexerClaimed)) {
+ indexer.RemoveFlag(kIndexerUnclaimed);
+ indexer.AddFlag(kIndexerClaimed);
+ rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(filename)),
+ (VoidPtr) indexer.Leak().Path, filenameLen, kIndexerCatalogNameLength);
+
+ (Void)(kout << "FSKit: Indexed new file: " << filename << kendl);
+ }
+ }
+} // namespace Indexer
+} // namespace Kernel
diff --git a/src/kernel/src/Json.cc b/src/kernel/src/Json.cc
new file mode 100644
index 00000000..198aed99
--- /dev/null
+++ b/src/kernel/src/Json.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Json.h>
+
+namespace Kernel {} \ No newline at end of file
diff --git a/src/kernel/src/KPC.cc b/src/kernel/src/KPC.cc
new file mode 100644
index 00000000..4318b9cd
--- /dev/null
+++ b/src/kernel/src/KPC.cc
@@ -0,0 +1,39 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/KernelPanic.h>
+
+namespace Kernel {
+STATIC Bool kRaiseOnBugCheck = false;
+
+/// @brief Does a system wide bug check.
+/// @param void no params are needed.
+/// @return if error-free: false, otherwise true.
+Boolean err_bug_check_raise(Void) noexcept {
+ Char* ptr = new Char[512];
+
+ if (ptr == nullptr) goto bug_check_fail;
+
+ if (!mm_is_valid_ptr(ptr)) goto bug_check_fail;
+
+ delete[] ptr;
+
+ return Yes;
+
+bug_check_fail:
+ if (ptr) delete[] ptr;
+
+ ptr = nullptr;
+
+ if (kRaiseOnBugCheck) {
+ ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR);
+ }
+
+ return No;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/KernelTaskScheduler.cc b/src/kernel/src/KernelTaskScheduler.cc
new file mode 100644
index 00000000..c3628765
--- /dev/null
+++ b/src/kernel/src/KernelTaskScheduler.cc
@@ -0,0 +1,37 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ FILE: KernelTaskScheduler.cc
+ PURPOSE: Kernel Task scheduler.
+
+======================================== */
+
+#include <KernelKit/KernelTaskScheduler.h>
+
+/***********************************************************************************/
+/// @file KernelTaskScheduler.cc
+/// @brief Kernel Task scheduler.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+/***********************************************************************************/
+
+namespace Kernel {
+EXTERN_C Void hal_switch_kernel_task(HAL::StackFramePtr frame, KID kid);
+
+Bool KernelTaskHelper::Add(HAL::StackFramePtr frame_ptr, KID new_kid) {
+ NE_UNUSED(frame_ptr);
+ NE_UNUSED(new_kid);
+
+ return NO;
+}
+
+Bool KernelTaskHelper::Remove(const KID kid) {
+ NE_UNUSED(kid);
+
+ return NO;
+}
+
+Bool KernelTaskHelper::CanBeScheduled(const KERNEL_TASK& task) {
+ return task.Kid > 0 && task.Image.HasCode();
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/src/LockDelegate.cc b/src/kernel/src/LockDelegate.cc
new file mode 100644
index 00000000..2fe2b464
--- /dev/null
+++ b/src/kernel/src/LockDelegate.cc
@@ -0,0 +1,11 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/LockDelegate.h>
+
+namespace Kernel {
+/// @note Leave it empty for now.
+} // namespace Kernel
diff --git a/src/kernel/src/MutableArray.cc b/src/kernel/src/MutableArray.cc
new file mode 100644
index 00000000..3c86e8b8
--- /dev/null
+++ b/src/kernel/src/MutableArray.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/MutableArray.h>
diff --git a/src/kernel/src/Network/IPAddress.cc b/src/kernel/src/Network/IPAddress.cc
new file mode 100644
index 00000000..98279979
--- /dev/null
+++ b/src/kernel/src/Network/IPAddress.cc
@@ -0,0 +1,113 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Utils.h>
+#include <NetworkKit/IP.h>
+
+namespace Kernel {
+UInt8* RawIPAddress::Address() {
+ return fAddr;
+}
+
+RawIPAddress::RawIPAddress(UInt8 bytes[4]) {
+ rt_copy_memory(bytes, fAddr, 4);
+}
+
+BOOL RawIPAddress::operator==(const RawIPAddress& ipv4) {
+ for (Size index = 0; index < 4; ++index) {
+ if (ipv4.fAddr[index] != fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+BOOL RawIPAddress::operator!=(const RawIPAddress& ipv4) {
+ for (Size index = 0; index < 4; ++index) {
+ if (ipv4.fAddr[index] == fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+UInt8& RawIPAddress::operator[](const Size& index) {
+ kout << "[RawIPAddress::operator[]] Fetching Index...\r";
+
+ static UInt8 IP_PLACEHOLDER = '0';
+ if (index >= 4) return IP_PLACEHOLDER;
+
+ return fAddr[index];
+}
+
+RawIPAddress6::RawIPAddress6(UInt8 bytes[16]) {
+ rt_copy_memory(bytes, fAddr, 16);
+}
+
+UInt8& RawIPAddress6::operator[](const Size& index) {
+ kout << "[RawIPAddress6::operator[]] Fetching Index...\r";
+
+ static UInt8 IP_PLACEHOLDER = '0';
+ if (index >= 16) return IP_PLACEHOLDER;
+
+ return fAddr[index];
+}
+
+bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) {
+ for (SizeT index = 0; index < 16; ++index) {
+ if (ipv6.fAddr[index] != fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) {
+ for (SizeT index = 0; index < 16; ++index) {
+ if (ipv6.fAddr[index] == fAddr[index]) return false;
+ }
+
+ return true;
+}
+
+/// @todo
+ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress6>& ipv6) {
+ NE_UNUSED(ipv6);
+ auto str = KStringBuilder::Construct("");
+ return str;
+}
+
+/// @todo
+ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4) {
+ NE_UNUSED(ipv4);
+ auto str = KStringBuilder::Construct("");
+ return str;
+}
+
+/// @note Doesn't catch IPs such as 256.999.0.1, UNSAFE!
+bool IPFactory::IpCheckVersion4(const Char* ip) {
+ if (!ip) return NO;
+
+ Int32 cnter = 0;
+ Int32 dot_cnter = 0;
+
+ constexpr const auto kIP4DotCharacter = '.';
+
+ for (SizeT base = 0; base < rt_string_len(ip); ++base) {
+ if (ip[base] == kIP4DotCharacter) {
+ cnter = 0;
+ ++dot_cnter;
+ } else {
+ if (ip[base] > '5' || ip[base] < '0') return NO;
+ if (!rt_is_alnum(ip[base])) return NO;
+ if (cnter == 3) return NO;
+
+ ++cnter;
+ }
+ }
+
+ if (dot_cnter != 3) return NO;
+
+ return YES;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Network/IPCAddress.cc b/src/kernel/src/Network/IPCAddress.cc
new file mode 100644
index 00000000..2da5ac0a
--- /dev/null
+++ b/src/kernel/src/Network/IPCAddress.cc
@@ -0,0 +1,27 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ ======================================== */
+
+#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NetworkKit/IPC.h>
+
+namespace Kernel {
+bool IPC_ADDR::operator==(const IPC_ADDR& addr) noexcept {
+ return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam;
+}
+
+bool IPC_ADDR::operator==(IPC_ADDR& addr) noexcept {
+ return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam;
+}
+
+bool IPC_ADDR::operator!=(const IPC_ADDR& addr) noexcept {
+ return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam;
+}
+
+bool IPC_ADDR::operator!=(IPC_ADDR& addr) noexcept {
+ return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Network/IPCMessage.cc b/src/kernel/src/Network/IPCMessage.cc
new file mode 100644
index 00000000..b376b7c8
--- /dev/null
+++ b/src/kernel/src/Network/IPCMessage.cc
@@ -0,0 +1,129 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NetworkKit/IPC.h>
+
+namespace Kernel {
+/***********************************************************************************/
+/// @internal internal use for IPC system only.
+/// @brief The internal sanitize function.
+/***********************************************************************************/
+Bool ipc_int_sanitize_packet(IPC_MSG* pckt) {
+ auto endian = RTL_ENDIAN(pckt, ((Char*) pckt)[0]);
+
+ switch (endian) {
+ case Endian::kEndianBig: {
+ if (pckt->IpcEndianess == kIPCLittleEndian) goto ipc_check_failed;
+
+ break;
+ }
+ case Endian::kEndianLittle: {
+ if (pckt->IpcEndianess == kIPCBigEndian) goto ipc_check_failed;
+
+ break;
+ }
+ case Endian::kEndianMixed: {
+ if (pckt->IpcEndianess == kIPCMixedEndian) goto ipc_check_failed;
+
+ break;
+ }
+ default:
+ goto ipc_check_failed;
+ }
+
+ if (pckt->IpcFrom == pckt->IpcTo || pckt->IpcPacketSize > kIPCMsgSize) {
+ goto ipc_check_failed;
+ }
+
+ return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == kIPCHeaderMagic;
+
+ipc_check_failed:
+ err_local_get() = kErrorIPC;
+ return false;
+}
+
+/***********************************************************************************/
+/// @brief Sanitize packet function
+/// @retval true packet is correct.
+/// @retval false packet is incorrect and process has crashed.
+/***********************************************************************************/
+Bool ipc_sanitize_packet(IPC_MSG* pckt) {
+ if (!pckt || !ipc_int_sanitize_packet(pckt)) {
+ return false;
+ }
+
+ return true;
+}
+
+/***********************************************************************************/
+/// @brief Construct packet function
+/// @retval true packet is correct.
+/// @retval false packet is incorrect and process has crashed.
+/***********************************************************************************/
+Bool ipc_construct_packet(_Output IPC_MSG** pckt_in) {
+ // don't act if it's not even valid.
+ if (!pckt_in) return false;
+
+ if (!*pckt_in) *pckt_in = new IPC_MSG();
+
+ MUST_PASS(*pckt_in);
+
+ if (*pckt_in) {
+ const auto endianess = RTL_ENDIAN((*pckt_in), ((Char*) (*pckt_in))[0]);
+
+ (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic;
+
+ (*pckt_in)->IpcEndianess = static_cast<UInt8>(endianess);
+ (*pckt_in)->IpcPacketSize = sizeof(IPC_MSG);
+
+ (*pckt_in)->IpcTo.UserProcessID = 0;
+ (*pckt_in)->IpcTo.UserProcessTeam = 0;
+
+ (*pckt_in)->IpcFrom.UserProcessID = 0;
+ (*pckt_in)->IpcFrom.UserProcessTeam = 0;
+
+ (*pckt_in)->IpcLock = kIPCLockFree;
+
+ return Yes;
+ }
+
+ return No;
+}
+
+/***********************************************************************************/
+/// @brief Pass message from **src** to **target**
+/// @param src Source message.
+/// @param target Target message.
+/***********************************************************************************/
+Bool IPC_MSG::Pass(IPC_MSG* src, IPC_MSG* target) noexcept {
+ if (src && target && (target != src)) {
+ if (src->IpcMsgSz > target->IpcMsgSz) return No;
+ if (target->IpcMsgSz > src->IpcMsgSz) return No;
+
+ auto timeout = 0U;
+
+ const auto kLimitTimeout = 1000000U;
+
+ while ((target->IpcLock % kIPCLockUsed) != 0) {
+ if (timeout > kLimitTimeout) {
+ return No;
+ }
+ }
+
+ ++target->IpcLock;
+
+ rt_copy_memory_safe(src->IpcData, target->IpcData, src->IpcMsgSz, kIPCMsgSize);
+
+ --target->IpcLock;
+
+ return Yes;
+ }
+
+ return No;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Network/MACAddressGetter.cc b/src/kernel/src/Network/MACAddressGetter.cc
new file mode 100644
index 00000000..09d82a78
--- /dev/null
+++ b/src/kernel/src/Network/MACAddressGetter.cc
@@ -0,0 +1,13 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NetworkKit/MAC.h>
+
+namespace Kernel {
+Array<UInt8, kMACAddrLen>& MacAddressGetter::AsBytes() {
+ return this->fMacAddress;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Network/NetworkDevice.cc b/src/kernel/src/Network/NetworkDevice.cc
new file mode 100644
index 00000000..450c0191
--- /dev/null
+++ b/src/kernel/src/Network/NetworkDevice.cc
@@ -0,0 +1,29 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Utils.h>
+#include <NetworkKit/NetworkDevice.h>
+
+namespace Kernel {
+/// \brief Getter for fNetworkName.
+/// \return Network device name.
+const Char* NetworkDevice::Name() const {
+ return "/devices/net/net{}";
+}
+
+/// \brief Setter for fNetworkName.
+Boolean NetworkDevice::Name(const Char* name) {
+ if (name == nullptr) return NO;
+
+ if (*name == 0) return NO;
+
+ if (rt_string_len(name) > rt_string_len(this->Name())) return NO;
+
+ rt_copy_memory((VoidPtr) name, (VoidPtr) this->Name(), rt_string_len(this->Name()));
+
+ return YES;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/New+Delete.cc b/src/kernel/src/New+Delete.cc
new file mode 100644
index 00000000..ba37e7ec
--- /dev/null
+++ b/src/kernel/src/New+Delete.cc
@@ -0,0 +1,48 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/HeapMgr.h>
+#include <NeKit/New.h>
+
+void* operator new[](size_t sz) {
+ if (sz == 0) ++sz;
+
+ return Kernel::mm_alloc_ptr(sz, true, false);
+}
+
+void* operator new(size_t sz) {
+ if (sz == 0) ++sz;
+
+ return Kernel::mm_alloc_ptr(sz, true, false);
+}
+
+void operator delete[](void* ptr) noexcept {
+ if (ptr == nullptr) return;
+
+ Kernel::mm_free_ptr(ptr);
+}
+
+void operator delete(void* ptr) noexcept {
+ if (ptr == nullptr) return;
+
+ Kernel::mm_free_ptr(ptr);
+}
+
+void operator delete(void* ptr, size_t sz) {
+ if (ptr == nullptr) return;
+
+ NE_UNUSED(sz);
+
+ Kernel::mm_free_ptr(ptr);
+}
+
+void operator delete[](void* ptr, size_t sz) {
+ if (ptr == nullptr) return;
+
+ NE_UNUSED(sz);
+
+ Kernel::mm_free_ptr(ptr);
+}
diff --git a/src/kernel/src/OwnPtr.cc b/src/kernel/src/OwnPtr.cc
new file mode 100644
index 00000000..e223d448
--- /dev/null
+++ b/src/kernel/src/OwnPtr.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/OwnPtr.h>
diff --git a/src/kernel/src/PE32CodeMgr.cc b/src/kernel/src/PE32CodeMgr.cc
new file mode 100644
index 00000000..a8440c23
--- /dev/null
+++ b/src/kernel/src/PE32CodeMgr.cc
@@ -0,0 +1,258 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <CFKit/Utils.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/PE32CodeMgr.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/OwnPtr.h>
+
+namespace Kernel {
+namespace Detail {
+ /***********************************************************************************/
+ /// @brief Get the PE32+ platform signature according to the compiled architecture.
+ /***********************************************************************************/
+
+ UInt32 ldr_get_platform_pe(void) noexcept {
+#if defined(__NE_AMD64__)
+ return kPEPlatformAMD64;
+#elif defined(__NE_ARM64__)
+ return kPEPlatformARM64;
+#else
+ return kPEPlatformInvalid;
+#endif // __32x0__ || __64x0__ || __x86_64__
+ }
+} // namespace Detail
+
+/***********************************************************************************/
+/// @brief PE32+ loader constructor w/ blob.
+/// @param blob file blob.
+/***********************************************************************************/
+
+PE32Loader::PE32Loader(const VoidPtr blob) : fCachedBlob(blob) {
+ MUST_PASS(fCachedBlob);
+ fBad = false;
+}
+
+/***********************************************************************************/
+/// @brief PE32+ loader constructor.
+/// @param path the filesystem path.
+/***********************************************************************************/
+
+PE32Loader::PE32Loader(const Char* path) : fCachedBlob(nullptr), fBad(false) {
+ fFile.New(const_cast<Char*>(path), kRestrictRB);
+ fPath = KStringBuilder::Construct(path).Leak();
+
+ auto kPefHeader = "PE32_BLOB";
+ fCachedBlob = fFile->Read(kPefHeader, 0);
+
+ if (!fCachedBlob) fBad = YES;
+}
+
+/***********************************************************************************/
+/// @brief PE32+ destructor.
+/***********************************************************************************/
+
+PE32Loader::~PE32Loader() {
+ if (fCachedBlob) mm_free_ptr(fCachedBlob);
+
+ fFile.Delete();
+}
+
+/***********************************************************************************/
+/// @brief Finds the section according to its name.
+/// @param name name of section.
+/***********************************************************************************/
+
+ErrorOr<VoidPtr> PE32Loader::FindSectionByName(const Char* name) {
+ if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header((const Char*) fCachedBlob);
+ LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header((const Char*) fCachedBlob);
+
+ if (!header_ptr || !opt_header_ptr) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+#ifdef __NE_AMD64__
+ if (header_ptr->Machine != kPeMachineAMD64 || header_ptr->Signature != kPeSignature) {
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+
+#elif defined(__NE_ARM64__)
+ if (header_ptr->Machine != kPeMachineARM64 || header_ptr->Signature != kPeSignature) {
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+#endif // __NE_AMD64__ || __NE_ARM64__
+
+ if (header_ptr->NumberOfSections < 1) {
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+
+ LDR_SECTION_HEADER_PTR secs =
+ (LDR_SECTION_HEADER_PTR) (((Char*) opt_header_ptr) + header_ptr->SizeOfOptionalHeader);
+
+ for (SizeT sectIndex = 0; sectIndex < header_ptr->NumberOfSections; ++sectIndex) {
+ LDR_SECTION_HEADER_PTR sect = &secs[sectIndex];
+
+ if (KStringBuilder::Equals(name, sect->Name)) {
+ return ErrorOr<VoidPtr>(sect);
+ }
+ }
+
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+}
+
+/***********************************************************************************/
+/// @brief Finds the symbol according to it's name.
+/// @param name name of symbol.
+/// @param kind kind of symbol we want.
+/***********************************************************************************/
+
+ErrorOr<VoidPtr> PE32Loader::FindSymbol(const Char* name, Int32 kind) {
+ if (!name || *name == 0) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ auto section_name = "\0";
+
+ switch (kind) {
+ case kPETypeData:
+ section_name = ".data";
+ break;
+ case kPETypeBSS:
+ section_name = ".bss";
+ break;
+ case kPETypeText:
+ section_name = ".text";
+ break;
+ default:
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+
+ auto sec = this->FindSectionByName(section_name);
+ LDR_SECTION_HEADER_PTR* sec_ptr = (LDR_SECTION_HEADER_PTR*) sec.Leak().Leak();
+
+ if (!sec_ptr || !*sec_ptr) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header((const Char*) fCachedBlob);
+
+ if (opt_header_ptr) {
+ LDR_DATA_DIRECTORY_PTR data_dirs =
+ (LDR_DATA_DIRECTORY_PTR) ((UInt8*) opt_header_ptr + sizeof(LDR_OPTIONAL_HEADER));
+
+ LDR_DATA_DIRECTORY_PTR export_dir_entry = &data_dirs[0];
+
+ if (export_dir_entry->VirtualAddress == 0 || export_dir_entry->Size == 0)
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ LDR_EXPORT_DIRECTORY* export_dir =
+ (LDR_EXPORT_DIRECTORY*) ((UIntPtr) fCachedBlob + export_dir_entry->VirtualAddress);
+
+ UInt32* name_table = (UInt32*) ((UIntPtr) fCachedBlob + export_dir->AddressOfNames);
+ UInt16* ordinal_table = (UInt16*) ((UIntPtr) fCachedBlob + export_dir->AddressOfNameOrdinal);
+ UInt32* function_table = (UInt32*) ((UIntPtr) fCachedBlob + export_dir->AddressOfFunctions);
+
+ for (UInt32 i = 0; i < export_dir->NumberOfNames; ++i) {
+ const char* exported_name = (const char*) ((UIntPtr) fCachedBlob + name_table[i]);
+
+ if (KStringBuilder::Equals(exported_name, name)) {
+ UInt16 ordinal = ordinal_table[i];
+ UInt32 rva = function_table[ordinal];
+
+ VoidPtr symbol_addr = (VoidPtr) ((UIntPtr) fCachedBlob + rva);
+
+ return ErrorOr<VoidPtr>{symbol_addr};
+ }
+ }
+ }
+
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+}
+
+/// @brief Finds the executable entrypoint.
+/// @return
+ErrorOr<VoidPtr> PE32Loader::FindStart() {
+ if (auto sym = this->FindSymbol(kPeImageStart, 0); sym) return sym;
+
+ return ErrorOr<VoidPtr>(kErrorExecutable);
+}
+
+/// @brief Tells if the executable is loaded or not.
+/// @return Whether it's not bad and is cached.
+bool PE32Loader::IsLoaded() noexcept {
+ return !fBad && fCachedBlob;
+}
+
+const Char* PE32Loader::Path() {
+ return fPath.Leak().CData();
+}
+
+const Char* PE32Loader::AsString() {
+#ifdef __32x0__
+ return "32x0 PE";
+#elif defined(__64x0__)
+ return "64x0 PE";
+#elif defined(__x86_64__)
+ return "x86_64 PE";
+#elif defined(__aarch64__)
+ return "AARCH64 PE";
+#elif defined(__powerpc64__)
+ return "POWER64 PE";
+#else
+ return "???? PE";
+#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__
+}
+
+const Char* PE32Loader::MIME() {
+ return kPeApplicationMime;
+}
+
+ErrorOr<VoidPtr> PE32Loader::GetBlob() {
+ return ErrorOr<VoidPtr>{this->fCachedBlob};
+}
+
+namespace Utils {
+ ProcessID rtl_create_user_process(PE32Loader& exec, const Int32& process_kind) noexcept {
+ auto errOrStart = exec.FindStart();
+
+ if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID;
+
+ auto symname = exec.FindSymbol(kPeImageStart, 0);
+
+ if (!symname) {
+ symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS_PE32+")};
+ }
+
+ auto id =
+ UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()),
+ errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
+
+ mm_free_ptr(symname.Leak().Leak());
+
+ if (id != kSchedInvalidPID) {
+ auto stacksym = exec.FindSymbol(kPeStackSizeSymbol, 0);
+
+ if (!stacksym) {
+ stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)};
+ }
+
+ if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) {
+ *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz;
+ }
+
+ UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].Kind = process_kind;
+ UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].StackSize =
+ *(UIntPtr*) stacksym.Leak().Leak();
+
+ mm_free_ptr(stacksym.Leak().Leak());
+ stacksym.Leak().Leak() = nullptr;
+ }
+
+ return id;
+ }
+} // namespace Utils
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/src/PEFCodeMgr.cc b/src/kernel/src/PEFCodeMgr.cc
new file mode 100644
index 00000000..c0a79c32
--- /dev/null
+++ b/src/kernel/src/PEFCodeMgr.cc
@@ -0,0 +1,335 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ Copyright (C) 2025, Amlal El Mahrouss & NeKernel contributors, licensed under the Apache 2.0
+license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/OwnPtr.h>
+#include <NeKit/Utils.h>
+
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+/// @brief PEF backend for the Code Manager.
+/// @file PEFCodeMgr.cc
+
+/// @brief PEF stack size symbol.
+#define kPefStackSizeSymbol "__PEFSizeOfReserveStack"
+#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap"
+#define kPefNameSymbol "__PEFProgramName"
+
+namespace Kernel {
+namespace Detail {
+ /***********************************************************************************/
+ /// @brief Get the PEF platform signature according to the compiled architecture.
+ /***********************************************************************************/
+ static UInt32 ldr_get_platform(void) noexcept {
+#if defined(__NE_32X0__)
+ return kPefArch32x0;
+#elif defined(__NE_64X0__)
+ return kPefArch64x0;
+#elif defined(__NE_AMD64__)
+ return kPefArchAMD64;
+#elif defined(__NE_PPC64__)
+ return kPefArchPowerPC;
+#elif defined(__NE_ARM64__)
+ return kPefArchARM64;
+#else
+ return kPefArchInvalid;
+#endif // __32x0__ || __64x0__ || __x86_64__
+ }
+} // namespace Detail
+
+/***********************************************************************************/
+/// @brief PEF loader constructor w/ blob.
+/// @param blob file blob.
+/***********************************************************************************/
+PEFLoader::PEFLoader(const VoidPtr blob) : fCachedBlob(blob) {
+ MUST_PASS(fCachedBlob);
+
+ if (!fCachedBlob) {
+ this->fBad = YES;
+ return;
+ }
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ if (container->Abi == kPefAbi &&
+ container->Count >=
+ 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */
+ if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] &&
+ container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] &&
+ container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4]) {
+ return;
+ } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] &&
+ container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] &&
+ container->Magic[4] == kPefMagicFat[4]) {
+ /// This is a fat binary. Treat it as such.
+ this->fFatBinary = YES;
+ return;
+ }
+ }
+
+ kout << "PEFLoader: warning: Binary format error!\r";
+
+ this->fFatBinary = NO;
+ this->fBad = YES;
+
+ if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob);
+ this->fCachedBlob = nullptr;
+}
+
+/***********************************************************************************/
+/// @brief PEF loader constructor.
+/// @param path the filesystem path.
+/***********************************************************************************/
+PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false), fBad(false) {
+ fFile.New(const_cast<Char*>(path), kRestrictRB);
+ fPath = KStringBuilder::Construct(path).Leak();
+
+ constexpr auto kPefHeader = "PEF_CONTAINER";
+
+ /// @note zero here means that the FileMgr will read every container header inside the file.
+ fCachedBlob = fFile->Read(kPefHeader, 0UL);
+
+ if (!fCachedBlob) {
+ this->fBad = YES;
+ return;
+ }
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ if (container->Abi == kPefAbi &&
+ container->Count >=
+ 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */
+ if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] &&
+ container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] &&
+ container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4]) {
+ return;
+ } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] &&
+ container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] &&
+ container->Magic[4] == kPefMagicFat[4]) {
+ /// This is a fat binary, treat it as such.
+ this->fFatBinary = YES;
+ return;
+ }
+ }
+
+ kout << "PEFLoader: warning: Binary format error!\r";
+
+ this->fFatBinary = NO;
+ this->fBad = YES;
+
+ if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob);
+ this->fCachedBlob = nullptr;
+}
+
+/***********************************************************************************/
+/// @brief PEF destructor.
+/***********************************************************************************/
+PEFLoader::~PEFLoader() {
+ if (fCachedBlob) mm_free_ptr(fCachedBlob);
+
+ fFile.Delete();
+}
+
+/***********************************************************************************/
+/// @brief Finds the symbol according to it's name.
+/// @param name name of symbol.
+/// @param kind kind of symbol we want.
+/***********************************************************************************/
+ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) {
+ if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ auto blob = fFile->Read(name, sizeof(PEFCommandHeader));
+
+ if (!blob) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ if (!container) return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ PEFCommandHeader* command_header = reinterpret_cast<PEFCommandHeader*>(blob);
+
+ if (command_header->VMSize < 1 || command_header->VMAddress == 0)
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ /// fat binary check.
+ if (command_header->Cpu != container->Cpu && !this->fFatBinary)
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+
+ const auto kMangleCharacter = '$';
+ const Char* kContainerKinds[] = {".code64", ".data64", ".zero64", nullptr};
+
+ ErrorOr<KString> error_or_symbol;
+
+ switch (kind) {
+ case kPefCode: {
+ error_or_symbol = KStringBuilder::Construct(kContainerKinds[0]); // code symbol.
+ break;
+ }
+ case kPefData: {
+ error_or_symbol = KStringBuilder::Construct(kContainerKinds[1]); // data symbol.
+ break;
+ }
+ case kPefZero: {
+ error_or_symbol = KStringBuilder::Construct(kContainerKinds[2]); // block starting symbol.
+ break;
+ }
+ default:
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ // prevent that from the kernel's mode perspective, let that happen if it
+ // were a user process.
+ }
+
+ Char* unconst_symbol = const_cast<Char*>(name);
+
+ for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) {
+ if (rt_is_space(unconst_symbol[i])) {
+ unconst_symbol[i] = kMangleCharacter;
+ }
+ }
+
+ error_or_symbol.Leak().Leak() += name;
+
+ if (KStringBuilder::Equals(command_header->Name, error_or_symbol.Leak().Leak().CData())) {
+ if (command_header->Kind == kind) {
+ if (command_header->Cpu != Detail::ldr_get_platform()) {
+ if (!this->fFatBinary) {
+ mm_free_ptr(blob);
+ blob = nullptr;
+
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+ }
+
+ Char* container_blob_value = new Char[command_header->VMSize];
+
+ rt_copy_memory_safe((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value,
+ command_header->VMSize, command_header->VMSize);
+
+ mm_free_ptr(blob);
+
+ kout << "PEFLoader: info: Load stub: " << command_header->Name << "!\r";
+
+ Int32 ret = 0;
+ SizeT pages_count = (command_header->VMSize + kPageSize - 1) / kPageSize;
+
+ for (SizeT i_vm{}; i_vm < pages_count; ++i_vm) {
+ ret = HAL::mm_map_page(
+ (VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)),
+ (VoidPtr) (HAL::mm_get_page_addr(container_blob_value) + (i_vm * kPageSize)),
+ HAL::kMMFlagsPresent | HAL::kMMFlagsUser);
+
+ if (ret != kErrorSuccess) {
+ /// We set the VMAddress to nullptr, if the mapping fail here.
+ for (SizeT i_vm_unmap{}; i_vm_unmap < i_vm; ++i_vm_unmap) {
+ ret = HAL::mm_map_page((VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)),
+ nullptr, HAL::kMMFlagsPresent | HAL::kMMFlagsUser);
+ }
+
+ delete[] container_blob_value;
+ container_blob_value = nullptr;
+
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+ }
+ }
+
+ return ErrorOr<VoidPtr>{container_blob_value};
+ }
+ }
+
+ mm_free_ptr(blob);
+ return ErrorOr<VoidPtr>{kErrorInvalidData};
+}
+
+/// @brief Finds the executable entrypoint.
+/// @return
+ErrorOr<VoidPtr> PEFLoader::FindStart() {
+ if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return sym;
+
+ return ErrorOr<VoidPtr>(kErrorExecutable);
+}
+
+/// @brief Tells if the executable is loaded or not.
+/// @return Whether it's not bad and is cached.
+bool PEFLoader::IsLoaded() noexcept {
+ return !fBad && fCachedBlob;
+}
+
+const Char* PEFLoader::Path() {
+ return fPath.Leak().CData();
+}
+
+const Char* PEFLoader::AsString() {
+#ifdef __32x0__
+ return "32x0 PEF";
+#elif defined(__64x0__)
+ return "64x0 PEF";
+#elif defined(__x86_64__)
+ return "x86_64 PEF";
+#elif defined(__aarch64__)
+ return "AARCH64 PEF";
+#elif defined(__powerpc64__)
+ return "POWER64 PEF";
+#else
+ return "???? PEF";
+#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__
+}
+
+const Char* PEFLoader::MIME() {
+ return kPefApplicationMime;
+}
+
+ErrorOr<VoidPtr> PEFLoader::GetBlob() {
+ return ErrorOr<VoidPtr>{this->fCachedBlob};
+}
+
+namespace Utils {
+ ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& process_kind) noexcept {
+ auto errOrStart = exec.FindStart();
+
+ if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID;
+
+ auto symname = exec.FindSymbol(kPefNameSymbol, kPefData);
+
+ if (!symname) {
+ symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS_PEF")};
+ }
+
+ ProcessID id =
+ UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()),
+ errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
+
+ mm_free_ptr(symname.Leak().Leak());
+
+ if (id != kSchedInvalidPID) {
+ auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData);
+
+ if (!stacksym) {
+ stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)};
+ }
+
+ if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) {
+ *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz;
+ }
+
+ UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].Kind = process_kind;
+ UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].StackSize =
+ *(UIntPtr*) stacksym.Leak().Leak();
+
+ mm_free_ptr(stacksym.Leak().Leak());
+ }
+
+ return id;
+ }
+} // namespace Utils
+} // namespace Kernel
diff --git a/src/kernel/src/PRDT.cc b/src/kernel/src/PRDT.cc
new file mode 100644
index 00000000..626a7e16
--- /dev/null
+++ b/src/kernel/src/PRDT.cc
@@ -0,0 +1,22 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/KString.h>
+#include <StorageKit/PRDT.h>
+
+namespace Kernel {
+/***********************************************************************************/
+/// @brief constructs a new PRD.
+/// @param prd PRD reference.
+/// @note This doesnt construct a valid, please fill it by yourself.
+/***********************************************************************************/
+void construct_prdt(Ref<PRDT>& prd) {
+ prd.Leak().fPhysAddress = 0x0;
+ prd.Leak().fSectorCount = 0x0;
+ prd.Leak().fEndBit = 0x0;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/PageMgr.cc b/src/kernel/src/PageMgr.cc
new file mode 100644
index 00000000..81833ee2
--- /dev/null
+++ b/src/kernel/src/PageMgr.cc
@@ -0,0 +1,95 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/PageMgr.h>
+
+#ifdef __NE_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#elif defined(__NE_ARM64__)
+#include <HALKit/ARM64/Paging.h>
+#endif // ifdef __NE_AMD64__ || defined(__NE_ARM64__)
+
+namespace Kernel {
+PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr)
+ : fRw(Rw),
+ fUser(User),
+ fExecDisable(ExecDisable),
+ fVirtAddr(VirtAddr),
+ fCache(false),
+ fShareable(false),
+ fWt(false),
+ fPresent(true),
+ fAccessed(false) {}
+
+PTEWrapper::~PTEWrapper() = default;
+
+/// @brief Flush virtual address.
+/// @param VirtAddr
+Void PageMgr::FlushTLB() {
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ hal_flush_tlb();
+#endif // !__NE_VIRTUAL_MEMORY_SUPPORT__
+}
+
+/// @brief Reclaim freed page.
+/// @return
+Bool PTEWrapper::Reclaim() {
+ if (!this->fPresent) {
+ this->fPresent = true;
+ return true;
+ }
+
+ return false;
+}
+
+/// @brief Request a PTE.
+/// @param Rw Is it read write? or is it read only?
+/// @param User user mode?
+/// @param ExecDisable disable execution on page?
+/// @return
+PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad) {
+ // Store PTE wrapper right after PTE.
+ VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, NO, Pad);
+
+ return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast<UIntPtr>(ptr)};
+}
+
+/// @brief Disable BitMap.
+/// @param wrapper the wrapper.
+/// @return If the page bitmap was cleared or not.
+Bool PageMgr::Free(Ref<PTEWrapper>& wrapper) {
+ if (!Kernel::HAL::mm_free_bitmap((VoidPtr) wrapper.Leak().VirtualAddress())) return false;
+
+ return true;
+}
+
+/// @brief Virtual PTE address.
+/// @return The virtual address of the page.
+UIntPtr PTEWrapper::VirtualAddress() {
+ return (fVirtAddr);
+}
+
+Bool PTEWrapper::Shareable() {
+ return fShareable;
+}
+
+Bool PTEWrapper::Present() {
+ return fPresent;
+}
+
+Bool PTEWrapper::Access() {
+ return fAccessed;
+}
+
+Void PTEWrapper::NoExecute(const bool enable) {
+ fExecDisable = enable;
+}
+
+Bool PTEWrapper::NoExecute() {
+ return fExecDisable;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Pmm.cc b/src/kernel/src/Pmm.cc
new file mode 100644
index 00000000..84086929
--- /dev/null
+++ b/src/kernel/src/Pmm.cc
@@ -0,0 +1,83 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/Pmm.h>
+
+#if defined(__NE_ARM64__)
+#include <HALKit/ARM64/Processor.h>
+#endif // defined(__NE_ARM64__)
+
+#if defined(__NE_AMD64__)
+#include <HALKit/AMD64/Processor.h>
+#endif // defined(__NE_AMD64__)
+
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Pmm constructor.
+/***********************************************************************************/
+Pmm::Pmm() : fPageMgr() {
+ kout << "[PMM] Allocate PageMemoryMgr.\r";
+}
+
+Pmm::~Pmm() = default;
+
+/***********************************************************************************/
+/// @param If this returns Null pointer, enter emergency mode.
+/// @param user is this a user page?
+/// @param readWrite is it r/w?
+/***********************************************************************************/
+Ref<PTEWrapper> Pmm::RequestPage(Boolean user, Boolean readWrite) {
+ PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize, 0);
+
+ if (pt.fPresent) {
+ kout << "[PMM]: Allocation failed.\r";
+ return {pt};
+ }
+
+ return Ref<PTEWrapper>(pt);
+}
+
+Boolean Pmm::FreePage(Ref<PTEWrapper> PageRef) {
+ if (!PageRef) return false;
+
+ PageRef.Leak().fPresent = false;
+
+ return true;
+}
+
+Boolean Pmm::TogglePresent(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
+
+ PageRef.Leak().fPresent = Enable;
+
+ return true;
+}
+
+Boolean Pmm::ToggleUser(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
+
+ PageRef.Leak().fRw = Enable;
+
+ return true;
+}
+
+Boolean Pmm::ToggleRw(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
+
+ PageRef.Leak().fRw = Enable;
+
+ return true;
+}
+
+Boolean Pmm::ToggleShare(Ref<PTEWrapper> PageRef, Boolean Enable) {
+ if (!PageRef) return false;
+
+ PageRef.Leak().fShareable = Enable;
+
+ return true;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Property.cc b/src/kernel/src/Property.cc
new file mode 100644
index 00000000..8b7454fe
--- /dev/null
+++ b/src/kernel/src/Property.cc
@@ -0,0 +1,41 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <CFKit/Property.h>
+
+namespace Kernel::CF {
+/***********************************************************************************/
+/// @brief Destructor.
+/***********************************************************************************/
+Property::~Property() = default;
+
+/***********************************************************************************/
+/// @brief Constructor.
+/***********************************************************************************/
+Property::Property() = default;
+
+/***********************************************************************************/
+/// @brief Check if property's name equals to name.
+/// @param name string to check.
+/***********************************************************************************/
+Bool Property::StringEquals(KBasicString<>& name) {
+ return this->fName && this->fName == name;
+}
+
+/***********************************************************************************/
+/// @brief Gets the key (name) of property.
+/***********************************************************************************/
+KBasicString<>& Property::GetKey() {
+ return this->fName;
+}
+
+/***********************************************************************************/
+/// @brief Gets the value of the property.
+/***********************************************************************************/
+PropertyId& Property::GetValue() {
+ return fValue;
+}
+} // namespace Kernel::CF
diff --git a/src/kernel/src/Ref.cc b/src/kernel/src/Ref.cc
new file mode 100644
index 00000000..90b1c22d
--- /dev/null
+++ b/src/kernel/src/Ref.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Ref.h>
diff --git a/src/kernel/src/Semaphore.cc b/src/kernel/src/Semaphore.cc
new file mode 100644
index 00000000..484c89ca
--- /dev/null
+++ b/src/kernel/src/Semaphore.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/Semaphore.h> \ No newline at end of file
diff --git a/src/kernel/src/SoftwareTimer.cc b/src/kernel/src/SoftwareTimer.cc
new file mode 100644
index 00000000..eafe8db6
--- /dev/null
+++ b/src/kernel/src/SoftwareTimer.cc
@@ -0,0 +1,36 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/Timer.h>
+
+/// ================================================================================
+/// @brief SoftwareTimer class, meant to be generic.
+///! @author Amlal El Mahrouss (amlal@nekernel.org)
+/// ================================================================================
+
+using namespace Kernel;
+
+SoftwareTimer::SoftwareTimer(Int64 seconds) : fWaitFor(seconds) {
+ fDigitalTimer = new UIntPtr();
+ MUST_PASS(fDigitalTimer);
+}
+
+SoftwareTimer::~SoftwareTimer() {
+ delete fDigitalTimer;
+ fDigitalTimer = nullptr;
+
+ fWaitFor = 0;
+}
+
+BOOL SoftwareTimer::Wait() noexcept {
+ if (fWaitFor < 1) return NO;
+
+ while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) {
+ ++(*fDigitalTimer);
+ }
+
+ return YES;
+}
diff --git a/src/kernel/src/Storage/AHCIDeviceInterface.cc b/src/kernel/src/Storage/AHCIDeviceInterface.cc
new file mode 100644
index 00000000..02b39fb5
--- /dev/null
+++ b/src/kernel/src/Storage/AHCIDeviceInterface.cc
@@ -0,0 +1,87 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <StorageKit/AHCI.h>
+
+using namespace Kernel;
+
+/// @brief Class constructor
+/// @param Out Drive output
+/// @param In Drive input
+/// @param Cleanup Drive cleanup.
+AHCIDeviceInterface::AHCIDeviceInterface(void (*out)(DeviceInterface* self, IMountpoint* outpacket),
+ void (*in)(DeviceInterface* self, IMountpoint* inpacket))
+ : DeviceInterface(out, in) {}
+
+/// @brief Class desctructor
+AHCIDeviceInterface::~AHCIDeviceInterface() = default;
+
+/// @brief Returns the name of the device interface.
+/// @return it's name as a string.
+const Char* AHCIDeviceInterface::Name() const {
+ return "/devices/sda{}";
+}
+
+/// @brief Output operator.
+/// @param mnt the disk mountpoint.
+/// @return the class itself after operation.
+AHCIDeviceInterface& AHCIDeviceInterface::operator<<(IMountpoint* mnt) {
+ if (!mnt) return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
+ auto interface = mnt->GetAddressOf(driveCount);
+
+ if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) == 0) {
+ continue;
+ } else if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) != 0) {
+ return *this;
+ }
+ }
+
+ return (AHCIDeviceInterface&) DeviceInterface<IMountpoint*>::operator<<(mnt);
+}
+
+/// @brief Input operator.
+/// @param mnt the disk mountpoint.
+/// @return the class itself after operation.
+AHCIDeviceInterface& AHCIDeviceInterface::operator>>(IMountpoint* mnt) {
+ if (!mnt) return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
+ auto interface = mnt->GetAddressOf(driveCount);
+
+ // really check if it's ATA.
+ if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) == 0) {
+ continue;
+ } else if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) != 0) {
+ return *this;
+ }
+ }
+
+ return (AHCIDeviceInterface&) DeviceInterface<IMountpoint*>::operator>>(mnt);
+}
+
+const UInt16& AHCIDeviceInterface::GetPortsImplemented() {
+ return this->fPortsImplemented;
+}
+
+Void AHCIDeviceInterface::SetPortsImplemented(const UInt16& pi) {
+ MUST_PASS(pi > 0);
+ this->fPortsImplemented = pi;
+}
+
+const UInt32& AHCIDeviceInterface::GetIndex() {
+ return this->fDriveIndex;
+}
+
+Void AHCIDeviceInterface::SetIndex(const UInt32& drv) {
+ MUST_PASS(IMountpoint::kDriveIndexInvalid < drv);
+ this->fDriveIndex = drv;
+} \ No newline at end of file
diff --git a/src/kernel/src/Storage/ATADeviceInterface.cc b/src/kernel/src/Storage/ATADeviceInterface.cc
new file mode 100644
index 00000000..8e15fdea
--- /dev/null
+++ b/src/kernel/src/Storage/ATADeviceInterface.cc
@@ -0,0 +1,96 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <StorageKit/ATA.h>
+
+using namespace Kernel;
+
+/// @brief Class constructor
+/// @param Out Drive output
+/// @param In Drive input
+/// @param Cleanup Drive cleanup.
+ATADeviceInterface::ATADeviceInterface(void (*Out)(DeviceInterface*, IMountpoint* outpacket),
+ void (*In)(DeviceInterface*, IMountpoint* inpacket))
+ : DeviceInterface(Out, In) {}
+
+/// @brief Class desctructor
+ATADeviceInterface::~ATADeviceInterface() = default;
+
+/// @brief Returns the name of the device interface.
+/// @return it's name as a string.
+const Char* ATADeviceInterface::Name() const {
+ return "/devices/hda{}";
+}
+
+/// @brief Output operator.
+/// @param Data the disk mountpoint.
+/// @return the class itself after operation.
+ATADeviceInterface& ATADeviceInterface::operator<<(IMountpoint* Data) {
+ if (!Data) return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
+ auto interface = Data->GetAddressOf(driveCount);
+
+ if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) == 0) {
+ continue;
+ } else if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) != 0) {
+ return *this;
+ }
+ }
+
+ return (ATADeviceInterface&) DeviceInterface<IMountpoint*>::operator<<(Data);
+}
+
+/// @brief Input operator.
+/// @param Data the disk mountpoint.
+/// @return the class itself after operation.
+ATADeviceInterface& ATADeviceInterface::operator>>(IMountpoint* Data) {
+ if (!Data) return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) {
+ auto interface = Data->GetAddressOf(driveCount);
+
+ // really check if it's ATA.
+ if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) == 0) {
+ continue;
+ } else if ((interface) &&
+ rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) != 0) {
+ return *this;
+ }
+ }
+
+ return (ATADeviceInterface&) DeviceInterface<IMountpoint*>::operator>>(Data);
+}
+
+const UInt32& ATADeviceInterface::GetIndex() {
+ return this->fDriveIndex;
+}
+
+Void ATADeviceInterface::SetIndex(const UInt32& drv) {
+ MUST_PASS(IMountpoint::kDriveIndexInvalid < drv);
+ this->fDriveIndex = drv;
+}
+
+const UInt16& ATADeviceInterface::GetIO() {
+ return this->fIO;
+}
+
+Void ATADeviceInterface::SetIO(const UInt16& drv) {
+ MUST_PASS(0xFFFF != drv);
+ this->fIO = drv;
+}
+
+const UInt16& ATADeviceInterface::GetMaster() {
+ return this->fIO;
+}
+
+Void ATADeviceInterface::SetMaster(const UInt16& drv) {
+ MUST_PASS(0xFFFF != drv);
+ this->fMaster = drv;
+} \ No newline at end of file
diff --git a/src/kernel/src/Storage/NVMEDeviceInterface.cc b/src/kernel/src/Storage/NVMEDeviceInterface.cc
new file mode 100644
index 00000000..f05d384e
--- /dev/null
+++ b/src/kernel/src/Storage/NVMEDeviceInterface.cc
@@ -0,0 +1,22 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <StorageKit/NVME.h>
+
+namespace Kernel {
+NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(DeviceInterface*, IMountpoint* outpacket),
+ void (*in)(DeviceInterface*, IMountpoint* inpacket),
+ void (*cleanup)(void))
+ : DeviceInterface(out, in), fCleanup(cleanup) {}
+
+NVMEDeviceInterface::~NVMEDeviceInterface() {
+ if (fCleanup) fCleanup();
+}
+
+const Char* NVMEDeviceInterface::Name() const {
+ return ("/devices/nvme{}");
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Storage/SCSIDeviceInterface.cc b/src/kernel/src/Storage/SCSIDeviceInterface.cc
new file mode 100644
index 00000000..2e331ae9
--- /dev/null
+++ b/src/kernel/src/Storage/SCSIDeviceInterface.cc
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <StorageKit/SCSI.h>
+
+using namespace Kernel;
diff --git a/src/kernel/src/Stream.cc b/src/kernel/src/Stream.cc
new file mode 100644
index 00000000..8572e222
--- /dev/null
+++ b/src/kernel/src/Stream.cc
@@ -0,0 +1,12 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: Stream.cc
+ Purpose: Stream object
+
+ Revision History:
+
+======================================== */
+
+#include <NeKit/Stream.h>
diff --git a/src/kernel/src/Swap/DiskSwap.cc b/src/kernel/src/Swap/DiskSwap.cc
new file mode 100644
index 00000000..f0fa5915
--- /dev/null
+++ b/src/kernel/src/Swap/DiskSwap.cc
@@ -0,0 +1,64 @@
+/* ========================================
+
+ Copyright (C) 2024-2025 Amlal El Mahrouss , licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/FileMgr.h>
+#include <SwapKit/DiskSwap.h>
+
+namespace Kernel {
+static constexpr UInt32 kSwapDiskHeaderMagic = 0x44535750; // 'DSWP'
+
+/***********************************************************************************/
+/// @brief Write memory chunk onto disk.
+/// @param fork_name The swap name to recognize this memory region.
+/// @param fork_name_len length of fork name.
+/// @param data the data packet.
+/// @return Whether the swap was written to disk, or not.
+/***********************************************************************************/
+BOOL DiskSwapInterface::Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data) {
+ if (!fork_name || !fork_name_len) return NO;
+
+ if (*fork_name == 0) return NO;
+
+ if (!data || data->fMagic != kSwapDiskHeaderMagic) return NO;
+
+ FileStream file(kSwapPageFilePath, kRestrictWRB);
+
+ ErrorOr<Int64> ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz);
+
+ if (ret.Error()) return NO;
+
+ return YES;
+}
+
+/***********************************************************************************/
+/// @brief Read memory chunk from disk.
+/// @param fork_name The swap name to recognize this memory region.
+/// @param fork_name_len length of fork name.
+/// @param data the data packet length.
+/// @return Whether the swap was fetched to disk, or not.
+/***********************************************************************************/
+SWAP_DISK_HEADER* DiskSwapInterface::Read(const Char* fork_name, SizeT fork_name_len,
+ SizeT data_len) {
+ if (!fork_name || !fork_name_len) return nullptr;
+
+ if (*fork_name == 0) return nullptr;
+
+ if (data_len > kSwapBlockMaxSize) return nullptr;
+
+ if (data_len == 0) return nullptr;
+
+ FileStream file(kSwapPageFilePath, kRestrictRB);
+
+ VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len);
+
+ if (!blob || ((SWAP_DISK_HEADER*) blob)->fMagic != kSwapDiskHeaderMagic) {
+ if (blob) mm_free_ptr(blob);
+ return nullptr;
+ }
+
+ return reinterpret_cast<SWAP_DISK_HEADER*>(blob);
+}
+} // namespace Kernel
diff --git a/src/kernel/src/ThreadLocalStorage.cc b/src/kernel/src/ThreadLocalStorage.cc
new file mode 100644
index 00000000..fa445d84
--- /dev/null
+++ b/src/kernel/src/ThreadLocalStorage.cc
@@ -0,0 +1,52 @@
+/*
+ * ========================================================
+ *
+ * NeKernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * ========================================================
+ */
+
+#include <CFKit/Property.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/ThreadLocalStorage.h>
+#include <NeKit/KString.h>
+
+/***********************************************************************************/
+/// @bugs: 0
+/// @file ThreadLocalStorage.cc
+/// @brief NeKernel Thread Local Storage.
+///! @author Amlal El Mahrouss (amlal@nekernel.org)
+/***********************************************************************************/
+
+using namespace Kernel;
+
+/**
+ * @brief Checks for cookie inside the TIB.
+ * @param tib_ptr the TIB to check.
+ * @return if the cookie is enabled, true; false otherwise
+ */
+
+Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) {
+ if (!tib_ptr) return false;
+
+ return tib_ptr->Cookie[kCookieMag0Idx] == kCookieMag0 &&
+ tib_ptr->Cookie[kCookieMag1Idx] == kCookieMag1 &&
+ tib_ptr->Cookie[kCookieMag2Idx] == kCookieMag2;
+}
+
+/**
+ * @brief System call implementation of the TLS check.
+ * @param tib_ptr The TIB record.
+ * @return if the TIB record is valid or not.
+ */
+EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept {
+ if (!tib_ptr) {
+ kout << "TLS: Failed because of an invalid TIB...\r";
+ return No;
+ }
+
+ THREAD_INFORMATION_BLOCK* tib = reinterpret_cast<THREAD_INFORMATION_BLOCK*>(tib_ptr);
+
+ return tls_check_tib(tib);
+}
diff --git a/src/kernel/src/Timer.cc b/src/kernel/src/Timer.cc
new file mode 100644
index 00000000..648cc92b
--- /dev/null
+++ b/src/kernel/src/Timer.cc
@@ -0,0 +1,19 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/Timer.h>
+
+///! BUGS: 0
+///! @file Timer.cc
+///! @brief Software Timer implementation
+///! @author Amlal El Mahrouss (amlal@nekernel.org)
+
+using namespace Kernel;
+
+/// @brief Unimplemented as it is an interface.
+BOOL TimerInterface::Wait() noexcept {
+ return NO;
+}
diff --git a/src/kernel/src/UserMgr.cc b/src/kernel/src/UserMgr.cc
new file mode 100644
index 00000000..103e8ec9
--- /dev/null
+++ b/src/kernel/src/UserMgr.cc
@@ -0,0 +1,131 @@
+/*
+ * ========================================================
+ *
+ * NeKernel
+ * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+ *
+ * File: UserMgr.cc
+ * Purpose: User Manager, used to provide authentication and security.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/ThreadLocalStorage.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+
+#define kStdUserType (0xEE)
+#define kSuperUserType (0xEF)
+
+/// @file UserMgr.cc
+/// @brief Multi-user support.
+
+namespace Kernel {
+namespace Detail {
+ ////////////////////////////////////////////////////////////
+ /// \brief Constructs a password by hashing the password.
+ /// \param password password to hash.
+ /// \return the hashed password
+ ////////////////////////////////////////////////////////////
+ STATIC UInt64 user_fnv_generator(const Char* password, User* user) {
+ if (!password || !user) return 0;
+ if (*password == 0) return 0;
+
+ kout << "user_fnv_generator: Hashing user password...\r";
+
+ const UInt64 kFnvOffsetBasis = 0xcbf29ce484222325ULL;
+ const UInt64 fFnvPrime = 0x100000001b3ULL;
+
+ UInt64 hash = kFnvOffsetBasis;
+
+ while (*password) {
+ hash ^= (Char) (*password++);
+ hash *= fFnvPrime;
+ }
+
+ kout << "user_fnv_generator: Hashed user password.\r";
+
+ return hash;
+ }
+} // namespace Detail
+
+////////////////////////////////////////////////////////////
+/// @brief User ring constructor.
+////////////////////////////////////////////////////////////
+User::User(const Int32& sel, const Char* user_name) : mUserRing((UserRingKind) sel) {
+ MUST_PASS(sel >= 0);
+ rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name),
+ kMaxUserNameLen);
+}
+
+////////////////////////////////////////////////////////////
+/// @brief User ring constructor.
+////////////////////////////////////////////////////////////
+User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) {
+ rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name),
+ kMaxUserNameLen);
+}
+
+////////////////////////////////////////////////////////////
+/// @brief User destructor class.
+////////////////////////////////////////////////////////////
+User::~User() = default;
+
+Bool User::Save(const UserPublicKey password) noexcept {
+ if (!password || *password == 0) return No;
+
+ this->mUserFNV = Detail::user_fnv_generator(password, this);
+
+ kout << "User::Save: Saved password successfully...\r";
+
+ return Yes;
+}
+
+Bool User::Login(const UserPublicKey password) noexcept {
+ if (!password || !*password) return No;
+
+ auto ret = this->mUserFNV == Detail::user_fnv_generator(password, this);
+
+ // now check if the password matches.
+ kout << (ret ? "User::Login: Password matches.\r" : "User::Login: Password doesn't match.\r");
+ return ret;
+}
+
+Bool User::operator==(const User& lhs) {
+ return lhs.mUserRing == this->mUserRing;
+}
+
+Bool User::operator!=(const User& lhs) {
+ return lhs.mUserRing != this->mUserRing;
+}
+
+////////////////////////////////////////////////////////////
+/// @brief Returns the user's name.
+////////////////////////////////////////////////////////////
+
+Char* User::Name() noexcept {
+ return this->mUserName;
+}
+
+////////////////////////////////////////////////////////////
+/// @brief Returns the user's ring.
+/// @return The king of ring the user is attached to.
+////////////////////////////////////////////////////////////
+
+const UserRingKind& User::Ring() noexcept {
+ return this->mUserRing;
+}
+
+Bool User::IsStdUser() noexcept {
+ return this->Ring() == UserRingKind::kRingStdUser;
+}
+
+Bool User::IsSuperUser() noexcept {
+ return this->Ring() == UserRingKind::kRingSuperUser;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/UserProcessScheduler.cc b/src/kernel/src/UserProcessScheduler.cc
new file mode 100644
index 00000000..264bddf3
--- /dev/null
+++ b/src/kernel/src/UserProcessScheduler.cc
@@ -0,0 +1,690 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ FILE: UserProcessScheduler.cc
+ PURPOSE: Low-Privilege/Ring-3 process scheduler.
+
+======================================== */
+
+/***********************************************************************************/
+/// @file UserProcessScheduler.cc
+/// @brief Unprivileged/Ring-3 process scheduler.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+/***********************************************************************************/
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/KString.h>
+#include <NeKit/Utils.h>
+#include <SignalKit/Signals.h>
+
+///! BUGS: 0
+
+namespace Kernel {
+USER_PROCESS::USER_PROCESS() = default;
+USER_PROCESS::~USER_PROCESS() = default;
+
+/// @brief Gets the last exit code.
+/// @note Not thread-safe.
+/// @return Int32 the last exit code.
+
+/***********************************************************************************/
+/// @brief Crashes the current process.
+/***********************************************************************************/
+
+Void USER_PROCESS::Crash() {
+ if (this->Status != ProcessStatusKind::kRunning) return;
+
+ this->Status = ProcessStatusKind::kKilled;
+
+ (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl);
+}
+
+/***********************************************************************************/
+/// @brief boolean operator, check status.
+/***********************************************************************************/
+
+USER_PROCESS::operator bool() {
+ return this->Status == ProcessStatusKind::kRunning;
+}
+
+/***********************************************************************************/
+/// @brief Gets the local last exit code.
+/// @note Not thread-safe.
+/// @return Int32 the last exit code.
+/***********************************************************************************/
+
+KPCError& USER_PROCESS::GetExitCode() noexcept {
+ return this->LastExitCode;
+}
+
+/***********************************************************************************/
+/// @brief Error code variable getter.
+/***********************************************************************************/
+
+KPCError& USER_PROCESS::GetLocalCode() noexcept {
+ return this->LocalCode;
+}
+
+/***********************************************************************************/
+/// @brief Wakes process header.
+/// @param should_wakeup if the program shall wakeup or not.
+/***********************************************************************************/
+
+Void USER_PROCESS::Wake(Bool should_wakeup) {
+ this->Status = should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen;
+}
+
+/***********************************************************************************/
+/** @brief Allocate pointer to heap tree. */
+/** @param tree The tree to calibrate */
+/***********************************************************************************/
+
+template <typename T>
+STATIC T* sched_try_go_upper_ptr_tree(T* tree) {
+ if (!tree) {
+ return nullptr;
+ }
+
+ tree = tree->Parent;
+
+ if (tree) {
+ auto tree_tmp = tree->Next;
+
+ if (!tree_tmp) {
+ return tree;
+ }
+
+ return tree_tmp;
+ }
+
+ return tree;
+}
+
+/***********************************************************************************/
+/** @brief Allocate pointer to heap/file tree. */
+/***********************************************************************************/
+
+ErrorOr<VoidPtr> USER_PROCESS::New(SizeT sz, SizeT pad_amount) {
+ if (this->UsedMemory > kSchedMaxMemoryLimit) return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
+
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ auto vm_register = kKernelVM;
+
+ hal_write_cr3(this->VMRegister);
+
+ auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount);
+
+ hal_write_cr3(vm_register);
+#else
+ auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount);
+#endif
+
+ if (!this->HeapTree) {
+ this->HeapTree = new PROCESS_HEAP_TREE<VoidPtr>();
+
+ if (!this->HeapTree) {
+ this->Crash();
+ return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
+ }
+
+ this->HeapTree->EntryPad = pad_amount;
+ this->HeapTree->EntrySize = sz;
+
+ this->HeapTree->Entry = ptr;
+
+ this->HeapTree->Color = kBlackTreeKind;
+
+ this->HeapTree->Prev = nullptr;
+ this->HeapTree->Next = nullptr;
+ this->HeapTree->Parent = nullptr;
+ this->HeapTree->Child = nullptr;
+ } else {
+ PROCESS_HEAP_TREE<VoidPtr>* entry = this->HeapTree;
+ PROCESS_HEAP_TREE<VoidPtr>* prev_entry = entry;
+
+ BOOL is_parent = NO;
+
+ while (entry) {
+ if (entry->EntrySize < 1) break;
+
+ prev_entry = entry;
+
+ if (entry->Child && entry->Child->EntrySize > 0 && entry->Child->EntrySize == sz) {
+ entry = entry->Child;
+ is_parent = YES;
+ } else if (entry->Next && entry->Next->EntrySize > 0 && entry->Next->EntrySize == sz) {
+ is_parent = NO;
+ entry = entry->Next;
+ } else {
+ entry = sched_try_go_upper_ptr_tree(entry);
+ if (entry && entry->Color == kBlackTreeKind) break;
+ }
+ }
+
+ auto new_entry = new PROCESS_HEAP_TREE<VoidPtr>();
+
+ if (!new_entry) {
+ this->Crash();
+ return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
+ }
+
+ new_entry->Entry = ptr;
+ new_entry->EntrySize = sz;
+ new_entry->EntryPad = pad_amount;
+ new_entry->Parent = entry;
+ new_entry->Child = nullptr;
+ new_entry->Next = nullptr;
+ new_entry->Prev = nullptr;
+
+ new_entry->Color = kBlackTreeKind;
+ prev_entry->Color = kRedTreeKind;
+
+ if (is_parent) {
+ prev_entry->Child = new_entry;
+ new_entry->Parent = prev_entry;
+ } else {
+ prev_entry->Next = new_entry;
+ new_entry->Prev = prev_entry;
+ }
+ }
+
+ this->UsedMemory += sz;
+
+ return ErrorOr<VoidPtr>(ptr);
+}
+
+/***********************************************************************************/
+/// @brief Gets the name of the current process.
+/***********************************************************************************/
+
+const Char* USER_PROCESS::GetName() noexcept {
+ return this->Name;
+}
+
+/***********************************************************************************/
+/// @brief Gets the owner of the process.
+/***********************************************************************************/
+
+const User* USER_PROCESS::GetOwner() noexcept {
+ return this->Owner;
+}
+
+/// @brief USER_PROCESS status getter.
+const ProcessStatusKind& USER_PROCESS::GetStatus() noexcept {
+ return this->Status;
+}
+
+/***********************************************************************************/
+/**
+@brief Affinity is the time slot allowed for the process.
+*/
+/***********************************************************************************/
+
+const AffinityKind& USER_PROCESS::GetAffinity() noexcept {
+ return this->Affinity;
+}
+
+/***********************************************************************************/
+/** @brief Free heap tree. */
+/***********************************************************************************/
+
+template <typename T>
+STATIC Void sched_free_ptr_tree(T* tree) {
+ // Deleting memory lists. Make sure to free all of them.
+ while (tree) {
+ if (tree->Entry) {
+ MUST_PASS(mm_free_ptr(tree->Entry));
+ }
+
+ auto next = tree->Next;
+
+ if (next->Child) sched_free_ptr_tree(next->Child);
+
+ tree->Child = nullptr;
+
+ mm_free_ptr(tree);
+
+ tree = nullptr;
+ tree = next;
+ }
+}
+
+/***********************************************************************************/
+/**
+@brief Exit process method.
+@param exit_code The process's exit code.
+*/
+/***********************************************************************************/
+
+Void USER_PROCESS::Exit(const Int32& exit_code) {
+ this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen;
+ this->LastExitCode = exit_code;
+
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ auto pd = kKernelVM;
+ hal_write_cr3(this->VMRegister);
+#endif
+
+ sched_free_ptr_tree(this->HeapTree);
+ this->HeapTree = nullptr;
+
+ sched_free_ptr_tree(this->FileTree);
+ this->FileTree = nullptr;
+
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ hal_write_cr3(pd);
+#endif
+
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ //! Free the memory's page directory.
+ if (this->VMRegister) HAL::mm_free_bitmap(this->VMRegister);
+#endif
+
+ //! Delete image if not done already.
+ if (this->Image.fCode && mm_is_valid_ptr(this->Image.fCode)) mm_free_ptr(this->Image.fCode);
+
+ //! Delete blob too.
+ if (this->Image.fBlob && mm_is_valid_ptr(this->Image.fBlob)) mm_free_ptr(this->Image.fBlob);
+
+ //! Delete stack frame.
+ if (this->StackFrame && mm_is_valid_ptr(this->StackFrame))
+ mm_free_ptr((VoidPtr) this->StackFrame);
+
+ //! Avoid use after free.
+ this->Image.fBlob = nullptr;
+ this->Image.fCode = nullptr;
+ this->StackFrame = nullptr;
+
+ if (this->Kind == kExecutableDylibKind) {
+ Bool success = false;
+
+ rtl_fini_dylib_pef(*this, reinterpret_cast<IPEFDylibObject*>(this->DylibDelegate), &success);
+
+ if (!success) {
+ ke_panic(RUNTIME_CHECK_PROCESS);
+ }
+
+ this->DylibDelegate = nullptr;
+ }
+
+ this->ProcessId = 0UL;
+ this->Status = ProcessStatusKind::kFinished;
+
+ --this->ParentTeam->mProcessCur;
+}
+
+/***********************************************************************************/
+/// @brief Add dylib to the process object.
+/***********************************************************************************/
+
+Bool USER_PROCESS::InitDylib() {
+ // React according to the process's kind.
+ switch (this->Kind) {
+ case USER_PROCESS::kExecutableDylibKind: {
+ this->DylibDelegate = rtl_init_dylib_pef(*this);
+
+ if (!this->DylibDelegate) {
+ this->Crash();
+ return NO;
+ }
+
+ return YES;
+ }
+ case USER_PROCESS::kExecutableKind: {
+ return NO;
+ }
+ default: {
+ break;
+ }
+ }
+
+ (Void)(kout << "Unknown process kind: " << hex_number(this->Kind) << kendl);
+ this->Crash();
+
+ return NO;
+}
+
+/***********************************************************************************/
+/// @brief Add process to team.
+/// @param process the process *Ref* class.
+/// @return the process index inside the team.
+/***********************************************************************************/
+
+ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image) {
+ if (!name || !code) {
+ return -kErrorProcessFault;
+ }
+
+ if (*name == 0) {
+ return -kErrorProcessFault;
+ }
+
+ ProcessID pid = this->mTeam.mProcessCur;
+
+ if (pid > kSchedProcessLimitPerTeam) {
+ return -kErrorProcessFault;
+ }
+
+ ++this->mTeam.mProcessCur;
+
+ USER_PROCESS& process = this->mTeam.mProcessList[pid];
+
+ process.Image.fCode = code;
+ process.Image.fBlob = image;
+
+ SizeT len = rt_string_len(name);
+
+ if (len > kSchedNameLen) {
+ return -kErrorProcessFault;
+ }
+
+ rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, len,
+ kSchedNameLen);
+
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ process.VMRegister = kKernelVM;
+#else
+ process.VMRegister = 0UL;
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+
+ process.StackFrame = new HAL::StackFrame();
+
+ if (!process.StackFrame) {
+ process.Crash();
+ return -kErrorProcessFault;
+ }
+
+ rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame));
+
+ process.StackFrame->IP = reinterpret_cast<UIntPtr>(code);
+ process.StackFrame->SP = reinterpret_cast<UIntPtr>(&process.StackReserve[0] + process.StackSize);
+
+#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+ HAL::mm_map_page((VoidPtr) process.StackFrame->IP,
+ (VoidPtr) HAL::mm_get_page_addr((VoidPtr) process.StackFrame->IP),
+ HAL::kMMFlagsUser | HAL::kMMFlagsPresent);
+ HAL::mm_map_page((VoidPtr) process.StackFrame->SP,
+ (VoidPtr) HAL::mm_get_page_addr((VoidPtr) process.StackFrame->SP),
+ HAL::kMMFlagsUser | HAL::kMMFlagsPresent);
+#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__
+
+ process.StackSize = kSchedMaxStackSz;
+
+ rt_set_memory(process.StackReserve, 0, process.StackSize);
+
+ process.ParentTeam = &mTeam;
+
+ process.ProcessId = pid;
+ process.Status = ProcessStatusKind::kRunning;
+ process.PTime = 0;
+ process.UTime = 0;
+ process.RTime = 0;
+
+ if (!process.FileTree) {
+ process.FileTree = new PROCESS_FILE_TREE<VoidPtr>();
+
+ if (!process.FileTree) {
+ process.Crash();
+ return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory);
+ }
+
+ /// @todo File Tree allocation and dispose methods (amlal)
+ }
+
+ (Void)(kout << "ProcessID: " << number(process.ProcessId) << kendl);
+ (Void)(kout << "ProcesName: " << process.Name << kendl);
+
+ return pid;
+}
+
+/***********************************************************************************/
+/// @brief Retrieves the singleton of the process scheduler.
+/***********************************************************************************/
+
+UserProcessScheduler& UserProcessScheduler::The() {
+ STATIC UserProcessScheduler kScheduler;
+ return kScheduler;
+}
+
+/***********************************************************************************/
+
+/// @brief Remove process from the team.
+/// @param process_id process slot inside team.
+/// @retval true process was removed.
+/// @retval false process doesn't exist in team.
+
+/***********************************************************************************/
+
+Void UserProcessScheduler::Remove(ProcessID process_id) {
+ if (process_id < 0 || process_id > kSchedProcessLimitPerTeam) return;
+ if (this->mTeam.mProcessList[process_id].Status == ProcessStatusKind::kInvalid) return;
+
+ mTeam.mProcessList[process_id].Exit(kErrorSuccess);
+}
+
+/// @brief Is it a user scheduler?
+
+Bool UserProcessScheduler::IsUser() {
+ return Yes;
+}
+
+/// @brief Is it a kernel scheduler?
+
+Bool UserProcessScheduler::IsKernel() {
+ return No;
+}
+
+/// @brief Is it a SMP scheduler?
+
+Bool UserProcessScheduler::HasMP() {
+ MUST_PASS(kHandoverHeader);
+ return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled;
+}
+
+/***********************************************************************************/
+/// @brief Run User scheduler object.
+/// @return USER_PROCESS count executed within a team.
+/***********************************************************************************/
+
+SizeT UserProcessScheduler::Run() noexcept {
+ if (mTeam.mProcessCur < 1) {
+ return 0UL;
+ }
+
+ SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many
+ //! things we have scheduled.
+
+ for (; process_index < mTeam.AsArray().Capacity(); ++process_index) {
+ auto& process = mTeam.AsArray()[process_index];
+
+ //! Check if the process needs to be run.
+ if (UserProcessHelper::CanBeScheduled(process)) {
+ kout << process.Name << " will be run...\r";
+
+ //! Increase the usage time of the process.
+ if (process.UTime < process.PTime) {
+ ++process.UTime;
+ }
+
+ this->TheCurrentProcess() = process;
+
+ if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) {
+ process.PTime = static_cast<Int32>(process.Affinity);
+
+ // We add a bigger cooldown according to the RTime and affinity here.
+ if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) {
+ if (process.RTime < (Int32) AffinityKind::kVeryHigh)
+ process.RTime += (Int32) AffinityKind::kLowUsage;
+ else if (process.RTime < (Int32) AffinityKind::kHigh)
+ process.RTime += (Int32) AffinityKind::kStandard;
+ else if (process.RTime < (Int32) AffinityKind::kStandard)
+ process.RTime += (Int32) AffinityKind::kHigh;
+
+ process.PTime -= process.RTime;
+ process.RTime = 0UL;
+ }
+ }
+ } else {
+ ++process.RTime;
+ --process.PTime;
+ }
+ }
+
+ return process_index;
+}
+
+/// @brief Gets the current scheduled team.
+/// @return
+UserProcessTeam& UserProcessScheduler::TheCurrentTeam() {
+ return mTeam;
+}
+
+/***********************************************************************************/
+/// @brief Switches the current team.
+/// @param team the new team to switch to.
+/// @retval true team was switched.
+/// @retval false team was not switched.
+/***********************************************************************************/
+
+BOOL UserProcessScheduler::SwitchTeam(UserProcessTeam& team) {
+ if (team.AsArray().Count() < 1) return No;
+
+ this->mTeam = team;
+
+ return Yes;
+}
+
+/// @brief Gets current running process.
+/// @return
+Ref<USER_PROCESS>& UserProcessScheduler::TheCurrentProcess() {
+ return mTeam.AsRef();
+}
+
+/// @brief Current proccess id getter.
+/// @return USER_PROCESS ID integer.
+ErrorOr<ProcessID> UserProcessHelper::TheCurrentPID() {
+ if (!UserProcessScheduler::The().TheCurrentProcess())
+ return ErrorOr<ProcessID>{-kErrorProcessFault};
+
+ kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r";
+ return ErrorOr<ProcessID>{UserProcessScheduler::The().TheCurrentProcess().Leak().ProcessId};
+}
+
+/// @brief Check if process can be schedulded.
+/// @param process the process reference.
+/// @retval true can be schedulded.
+/// @retval false cannot be schedulded.
+Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) {
+ if (process.Affinity == AffinityKind::kRealTime) return Yes;
+
+ if (process.Status != ProcessStatusKind::kRunning) return No;
+ if (process.Affinity == AffinityKind::kInvalid) return No;
+ if (process.StackSize > kSchedMaxStackSz) return No;
+ if (!process.Name[0]) return No;
+ if (process.Signal.SignalID == sig_generate_unique<SIGTRAP>()) return No;
+
+ return process.PTime < 1;
+}
+
+/***********************************************************************************/
+/**
+ * @brief Start scheduling the current team.
+ */
+/***********************************************************************************/
+
+SizeT UserProcessHelper::StartScheduling() {
+ return UserProcessScheduler::The().Run();
+}
+
+/***********************************************************************************/
+/**
+ * \brief Does a context switch in a CPU.
+ * \param the_stack the stackframe of the running app.
+ * \param new_pid the process's ProcessID.
+ */
+/***********************************************************************************/
+
+Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid) {
+ (Void)(kout << "IP: " << hex_number(frame_ptr->IP) << kendl);
+
+ for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) {
+ if (!HardwareThreadScheduler::The()[index].Leak()) continue;
+
+ if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid ||
+ HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot)
+ continue;
+
+ (Void)(kout << "AP_" << hex_number(index) << kendl);
+
+ if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) {
+ (Void)(kout << "AP_" << hex_number(index));
+ kout << " is busy\r";
+
+ continue;
+ }
+
+ (Void)(kout << "AP_" << hex_number(index));
+ kout << " is now trying to run a new task!\r";
+
+ ////////////////////////////////////////////////////////////
+ /// Prepare task switch. ///
+ ////////////////////////////////////////////////////////////
+
+ HardwareThreadScheduler::The()[index].Leak()->Busy(YES);
+
+ Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr);
+
+ ////////////////////////////////////////////////////////////
+ /// Rollback on fail. ///
+ ////////////////////////////////////////////////////////////
+
+ if (!ret) continue;
+
+ UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid;
+
+ HardwareThreadScheduler::The()[index].Leak()->fPTime =
+ UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime;
+
+ (Void)(kout << "AP_" << hex_number(index));
+ kout << " is now running a new task!\r";
+
+ return YES;
+ }
+
+ kout << "Couldn't find a suitable core for the current process!\r";
+
+ return NO;
+}
+
+////////////////////////////////////////////////////////////
+/// @brief this checks if any process is on the team.
+////////////////////////////////////////////////////////////
+UserProcessScheduler::operator bool() {
+ for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) {
+ auto& process = mTeam.AsArray()[process_index];
+ if (UserProcessHelper::CanBeScheduled(process)) return true;
+ }
+
+ return false;
+}
+
+////////////////////////////////////////////////////////////
+/// @brief this checks if no process is on the team.
+////////////////////////////////////////////////////////////
+Bool UserProcessScheduler::operator!() {
+ SInt64 cnt = 0UL;
+
+ for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) {
+ auto& process = mTeam.AsArray()[process_index];
+ if (UserProcessHelper::CanBeScheduled(process)) ++cnt;
+ }
+
+ return cnt == 0L;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/UserProcessTeam.cc b/src/kernel/src/UserProcessTeam.cc
new file mode 100644
index 00000000..e5b7a7eb
--- /dev/null
+++ b/src/kernel/src/UserProcessTeam.cc
@@ -0,0 +1,57 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/***********************************************************************************/
+/// @file UserProcessTeam.cc
+/// @brief Process teams implementation.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+/***********************************************************************************/
+
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel {
+UserProcessTeam::UserProcessTeam() {
+ for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) {
+ this->mProcessList[i] = USER_PROCESS();
+ this->mProcessList[i].PTime = 0;
+ this->mProcessList[i].RTime = 0;
+ this->mProcessList[i].UTime = 0;
+ this->mProcessList[i].Status = ProcessStatusKind::kKilled;
+ this->mProcessList[i].ParentTeam = this;
+ }
+
+ this->mProcessCur = 0UL;
+}
+
+/***********************************************************************************/
+/// @brief Process list array getter.
+/// @return The list of process to schedule.
+/***********************************************************************************/
+
+Array<USER_PROCESS, kSchedProcessLimitPerTeam>& UserProcessTeam::AsArray() {
+ return this->mProcessList;
+}
+
+/***********************************************************************************/
+/// @brief Get team ID.
+/// @return The team's ID.
+/***********************************************************************************/
+
+ProcessID& UserProcessTeam::Id() noexcept {
+ return this->mTeamId;
+}
+
+/***********************************************************************************/
+/// @brief Get current process getter as Ref.
+/// @return The current process header.
+/***********************************************************************************/
+
+Ref<USER_PROCESS>& UserProcessTeam::AsRef() {
+ return this->mCurrentProcess;
+}
+} // namespace Kernel
+
+// last rev 05-03-24
diff --git a/src/kernel/src/UtfUtils.cc b/src/kernel/src/UtfUtils.cc
new file mode 100644
index 00000000..47ac2729
--- /dev/null
+++ b/src/kernel/src/UtfUtils.cc
@@ -0,0 +1,62 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Utils.h>
+
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+namespace Kernel {
+Size urt_string_len(const Utf8Char* str) {
+ if (!str) return 0;
+
+ SizeT len{0};
+
+ while (str[len] != u8'\0') ++len;
+
+ return len;
+}
+
+Void urt_set_memory(const voidPtr src, UInt32 dst, Size len) {
+ if (!src) return;
+
+ Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src);
+ Size index = 0;
+
+ while (index < len) {
+ srcChr[index] = dst;
+ ++index;
+ }
+}
+
+Int32 urt_string_cmp(const Utf8Char* src, const Utf8Char* cmp, Size size) {
+ if (!src) return 0;
+
+ Int32 counter = 0;
+
+ for (Size index = 0; index < size; ++index) {
+ if (src[index] != cmp[index]) ++counter;
+ }
+
+ return counter;
+}
+
+Int32 urt_copy_memory(const VoidPtr src, VoidPtr dst, Size len) {
+ if (!src) return 0;
+ if (!dst) return 0;
+
+ Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src);
+ Utf8Char* dstChar = reinterpret_cast<Utf8Char*>(dst);
+
+ Size index = 0;
+
+ while (index < len) {
+ dstChar[index] = srcChr[index];
+ ++index;
+ }
+
+ return index;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/Variant.cc b/src/kernel/src/Variant.cc
new file mode 100644
index 00000000..fcf2f443
--- /dev/null
+++ b/src/kernel/src/Variant.cc
@@ -0,0 +1,38 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <NeKit/Variant.h>
+
+namespace Kernel {
+const Char* Variant::ToString() {
+ switch (fKind) {
+ case VariantKind::kTOML:
+ return ("Class:{TOML}");
+ case VariantKind::kJson:
+ return ("Class:{Json}");
+ case VariantKind::kString:
+ return ("Class:{String}");
+ case VariantKind::kBlob:
+ return ("Class:{Blob}");
+ case VariantKind::kNull:
+ return ("Class:{Null}");
+ case VariantKind::kSwap:
+ return ("Class:{Swap}");
+ default:
+ return ("Class:{Unknown}");
+ }
+}
+
+/// @brief Return variant's kind.
+Variant::VariantKind& Variant::Kind() {
+ return this->fKind;
+}
+
+/// @brief Leak variant's instance.
+VoidPtr Variant::Leak() {
+ return this->fPtr;
+}
+} // namespace Kernel
diff --git a/src/kernel/src/ZXD.cc b/src/kernel/src/ZXD.cc
new file mode 100644
index 00000000..1baa18f3
--- /dev/null
+++ b/src/kernel/src/ZXD.cc
@@ -0,0 +1,7 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/ZXD.h>
diff --git a/src/launch/.keep b/src/launch/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/launch/.keep
diff --git a/src/launch/LaunchKit/Foundation.h b/src/launch/LaunchKit/Foundation.h
new file mode 100644
index 00000000..d7eb901f
--- /dev/null
+++ b/src/launch/LaunchKit/Foundation.h
@@ -0,0 +1,21 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ ======================================== */
+
+#pragma once
+
+#include <CoreFoundation.fwrk/headers/Ref.h>
+#include <libSystem/SystemKit/System.h>
+
+/// @author Amlal El Mahrouss
+/// @brief NeKernel Launch Kit - launch programs from it.
+
+#define NELAUNCH_INFO(MSG) PrintOut(nullptr, "INFO: [LAUNCH] %s\n", MSG)
+#define NELAUNCH_WARN(MSG) PrintOut(nullptr, "WARN: [LAUNCH] %s\n", MSG)
+
+namespace Launch {
+using AnyRef = CF::CFRef<VoidPtr>;
+using StatusRef = CF::CFRef<SInt32>;
+} // namespace Launch
diff --git a/src/launch/launch.json b/src/launch/launch.json
new file mode 100644
index 00000000..dbc111b2
--- /dev/null
+++ b/src/launch/launch.json
@@ -0,0 +1,20 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "./", "../../public/frameworks"],
+ "sources_path": ["src/*.cc", "src/*.S"],
+ "output_name": "ne_launch",
+ "compiler_flags": [
+ "-ffreestanding",
+ "-shared",
+ "-fPIC",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17"
+ ],
+ "cpp_macros": [
+ "kNeLaunchVersion=0x0100",
+ "kNeLaunchVersionHighest=0x0100",
+ "kNeLaunchVersionLowest=0x0100"
+ ]
+}
diff --git a/src/launch/obj/.keep b/src/launch/obj/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/launch/obj/.keep
diff --git a/src/launch/src/.keep b/src/launch/src/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/launch/src/.keep
diff --git a/src/launch/src/AppMain.cc b/src/launch/src/AppMain.cc
new file mode 100644
index 00000000..10e9ff2b
--- /dev/null
+++ b/src/launch/src/AppMain.cc
@@ -0,0 +1,28 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ ======================================== */
+
+#include <LaunchKit/Foundation.h>
+#include <libSystem/SystemKit/Err.h>
+#include <libSystem/SystemKit/Syscall.h>
+
+/// @note This called by _NeMain from its own runtime.
+extern "C" SInt32 nelaunch_startup_fn(Void) {
+ /// Start LaunchHelpers.fwrk services, and make the launcher manageable too (via mgmt.launch)
+ UInt32* ret = (UInt32*) libsys_syscall_arg_1(libsys_hash_64("__launch_register_launch_service"));
+
+ if (ret) {
+ switch (*ret) {
+ case kErrorSuccess: {
+ libsys_syscall_arg_1(libsys_hash_64("__launch_listen_as_root"));
+ return *ret;
+ }
+ default:
+ break;
+ }
+ }
+
+ return kErrorExecutable;
+}
diff --git a/src/launch/src/CRuntimeZero.S b/src/launch/src/CRuntimeZero.S
new file mode 100644
index 00000000..4f983b46
--- /dev/null
+++ b/src/launch/src/CRuntimeZero.S
@@ -0,0 +1,23 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ ======================================== */
+
+.text
+
+.extern nelaunch_startup_fn
+.extern ThrExitMainThread
+.globl _NeMain
+
+_NeMain:
+ push %rbp
+ movq %rsp, %rbp
+
+ callq nelaunch_startup_fn
+
+ movq %rcx, 0
+
+ callq ThrExitMainThread
+
+ popq %rbp
diff --git a/src/libDDK/DriverKit/ddk.h b/src/libDDK/DriverKit/ddk.h
new file mode 100644
index 00000000..45f7d356
--- /dev/null
+++ b/src/libDDK/DriverKit/ddk.h
@@ -0,0 +1,76 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss 2025, licensed under the Apache 2.0 license.
+
+ FILE: ddk.h
+ PURPOSE: DDK Driver model base header.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/macros.h>
+
+struct DDK_STATUS_STRUCT;
+struct DDK_OBJECT_MANIFEST;
+
+/// \brief Object handle manifest.
+struct DDK_OBJECT_MANIFEST DDK_FINAL {
+ char* p_name;
+ int32_t p_kind;
+ void* p_object;
+};
+
+/// \brief DDK status ping structure.
+struct DDK_STATUS_STRUCT DDK_FINAL {
+ int32_t s_action_id;
+ int32_t s_issuer_id;
+ int32_t s_group_id;
+ struct DDK_OBJECT_MANIFEST* s_object;
+};
+
+typedef void* ptr_t;
+
+/// @brief Call Kernel procedure.
+/// @param name the procedure name.
+/// @param cnt number of elements in **dat**
+/// @param dat data argument pointer.
+/// @param sz sz of whole data argument pointer.
+/// @return result of call
+DDK_EXTERN void* ke_call_dispatch(const char* name, int32_t cnt, void* dat, size_t sz);
+
+/// @brief add a system call.
+/// @param slot system call slot id.
+/// @param slotFn, syscall slot.
+DDK_EXTERN void ke_set_syscall(const int32_t slot, void (*slotFn)(void* a0));
+
+/// @brief Allocates an heap ptr.
+/// @param sz size of the allocated struct/type.
+/// @return the pointer allocated or **nil**.
+DDK_EXTERN void* kalloc(size_t sz);
+
+/// @brief Frees an heap ptr.
+/// @param pointer kernel pointer to free.
+DDK_EXTERN void kfree(void* the_ptr);
+
+/// @brief Gets a Kernel object.
+/// @param slot object id (can be 0)
+/// @param name the property's name.
+/// @return DDK_OBJECT_MANIFEST.
+DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name);
+
+/// @brief Set a Kernel object.
+/// @param slot object id (can be 0)
+/// @param name the property's name.
+/// @param ddk_pr pointer to a object's DDK_OBJECT_MANIFEST.
+/// @return returned object.
+DDK_EXTERN void* ke_set_obj(const int32_t slot, const struct DDK_OBJECT_MANIFEST* ddk_pr);
+
+/// @brief The highest API version of the DDK.
+DDK_EXTERN uint32_t kApiVersionHighest;
+
+/// @brief The lowest API version of the DDK.
+DDK_EXTERN uint32_t kApiVersionLowest;
+
+/// @brief API version in BCD.
+DDK_EXTERN uint32_t kApiVersion;
diff --git a/src/libDDK/DriverKit/dev.h b/src/libDDK/DriverKit/dev.h
new file mode 100644
index 00000000..a88a00dd
--- /dev/null
+++ b/src/libDDK/DriverKit/dev.h
@@ -0,0 +1,36 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ File: dev.h
+ Purpose: DDK device support.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/ddk.h>
+
+struct _DDK_DEVICE;
+
+#define DDK_DEVICE_NAME_LEN (255)
+
+/// @brief Kernel Device driver.
+typedef struct _DDK_DEVICE DDK_FINAL {
+ char d_name[DDK_DEVICE_NAME_LEN]; // the device name. Could be /./DEVICE_NAME/
+ void* (*d_read)(void* arg, int len); // read from device.
+ void (*d_write)(void* arg, int len);
+ void (*d_wait)(void); // write to device.
+ struct _DDK_DEVICE* (*d_open)(const char* path); // open device.
+ void (*d_close)(struct _DDK_DEVICE* dev); // close device.
+ void (*d_seek)(struct _DDK_DEVICE* dev, size_t off);
+ size_t (*d_tell)(struct _DDK_DEVICE* dev);
+} DDK_DEVICE, *DDK_DEVICE_PTR;
+
+/// @brief Open a new device from path.
+/// @param path the device's path.
+DDK_EXTERN DDK_DEVICE_PTR kopen_dev(const char* path);
+
+/// @brief Close any device.
+/// @param device valid device.
+DDK_EXTERN BOOL kclose_dev(DDK_DEVICE_PTR device);
diff --git a/src/libDDK/DriverKit/dki/contract.h b/src/libDDK/DriverKit/dki/contract.h
new file mode 100644
index 00000000..7361d792
--- /dev/null
+++ b/src/libDDK/DriverKit/dki/contract.h
@@ -0,0 +1,34 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss 2025, licensed under the Apache 2.0 license.
+
+ FILE: ddk.h
+ PURPOSE: Driver Kernel Interface Model base header.
+
+ ======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <libDDK/DriverKit/macros.h>
+
+#define DKI_CONTRACT_IMPL final : public ::Kernel::DKI::DKIContract
+
+/// @author Amlal El Mahrouss
+
+namespace Kernel::DKI {
+class DKIContract {
+ public:
+ explicit DKIContract() = default;
+ virtual ~DKIContract() = default;
+
+ NE_COPY_DEFAULT(DKIContract);
+
+ using PtrType = VoidPtr;
+
+ virtual BOOL IsCastable() { return NO; }
+ virtual BOOL IsActive() { return NO; }
+ virtual VoidPtr Leak() { return nullptr; }
+ virtual Int32 Type() { return 0; }
+};
+} // namespace Kernel::DKI
diff --git a/src/libDDK/DriverKit/io.h b/src/libDDK/DriverKit/io.h
new file mode 100644
index 00000000..58b625ac
--- /dev/null
+++ b/src/libDDK/DriverKit/io.h
@@ -0,0 +1,18 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/str.h>
+
+/// @brief print character into UART.
+DDK_EXTERN void kputc(const char ch);
+
+/// @brief print string to UART.
+/// @param message string to transmit to UART.
+DDK_EXTERN void kprint(const char* message);
diff --git a/src/libDDK/DriverKit/macros.h b/src/libDDK/DriverKit/macros.h
new file mode 100644
index 00000000..7fd1403b
--- /dev/null
+++ b/src/libDDK/DriverKit/macros.h
@@ -0,0 +1,48 @@
+/* ========================================
+
+ Copyright 2025 Amlal El Mahrouss.
+
+ FILE: ddk.h
+ PURPOSE: DDK Driver model base header.
+
+======================================== */
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(__cplusplus)
+#define BOOL bool
+#define YES true
+#define NO false
+#define DDK_EXTERN extern "C"
+#define nil nullptr
+#undef NULL
+#define NULL 0
+#define DDK_FINAL final
+#else
+#define BOOL char
+#define YES 1
+#define NO 0
+#define DDK_EXTERN extern
+#define nil ((void*) 0)
+#undef NULL
+#define NULL ((void*) 0)
+#define DDK_FINAL
+#endif // defined(__cplusplus)
+
+#ifndef __DDK__
+#undef DDK_EXTERN
+#if defined(__cplusplus)
+#define DDK_EXTERN extern "C"
+#else
+#define DDK_EXTERN
+#endif
+#endif
+
+#define ATTRIBUTE(X) __attribute__((X))
+
+#ifndef __NEOSKRNL__
+#error !!! Do not include header in EL0/Ring 3 mode !!!
+#endif // __NEOSKRNL__ \ No newline at end of file
diff --git a/src/libDDK/DriverKit/net.h b/src/libDDK/DriverKit/net.h
new file mode 100644
index 00000000..5dfe6374
--- /dev/null
+++ b/src/libDDK/DriverKit/net.h
@@ -0,0 +1,16 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ FILE: net.h
+ PURPOSE: Network model base header.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/macros.h>
+
+struct DDK_NET_MANIFEST;
+
+/// @brief IFS hooks to plug into the FileMgr.
diff --git a/src/libDDK/DriverKit/str.h b/src/libDDK/DriverKit/str.h
new file mode 100644
index 00000000..6409b1a7
--- /dev/null
+++ b/src/libDDK/DriverKit/str.h
@@ -0,0 +1,17 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Strings.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/ddk.h>
+
+/// @brief DDK equivalent of POSIX's string.h
+/// @file str.h
+
+DDK_EXTERN size_t kstrlen(const char* in);
+DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len);
diff --git a/src/libDDK/docs/SPECIFICATION_DDK.md b/src/libDDK/docs/SPECIFICATION_DDK.md
new file mode 100644
index 00000000..d59b6e77
--- /dev/null
+++ b/src/libDDK/docs/SPECIFICATION_DDK.md
@@ -0,0 +1,18 @@
+===================================
+
+# 0: General Information
+
+===================================
+
+- Programming Language: C/C++
+- Build System: Make/NeBuild
+- Purpose: Driver Tool Kit, which you link against libDDK.dll
+
+===================================
+
+# 1: How It works
+
+===================================
+
+- Driver shall directly call the kernel at specific ports. (Or a kernel call)
+- Kernel must respond according to kernel call, otherwise a panic will occur. \ No newline at end of file
diff --git a/src/libDDK/libDDK.json b/src/libDDK/libDDK.json
new file mode 100644
index 00000000..113dd585
--- /dev/null
+++ b/src/libDDK/libDDK.json
@@ -0,0 +1,23 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-gcc",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "./"],
+ "sources_path": ["src/*.c", "src/*.cc", "src/*.S"],
+ "output_name": "libDDK.dll",
+ "compiler_flags": [
+ "-ffreestanding",
+ "-shared",
+ "-std=c17",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__DDK_AMD64__",
+ "__DDK__",
+ "kDDKVersionHighest=0x0100",
+ "kDDKVersionLowest=0x0100",
+ "kDDKVersion=0x0100"
+ ]
+}
diff --git a/src/libDDK/obj/.gitkeep b/src/libDDK/obj/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/libDDK/obj/.gitkeep
diff --git a/src/libDDK/src/ddk_abi_cxx.cc b/src/libDDK/src/ddk_abi_cxx.cc
new file mode 100644
index 00000000..196f7f6a
--- /dev/null
+++ b/src/libDDK/src/ddk_abi_cxx.cc
@@ -0,0 +1,27 @@
+/* ========================================
+
+ DDK
+ Copyright Amlal El Mahrouss.
+
+ Author: Amlal El Mahrouss
+ Purpose: DDK C++ ABI.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+
+void* operator new(size_t sz) {
+ return ::kalloc(sz);
+}
+
+void operator delete(void* ptr) {
+ ::kfree(ptr);
+}
+
+void* operator new[](size_t sz) {
+ return ::kalloc(sz);
+}
+
+void operator delete[](void* ptr) {
+ ::kfree(ptr);
+}
diff --git a/src/libDDK/src/ddk_alloc.c b/src/libDDK/src/ddk_alloc.c
new file mode 100644
index 00000000..09f3034f
--- /dev/null
+++ b/src/libDDK/src/ddk_alloc.c
@@ -0,0 +1,32 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK allocator.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+
+/**
+ \brief Allocates a new heap on the Kernel's side.
+ \param sz the size of the heap block.
+ \return the newly allocated pointer.
+*/
+DDK_EXTERN void* kalloc(size_t sz) {
+ if (!sz) ++sz;
+
+ void* ptr = ke_call_dispatch("mm_alloc_ptr", 1, &sz, sizeof(size_t));
+
+ return ptr;
+}
+
+/**
+ \brief Frees a pointer from the heap.
+ \param ptr the pointer to free.
+*/
+DDK_EXTERN void kfree(void* ptr) {
+ if (!ptr) return;
+
+ ke_call_dispatch("mm_free_ptr", 1, ptr, 0);
+}
diff --git a/src/libDDK/src/ddk_dev.c b/src/libDDK/src/ddk_dev.c
new file mode 100644
index 00000000..64ecefb6
--- /dev/null
+++ b/src/libDDK/src/ddk_dev.c
@@ -0,0 +1,27 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+======================================== */
+
+#include <DriverKit/dev.h>
+#include <DriverKit/str.h>
+
+/// @brief Open a new binary device from path.
+DDK_EXTERN DDK_DEVICE_PTR kopen_dev(const char* devicePath) {
+ if (nil == devicePath) return nil;
+
+ return (DDK_DEVICE_PTR) ke_call_dispatch("dk_open_dev", 1, (void*) devicePath,
+ kstrlen(devicePath));
+}
+
+/// @brief Close any device.
+/// @param device valid device.
+DDK_EXTERN BOOL kclose_dev(DDK_DEVICE_PTR device) {
+ if (nil == device) return NO;
+
+ ke_call_dispatch("dk_close_dev", 1, device, sizeof(DDK_DEVICE));
+ return YES;
+}
diff --git a/src/libDDK/src/ddk_io.c b/src/libDDK/src/ddk_io.c
new file mode 100644
index 00000000..07287b91
--- /dev/null
+++ b/src/libDDK/src/ddk_io.c
@@ -0,0 +1,36 @@
+/* ========================================
+
+ libDDK - Device Driver Kit
+ Copyright 2025 - Amlal El Mahrouss and NeKernel contributors.
+
+ File: ddk_io.c
+ Purpose: DDK Text I/O.
+
+======================================== */
+
+#include <DriverKit/io.h>
+
+DDK_EXTERN void kputc(const char ch) {
+ if (!ch) return;
+
+ char assembled[2] = {0};
+ assembled[0] = ch;
+ assembled[1] = 0;
+
+ ke_call_dispatch("ke_put_string", 1, assembled, 1);
+}
+
+/// @brief print string to UART.
+/// @param message UART to transmit.
+DDK_EXTERN void kprint(const char* message) {
+ if (nil == message) return;
+ if (*message == '\0') return;
+
+ size_t index = 0;
+ size_t len = kstrlen(message);
+
+ while (index < len) {
+ kputc(message[index]);
+ ++index;
+ }
+}
diff --git a/src/libDDK/src/ddk_kernel_call.c b/src/libDDK/src/ddk_kernel_call.c
new file mode 100644
index 00000000..92652969
--- /dev/null
+++ b/src/libDDK/src/ddk_kernel_call.c
@@ -0,0 +1,77 @@
+/* ========================================
+
+ DDK
+ Copyright Amlal El Mahrouss.
+
+ Author: Amlal El Mahrouss
+ Purpose: DDK kernel dispatch system.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+#include <stdarg.h>
+
+/// @brief this is an internal call, do not use it.
+DDK_EXTERN ATTRIBUTE(naked) ptr_t
+ __ke_call_dispatch(const int32_t name, int32_t cnt, void* data, size_t sz);
+
+/// @brief This function hashes the path into a FNV symbol.
+/// @param path the path to hash.
+/// @retval 0 symbol wasn't hashed.
+/// @retval > 0 hashed symbol.
+static uint64_t ddk_fnv_64(const char* path) {
+ if (path == nil || *path == 0) return 0;
+
+ const uint64_t kFnvOffsetBase = 0xcbf29ce484222325ULL;
+ const uint64_t kFnvPrime64 = 0x100000001b3ULL;
+
+ uint64_t hash = kFnvOffsetBase;
+
+ while (*path) {
+ hash ^= (char) (*path++);
+ hash *= kFnvPrime64;
+ }
+
+ return hash;
+}
+
+/// @brief Interrupt Kernel and call it's RPC.
+/// @param name RPC name
+/// @param cnt number of elements in **data** pointer.
+/// @param data data pointer.
+/// @param sz The size of the whole data pointer.
+/// @retval void* Kernel call was successful.
+/// @retval nil Kernel call failed, call KernelLastError(void)
+DDK_EXTERN void* ke_call_dispatch(const char* name, int32_t cnt, void* data, size_t sz) {
+ if (name == nil || *name == 0 || data == nil || cnt == 0) return nil;
+ return __ke_call_dispatch(ddk_fnv_64(name), cnt, data, sz);
+}
+
+/// @brief Add system call.
+/// @param slot system call slot
+/// @param slotFn, syscall slot.
+DDK_EXTERN void ke_set_syscall(const int slot, void (*slotFn)(void* a0)) {
+ ke_call_dispatch("ke_set_syscall", slot, slotFn, 1);
+}
+
+/// @brief Get a Kernel object.
+/// @param slot property id (always 0)
+/// @param name the object's name.
+/// @return Object manifest.
+DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name) {
+ struct DDK_OBJECT_MANIFEST* manifest =
+ (struct DDK_OBJECT_MANIFEST*) ke_call_dispatch("cfkit_get_kobj", slot, (void*) name, 1);
+
+ if (!manifest) return nil;
+
+ return manifest;
+}
+
+/// @brief Set a Kernel object.
+/// @param slot property id (always 0)
+/// @param name the object's name.
+/// @param ddk_pr pointer to a object's DDK_OBJECT_MANIFEST.
+/// @return property's object.
+DDK_EXTERN void* ke_set_obj(const int slot, const struct DDK_OBJECT_MANIFEST* ddk_pr) {
+ return ke_call_dispatch("cfkit_set_kobj", slot, (void*) ddk_pr, 1);
+}
diff --git a/src/libDDK/src/ddk_kernel_call_dispatch.S b/src/libDDK/src/ddk_kernel_call_dispatch.S
new file mode 100644
index 00000000..a607fe40
--- /dev/null
+++ b/src/libDDK/src/ddk_kernel_call_dispatch.S
@@ -0,0 +1,47 @@
+/**
+ lang: asm
+ compiler: gnu
+ */
+
+#define kKernelCallTrapId 51
+
+.globl __ke_call_dispatch
+
+.text
+
+/* Really simple function, takes our va-list,
+ and brings it to the trap handler in the Kernel. */
+
+#if defined(__DDK_AMD64__)
+
+ .intel_syntax noprefix
+
+/* args rcx, rdx, r8, r9 */
+__ke_call_dispatch:
+ push rbp
+ mov rbp, rsp
+
+ /* registers have already been pushed. */
+
+ int kKernelCallTrapId
+
+ pop rbp
+ ret
+
+#elif defined(__DDK_POWER64__)
+
+/* args r8, r9, r10, r11 */
+__ke_call_dispatch:
+ /* There is no specific interrupt request id for a system call in POWER. */
+ sc
+ blr
+
+#elif defined(__DDK_ARM64__)
+
+/* args x0, x8, x9, x10, x11 is kept to tell that this is a Kernel call */
+__ke_call_dispatch:
+ /* There is no specific interrupt request id for a system call in ARM64 as well. */
+ mov x9, #kKernelCallTrapId
+ svc #0
+
+#endif
diff --git a/src/libDDK/src/ddk_str.c b/src/libDDK/src/ddk_str.c
new file mode 100644
index 00000000..3021f84a
--- /dev/null
+++ b/src/libDDK/src/ddk_str.c
@@ -0,0 +1,36 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK String API.
+
+======================================== */
+
+#include <DriverKit/str.h>
+
+DDK_EXTERN size_t kstrlen(const char* in) {
+ if (in == nil) return 0;
+
+ if (*in == 0) return 0;
+
+ size_t index = 0;
+
+ while (in[index] != 0) {
+ ++index;
+ }
+
+ return index;
+}
+
+DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len) {
+ if (nil == dst || nil == src) return 0;
+
+ size_t index = 0;
+
+ while (index != len) {
+ dst[index] = src[index];
+ ++index;
+ }
+
+ return index;
+}
diff --git a/src/libDDK/src/ddk_ver.c b/src/libDDK/src/ddk_ver.c
new file mode 100644
index 00000000..3679bdef
--- /dev/null
+++ b/src/libDDK/src/ddk_ver.c
@@ -0,0 +1,25 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK version system.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+
+#ifndef kDDKVersionHighest
+#define kDDKVersionHighest 1
+#endif // !kDDKVersionHighest
+
+#ifndef kDDKVersionLowest
+#define kDDKVersionLowest 1
+#endif // !kDDKVersionLowest
+
+#ifndef kDDKVersion
+#define kDDKVersion 1
+#endif // !kDDKVersion
+
+uint32_t kApiVersionHighest = kDDKVersionHighest;
+uint32_t kApiVersionLowest = kDDKVersionLowest;
+uint32_t kApiVersion = kDDKVersion;
diff --git a/src/libMsg/.keep b/src/libMsg/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/libMsg/.keep
diff --git a/src/libMsg/MsgKit/Network.h b/src/libMsg/MsgKit/Network.h
new file mode 100644
index 00000000..ca7cf2d3
--- /dev/null
+++ b/src/libMsg/MsgKit/Network.h
@@ -0,0 +1,9 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <libMsg/MsgKit/Server.h> \ No newline at end of file
diff --git a/src/libMsg/MsgKit/Server.h b/src/libMsg/MsgKit/Server.h
new file mode 100644
index 00000000..b75fb96a
--- /dev/null
+++ b/src/libMsg/MsgKit/Server.h
@@ -0,0 +1,41 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#ifdef __cplusplus
+#include <public/frameworks/CoreFoundation.fwrk/headers/String.h>
+#else
+#include <libSystem/SystemKit/System.h>
+#endif
+
+/// @author Amlal El Mahrouss
+/// @file Server.h
+/// @brief libMsg LISP system.
+
+struct LIBMSG_EXPR;
+
+/// @brief an expression chain of LibMSG.
+struct LIBMSG_EXPR final {
+#ifdef __cplusplus
+ CF::CFString* l_key{nullptr};
+ CF::CFString* l_value{nullptr};
+#else
+ // if we use C, we won't know about CF, so let's make those private.
+ VoidPtr l_private_data[2]{nullptr};
+#endif
+
+ LIBMSG_EXPR* l_head{nullptr};
+ LIBMSG_EXPR* l_tail{nullptr};
+ LIBMSG_EXPR* l_child{nullptr};
+};
+
+/// @brief Function type for LibMSG lisp.
+typedef Void (*libmsg_func_type)(struct LIBMSG_EXPR* self, VoidPtr arg, SizeT arg_size);
+
+IMPORT_C Void libmsg_init_library(libmsg_func_type* funcs, SizeT cnt);
+IMPORT_C UInt32 libmsg_close_library(Void);
+IMPORT_C UInt32 libmsg_eval_expr(struct LIBMSG_EXPR* head);
diff --git a/src/libMsg/obj/.keep b/src/libMsg/obj/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/libMsg/obj/.keep
diff --git a/src/libMsg/script/window_client.json b/src/libMsg/script/window_client.json
new file mode 100644
index 00000000..4c8a21ba
--- /dev/null
+++ b/src/libMsg/script/window_client.json
@@ -0,0 +1,7 @@
+{
+ "id": 1,
+ "pos": { "x": 100, "y": 100 },
+ "size": { "w": 300, "h": 200 },
+ "title": "Window Client",
+ "on-click": "_OnClickCSymbol"
+} \ No newline at end of file
diff --git a/src/libMsg/src/.keep b/src/libMsg/src/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/libMsg/src/.keep
diff --git a/src/libSystem/SystemKit/Err.h b/src/libSystem/SystemKit/Err.h
new file mode 100644
index 00000000..ea36abde
--- /dev/null
+++ b/src/libSystem/SystemKit/Err.h
@@ -0,0 +1,58 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <libSystem/SystemKit/Macros.h>
+
+/// @file Err.h
+/// @brief Process Codes type and values.
+/// @author Amlal El Mahrouss (amlal@nekernel.org)
+
+#define err_local_ok() (kLastError == kErrorSuccess)
+#define err_local_fail() (kLastError != kErrorSuccess)
+#define err_local_get() (kLastError)
+
+typedef SInt32 ErrRef;
+
+inline constexpr ErrRef kErrorSuccess = 0;
+inline constexpr ErrRef kErrorExecutable = 33;
+inline constexpr ErrRef kErrorExecutableLib = 34;
+inline constexpr ErrRef kErrorFileNotFound = 35;
+inline constexpr ErrRef kErrorDirectoryNotFound = 36;
+inline constexpr ErrRef kErrorDiskReadOnly = 37;
+inline constexpr ErrRef kErrorDiskIsFull = 38;
+inline constexpr ErrRef kErrorProcessFault = 39;
+inline constexpr ErrRef kErrorSocketHangUp = 40;
+inline constexpr ErrRef kErrorThreadLocalStorage = 41;
+inline constexpr ErrRef kErrorMath = 42;
+inline constexpr ErrRef kErrorNoNetwork = 43;
+inline constexpr ErrRef kErrorHeapOutOfMemory = 44;
+inline constexpr ErrRef kErrorNoSuchDisk = 45;
+inline constexpr ErrRef kErrorFileExists = 46;
+inline constexpr ErrRef kErrorFormatFailed = 47;
+inline constexpr ErrRef kErrorNetworkTimeout = 48;
+inline constexpr ErrRef kErrorInternal = 49;
+inline constexpr ErrRef kErrorForkAlreadyExists = 50;
+inline constexpr ErrRef kErrorOutOfTeamSlot = 51;
+inline constexpr ErrRef kErrorHeapNotPresent = 52;
+inline constexpr ErrRef kErrorNoEntrypoint = 53;
+inline constexpr ErrRef kErrorDiskIsCorrupted = 54;
+inline constexpr ErrRef kErrorDisk = 55;
+inline constexpr ErrRef kErrorInvalidData = 56;
+inline constexpr ErrRef kErrorAsync = 57;
+inline constexpr ErrRef kErrorNonBlocking = 58;
+inline constexpr ErrRef kErrorIPC = 59;
+inline constexpr ErrRef kErrorSign = 60;
+inline constexpr ErrRef kErrorInvalidCreds = 61;
+inline constexpr ErrRef kErrorCDTrayBroken = 62;
+inline constexpr ErrRef kErrorUnrecoverableDisk = 63;
+inline constexpr ErrRef kErrorFileLocked = 64;
+inline constexpr ErrRef kErrorDiskIsTooTiny = 65;
+inline constexpr ErrRef kErrorUnimplemented = -1;
+
+/// @brief The last error reported by the system to the process.
+IMPORT_C ErrRef kLastError;
diff --git a/src/libSystem/SystemKit/Jail.h b/src/libSystem/SystemKit/Jail.h
new file mode 100644
index 00000000..f28968b4
--- /dev/null
+++ b/src/libSystem/SystemKit/Jail.h
@@ -0,0 +1,36 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <libSystem/SystemKit/System.h>
+
+/// @file Jail.h
+/// @author Amlal El Mahrouss
+/// @brief NeKernel Jail System, part of OpenEnclave.
+
+struct JAIL_INFO;
+struct JAIL;
+
+/// @brief Jail information (client side struct)
+struct JAIL_INFO {
+ SInt32 fParentID;
+ SInt32 fJailHash;
+ SInt64 fACL;
+};
+
+/// @brief Jail information (we grab a JAIL from JailGetCurrent())
+struct JAIL {
+ struct JAIL_INFO* fServer;
+ struct JAIL_INFO* fClient;
+ SInt32 fJailHash;
+ SInt32 fParentID;
+ SInt64 fACL;
+};
+
+/// @brief Get the current jail
+/// @return Pointer to the current jail structure, or NULL if not in a jail
+IMPORT_C struct JAIL* JailGetCurrent(Void);
diff --git a/src/libSystem/SystemKit/Macros.h b/src/libSystem/SystemKit/Macros.h
new file mode 100644
index 00000000..aac2bf1b
--- /dev/null
+++ b/src/libSystem/SystemKit/Macros.h
@@ -0,0 +1,126 @@
+/* ========================================
+
+Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+File: Macros.h
+Purpose: libsci Macros header.
+
+======================================== */
+
+#pragma once
+
+/***********************************************************************************/
+/// @file libSystem/Macros.h
+/// @brief Macros and Core types of the SCI (System Call Interface).
+/***********************************************************************************/
+
+#include <hint/CompilerHint.h>
+
+#define ATTRIBUTE(X) __attribute__((X))
+
+#define IMPORT_CXX extern "C++"
+#define IMPORT_C extern "C"
+
+#define DEPRECATED ATTRIBUTE(deprecated)
+
+#define EXIT_SUCCESS (0)
+#define EXIT_FAILURE (1)
+
+#define FILE_MAX_LEN (256)
+
+#ifndef BOOL
+#define BOOL bool
+#endif
+
+typedef bool Bool;
+typedef bool Boolean;
+typedef void Void;
+
+#ifndef __cplusplus
+#define true (1)
+#define false (0)
+#endif
+
+#define YES true
+#define NO false
+
+typedef __UINT64_TYPE__ UInt64;
+typedef __UINT32_TYPE__ UInt32;
+typedef __UINT16_TYPE__ UInt16;
+typedef __UINT8_TYPE__ UInt8;
+
+typedef __SIZE_TYPE__ SizeT;
+
+typedef __INT64_TYPE__ SInt64;
+typedef __INT32_TYPE__ SInt32;
+typedef __INT16_TYPE__ SInt16;
+typedef __INT8_TYPE__ SInt8;
+
+typedef void* VoidPtr;
+typedef __UINTPTR_TYPE__ UIntPtr;
+typedef char Char;
+
+#ifdef __cplusplus
+typedef decltype(nullptr) nullPtr;
+typedef nullPtr NullPtr;
+
+#define LIBSYS_COPY_DELETE(KLASS) \
+ KLASS& operator=(const KLASS&) = delete; \
+ KLASS(const KLASS&) = delete;
+
+#define LIBSYS_COPY_DEFAULT(KLASS) \
+ KLASS& operator=(const KLASS&) = default; \
+ KLASS(const KLASS&) = default;
+
+#define LIBSYS_MOVE_DELETE(KLASS) \
+ KLASS& operator=(KLASS&&) = delete; \
+ KLASS(KLASS&&) = delete;
+
+#define LIBSYS_MOVE_DEFAULT(KLASS) \
+ KLASS& operator=(KLASS&&) = default; \
+ KLASS(KLASS&&) = default;
+
+#endif
+
+#define MUST_PASS(X) _rtl_assert(X, __FILE__)
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(X) \
+ (((sizeof(X) / sizeof(*(X))) / (static_cast<SizeT>(!(sizeof(X) % sizeof(*(X)))))))
+#endif
+
+#ifndef KIB
+#define KIB(X) (UInt64)((X) / 1024)
+#endif
+
+#ifndef kib_cast
+#define kib_cast(X) (UInt64)((X) *1024)
+#endif
+
+#ifndef MIB
+#define MIB(X) (UInt64)((UInt64) KIB(X) / 1024)
+#endif
+
+#ifndef mib_cast
+#define mib_cast(X) (UInt64)((UInt64) kib_cast(X) * 1024)
+#endif
+
+#ifndef GIB
+#define GIB(X) (UInt64)((UInt64) MIB(X) / 1024)
+#endif
+
+#ifndef gib_cast
+#define gib_cast(X) (UInt64)((UInt64) mib_cast(X) * 1024)
+#endif
+
+#ifndef TIB
+#define TIB(X) (UInt64)((UInt64) GIB(X) / 1024)
+#endif
+
+#ifndef tib_cast
+#define tib_cast(X) ((UInt64) gib_cast(X) * 1024)
+#endif
+
+#define LIBSYS_UNUSED(X) ((void) X)
+
+IMPORT_C void _rtl_assert(Bool expr, const Char* origin);
diff --git a/src/libSystem/SystemKit/Syscall.h b/src/libSystem/SystemKit/Syscall.h
new file mode 100644
index 00000000..58d7d7f1
--- /dev/null
+++ b/src/libSystem/SystemKit/Syscall.h
@@ -0,0 +1,21 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <libSystem/SystemKit/System.h>
+#include <cstdarg>
+
+IMPORT_C VoidPtr libsys_syscall_arg_1(SizeT id);
+IMPORT_C VoidPtr libsys_syscall_arg_2(SizeT id, VoidPtr arg1);
+IMPORT_C VoidPtr libsys_syscall_arg_3(SizeT id, VoidPtr arg1, VoidPtr arg3);
+IMPORT_C VoidPtr libsys_syscall_arg_4(SizeT id, VoidPtr arg1, VoidPtr arg3, VoidPtr arg4);
+
+IMPORT_C UInt64 libsys_hash_64(const Char* path);
+
+#ifndef SYSCALL_HASH
+#define SYSCALL_HASH(str) libsys_hash_64(str)
+#endif // !SYSCALL_HASH
diff --git a/src/libSystem/SystemKit/System.h b/src/libSystem/SystemKit/System.h
new file mode 100644
index 00000000..544b7ee3
--- /dev/null
+++ b/src/libSystem/SystemKit/System.h
@@ -0,0 +1,389 @@
+/* ========================================
+
+Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+File: System.h
+Purpose: System Call Interface.
+
+======================================== */
+
+#ifndef LIBSYS_SYSTEM_CALLS_H
+#define LIBSYS_SYSTEM_CALLS_H
+
+#include <libSystem/SystemKit/Macros.h>
+
+/// @brief TTY device path.
+#define kPrintDevicePath "/devices/tty{}"
+#define kCDDevicePath "/devices/dvd{}"
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Types API.
+// ------------------------------------------------------------------------------------------ //
+
+struct REF_TYPE {
+ UInt64 __hash; /// @brief Hash of the syscall
+ VoidPtr __self; /// @brief Syscall self value.
+};
+
+typedef REF_TYPE* Ref;
+
+typedef Ref IORef;
+typedef Ref FSRef;
+typedef Ref DylibRef;
+typedef Ref ThreadRef;
+typedef Ref SocketRef;
+typedef Ref NetworkRef;
+typedef Ref MutexRef;
+typedef Ref EventRef;
+typedef Ref SemaphoreRef;
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Dynamic Loader API.
+// ------------------------------------------------------------------------------------------ //
+
+/// @brief Get function which is part of the Dylib.
+/// @param symbol the symbol to look for
+/// @param dll_handle the Dylib handle.
+/// @return the proc pointer.
+IMPORT_C Ref LdrGetDylibSymbolFromHandle(_Input const Char* symbol, _Input Ref dll_handle);
+
+/// @brief Open Dylib handle.
+/// @param path dll path.
+/// @param drv driver letter.
+/// @return a dylib ref.
+IMPORT_C Ref LdrOpenDylibHandle(_Input const Char* path, _Input const Char* drive_letter);
+
+/// @brief Close Dylib handle
+/// @param dll_handle the dylib ref.
+/// @return whether it closed or not.
+IMPORT_C UInt32 LdrCloseDylibHandle(_Input Ref* dll_handle);
+
+// ------------------------------------------------------------------------------------------ //
+// File API.
+// ------------------------------------------------------------------------------------------ //
+
+/// @brief Opens a file from a drive.
+/// @param fs_path the filesystem path.
+/// @param drive_letter drive name, use NULL to use default drive location.
+/// @return the file descriptor of the file.
+IMPORT_C Ref IoOpenFile(const Char* fs_path, const Char* drive_letter);
+
+/// @brief Closes a file and flushes its content.
+/// @param file_desc the file descriptor.
+/// @return Function doesn't return a type.
+IMPORT_C Void IoCloseFile(_Input Ref file_desc);
+
+/// @brief I/O control (ioctl) on a file.
+/// @param file_desc the file descriptor.
+/// @param ioctl_code the ioctl code.
+/// @param in_data the input data.
+/// @param out_data the output data.
+/// @return the number of bytes written.
+/// @note This function is used to control the file descriptor, introduced for OpenHeFS.
+IMPORT_C SInt32 IoCtrlFile(_Input Ref file_desc, _Input UInt32 ioctl_code, _Input VoidPtr in_data,
+ _Output VoidPtr out_data);
+
+/// @brief Gets the file mime (if any)
+/// @param file_desc the file descriptor.
+IMPORT_C const Char* IoMimeFile(_Input Ref file_desc);
+
+/// @brief Gets the dir DIM.
+/// @param dir_desc directory descriptor.
+/// @note only works in OpenHeFS, will return nil-x/nil if used on any other filesystem.
+IMPORT_C const Char* IoDimFile(_Input Ref dir_desc);
+
+/// @brief Write data to a file ref
+/// @param file_desc the file descriptor.
+/// @param out_data the data to write.
+/// @param sz_data the size of the data to write.
+/// @return the number of bytes written.
+IMPORT_C UInt32 IoWriteFile(_Input Ref file_desc, _Output VoidPtr out_data, SizeT sz_data);
+
+/// @brief Read data from a file.
+/// @param file_desc the file descriptor.
+/// @param out_data the data to read.
+/// @param sz_data the size of the data to read.
+IMPORT_C UInt32 IoReadFile(_Input Ref file_desc, _Output VoidPtr* out_data, SizeT sz_data);
+
+/// @brief Rewind the file pointer to the beginning of the file.
+/// @param file_desc the file descriptor.
+/// @return the number of bytes read.
+IMPORT_C UInt64 IoRewindFile(_Input Ref file_desc);
+
+/// @brief Tell the current position of the file pointer.
+/// @param file_desc the file descriptor.
+/// @return the current position of the file pointer.
+IMPORT_C UInt64 IoTellFile(_Input Ref file_desc);
+
+/// @brief Seek file offset from file descriptor.
+IMPORT_C UInt64 IoSeekFile(_Input Ref file_desc, UInt64 file_offset);
+
+// ------------------------------------------------------------------------
+// Process API.
+// ------------------------------------------------------------------------
+
+/// @brief Spawns a Thread Information Block and Global Information Block inside the current
+/// process.
+/// @param process_id Target Process ID, must be valid.
+/// @return > 0 error occurred or already present, = 0 success.
+IMPORT_C UInt32 RtlSpawnIB(UIntPtr process_id);
+
+/// @brief Spawns a process with a unique pid (stored as UIntPtr).
+/// @param process_path process filesystem path.
+/// @return > 0 process was created.
+IMPORT_C UIntPtr RtlSpawnProcess(const Char* process_path, SizeT argc, Char** argv, Char** envp,
+ SizeT envp_len);
+
+/// @brief Exits a process with an exit_code.
+/// @return if it has succeeded true, otherwise false.
+IMPORT_C Bool RtlExitProcess(UIntPtr handle, UIntPtr exit_code);
+
+// ------------------------------------------------------------------------
+// Memory Manager API.
+// ------------------------------------------------------------------------
+
+/// @brief Creates a new heap from the process's address space.
+/// @param len the length of it.
+/// @param flags the flags of it.
+/// @return heap pointer.
+IMPORT_C VoidPtr MmCreateHeap(_Input SizeT len, _Input UInt32 flags);
+
+/// @brief Destroys the pointer
+/// @param heap the heap itself.
+/// @return void.
+IMPORT_C SInt32 MmDestroyHeap(_Input VoidPtr heap);
+
+/// @brief Change protection flags of a memory region.
+IMPORT_C SInt32 MmSetHeapFlags(_Input VoidPtr heap, _Input UInt32 flags);
+
+/// @brief Change protection flags of a memory region.
+IMPORT_C UInt32 MmGetHeapFlags(_Input VoidPtr heap);
+
+/// @brief Fill memory region with CRC32.
+IMPORT_C UInt32 MmFillCRC32Heap(_Input VoidPtr heap);
+
+/// @brief Copy memory region.
+IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len);
+
+/// @brief Compare memory regions.
+IMPORT_C SInt64 MmCmpMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len);
+
+/// @brief Fill memory region.
+IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt8 value);
+
+/// @brief Compare string regions.
+IMPORT_C SInt64 MmStrCmp(_Input const Char* dest, _Input const Char* src);
+
+/// @brief Get length of string.
+IMPORT_C SInt64 MmStrLen(const Char* str);
+
+// ------------------------------------------------------------------------
+// @brief Error API.
+// ------------------------------------------------------------------------
+
+IMPORT_C SInt32 ErrGetLastError(Void);
+
+// ------------------------------------------------------------------------
+// @brief Threading API.
+// ------------------------------------------------------------------------
+
+/// @brief Exit the current thread.
+/// @param exit_code the exit code.
+IMPORT_C SInt32 ThrExitCurrentThread(_Input SInt32 exit_code);
+
+/// @brief Exit the main thread.
+/// @param exit_code the exit code.
+IMPORT_C SInt32 ThrExitMainThread(_Input SInt32 exit_code);
+
+/// @brief Exit a thread.
+/// @param thread the thread to exit.
+/// @param exit_code the exit code.
+IMPORT_C SInt32 ThrExitThread(_Input ThreadRef thread, _Input SInt32 exit_code);
+
+/// @brief Thread procedure function type.
+typedef SInt32 (*ThrProcKind)(SInt32 argc, Char** argv);
+
+/// @brief Creates a thread.
+/// @param procedure the thread procedure.
+/// @param argument_count number of arguments inside that thread.
+/// @param flags Thread flags.
+/// @return the thread object.
+IMPORT_C ThreadRef ThrCreateThread(const Char* thread_name, ThrProcKind procedure,
+ SInt32 argument_count, SInt32 flags);
+
+/// @brief Yields the current thread.
+/// @param thread the thread to yield.
+IMPORT_C SInt32 ThrYieldThread(ThreadRef thrd);
+
+/// @brief Joins a thread.
+/// @param thread the thread to join.
+IMPORT_C SInt32 ThrJoinThread(ThreadRef thrd);
+
+/// @brief Detach a thread.
+/// @param thread the thread to detach.
+IMPORT_C SInt32 ThrDetachThread(ThreadRef thrd);
+
+// ------------------------------------------------------------------------
+// @brief Drive Management API.
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Get the default drive letter.
+/// @param void.
+/// @return the drive letter.
+// ------------------------------------------------------------------------------------------ //
+IMPORT_C Char* DrvGetDefaultDriveLetter(Void);
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Get the drive letter from a path.
+/// @param path the path.
+/// @return the drive letter.
+// ------------------------------------------------------------------------------------------ //
+IMPORT_C Char* DrvGetDriveLetterFromPath(_Input const Char* path);
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Get a mounted drive from a letter.
+/// @param letter the letter (A..Z).
+/// @return the drive object.
+// ------------------------------------------------------------------------------------------ //
+IMPORT_C Ref DrvGetMountedDrive(_Input Char letter);
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Mount a drive.
+/// @param path the path to mount.
+/// @param letter the letter to mount.
+// ------------------------------------------------------------------------------------------ //
+IMPORT_C Void DrvMountDrive(_Input const Char* path, _Input const Char* letter);
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Unmount a drive.
+/// @param letter the letter to unmount.
+// ------------------------------------------------------------------------------------------ //
+IMPORT_C Void DrvUnmountDrive(_Input Char letter);
+
+// ------------------------------------------------------------------------
+// Event handling API, use to listen to OS specific events.
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Add an event listener.
+/// @param event_name the event name.
+/// @param listener the listener to add.
+/// @return the event listener.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C Void EvtAddListener(_Input const Char* event_name, _Input Ref listener);
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Remove an event listener.
+/// @param event_name the event name.
+/// @param listener the listener to remove.
+/// @return the event listener.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C Void EvtRemoveListener(_Input const Char* event_name, _Input Ref listener);
+
+// ------------------------------------------------------------------------------------------ //
+/// @brief Dispatch an event.
+/// @param event_name the event name.
+/// @param event_data the event data.
+/// @return the event data.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C VoidPtr EvtDispatchEvent(_Input const Char* event_name, _Input VoidPtr event_data);
+
+// ------------------------------------------------------------------------------------------ //
+// Power API.
+// ------------------------------------------------------------------------------------------ //
+
+enum {
+ kPowerCodeInvalid = 0,
+ kPowerCodeShutdown = 12,
+ kPowerCodeReboot,
+ kPowerCodeSleep,
+ kPowerCodeWake,
+ kPowerCodeCount,
+};
+
+IMPORT_C SInt32 PwrReadCode(_Output SInt32& code);
+
+IMPORT_C SInt32 PwrSendCode(_Output SInt32& code);
+
+// ------------------------------------------------------------------------------------------ //
+// CD-ROM API.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C IORef CdOpenTray(Void);
+
+IMPORT_C SInt32 CdEjectDrive(_Input IORef cdrom);
+
+IMPORT_C SInt32 CdCloseTray(Void);
+
+// ------------------------------------------------------------------------------------------ //
+// TTY API.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C SInt32 PrintOut(IORef file /* nullptr to direct to stdout */, const Char* fmt, ...);
+
+IMPORT_C SInt32 PrintIn(IORef file /* nullptr to direct to stdout */, const Char* fmt, ...);
+
+IMPORT_C IORef PrintCreate(Void);
+
+IMPORT_C SInt32 PrintRelease(IORef);
+
+IMPORT_C IORef PrintGet(const Char* path);
+
+// ------------------------------------------------------------------------------------------ //
+// @brief Scheduler/Debug API.
+// ------------------------------------------------------------------------------------------ //
+
+typedef SInt32 AffinityRef;
+typedef UInt64 ProcessRef;
+
+IMPORT_C SInt32 SchedSetAffinity(_Input ProcessRef, SInt32 req, _Input AffinityRef*);
+
+IMPORT_C SInt32 SchedGetAffinity(_Input ProcessRef, _InOut AffinityRef*);
+
+IMPORT_C SInt32 SchedFireSignal(_Input ProcessRef, SInt32);
+
+IMPORT_C SInt32 SchedReadMemory(_Input ProcessRef, SInt32, SInt32);
+
+IMPORT_C SInt32 SchedWriteMemory(_Input ProcessRef, SInt32, SInt32);
+
+IMPORT_C UIntPtr SchedGetCurrentProcessID(Void);
+
+// ------------------------------------------------------------------------------------------ //
+// @brief Filesystem API.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C BOOL FsCopy(const Char* path, const Char* dst);
+
+IMPORT_C BOOL FsMove(const Char* path, const Char* dst);
+
+IMPORT_C BOOL FsExists(const Char* path);
+
+IMPORT_C BOOL FsCreateDir(const Char* path);
+
+IMPORT_C BOOL FsCreateFile(const Char* path);
+
+IMPORT_C BOOL FsCreateAlias(const Char* path, const Char* from);
+
+// ------------------------------------------------------------------------------------------ //
+// @brief Installable Filesystem API.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C BOOL IfsMount(const Char* path, const Char* drive_letter);
+
+IMPORT_C BOOL IfsUnmount(const Char* drive_letter);
+
+IMPORT_C BOOL IfsIsMounted(const Char* drive_letter);
+
+// ------------------------------------------------------------------------------------------ //
+// @brief String Manip API.
+// ------------------------------------------------------------------------------------------ //
+
+IMPORT_C Char* StrFmt(const Char* fmt, ...);
+
+IMPORT_C UInt64 StrMathToNumber(const Char* in, const Char** endp, const SInt16 base);
+
+#endif // ifndef LIBSYS_SYSTEM_CALLS_H
diff --git a/src/libSystem/SystemKit/Verify.h b/src/libSystem/SystemKit/Verify.h
new file mode 100644
index 00000000..7d15435a
--- /dev/null
+++ b/src/libSystem/SystemKit/Verify.h
@@ -0,0 +1,40 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: Verify.h
+ Purpose: System Call Interface Verification Layer.
+
+ ======================================== */
+
+#pragma once
+
+#include <libSystem/SystemKit/System.h>
+
+namespace LibSystem::Verify {
+/// @author 0xf00sec, and Amlal El Mahrouss
+/// @brief safe cast operator.
+template <typename T, typename R = VoidPtr>
+inline R sys_safe_cast(const T* ptr) {
+ _rtl_assert(ptr, "safe cast failed!");
+ return static_cast<R>(const_cast<T*>(ptr));
+}
+
+template <typename T, typename U>
+struct must_cast_traits {
+ constexpr static BOOL value = false;
+};
+
+template <typename T>
+struct must_cast_traits<T, T> {
+ constexpr static BOOL value = true;
+};
+
+/// @author Amlal El Mahrouss
+/// @brief Safe constexpr cast.
+template <typename T, typename R>
+inline constexpr R* sys_constexpr_cast(T* ptr) {
+ static_assert(must_cast_traits<T, R>::value, "constexpr cast failed! types are mismatching!");
+ return static_cast<R*>(ptr);
+}
+} // namespace LibSystem::Verify
diff --git a/src/libSystem/docs/SPECIFICATION_SYSCALLS.md b/src/libSystem/docs/SPECIFICATION_SYSCALLS.md
new file mode 100644
index 00000000..89f61498
--- /dev/null
+++ b/src/libSystem/docs/SPECIFICATION_SYSCALLS.md
@@ -0,0 +1,25 @@
+===================================
+# 0: General Information
+===================================
+
+- **Programming Language**: C / C++
+- **Build System**: Make / NeBuild
+- **Purpose**: System Call Interface (SCI) for NeKernel
+
+===================================
+# 1: How It Works
+===================================
+
+- This header provides the raw API surface for accessing NeKernel's system calls.
+
+- It is **not** directly used by applications.
+ - Instead, it is abstracted by the **SystemSDK**, which presents a stable, high-level interface.
+
+- At runtime:
+ - System calls are routed from user-space code to the **kernel syscall manager**.
+ - The syscall manager executes the requested operation and returns control to `libSystem`.
+ - Finally, the result is delivered back to the originating process.
+
+- This separation ensures that:
+ - The SCI remains low-level and close to the ABI.
+ - `SystemSDK` provides portability and shielding from changes in syscall internals. \ No newline at end of file
diff --git a/src/libSystem/libSystem.json b/src/libSystem/libSystem.json
new file mode 100644
index 00000000..9df1b8f0
--- /dev/null
+++ b/src/libSystem/libSystem.json
@@ -0,0 +1,20 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-g++",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "./"],
+ "sources_path": ["src/*.cc", "src/*.stub.obj"],
+ "output_name": "libSystem.dll",
+ "compiler_flags": [
+ "-ffreestanding",
+ "-shared",
+ "-fPIC",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17"
+ ],
+ "cpp_macros": [
+ "kLibSystemVersion=0x0100",
+ "kLibSystemVersionHighest=0x0100",
+ "kLibSystemVersionLowest=0x0100"
+ ]
+}
diff --git a/src/libSystem/obj/.keep b/src/libSystem/obj/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/libSystem/obj/.keep
diff --git a/src/libSystem/src/JailCalls.cc b/src/libSystem/src/JailCalls.cc
new file mode 100644
index 00000000..f7ca5bec
--- /dev/null
+++ b/src/libSystem/src/JailCalls.cc
@@ -0,0 +1,17 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <libSystem/SystemKit/Err.h>
+#include <libSystem/SystemKit/Jail.h>
+#include <libSystem/SystemKit/Syscall.h>
+#include <libSystem/SystemKit/System.h>
+#include <libSystem/SystemKit/Verify.h>
+
+using namespace LibSystem;
+
+IMPORT_C struct JAIL* JailGetCurrent(Void) {
+ return (struct JAIL*) libsys_syscall_arg_1(SYSCALL_HASH("JailGetCurrent"));
+} \ No newline at end of file
diff --git a/src/libSystem/src/Makefile b/src/libSystem/src/Makefile
new file mode 100644
index 00000000..622223b4
--- /dev/null
+++ b/src/libSystem/src/Makefile
@@ -0,0 +1,16 @@
+##################################################
+# (c) Amlal El Mahrouss and NeKernel contributors, licensed under the Apache 2.0 license.
+# This file is for libSystem.dll's syscall stubs.
+##################################################
+
+ASM=nasm
+FLAGS=-f win64
+
+.PHONY: error
+error:
+ @echo "==> Invalid recipe."
+ @echo "==> Use libsys_asm_io_<arch> instead."
+
+.PHONY: libsys_asm_io_x64
+libsys_asm_io_x64:
+ $(ASM) $(FLAGS) SystemCallsABI+AMD64.asm -o SystemCallsABI+AMD64.stub.obj
diff --git a/src/libSystem/src/SystemCalls.cc b/src/libSystem/src/SystemCalls.cc
new file mode 100644
index 00000000..7409c9b7
--- /dev/null
+++ b/src/libSystem/src/SystemCalls.cc
@@ -0,0 +1,169 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <libSystem/SystemKit/Err.h>
+#include <libSystem/SystemKit/Syscall.h>
+#include <libSystem/SystemKit/System.h>
+#include <libSystem/SystemKit/Verify.h>
+
+using namespace LibSystem;
+
+IMPORT_C Char* StrFmt(const Char* fmt, ...) {
+ if (!fmt || *fmt == 0) return const_cast<Char*>("(null)");
+
+ return const_cast<Char*>("");
+}
+
+// memmove-style copy
+IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len) {
+ // handles overlap, prefers 64-bit word copies when aligned
+ if (!len || !dest || !src) return nullptr;
+
+ auto s = static_cast<const UInt8*>(src);
+ auto d = static_cast<UInt8*>(dest);
+
+ if (d == s) return dest;
+
+ // decide direction
+ if (d > s && d < s + len) {
+ const UInt8* rs = s + len;
+ UInt8* rd = d + len;
+
+ // try 64-bit aligned backward copy
+ if (len >= sizeof(UInt64) && (reinterpret_cast<UIntPtr>(rs) % sizeof(UInt64) == 0) &&
+ (reinterpret_cast<UIntPtr>(rd) % sizeof(UInt64) == 0)) {
+ auto rsw = reinterpret_cast<const UInt64*>(rs);
+ auto rdw = reinterpret_cast<UInt64*>(rd);
+
+ SizeT words = len / sizeof(UInt64);
+
+ for (SizeT i = 0; i < words; ++i) {
+ rdw[-1 - static_cast<SizeT>(i)] = rsw[-1 - static_cast<SizeT>(i)];
+ }
+
+ SizeT rem = len % sizeof(UInt64);
+ for (SizeT i = 0; i < rem; ++i) {
+ rd[-1 - i] = rs[-1 - i];
+ }
+ } else {
+ // byte-wise backward
+ for (SizeT i = 0; i < len; ++i) {
+ rd[-1 - i] = rs[-1 - i];
+ }
+ }
+ } else {
+ // try 64-bit aligned forward copy
+ if (len >= sizeof(UInt64) && (reinterpret_cast<UIntPtr>(s) % sizeof(UInt64) == 0) &&
+ (reinterpret_cast<UIntPtr>(d) % sizeof(UInt64) == 0)) {
+ auto sw = reinterpret_cast<const UInt64*>(s);
+ auto dw = reinterpret_cast<UInt64*>(d);
+ SizeT words = len / sizeof(UInt64);
+
+ for (SizeT i = 0; i < words; ++i) {
+ dw[i] = sw[i];
+ }
+
+ SizeT rem = len % sizeof(UInt64);
+ const SizeT offset = words * sizeof(UInt64);
+ for (SizeT i = 0; i < rem; ++i) {
+ d[offset + i] = s[offset + i];
+ }
+ } else {
+ for (SizeT i = 0; i < len; ++i) {
+ d[i] = s[i];
+ }
+ }
+ }
+
+ return dest;
+}
+
+IMPORT_C SInt64 MmStrLen(const Char* in) {
+ // strlen via pointer walk
+ if (!in) return -kErrorInvalidData;
+
+ const Char* p = in;
+ while (*p) ++p;
+
+ return static_cast<SInt64>(p - in);
+}
+
+IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt8 value) {
+ if (!len || !dest) return nullptr;
+
+ auto d = static_cast<UInt8*>(dest);
+
+ if (len >= sizeof(UInt64) && (reinterpret_cast<UIntPtr>(d) % sizeof(UInt64)) == 0) {
+ UInt64 pattern = static_cast<UInt64>(value);
+ pattern |= (pattern << 8);
+ pattern |= (pattern << 16);
+ pattern |= (pattern << 32);
+
+ auto dw = reinterpret_cast<UInt64*>(d);
+ SizeT words = len / sizeof(UInt64);
+
+ for (SizeT i = 0; i < words; ++i) {
+ dw[i] = pattern;
+ }
+
+ SizeT rem = len % sizeof(UInt64);
+ const SizeT offset = words * sizeof(UInt64);
+ for (SizeT i = 0; i < rem; ++i) {
+ d[offset + i] = value;
+ }
+ } else {
+ for (SizeT i = 0; i < len; ++i) d[i] = value;
+ }
+
+ return dest;
+}
+
+IMPORT_C Ref IoOpenFile(_Input const Char* path, _Input const Char* drv_letter) {
+ return static_cast<Ref>(libsys_syscall_arg_3(
+ SYSCALL_HASH("IoOpenFile"), Verify::sys_safe_cast(path), Verify::sys_safe_cast(drv_letter)));
+}
+
+IMPORT_C Void IoCloseFile(_Input Ref desc) {
+ libsys_syscall_arg_2(SYSCALL_HASH("IoCloseFile"), static_cast<VoidPtr>(desc));
+}
+
+IMPORT_C UInt64 IoSeekFile(_Input Ref desc, _Input UInt64 off) {
+ auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("IoSeekFile"), static_cast<VoidPtr>(desc),
+ reinterpret_cast<VoidPtr>(&off));
+
+ if (!ret_ptr) return ~0UL;
+
+ auto ret = static_cast<volatile UInt64*>(ret_ptr);
+ UInt64 result = *ret;
+ MUST_PASS(result != ~0UL);
+ return result;
+}
+
+IMPORT_C UInt64 IoTellFile(_Input Ref desc) {
+ auto ret_ptr = libsys_syscall_arg_2(SYSCALL_HASH("IoTellFile"), static_cast<VoidPtr>(desc));
+ if (!ret_ptr) return ~0UL;
+ auto ret = static_cast<volatile UInt64*>(ret_ptr);
+ return *ret;
+}
+
+IMPORT_C SInt32 PrintOut(_Input IORef desc, const Char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+
+ auto buf = StrFmt(fmt, args);
+
+ va_end(args);
+
+ // if truncated, `needed` >= kBufferSz; we still send truncated buffer
+ auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("PrintOut"), static_cast<VoidPtr>(desc),
+ Verify::sys_safe_cast(buf));
+
+ if (!ret_ptr) return -kErrorInvalidData;
+
+ auto ret = static_cast<const volatile SInt32*>(ret_ptr);
+
+ return *ret;
+}
diff --git a/src/libSystem/src/SystemCallsABI+AMD64.asm b/src/libSystem/src/SystemCallsABI+AMD64.asm
new file mode 100644
index 00000000..dd8fc9e8
--- /dev/null
+++ b/src/libSystem/src/SystemCallsABI+AMD64.asm
@@ -0,0 +1,81 @@
+;; /*
+;; * ========================================================
+;; *
+;; * libSystem/src/SystemCallsABI+AMD64.asm
+;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+[bits 64]
+
+section .text
+
+global libsys_syscall_arg_1
+global libsys_syscall_arg_2
+global libsys_syscall_arg_3
+global libsys_syscall_arg_4
+
+libsys_syscall_arg_1:
+ push rbp
+ mov rbp, rsp
+
+ mov r8, rcx
+
+ xor rax, rax
+
+ syscall
+
+ pop rbp
+
+ ret
+
+libsys_syscall_arg_2:
+ push rbp
+ mov rbp, rsp
+
+ mov r8, rcx
+ mov r9, rdx
+
+ xor rax, rax
+
+ syscall
+
+ pop rbp
+
+ ret
+
+libsys_syscall_arg_3:
+ push rbp
+ mov rbp, rsp
+
+ mov r8, rcx
+ mov r9, rdx
+ mov r10, rbx
+
+ xor rax, rax
+
+ syscall
+
+ pop rbp
+
+ ret
+
+libsys_syscall_arg_4:
+ push rbp
+ mov rbp, rsp
+
+ mov rax, r8
+
+ mov r8, rcx
+ mov r9, rdx
+ mov r10, rbx
+ mov r11, rax
+
+ xor rax, rax
+
+ syscall
+
+ pop rbp
+
+ ret
diff --git a/src/libSystem/src/Utils.cc b/src/libSystem/src/Utils.cc
new file mode 100644
index 00000000..9d0920e0
--- /dev/null
+++ b/src/libSystem/src/Utils.cc
@@ -0,0 +1,29 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <libSystem/SystemKit/Err.h>
+#include <libSystem/SystemKit/Syscall.h>
+#include <libSystem/SystemKit/System.h>
+#include <libSystem/SystemKit/Verify.h>
+
+using namespace LibSystem;
+
+/// @note This uses the FNV 64-bit variant.
+IMPORT_C UInt64 libsys_hash_64(const Char* path) {
+ if (!path || *path == 0) return 0;
+
+ const UInt64 kFNVSeed = 0xcbf29ce484222325ULL;
+ const UInt64 kFNVPrime = 0x100000001b3ULL;
+
+ UInt64 hash = kFNVSeed;
+
+ while (*path) {
+ hash ^= (Char) (*path++);
+ hash *= kFNVPrime;
+ }
+
+ return hash;
+}
diff --git a/src/libSystem/src/VerifyCalls.cc b/src/libSystem/src/VerifyCalls.cc
new file mode 100644
index 00000000..1c00612f
--- /dev/null
+++ b/src/libSystem/src/VerifyCalls.cc
@@ -0,0 +1,18 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <libSystem/SystemKit/Err.h>
+#include <libSystem/SystemKit/Syscall.h>
+#include <libSystem/SystemKit/Verify.h>
+
+using namespace LibSystem;
+
+IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) {
+ if (!expr) {
+ PrintOut(nullptr, "Assertion failed: %s\r", origin);
+ libsys_syscall_arg_1(SYSCALL_HASH("_rtl_debug_break"));
+ }
+} \ No newline at end of file
diff --git a/src/misc/.keep b/src/misc/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/misc/.keep
diff --git a/src/misc/BenchKit/Chronometer.h b/src/misc/BenchKit/Chronometer.h
new file mode 100644
index 00000000..8a1fa3ab
--- /dev/null
+++ b/src/misc/BenchKit/Chronometer.h
@@ -0,0 +1,40 @@
+/* ========================================
+
+Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef BENCHKIT_CHRONO_H
+#define BENCHKIT_CHRONO_H
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+
+/// @author Amlal El Mahrouss
+/// @brief BenchKit Chrono contract.
+
+#define BENCHKIT_INTERFACE : public ::Kernel::ChronoInterface
+
+namespace Kernel {
+class ChronoInterface;
+
+/// @brief a Chronometer interface used for benchmarking.
+class ChronoInterface {
+ public:
+ ChronoInterface() = default;
+ virtual ~ChronoInterface() = default;
+
+ NE_COPY_DEFAULT(ChronoInterface)
+
+ virtual Void Start() = 0;
+ virtual Void Stop() = 0;
+ virtual Void Reset() = 0;
+ virtual UInt64 GetElapsedTime() const = 0;
+};
+} // namespace Kernel
+
+namespace BenchKit {
+using namespace Kernel;
+}
+
+#endif // BENCHKIT_CHRONO_H
diff --git a/src/misc/BenchKit/HWChronometer.h b/src/misc/BenchKit/HWChronometer.h
new file mode 100644
index 00000000..331f9a7d
--- /dev/null
+++ b/src/misc/BenchKit/HWChronometer.h
@@ -0,0 +1,66 @@
+/* ========================================
+
+Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <misc/BenchKit/Chronometer.h>
+
+namespace Kernel {
+struct HWChronoTraits;
+
+template <typename ChronoTraits = HWChronoTraits>
+class HWChrono;
+
+/// @brief BenchKit chrono logic for x64/ARM64.
+struct HWChronoTraits final {
+ private:
+ STATIC UInt64 TickImpl_(void) {
+#ifdef __NE_AMD64__
+ UInt64 a = 0, d = 0;
+
+ asm volatile("rdtsc" : "=a"(a), "=d"(d));
+
+ return (d << 32) | a;
+#elif defined(__NE_ARM64__)
+ UInt64 result;
+
+ asm volatile("mrs %0, cntvct_el1" : "=r"(result));
+
+ return result;
+#else
+#error !!! no backend defined !!!
+#endif
+ }
+
+ friend HWChrono<HWChronoTraits>;
+};
+
+/// @brief hardware chronometer implementation using a trait to extract the data.
+template <typename ChronoTraits>
+class HWChrono BENCHKIT_INTERFACE {
+ public:
+ HWChrono() = default;
+ virtual ~HWChrono() override = default;
+
+ NE_COPY_DEFAULT(HWChrono)
+
+ public:
+ Void Start() override { fStart = ChronoTraits::TickImpl_(); }
+
+ Void Stop() override { fStop = ChronoTraits::TickImpl_(); }
+
+ Void Reset() override {
+ fStart = 0;
+ fStop = 0;
+ }
+
+ UInt64 GetElapsedTime() const override { return fStop - fStart; }
+
+ private:
+ UInt64 fStart{};
+ UInt64 fStop{};
+};
+} // namespace Kernel
diff --git a/src/modules/ACPI/ACPI.h b/src/modules/ACPI/ACPI.h
new file mode 100644
index 00000000..b5bf3b69
--- /dev/null
+++ b/src/modules/ACPI/ACPI.h
@@ -0,0 +1,83 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __ACPI__
+#define __ACPI__
+
+/**
+ https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html
+*/
+
+#include <NeKit/Defines.h>
+
+#define SDT_OBJECT : public Kernel::SDT
+
+namespace Kernel {
+class PACKED SDT {
+ public:
+ Char Signature[4];
+ UInt32 Length;
+ UInt8 Revision;
+ Char Checksum;
+ Char OemId[6];
+ Char OemTableId[8];
+ UInt32 OemRev;
+ UInt32 CreatorID;
+ UInt32 CreatorRevision;
+};
+
+class PACKED RSDP : public SDT {
+ public:
+ UInt32 RsdtAddress;
+ UIntPtr XsdtAddress;
+ UInt8 ExtendedChecksum;
+ UInt8 Reserved0[3];
+};
+
+class PACKED ConfigHeader {
+ public:
+ UInt64 BaseAddress;
+ UInt16 PciSegGroup;
+ UInt8 StartBus;
+ UInt8 EndBus;
+ UInt32 Reserved;
+};
+
+enum ACPI_ADDRESS_SPACE_KIND : UInt8 {
+ eSystemMemory = 0,
+ eSystemIO = 1,
+ ePci = 2,
+ eController = 3,
+ eSmBus = 4,
+ eCount = 5,
+ eInvalid = 0xFF,
+};
+
+class PACKED ACPI_ADDRESS final {
+ public:
+ UInt8 AddressSpaceId;
+ UInt8 RegisterBitWidth;
+ UInt8 RegisterBitOffset;
+ UInt8 Reserved;
+ UIntPtr Address;
+};
+
+class PACKED RSDT final {
+ public:
+ Char Signature[4];
+ UInt32 Length;
+ UInt8 Revision;
+ Char Checksum;
+ Char OemId[6];
+ Char OemTableId[8];
+ UInt32 OemRev;
+ UInt32 CreatorID;
+ UInt32 CreatorRevision;
+ UInt32 AddressArr[1];
+};
+} // namespace Kernel
+
+#endif // !__ACPI__
diff --git a/src/modules/ACPI/ACPIFactoryInterface.h b/src/modules/ACPI/ACPIFactoryInterface.h
new file mode 100644
index 00000000..da91a62e
--- /dev/null
+++ b/src/modules/ACPI/ACPIFactoryInterface.h
@@ -0,0 +1,57 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef __MOD_ACPI_H__
+#define __MOD_ACPI_H__
+
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/Ref.h>
+#include <modules/ACPI/ACPI.h>
+#include <modules/Power/PowerFactory.h>
+
+namespace Kernel {
+class PowerFactory;
+class ACPIFactoryInterface;
+
+typedef ACPIFactoryInterface PowerFactoryInterface;
+
+class ACPIFactoryInterface final NE_POWER_FACTORY {
+ public:
+ explicit ACPIFactoryInterface(voidPtr rsp_ptr);
+ ~ACPIFactoryInterface() = default;
+
+ ACPIFactoryInterface& operator=(const ACPIFactoryInterface&) = default;
+ ACPIFactoryInterface(const ACPIFactoryInterface&) = default;
+
+ public:
+ Bool Shutdown(); // shutdown
+ Void Reboot(); // soft-reboot
+
+ public:
+ /// @brief Descriptor find factory.
+ /// @param signature The signature of the descriptor table (MADT, ACPI...)
+ /// @return the blob inside an ErrorOr object.
+ ErrorOr<voidPtr> Find(const Char* signature);
+
+ /// @brief Checksum factory.
+ /// @param checksum the data to checksum
+ /// @param len it's size
+ /// @return if it succeed
+ bool Checksum(const Char* checksum, SSizeT len); // watch for collides!
+
+ public:
+ ErrorOr<voidPtr> operator[](const Char* signature);
+
+ private:
+ VoidPtr fRsdp{nullptr}; // pointer to root descriptor.
+ SizeT fEntries{0UL}; // number of entries, -1 tells that no invalid entries were
+ // found.
+};
+} // namespace Kernel
+
+#endif // !__MOD_ACPI_H__
diff --git a/src/modules/AHCI/AHCI.h b/src/modules/AHCI/AHCI.h
new file mode 100644
index 00000000..3c6fecc5
--- /dev/null
+++ b/src/modules/AHCI/AHCI.h
@@ -0,0 +1,360 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: AHCI.h
+ Purpose: AHCI protocol defines.
+
+ Revision History:
+
+ 03/02/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <modules/ACPI/ACPI.h>
+
+/// @file AHCI.h
+/// @brief AHCI support.
+
+#define kAHCISectorSize (512)
+
+struct HbaPort;
+struct FisData;
+struct FisRegD2H;
+struct FisRegH2D;
+
+/// @brief Frame information type.
+enum {
+ kFISTypeRegH2D = 0x27, // Register FIS - host to device
+ kFISTypeRegD2H = 0x34, // Register FIS - device to host
+ kFISTypeDMAAct = 0x39, // DMA activate FIS - device to host
+ kFISTypeDMASetup = 0x41, // DMA setup FIS - bidirectional
+ kFISTypeData = 0x46, // Data FIS - bidirectional
+ kFISTypeBIST = 0x58, // BIST activate FIS - bidirectional
+ kFISTypePIOSetup = 0x5F, // PIO setup FIS - device to host
+ kFISTypeDevBits = 0xA1, // Set device bits FIS - device to host
+};
+
+enum {
+ kAHCICmdIdentify = 0xEC,
+ kAHCICmdReadDma = 0xC8,
+ kAHCICmdReadDmaEx = 0x25,
+ kAHCICmdWriteDma = 0xCA,
+ kAHCICmdWriteDmaEx = 0x35
+};
+
+typedef struct FisRegH2D final {
+ // DWORD 0
+ Kernel::UInt8 FisType; // FIS_TYPE_REG_H2D
+
+ Kernel::UInt8 PortMul : 4; // Port multiplier
+ Kernel::UInt8 Reserved0 : 3; // Reserved
+ Kernel::UInt8 CmdOrCtrl : 1; // 1: Command, 0: Control
+
+ Kernel::UInt8 Command; // Command register
+ Kernel::UInt8 FeatureLow; // Feature register, 7:0
+
+ // DWORD 1
+ Kernel::UInt8 Lba0; // LBA low register, 7:0
+ Kernel::UInt8 Lba1; // LBA mid register, 15:8
+ Kernel::UInt8 Lba2; // LBA high register, 23:16
+ Kernel::UInt8 Device; // Device register
+
+ // DWORD 2
+ Kernel::UInt8 Lba3; // LBA register, 31:24
+ Kernel::UInt8 Lba4; // LBA register, 39:32
+ Kernel::UInt8 Lba5; // LBA register, 47:40
+ Kernel::UInt8 FeatureHigh; // Feature register, 15:8
+
+ // DWORD 3
+ Kernel::UInt8 CountLow; // Count register, 7:0
+ Kernel::UInt8 CountHigh; // Count register, 15:8
+ Kernel::UInt8 Icc; // Isochronous command completion
+ Kernel::UInt8 Control; // Control register
+
+ // DWORD 4
+ Kernel::UInt8 Reserved1[4]; // Reserved
+} FisRegH2D;
+
+typedef struct FisRegD2H final {
+ // DWORD 0
+ Kernel::UInt8 FisType; // FIS_TYPE_REG_D2H
+
+ Kernel::UInt8 PortMul : 4; // Port multiplier
+ Kernel::UInt8 Reserved0 : 2; // Reserved
+ Kernel::UInt8 IE : 1; // Interrupt bit
+ Kernel::UInt8 Reserved1 : 1; // Reserved
+
+ Kernel::UInt8 Status; // Status register
+ Kernel::UInt8 Error; // Error register
+
+ // DWORD 1
+ Kernel::UInt8 Lba0; // LBA low register, 7:0
+ Kernel::UInt8 Lba1; // LBA mid register, 15:8
+ Kernel::UInt8 Lba2; // LBA high register, 23:16
+ Kernel::UInt8 Device; // Device register
+
+ // DWORD 2
+ Kernel::UInt8 Lba3; // LBA register, 31:24
+ Kernel::UInt8 Lba4; // LBA register, 39:32
+ Kernel::UInt8 Lba5; // LBA register, 47:40
+ Kernel::UInt8 Rsv2; // Reserved
+
+ // DWORD 3
+ Kernel::UInt8 CountLow; // Count register, 7:0
+ Kernel::UInt8 CountHigh; // Count register, 15:8
+ Kernel::UInt8 Rsv3[2]; // Reserved
+
+ // DWORD 4
+ Kernel::UInt8 Rsv4[4]; // Reserved
+} FisRegD2H;
+
+typedef struct FisData final {
+ // DWORD 0
+ Kernel::UInt8 FisType; // FIS_TYPE_DATA
+
+ Kernel::UInt8 PortMul : 4; // Port multiplier
+ Kernel::UInt8 Reserved0 : 4; // Reserved
+
+ Kernel::UInt8 Reserved1[2]; // Reserved
+
+ // DWORD 1 ~ N
+ Kernel::UInt32 Data[1]; // Payload
+} FisData;
+
+typedef struct FisPioSetup final {
+ // DWORD 0
+ Kernel::UInt8 FisType; // FIS_TYPE_PIO_SETUP
+
+ Kernel::UInt8 PortMul : 4; // Port multiplier
+ Kernel::UInt8 Reserved0 : 1; // Reserved
+ Kernel::UInt8 DTD : 1; // Data transfer direction, 1 - device to host
+ Kernel::UInt8 IE : 1; // Interrupt bit
+ Kernel::UInt8 Reserved1 : 1;
+
+ Kernel::UInt8 Status; // Status register
+ Kernel::UInt8 Error; // Error register
+
+ // DWORD 1
+ Kernel::UInt8 Lba0; // LBA low register, 7:0
+ Kernel::UInt8 Lba1; // LBA mid register, 15:8
+ Kernel::UInt8 Lba2; // LBA high register, 23:16
+ Kernel::UInt8 Device; // Device register
+
+ // DWORD 2
+ Kernel::UInt8 Lba3; // LBA register, 31:24
+ Kernel::UInt8 Lba4; // LBA register, 39:32
+ Kernel::UInt8 Lba5; // LBA register, 47:40
+ Kernel::UInt8 Rsv2; // Reserved
+
+ // DWORD 3
+ Kernel::UInt8 CountLow; // Count register, 7:0
+ Kernel::UInt8 CountHigh; // Count register, 15:8
+ Kernel::UInt8 Rsv3; // Reserved
+ Kernel::UInt8 EStatus; // New value of status register
+
+ // DWORD 4
+ Kernel::UInt16 TranferCount; // Transfer count
+ Kernel::UInt8 Rsv4[2]; // Reserved
+} FisPioSetup;
+
+typedef struct FisDmaSetup final {
+ // DWORD 0
+ Kernel::UInt8 FisType; // FIS_TYPE_DMA_SETUP
+
+ Kernel::UInt8 PortMul : 4; // Port multiplier
+ Kernel::UInt8 Reserved0 : 1; // Reserved
+ Kernel::UInt8 DTD : 1; // Data transfer direction, 1 - device to host
+ Kernel::UInt8 IE : 1; // Interrupt bit
+ Kernel::UInt8 AutoEnable : 1; // Auto-activate. Specifies if DMA Activate FIS is needed
+
+ Kernel::UInt8 Reserved1[2]; // Reserved
+
+ // DWORD 1&2
+ volatile Kernel::UInt64 DmaBufferId; // DMA Buffer Identifier. Used to Identify DMA buffer in
+ // host memory. SATA Spec says host specific and not in
+ // Spec. Trying AHCI spec might work.
+
+ // DWORD 3
+ Kernel::UInt32 Rsvd; // More reserved
+
+ // DWORD 4
+ Kernel::UInt32 DmabufOffset; // Byte offset into buffer. First 2 bits must be 0
+
+ // DWORD 5
+ Kernel::UInt32 TransferCount; // Number of bytes to transfer. Bit 0 must be 0
+
+ // DWORD 6
+ Kernel::UInt32 Reserved3; // Reserved
+} FisDmaSetup;
+
+typedef struct FisDevBits final {
+ // DWORD 0
+ Kernel::UInt8 FisType; // FIS_TYPE_DMA_SETUP (A1h)
+
+ Kernel::UInt8 Reserved0 : 5; // Reserved
+ Kernel::UInt8 R0 : 1;
+ Kernel::UInt8 IE : 1;
+ Kernel::UInt8 N : 1;
+
+ Kernel::UInt8 StatusLow : 3;
+ Kernel::UInt8 R1 : 1;
+ Kernel::UInt8 StatusHigh : 3;
+
+ Kernel::UInt8 R2 : 1;
+ Kernel::UInt8 Error;
+
+ // DWORD 1
+ Kernel::UInt32 Act;
+} FisDevBits;
+
+/// \brief Enable AHCI device bit in GHC register.
+#ifndef kSATAGHC_AE
+#define kSATAGHC_AE (31)
+#endif //! ifndef kSATAGHC_AE
+
+typedef struct HbaPort final {
+ Kernel::UInt32 Clb; // 0x00, command list base address, 1K-byte aligned
+ Kernel::UInt32 Clbu; // 0x04, command list base address upper 32 bits
+ Kernel::UInt32 Fb; // 0x08, FIS base address, 256-byte aligned
+ Kernel::UInt32 Fbu; // 0x0C, FIS base address upper 32 bits
+ Kernel::UInt32 Is; // 0x10, interrupt status
+ Kernel::UInt32 Ie; // 0x14, interrupt enable
+ Kernel::UInt32 Cmd; // 0x18, command and status
+ Kernel::UInt32 Reserved0; // 0x1C, Reserved
+ Kernel::UInt32 Tfd; // 0x20, task file data
+ Kernel::UInt32 Sig; // 0x24, signature
+ Kernel::UInt32 Ssts; // 0x28, SATA status (SCR0:SStatus)
+ Kernel::UInt32 Sctl; // 0x2C, SATA control (SCR2:SControl)
+ Kernel::UInt32 Serr; // 0x30, SATA error (SCR1:SError)
+ Kernel::UInt32 Sact; // 0x34, SATA active (SCR3:SActive)
+ Kernel::UInt32 Ci; // 0x38, command issue
+ Kernel::UInt32 Sntf; // 0x3C, SATA notification (SCR4:SNotification)
+ Kernel::UInt32 Fbs; // 0x40, FIS-based switch control
+ Kernel::UInt32 Reserved1[11]; // 0x44 ~ 0x6F, Reserved
+ Kernel::UInt32 Vendor[4]; // 0x70 ~ 0x7F, vendor specific
+} HbaPort;
+
+typedef struct HbaMem final {
+ // 0x00 - 0x2B, Generic Host Control
+ Kernel::UInt32 Cap; // 0x00, Host capability
+ Kernel::UInt32 Ghc; // 0x04, Global host control
+ Kernel::UInt32 Is; // 0x08, Interrupt status
+ Kernel::UInt32 Pi; // 0x0C, Port implemented
+ Kernel::UInt32 Vs; // 0x10, Version
+ Kernel::UInt32 Ccc_ctl; // 0x14, Command completion coalescing control
+ Kernel::UInt32 Ccc_pts; // 0x18, Command completion coalescing ports
+ Kernel::UInt32 Em_loc; // 0x1C, Enclosure management location
+ Kernel::UInt32 Em_ctl; // 0x20, Enclosure management control
+ Kernel::UInt32 Cap2; // 0x24, Host capabilities extended
+ Kernel::UInt32 Bohc; // 0x28, BIOS/OS handoff control and status
+
+ Kernel::UInt8 Resv0[0xA0 - 0x2C];
+ Kernel::UInt8 Vendor[0x100 - 0xA0];
+
+ HbaPort Ports[1]; // 1 ~ 32, 32 is the max ahci devices per controller.
+} HbaMem;
+
+typedef HbaMem* HbaMemRef;
+
+typedef struct HbaCmdHeader final {
+ // DW0
+ union HbaFlags {
+ struct HbaFlags_ {
+ Kernel::UInt8 Cfl : 5; // Command FIS length in DWORDS, 2 ~ 16
+ Kernel::UInt8 Atapi : 1; // ATAPI
+ Kernel::UInt8 Write : 1; // Write, 1: H2D, 0: D2H
+ Kernel::UInt8 Prefetchable : 1; // Prefetchable
+
+ Kernel::UInt8 Reset : 1; // Reset
+ Kernel::UInt8 BIST : 1; // BIST
+ Kernel::UInt8 Clear : 1; // Clear busy upon R_OK
+ Kernel::UInt8 Reserved0 : 1; // Reserved
+ Kernel::UInt8 Pmp : 4; // Port multiplier port
+ } Struct;
+
+ Kernel::UInt16 Flags;
+ } HbaFlags;
+
+ Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries
+ Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred
+
+ Kernel::UInt32 Ctba; // Command table descriptor base address
+ Kernel::UInt32 Ctbau; // Command table descriptor base address upper 32 bits
+
+ Kernel::UInt32 Rsv[4];
+} ATTRIBUTE(packed, aligned(32)) HbaCmdHeader;
+
+typedef struct HbaFis final {
+ // 0x00
+ FisDmaSetup Dsfis; // DMA Setup FIS
+ Kernel::UInt8 Pad0[4];
+ // 0x20
+ FisPioSetup Psfis; // PIO Setup FIS
+ Kernel::UInt8 Pad1[12];
+ // 0x40
+ FisRegD2H Rfis; // Register – Device to Host FIS
+ Kernel::UInt8 Pad2[4];
+ // 0x58
+ FisDevBits Sdbfis; // Set Device Bit FIS
+ // 0x60
+ Kernel::UInt8 Ufis[64];
+ // 0xA0
+ Kernel::UInt8 Rsv[0x100 - 0xA0];
+} HbaFis;
+
+typedef struct HbaPrdtEntry final {
+ Kernel::UInt32 Dba; // Data base address
+ Kernel::UInt32 Dbau; // Data base address upper 32 bits
+ Kernel::UInt32 Reserved0; // Reserved
+ // DW3
+ Kernel::UInt32 Dbc : 22; // Byte count, 4M max
+ Kernel::UInt32 Reserved1 : 9; // Reserved
+ Kernel::UInt32 Ie : 1; // Interrupt on completion
+} HbaPrdtEntry;
+
+typedef struct HbaCmdTbl final {
+ Kernel::UInt8 Cfis[64]; // Command FIS
+ Kernel::UInt8 Acmd[16]; // ATAPI command, 12 or 16 bytes
+ Kernel::UInt8 Rsv[48]; // Reserved
+ struct HbaPrdtEntry Prdt[1]; // Physical region descriptor table entries, 0 ~ 65535
+} HbaCmdTbl;
+
+/// @brief Initializes an AHCI disk.
+/// @param PortsImplemented the amount of port that have been detected.
+/// @return
+Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented);
+
+Kernel::Boolean drv_std_detected(Kernel::Void);
+
+/// @brief Read from AHCI disk.
+/// @param lba
+/// @param buf
+/// @param sector_sz
+/// @param buf_sz
+/// @return
+Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buf, Kernel::SizeT sector_sz,
+ Kernel::SizeT buf_sz);
+
+/// @brief Write to AHCI disk.
+/// @param lba
+/// @param buf
+/// @param sector_sz
+/// @param buf_sz
+/// @return
+Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buf, Kernel::SizeT sector_sz,
+ Kernel::SizeT buf_sz);
+
+/// @brief Gets the sector count from AHCI disk.
+Kernel::SizeT drv_std_get_sector_count();
+
+/// @brief Gets the AHCI disk size.
+Kernel::SizeT drv_std_get_size();
+
+/// @brief Checks if the drive has completed the command.
+Kernel::Bool drv_is_ready(void);
+
+/* EOF */
diff --git a/src/modules/APM/APM.h b/src/modules/APM/APM.h
new file mode 100644
index 00000000..d9b0621e
--- /dev/null
+++ b/src/modules/APM/APM.h
@@ -0,0 +1,29 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+namespace Kernel {
+typedef Int32 APMPowerCmd;
+
+enum {
+ kAPMPowerCommandInvalid = 0x00,
+ kAPMPowerCommandStop = 0x01,
+ kAPMPowerCommandStart = 0x02,
+ kAPMPowerCommandSleep = 0x04,
+ kAPMPowerCommandWakeup = 0x06,
+ kAPMPowerCommandShutdown = 0x07,
+ kAPMPowerCommandReboot = 0x08,
+};
+
+/// @brief Send a APM command into it's controller. (Shutdown, Reboot, Sleep...)
+/// @param base_dma the IO base port.
+/// @param cmd the command.
+/// @return status code of the APM command.
+EXTERN_C Int32 apm_send_io_command(UInt16 cmd);
+} // namespace Kernel
diff --git a/src/modules/ATA/ATA.h b/src/modules/ATA/ATA.h
new file mode 100644
index 00000000..a1213b40
--- /dev/null
+++ b/src/modules/ATA/ATA.h
@@ -0,0 +1,157 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: Defines.h
+ Purpose: ATA header.
+
+ Revision History:
+
+ 03/02/24: Added file (amlel)
+
+======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NeKit/Defines.h>
+
+///! Status register
+#define ATA_SR_BSY 0x80
+#define ATA_SR_DRDY 0x40
+#define ATA_SR_DF 0x20
+#define ATA_SR_DSC 0x10
+#define ATA_SR_DRQ 0x08
+#define ATA_SR_CORR 0x04
+#define ATA_SR_IDX 0x02
+#define ATA_SR_ERR 0x01
+
+///! Error register
+#define ATA_ER_BBK 0x80
+#define ATA_ER_UNC 0x40
+#define ATA_ER_MC 0x20
+#define ATA_ER_IDNF 0x10
+#define ATA_ER_MCR 0x08
+#define ATA_ER_ABRT 0x04
+#define ATA_ER_TK0NF 0x02
+#define ATA_ER_AMNF 0x01
+
+#define ATA_CMD_READ_PIO 0x20
+#define ATA_CMD_READ_PIO_EXT 0x24
+#define ATA_CMD_READ_DMA 0xC8
+#define ATA_CMD_READ_DMA_EXT 0x25
+#define ATA_CMD_WRITE_PIO 0x30
+#define ATA_CMD_WRITE_PIO_EXT 0x34
+#define ATA_CMD_WRITE_DMA 0xCA
+#define ATA_CMD_WRITE_DMA_EXT 0x35
+#define ATA_CMD_CACHE_FLUSH 0xE7
+#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
+#define ATA_CMD_PACKET 0xA0
+#define ATA_CMD_IDENTIFY_PACKET 0xA1
+#define ATA_CMD_IDENTIFY 0xEC
+
+///! ident offsets, use with data that we got from ATA_CMD_IDENTIFY.
+#define ATA_IDENT_DEVICE_TYPE 0
+#define ATA_IDENT_CYLINDERS 2
+#define ATA_IDENT_HEADS 6
+#define ATA_IDENT_SECTORS 12
+#define ATA_IDENT_SERIAL 20
+#define ATA_IDENT_MODEL 54
+#define ATA_IDENT_CAPABILITIES 98
+#define ATA_IDENT_FIELDVALID 106
+#define ATA_IDENT_MAX_LBA 120
+#define ATA_IDENT_COMMANDSETS 164
+#define ATA_IDENT_MAX_LBA_EXT 200
+
+#define ATA_REG_SET_FEATURES 0xEF
+
+#define ATA_MASTER 0x00
+#define ATA_SLAVE 0x01
+
+///! Register
+#define ATA_REG_DATA 0x00
+#define ATA_REG_ERROR 0x01
+#define ATA_REG_FEATURES 0x01
+#define ATA_REG_SEC_COUNT0 0x02
+#define ATA_REG_LBA0 0x03
+#define ATA_REG_LBA1 0x04
+#define ATA_REG_LBA2 0x05
+#define ATA_REG_HDDEVSEL 0x06
+#define ATA_REG_COMMAND 0x07
+#define ATA_REG_STATUS 0x07
+#define ATA_REG_SEC_COUNT1 0x08
+#define ATA_REG_LBA3 0x09
+#define ATA_REG_LBA4 0x0A
+#define ATA_REG_LBA5 0x0B
+#define ATA_REG_CONTROL 0x0C
+#define ATA_REG_ALT_STATUS 0x0C
+#define ATA_REG_DEV_ADDRESS 0x0D
+
+#define ATA_REG_NEIN 0x01
+
+#define ATA_PRIMARY_IO 0x1F0
+#define ATA_SECONDARY_IO 0x170
+#define ATA_PRIMARY_DCR_AS 0x3F6
+#define ATA_SECONDARY_DCR_AS 0x376
+
+///! Irq
+#define ATA_PRIMARY_IRQ 14
+#define ATA_SECONDARY_IRQ 15
+
+///! Channels
+#define ATA_PRIMARY 0x00
+#define ATA_SECONDARY 0x01
+
+#define ATA_CYL_LOW 3
+#define ATA_CYL_MID 4
+#define ATA_CYL_HIGH 5
+
+///! IO Direction
+#define ATA_READ 0x00
+#define ATA_WRITE 0x013
+
+#define ATA_PRIMARY_SEL 0xA0
+#define ATA_SECONDARY_SEL 0xB0
+
+///! ATA address register.
+#define ATA_ADDRESS1(x) (x + 3)
+#define ATA_ADDRESS2(x) (x + 4)
+#define ATA_ADDRESS3(x) (x + 5)
+
+///! ATA command register.
+#define ATA_COMMAND(x) (x + 7)
+
+#define kATASectorSize (512U)
+
+enum {
+ kATADevicePATA,
+ kATADeviceSATA,
+ kATADevicePATA_PI,
+ kATADeviceSATA_PI,
+ kATADeviceCount,
+};
+
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+
+Kernel::Boolean drv_std_init(Kernel::UInt16 in_bus, Kernel::UInt8 drive, Kernel::UInt16& out_bus,
+ Kernel::UInt8& out_master);
+
+Kernel::Boolean drv_std_detected(Kernel::Void);
+
+Kernel::Void drv_std_select(Kernel::UInt16 bus);
+
+Kernel::Boolean drv_std_wait_io(Kernel::UInt16 io);
+
+Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::UInt16 io, Kernel::UInt8 is_master,
+ Kernel::Char* buf, Kernel::SizeT sec_sz, Kernel::SizeT buf_sz);
+
+Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::UInt16 io, Kernel::UInt8 is_master,
+ Kernel::Char* buf, Kernel::SizeT sec_sz, Kernel::SizeT buf_sz);
+
+/// @brief get sector count.
+Kernel::SizeT drv_std_get_sector_count();
+
+/// @brief get device size.
+Kernel::SizeT drv_std_get_size();
+
+#endif // ifdef __NEOSKRNL__ \ No newline at end of file
diff --git a/src/modules/CoreGfx/CoreAccess.h b/src/modules/CoreGfx/CoreAccess.h
new file mode 100644
index 00000000..942a1ad5
--- /dev/null
+++ b/src/modules/CoreGfx/CoreAccess.h
@@ -0,0 +1,33 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+======================================== */
+
+#ifndef CORE_GFX_ACCESSIBILITY_H
+#define CORE_GFX_ACCESSIBILITY_H
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/NeKit.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/MathGfx.h>
+
+namespace FB {
+using namespace Kernel;
+
+/// @brief common User interface class.
+class CGAccessibilty final {
+ explicit CGAccessibilty() = default;
+ ~CGAccessibilty() = default;
+
+ public:
+ NE_COPY_DELETE(CGAccessibilty)
+
+ static UInt64 Width() noexcept { return kHandoverHeader->f_GOP.f_Width; }
+
+ static UInt64 Height() noexcept { return kHandoverHeader->f_GOP.f_Height; }
+};
+} // namespace FB
+
+#endif // !CORE_GFX_ACCESSIBILITY_H_
diff --git a/src/modules/CoreGfx/CoreGfx.h b/src/modules/CoreGfx/CoreGfx.h
new file mode 100644
index 00000000..e1bfe462
--- /dev/null
+++ b/src/modules/CoreGfx/CoreGfx.h
@@ -0,0 +1,118 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define cg_init() Kernel::UInt32 kCGCursor = 0
+
+#define cg_color(R, G, B) RGB(R, G, B)
+
+#define cg_get_clear_clr() RGB(0, 0, 0x80)
+
+#define cg_clear() kCGCursor = 0UL
+
+#ifdef __NE_AMD64__
+/// @brief Performs Alpha drawing on the framebuffer.
+#define FBDrawBitMapInRegionA(reg_ptr, height, width, base_x, base_y) \
+ for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \
+ for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \
+ *(((Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \
+ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) |= \
+ (reg_ptr)[kCGCursor]; \
+ \
+ ++kCGCursor; \
+ } \
+ }
+
+/// @brief Performs drawing on the framebuffer.
+#define FBDrawBitMapInRegion(reg_ptr, height, width, base_x, base_y) \
+ for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \
+ for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \
+ *(((Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \
+ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) = \
+ (reg_ptr)[kCGCursor]; \
+ \
+ ++kCGCursor; \
+ } \
+ }
+
+#define FBDrawBitMapInRegionToRgn(_Rgn, reg_ptr, height, width, base_x, base_y) \
+ for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \
+ for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \
+ *(((Kernel::UInt32*) (_Rgn + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) = \
+ (reg_ptr)[kCGCursor]; \
+ \
+ ++kCGCursor; \
+ } \
+ }
+
+/// @brief Cleans a resource.
+#define FBClearRegion(height, width, base_x, base_y) \
+ for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \
+ for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \
+ *(((volatile Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \
+ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) = \
+ cg_get_clear_clr(); \
+ } \
+ }
+
+/// @brief Draws inside a zone.
+#define FBDrawInRegion(clr, height, width, base_x, base_y) \
+ for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) { \
+ for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) { \
+ *(((volatile Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \
+ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * x_base + \
+ 4 * y_base))) = clr; \
+ } \
+ }
+
+/// @brief Draws inside a zone.
+#define FBDrawInRegionToRgn(_Rgn, clr, height, width, base_x, base_y) \
+ for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) { \
+ for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) { \
+ *(((volatile Kernel::UInt32*) (_Rgn + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * x_base + \
+ 4 * y_base))) = clr[kCGCursor]; \
+ ++kCGCursor; \
+ } \
+ }
+
+#define FBDrawInRegionA(clr, height, width, base_x, base_y) \
+ for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) { \
+ for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) { \
+ *(((volatile Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \
+ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * x_base + \
+ 4 * y_base))) |= clr; \
+ } \
+ }
+#else
+#define FBDrawBitMapInRegionA(reg_ptr, height, width, base_x, base_y)
+#define FBDrawBitMapInRegion(reg_ptr, height, width, base_x, base_y)
+#define FBDrawBitMapInRegionToRgn(_Rgn, reg_ptr, height, width, base_x, base_y)
+#define FBClearRegion(height, width, base_x, base_y)
+#define FBDrawInRegion(clr, height, width, base_x, base_y)
+#define FBDrawInRegionToRgn(_Rgn, clr, height, width, base_x, base_y)
+#define FBDrawInRegionA(clr, height, width, base_x, base_y)
+#define FBDrawBitMapInRegionA(reg_ptr, height, width, base_x, base_y)
+#define FBDrawBitMapInRegion(reg_ptr, height, width, base_x, base_y)
+#define FBDrawBitMapInRegionToRgn(_Rgn, reg_ptr, height, width, base_x, base_y)
+#define FBClearRegion(height, width, base_x, base_y)
+#define FBDrawInRegion(clr, height, width, base_x, base_y)
+#define FBDrawInRegionToRgn(_Rgn, clr, height, width, base_x, base_y)
+#define FBDrawInRegionA(clr, height, width, base_x, base_y)
+#endif // __NE_AMD64__
+
+#ifndef CORE_GFX_ACCESSIBILITY_H
+#include <modules/CoreGfx/CoreAccess.h>
+#endif // ifndef CORE_GFX_ACCESSIBILITY_H
+
+namespace FB {
+inline Void cg_clear_video() noexcept {
+ FBDrawInRegion(cg_get_clear_clr(), FB::CGAccessibilty::Height(), FB::CGAccessibilty::Width(), 0,
+ 0);
+}
+} // namespace FB \ No newline at end of file
diff --git a/src/modules/CoreGfx/MathGfx.h b/src/modules/CoreGfx/MathGfx.h
new file mode 100644
index 00000000..dbd732d3
--- /dev/null
+++ b/src/modules/CoreGfx/MathGfx.h
@@ -0,0 +1,27 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+======================================== */
+
+#pragma once
+
+/// @file MathMgr.h
+/// @brief Linear interpolation implementation.
+
+namespace UI {
+#ifdef NE_CORE_GFX_USE_DOUBLE
+typedef double cg_real_t;
+#else
+typedef float cg_real_t;
+#endif
+
+/// @brief Linear interpolation equation solver.
+/// @param from where to start
+/// @param to to which value.
+/// @param stat
+/// @return Linear interop value.
+inline cg_real_t cg_math_lerp(cg_real_t to, cg_real_t from, cg_real_t stat) {
+ return (from) + (to - from) * stat;
+}
+} // namespace UI \ No newline at end of file
diff --git a/src/modules/CoreGfx/TextGfx.h b/src/modules/CoreGfx/TextGfx.h
new file mode 100644
index 00000000..b5dcd9e5
--- /dev/null
+++ b/src/modules/CoreGfx/TextGfx.h
@@ -0,0 +1,183 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <modules/CoreGfx/CoreGfx.h>
+
+#define kFontSizeX 8
+#define kFontSizeY 8
+#define kFontNOFChars 128
+
+inline const Kernel::UInt8 kFontBitmap[kFontNOFChars][kFontSizeX] = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space)
+ {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!)
+ {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (")
+ {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#)
+ {0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($)
+ {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%)
+ {0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&)
+ {0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (')
+ {0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (()
+ {0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ())
+ {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*)
+ {0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,)
+ {0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.)
+ {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/)
+ {0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0)
+ {0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1)
+ {0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2)
+ {0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3)
+ {0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4)
+ {0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5)
+ {0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6)
+ {0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7)
+ {0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8)
+ {0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9)
+ {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:)
+ {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;)
+ {0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<)
+ {0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=)
+ {0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>)
+ {0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?)
+ {0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@)
+ {0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A)
+ {0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B)
+ {0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C)
+ {0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D)
+ {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E)
+ {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F)
+ {0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G)
+ {0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H)
+ {0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I)
+ {0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J)
+ {0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K)
+ {0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L)
+ {0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M)
+ {0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N)
+ {0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O)
+ {0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P)
+ {0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q)
+ {0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R)
+ {0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S)
+ {0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T)
+ {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U)
+ {0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V)
+ {0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W)
+ {0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X)
+ {0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y)
+ {0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z)
+ {0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([)
+ {0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\)
+ {0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (])
+ {0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_)
+ {0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`)
+ {0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a)
+ {0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b)
+ {0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c)
+ {0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d)
+ {0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e)
+ {0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f)
+ {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g)
+ {0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h)
+ {0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i)
+ {0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j)
+ {0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k)
+ {0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l)
+ {0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m)
+ {0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n)
+ {0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o)
+ {0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p)
+ {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q)
+ {0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r)
+ {0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s)
+ {0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t)
+ {0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u)
+ {0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v)
+ {0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w)
+ {0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x)
+ {0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y)
+ {0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z)
+ {0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({)
+ {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|)
+ {0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (})
+ {0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F
+
+};
+
+inline Kernel::Void cg_render_string_for_bitmap(const Kernel::UInt8* bitmap,
+ const Kernel::SizeT x_sz, const Kernel::SizeT y_sz,
+ Kernel::Int32& x_dst, Kernel::Int32& y_dst,
+ Kernel::Int32& color) {
+ Kernel::SizeT x, y;
+ Kernel::SizeT set;
+
+ x = 0;
+ y = 0;
+ set = 0;
+
+ for (; y < y_sz; ++y) {
+ for (x = 0; x < x_sz; ++x) {
+ set = bitmap[x] & (1 << y);
+
+ if (set) {
+ FBDrawInRegion(color, 1, 1, ((x_dst) + x), ((y_dst) + y));
+ }
+ }
+ }
+}
+
+inline Kernel::Void cg_render_string(const Kernel::Char* text, Kernel::Int32 x_dst,
+ Kernel::Int32 y_dst, Kernel::Int32 color) {
+#ifndef __BOOTZ__
+ auto len = Kernel::rt_string_len(text);
+#else
+ auto len = StrLen(text);
+#endif
+
+ for (Kernel::SizeT i = 0; i < len; ++i) {
+ cg_render_string_for_bitmap(&kFontBitmap[(Kernel::UInt8) text[i]][0], kFontSizeX, kFontSizeY,
+ x_dst, y_dst, color);
+ y_dst += kFontSizeY;
+ }
+}
diff --git a/src/modules/GPRS/.keep b/src/modules/GPRS/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/GPRS/.keep
diff --git a/src/modules/HPET/Defines.h b/src/modules/HPET/Defines.h
new file mode 100644
index 00000000..56968a24
--- /dev/null
+++ b/src/modules/HPET/Defines.h
@@ -0,0 +1,39 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HPET.h
+ Purpose: HPET builtin.
+
+ Revision History:
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+#include <modules/ACPI/ACPI.h>
+
+namespace Kernel {
+struct PACKED HPETAddressStructure final {
+ Kernel::UInt8 AddressSpaceId; // 0 - system memory, 1 - system I/O
+ Kernel::UInt8 RegisterBitWidth;
+ Kernel::UInt8 RegisterBitOffset;
+ Kernel::UInt8 Reserved;
+ Kernel::UInt64 Address;
+};
+
+struct PACKED HPETHeader final : public SDT {
+ Kernel::UInt8 HardwareRevId;
+ Kernel::UInt8 ComparatorCount : 5;
+ Kernel::UInt8 CounterSize : 1;
+ Kernel::UInt8 Reserved : 1;
+ Kernel::UInt8 LegacyReplacement : 1;
+ Kernel::UInt16 PciVendorId;
+ HPETAddressStructure Address;
+ Kernel::UInt8 HpetNumber;
+ Kernel::UInt16 MinimumTick;
+ Kernel::UInt8 PageProtection;
+};
+
+} // namespace Kernel
diff --git a/src/modules/IEEE802/.gitkeep b/src/modules/IEEE802/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/IEEE802/.gitkeep
diff --git a/src/modules/LTE/LTE.h b/src/modules/LTE/LTE.h
new file mode 100644
index 00000000..7cee2c8d
--- /dev/null
+++ b/src/modules/LTE/LTE.h
@@ -0,0 +1,34 @@
+/* ========================================
+
+Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license..
+
+File: LTE\LTE.h.
+Purpose: LTE Standard Library.
+
+======================================== */
+
+#ifndef _INC_NETWORK_LTE_H_
+#define _INC_NETWORK_LTE_H_
+
+#include <NeKit/Defines.h>
+#include <NeKit/KString.h>
+
+/// @brief Long Term Evolution I/O routines.
+
+/// @brief Turn on SIM slot.
+Kernel::Boolean lte_turn_on_sim(Kernel::Int32 simSlot);
+
+/// @brief Turn off SIM slot.
+Kernel::Boolean lte_turn_off_sim(Kernel::Int32 simSlot);
+
+/// @brief Send AT command.
+Kernel::Boolean lte_send_at_command(Kernel::Char* buf, Kernel::Size bufReadSz,
+ Kernel::Int32 simSlot);
+
+Kernel::Boolean lte_write_sim_file(Kernel::Char* file, Kernel::VoidPtr buf, Kernel::Size bufSz,
+ Kernel::Size offset, Kernel::Int32 simSlot);
+
+Kernel::VoidPtr lte_read_sim_file(Kernel::Char* file, Kernel::Size bufSz, Kernel::Size offset,
+ Kernel::Int32 simSlot);
+
+#endif // ifndef _INC_NETWORK_LTE_H_
diff --git a/src/modules/MBCI/MBCI.h b/src/modules/MBCI/MBCI.h
new file mode 100644
index 00000000..a96f8f3a
--- /dev/null
+++ b/src/modules/MBCI/MBCI.h
@@ -0,0 +1,126 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#ifndef _INC_MODULE_MBCI_H_
+#define _INC_MODULE_MBCI_H_
+
+#include <NeKit/Defines.h>
+#include <hint/CompilerHint.h>
+#include <modules/ACPI/ACPI.h>
+
+/// @file MBCI.h
+/// @brief Mini Bus Controller Interface.
+
+/**
+- VCC (IN) (OUT for MCU)
+- CLK (IN) (OUT for MCU)
+- ACK (BI) (Contains an Acknowledge Packet Frame)
+- D0- (IN) (Starts with the Host Interface Packet Frame)
+- D1- (IN) (Starts with the Host Interface Packet Frame)
+- D0+ (OUT) (Starts with the Host Interface Packet Frame)
+- D1+ (OUT) (Starts with the Host Interface Packet Frame)
+- GND (IN) (OUT for MCU)
+ */
+
+#define kMBCIZeroSz (8)
+#define kMBCIESBSz (64)
+
+namespace Kernel {
+struct IMBCIHost;
+
+enum {
+ kMBCISpeedDeviceInvalid,
+ kMBCILowSpeedDevice,
+ kMBCIHighSpeedDevice,
+ kMBCISpeedDeviceCount,
+};
+
+/// @brief MBCI Host header.
+volatile struct PACKED IMBCIHost final {
+ UInt32 Magic;
+ UInt32 HostId;
+ UInt16 VendorId;
+ UInt16 DeviceId;
+ UInt8 MemoryType;
+ UInt16 HostType;
+ UInt16 HostFlags;
+ UInt8 Error;
+ UInt32 MMIOTest;
+ UInt16 State;
+ UInt8 Status;
+ UInt8 InterruptEnable;
+ UInt64 BaseAddressRegister;
+ UInt64 BaseAddressRegisterSize;
+ UInt32 CommandIssue;
+ UInt8 Esb[kMBCIESBSz]; // Extended Signature Block
+ UInt8 Zero[kMBCIZeroSz];
+};
+
+/// @brief MBCI host flags.
+enum MBCIHostFlags {
+ kMBCIHostFlagsSupportsNothing, // Invalid MBCI device.
+ kMBCIHostFlagsSupportsAPM, // FW's Advanced Power Management.
+ kMBCIHostFlagsSupportsDaisyChain, // Is daisy chained.
+ kMBCIHostFlagsSupportsHWInterrupts, // Has HW interrupts.
+ kMBCIHostFlagsSupportsDMA, // Has DMA.
+ kMBCIHostFlagsExtended, // Extended flags table.
+};
+
+/// @brief MBCI host kind.
+enum MBCIHostKind {
+ kMBCIHostKindHardDisk,
+ kMBCIHostKindOpticalDisk,
+ kMBCIHostKindKeyboardLow,
+ kMBCIHostKindMouseLow,
+ kMBCIHostKindMouseHigh,
+ kMBCIHostKindKeyboardHigh,
+ kMBCIHostKindNetworkInterface,
+ kMBCIHostKindDaisyChain,
+ kMBCIHostKindStartExtended, // Extended vendor table limit.
+};
+
+enum MBCIHostState {
+ kMBCIHostStateInvalid,
+ kMBCIHostStateReset,
+ kMBCIHostStateSuccess,
+ kMBCIHostStateReady,
+ kMBCIHostStateDmaStart,
+ kMBCIHostStateDmaEnd,
+ kMBCIHostStateFail,
+ kMBCIHostStateCount,
+};
+
+/// @brief An AuthKey is a context used to tokenize data for an MBCI packet.
+typedef UInt32 MBCIAuthKeyType;
+
+/// @internal
+inline BOOL busi_test_mmio(_Input struct IMBCIHost* host, _Input const UInt32 test) {
+ host->MMIOTest = test;
+ UInt16 timeout = 0UL;
+
+ while (host->MMIOTest == test) {
+ ++timeout;
+
+ if (timeout > 0x1000) return NO;
+ }
+
+ return host->MMIOTest == 0;
+}
+
+/// @brief Read Auth key for MBCI host.
+/// @param host the mbci host to get the key on.
+/// @return the 24-bit key.
+inline MBCIAuthKeyType mbci_read_auth_key(_Input struct IMBCIHost* host) {
+ auto const kChallengeMBCI = 0x1; // MBCI Challenge test
+
+ if (!busi_test_mmio(host, kChallengeMBCI)) return ~0;
+
+ return (host->Esb[kMBCIESBSz - 1] << 16) | (host->Esb[kMBCIESBSz - 2] << 8) |
+ (host->Esb[kMBCIESBSz - 3] & 0xFF);
+}
+} // namespace Kernel
+
+#endif // ifndef _INC_MODULE_MBCI_H_ \ No newline at end of file
diff --git a/src/modules/NVME/NVME.h b/src/modules/NVME/NVME.h
new file mode 100644
index 00000000..9ad8a3ce
--- /dev/null
+++ b/src/modules/NVME/NVME.h
@@ -0,0 +1,104 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ Revision History:
+
+ ??/??/24: Added file (amlel)
+ 23 Jul 24: Update filename to Defines.h and using NE_ALIGN_NVME for NVME structs. (amlel)
+
+======================================== */
+
+#ifndef __MODULE_NVME_H__
+#define __MODULE_NVME_H__
+
+#include <NeKit/Defines.h>
+
+/// @file NVME.h
+/// @brief Non Volatile Memory.
+
+#define NE_ALIGN_NVME ATTRIBUTE(aligned(sizeof(Kernel::UInt32)))
+
+namespace Kernel {
+struct NE_ALIGN_NVME HAL_NVME_BAR_0 final {
+ UInt32 fCapabilities;
+ UInt32 fVersion;
+ UInt32 fIntMaskSet;
+ UInt32 fIntMaskClr;
+ UInt32 fContrlConf;
+ UInt32 fContrlStat;
+ UInt32 fAdminQueueAttr;
+ UInt32 fAdminSubmissionQueue;
+ UInt32 fAdminCompletionQueue;
+};
+
+struct NE_ALIGN_NVME HAL_NVME_QUEUE final {
+ UInt32 fOpcode;
+ UInt32 fNSID;
+ UInt32 fReserved[3];
+ UInt32 fMetadataPtr[5];
+ UInt32 fDataPtr[9];
+ UInt32 CommandSpecific[15];
+};
+
+enum {
+ kInvalidNVME = 0xFF,
+ kCreateCompletionQueueNVME = 0x05,
+ kCreateSubmissionQueueNVME = 0x01,
+ kIdentifyNVME = 0x06,
+ kReadNVME = 0x02,
+ kWriteNVME = 0x01,
+ kCountNVME = 5,
+};
+
+/// @brief Creates an admin command for a DMA operation.
+template <Int32 Opcode>
+inline Bool nvme_create_admin_command(HAL_NVME_QUEUE* entry, UInt32 nsid, UInt32 prpTransfer[3],
+ UInt32 startingLba[2], UInt32 lowTransferBlocks) {
+ if (entry == nullptr) return false;
+
+ entry->CommandSpecific[9] = startingLba[0];
+ entry->CommandSpecific[10] = startingLba[1];
+
+ entry->CommandSpecific[11] = lowTransferBlocks;
+
+ entry->CommandSpecific[5] = prpTransfer[0];
+ entry->CommandSpecific[6] = prpTransfer[1];
+ entry->CommandSpecific[7] = prpTransfer[2];
+
+ entry->CommandSpecific[0] = nsid;
+
+ return true;
+}
+
+/// @brief Creates an I/O command for a DMA operation.
+template <Int32 Opcode>
+inline Bool nvme_create_io_command(HAL_NVME_QUEUE* entry, UInt64 baseAddress,
+ UInt32 identLoAndQueueSizeHi, UInt32 flagsLoAndQueueComplIdHi,
+ UInt32 identify, Bool provideIdentify = false,
+ Bool namespaceIdentify = false) {
+ if (entry == nullptr) return false;
+
+ if (baseAddress == 0) return false;
+
+ entry->fOpcode = Opcode;
+
+ entry->CommandSpecific[5] = (baseAddress & 0xFF);
+ entry->CommandSpecific[6] = static_cast<UInt32>(baseAddress);
+
+ if (!provideIdentify) {
+ entry->CommandSpecific[9] = identLoAndQueueSizeHi;
+ entry->CommandSpecific[10] = flagsLoAndQueueComplIdHi;
+ } else {
+ entry->CommandSpecific[9] = identify;
+
+ if (namespaceIdentify) {
+ entry->CommandSpecific[0] = YES;
+ }
+ }
+
+ return true;
+}
+} // namespace Kernel
+
+#endif // ifndef __MODULE_NVME_H__
diff --git a/src/modules/OHCI/.gitkeep b/src/modules/OHCI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/OHCI/.gitkeep
diff --git a/src/modules/Power/PowerFactory.h b/src/modules/Power/PowerFactory.h
new file mode 100644
index 00000000..2e349011
--- /dev/null
+++ b/src/modules/Power/PowerFactory.h
@@ -0,0 +1,30 @@
+/* ========================================
+
+ Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/Defines.h>
+#include <NeKit/ErrorOr.h>
+#include <NeKit/Ref.h>
+#include <modules/ACPI/ACPI.h>
+
+#define NE_POWER_FACTORY : public PowerFactory
+
+namespace Kernel {
+class PowerFactory {
+ public:
+ explicit PowerFactory() = default;
+ virtual ~PowerFactory() = default;
+
+ PowerFactory& operator=(const PowerFactory&) = default;
+ PowerFactory(const PowerFactory&) = default;
+
+ public:
+ virtual Bool Shutdown() { return NO; } // shutdown
+ virtual Void Reboot() {} // soft-reboot
+};
+} // namespace Kernel \ No newline at end of file
diff --git a/src/modules/SCSI/.gitkeep b/src/modules/SCSI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/SCSI/.gitkeep
diff --git a/src/modules/SCSI/SCSI.h b/src/modules/SCSI/SCSI.h
new file mode 100644
index 00000000..e0bc2517
--- /dev/null
+++ b/src/modules/SCSI/SCSI.h
@@ -0,0 +1,21 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+/// @file SCSI.h
+/// @brief Small Computer System Interface device.
+
+namespace Kernel {
+template <Int32 PacketBitLen>
+using scsi_packet_type = Kernel::UInt16[PacketBitLen];
+
+using scsi_packet_type_12 = scsi_packet_type<12>;
+
+extern const scsi_packet_type_12 kCDRomPacketTemplate;
+} // namespace Kernel \ No newline at end of file
diff --git a/src/modules/WiFi/.gitkeep b/src/modules/WiFi/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/modules/WiFi/.gitkeep
diff --git a/src/modules/XHCI/XHCI.h b/src/modules/XHCI/XHCI.h
new file mode 100644
index 00000000..40387c1e
--- /dev/null
+++ b/src/modules/XHCI/XHCI.h
@@ -0,0 +1,66 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: Defines.h
+ Purpose: XHCI (and backwards) header.
+
+ Revision History:
+
+ 01/02/24: Added file (amlel)
+ 03/02/24: Update filename to Defines.h (amlel)
+
+======================================== */
+
+#pragma once
+
+#include <NeKit/Defines.h>
+
+#define kUSBCommand (UInt16) 0x0
+#define kUSBStatus (UInt16) 0x2
+#define kUSBInterruptEnable (UInt16) 0x4
+#define kUSBFrameNum (UInt16) 0x6
+#define kUSBFrameListBaseAddress (UInt16) 0x8
+#define kUSBFrameModifyStart (UInt16) 0xC
+#define kUSBPort1StatusCtrl (UInt16) 0x10
+#define kUSBPort2StatusCtrl (UInt16) 0x12
+
+namespace Kernel {
+typedef struct USBCommandRegister final {
+ UInt8 mReserved[8]; // Reserved
+ UInt8 mMaxPacket; // 0 = Max packet size 32 bits 1 = Max packet size 64 bits
+ UInt8 mConfigure;
+ UInt8 mSoftwareDebug;
+ UInt8 mGlobalResume;
+ UInt8 mGlobalSuspend;
+ UInt8 mHostCtrlReset;
+ UInt8 mRun; // 1 = Controller execute frame list entries
+} USBCommandRegister;
+
+typedef struct USBStatusRegister final {
+ UInt8 mReserved[8]; // Reserved
+ UInt8 mHalted; // 1 = bit 0 in CMD is zero 0 = bit 0 in CMD is 1
+ UInt8 mProcessError;
+ UInt8 mSystemError;
+ UInt8 mResumeDetected;
+ UInt8 mErrorInterrupt;
+ UInt8 mInterrupt;
+} USBStatusRegister;
+
+typedef struct USBInterruptEnableRegister final {
+ UInt8 mReserved[4]; // Reserved
+ UInt8 mShortPacket; // 1=Enable interrupt 0=Disable interrupt
+ UInt8 mComplete; // 1=Enable interrupt 0=Disable interrupt
+ UInt8 mResume; // 1=Enable interrupt 0=Disable interrupt
+ UInt8 mTimeoutCRC; // 1=Enable interrupt 0=Disable interrupt
+} USBInterruptEnableRegister;
+
+/*
+ Some terminology:
+
+ Frame Number: Number of processed entry of the Frame List.
+ Frame List Base Address:
+ 32-bit physical adress of Frame List. Remember that first 12 bytes are
+ always 0. The Frame List must contain 1024 entries.
+*/
+} // namespace Kernel \ No newline at end of file