diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-09-28 14:18:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-28 14:18:55 +0200 |
| commit | 643fd1890646442e97f61c323bb1342ccae8c46b (patch) | |
| tree | 1dccc97ea6d52012d682f664995959fe7db9ddd1 | |
| parent | dfad97487744840f26ea8046d1a011688bd9edd0 (diff) | |
| parent | 2d673e164b98db5eb08d4c41c6225fbe73ee82d7 (diff) | |
Merge pull request #66 from 0xf00sec/patch-2
feat: `T.Value` (ErrorOr.h)
51 files changed, 581 insertions, 353 deletions
@@ -135,7 +135,10 @@ local.properties .externalToolBuilders/ # Locally stored "Eclipse launch configurations" -*.launch +# *.launch + +# NeKernel Launch +ne_launch # PyDev specific (Python IDE for Eclipse) *.pydevproject @@ -88,7 +88,7 @@ cd nekernel ## Documentation -- [API Reference (Doxygen)](https://nekernel-org.github.io/doc/) +- [OpenKnowledge](https://docs.nekernel.org/) - [Filesystem Specifications](docs/tex/) --- diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index 443e5677..d8c3fd86 100644 --- a/dev/boot/amd64-desktop.make +++ b/dev/boot/amd64-desktop.make @@ -117,15 +117,15 @@ compile-amd64: .PHONY: run-efi-amd64-ahci run-efi-amd64-ahci: - $(EMU) $(EMU_FLAGS) -monitor stdio -hda $(IMG) -s -S -boot menu=on + $(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 -S -d int -boot menu=on + $(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 -S -boot menu=on + $(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 diff --git a/dev/kernel/FSKit/Ext2+IFS.h b/dev/kernel/FSKit/Ext2+IFS.h new file mode 100644 index 00000000..d73ae43c --- /dev/null +++ b/dev/kernel/FSKit/Ext2+IFS.h @@ -0,0 +1,140 @@ +#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::Ext2 { +/// @brief Context for an EXT2 filesystem on a given drive +struct Ext2Context { + Kernel::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; + } + + Kernel::SizeT LeakBlockSize() const { + if (!superblock) return kExt2FSBlockSizeBase; + return kExt2FSBlockSizeBase << superblock->fLogBlockSize; + } + + BOOL operator bool() { return superblock != nullptr; } +}; + +/// ======================================================================= /// +/// IFS FUNCTIONS +/// ======================================================================= /// + +inline bool ext2_read_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, void* 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 void* buffer, + Kernel::UInt32 size) { + if (!drv || !buffer) return false; + + Kernel::DriveTrait::DrivePacket pkt{}; + pkt.fPacketContent = const_cast<void*>(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; + Kernel::UInt32 index = (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); +} + +inline Kernel::UInt32 inode_offset(const Ext2Context* ctx, Kernel::UInt32 inodeNumber) { + if (!ctx || !ctx->superblock) return 0; + return ((inodeNumber - 1) % ctx->superblock->fInodesPerGroup) * ctx->superblock->fInodeSize; +} +} // namespace Kernel::Ext2 diff --git a/dev/kernel/FSKit/Ext2.h b/dev/kernel/FSKit/Ext2.h index 42875c47..06370a8c 100644 --- a/dev/kernel/FSKit/Ext2.h +++ b/dev/kernel/FSKit/Ext2.h @@ -18,126 +18,126 @@ namespace Ext2 { /// EXT2 Constants -#define kExt2FSMagic (0xEF53) -#define kExt2FSMaxFileNameLen (255U) -#define kExt2FSSuperblockOffset (1024) -#define kExt2FSRootInodeNumber (2) -#define kExt2FSInodeSize (128U) -#define kExt2FSBlockSizeBase (1024U) +#define kExt2FSMagic (0xEF53) +#define kExt2FSMaxFileNameLen (255U) +#define kExt2FSSuperblockOffset (1024) +#define kExt2FSRootInodeNumber (2) +#define kExt2FSInodeSize (128U) +#define kExt2FSBlockSizeBase (1024U) -#define kExt2FSRev0 (0) -#define kExt2FSRev1 (1) +#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 + kExt2FileTypeUnknown = 0, + kExt2FileTypeRegular = 1, + kExt2FileTypeDirectory = 2, + kExt2FileTypeCharDevice = 3, + kExt2FileTypeBlockDevice = 4, + kExt2FileTypeFIFO = 5, + kExt2FileTypeSocket = 6, + kExt2FileTypeSymbolicLink = 7 }; struct PACKED EXT2_SUPER_BLOCK final { - Kernel::UInt32 fInodeCount; - Kernel::UInt32 fBlockCount; - Kernel::UInt32 fReservedBlockCount; - Kernel::UInt32 fFreeBlockCount; - Kernel::UInt32 fFreeInodeCount; - Kernel::UInt32 fFirstDataBlock; - Kernel::UInt32 fLogBlockSize; - Kernel::UInt32 fLogFragmentSize; - Kernel::UInt32 fBlocksPerGroup; - Kernel::UInt32 fFragmentsPerGroup; - Kernel::UInt32 fInodesPerGroup; - Kernel::UInt32 fMountTime; - Kernel::UInt32 fWriteTime; - Kernel::UInt16 fMountCount; - Kernel::UInt16 fMaxMountCount; - Kernel::UInt16 fMagic; - 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 + 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]; + 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]; + 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}; + Kernel::UInt32 inodeNumber; + EXT2_INODE inode; + Kernel::UInt32 cursor{0}; }; class Ext2FileSystemMgr; -} // namespace Ext2 +} // namespace Ext2 diff --git a/dev/kernel/FSKit/Ext2IFS.h b/dev/kernel/FSKit/Ext2IFS.h deleted file mode 100644 index 87095bc6..00000000 --- a/dev/kernel/FSKit/Ext2IFS.h +++ /dev/null @@ -1,133 +0,0 @@ -#pragma once - -#include <FSKit/Ext2.h> -#include <KernelKit/DriveMgr.h> -#include <KernelKit/HeapMgr.h> -#include <NeKit/Utils.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/ErrorOr.h> -#include <KernelKit/KPC.h> - -namespace Ext2 { - -/// @brief Context for an EXT2 filesystem on a given drive -struct Context { - Kernel::DriveTrait* drive{nullptr}; - EXT2_SUPER_BLOCK* superblock{nullptr}; - - /// @brief context with a drive - explicit Context(Kernel::DriveTrait* drv) : drive(drv) {} - - /// @brief Clean up - ~Context() { - if (superblock) { - Kernel::mm_free_ptr(superblock); - superblock = nullptr; - } - } - - Context(const Context&) = delete; - Context& operator=(const Context&) = delete; - - Context(Context&& other) noexcept : drive(other.drive), superblock(other.superblock) { - other.drive = nullptr; - other.superblock = nullptr; - } - - Context& operator=(Context&& 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; - } - - inline Kernel::UInt32 BlockSize() const { - if (!superblock) return kExt2FSBlockSizeBase; - return kExt2FSBlockSizeBase << superblock->fLogBlockSize; - } -}; - -inline bool ext2_read_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, void* 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 void* buffer, Kernel::UInt32 size) { - if (!drv || !buffer) return false; - - Kernel::DriveTrait::DrivePacket pkt{}; - pkt.fPacketContent = const_cast<void*>(buffer); - pkt.fPacketSize = size; - pkt.fPacketLba = lba; - drv->fOutput(pkt); - return pkt.fPacketGood; -} - -// Load superblock -inline Kernel::ErrorOr<EXT2_SUPER_BLOCK*> ext2_load_superblock(Context* 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(Context* 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; - Kernel::UInt32 index = (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); -} - -inline Kernel::UInt32 inode_offset(const Context* ctx, Kernel::UInt32 inodeNumber) { - if (!ctx || !ctx->superblock) return 0; - return ((inodeNumber - 1) % ctx->superblock->fInodesPerGroup) * ctx->superblock->fInodeSize; -} - -} // namespace Ext2 diff --git a/dev/kernel/HALKit/AMD64/CxxAbi.cc b/dev/kernel/HALKit/AMD64/CxxAbi.cc index cd135abc..84a00449 100644 --- a/dev/kernel/HALKit/AMD64/CxxAbi.cc +++ b/dev/kernel/HALKit/AMD64/CxxAbi.cc @@ -62,17 +62,18 @@ EXTERN_C void __cxa_finalize(void* f) { } namespace cxxabiv1 { -EXTERN_C int __cxa_guard_acquire(__guard* g) { - (void) g; +EXTERN_C int __cxa_guard_acquire(__guard g) { + if ((*g & 1) || (*g & 2)) return 1; + *g |= 2; return 0; } -EXTERN_C int __cxa_guard_release(__guard* g) { - *(char*) g = 1; - return 0; +EXTERN_C void __cxa_guard_release(__guard g) { + *g |= 1; + *g &= 2; } -EXTERN_C void __cxa_guard_abort(__guard* g) { - (void) g; +EXTERN_C void __cxa_guard_abort(__guard g) { + *g &= ~2; } } // namespace cxxabiv1 diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index df5386e4..e3e08830 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -88,7 +88,7 @@ struct LAPIC final { /// @param target /// @return /***********************************************************************************/ -Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) { +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); @@ -200,10 +200,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { UInt8 type = *entry_ptr; UInt8 length = *(entry_ptr + 1); - // Avoid infinite loop on bad APIC tables. - if (length < 2) break; - - if (type == 0) { + if (type == 0 && length == sizeof(struct LAPIC)) { volatile LAPIC* entry_struct = (volatile LAPIC*) entry_ptr; if (entry_struct->Flags & 0x1) { @@ -212,15 +209,15 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { ++kSMPCount; - kout << "Kind: LAPIC: ON\r"; + kout << "AP: kind: LAPIC: ON.\r"; // 0x7c00, as recommended by the Intel SDM. hal_send_ipi_msg(kApicBaseAddress, entry_struct->ProcessorID, 0x7c); } else { - kout << "Kind: LAPIC: OFF\r"; + kout << "AP: kind: LAPIC: OFF.\r"; } } else { - kout << "Kind: UNKNOWN: OFF\r"; + kout << "AP: kind: UNKNOWN: OFF.\r"; } entry_ptr += length; diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index f121fbb4..6f4d7e0a 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -32,17 +32,14 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { HAL::rt_sti(); - kHandoverHeader = handover_hdr; - - FB::fb_clear_video(); - fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]); Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, handover_hdr->f_HardwareTables.f_ImageHandle); - kBitMapCursor = 0UL; - kKernelVM = kHandoverHeader->f_PageStart; + kHandoverHeader = handover_hdr; + + kKernelVM = kHandoverHeader->f_PageStart; if (!kKernelVM) { MUST_PASS(kKernelVM); @@ -55,6 +52,7 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { /* INITIALIZE BIT MAP. */ /************************************** */ + kBitMapCursor = 0UL; kKernelBitMpSize = kHandoverHeader->f_BitMapSize; kKernelBitMpStart = reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(kHandoverHeader->f_BitMapStart)); @@ -120,6 +118,8 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { kGDTArray[4].fFlags = 0; kGDTArray[4].fBaseHigh = 0; + FB::fb_clear_video(); + // Load memory descriptors. HAL::Register64 gdt_reg; @@ -133,24 +133,14 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { return kEfiFail; } -EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { +EXTERN_C Kernel::Void hal_real_init(Kernel::Void) { using namespace Kernel; - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { - HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard; - HardwareThreadScheduler::The()[index].Leak()->ID() = index; - HardwareThreadScheduler::The()[index].Leak()->Busy(NO); - } - - for (SizeT index = 0UL; index < UserProcessScheduler::The().TheCurrentTeam().AsArray().Count(); - ++index) { - UserProcessScheduler::The().TheCurrentTeam().AsArray()[index].Status = - ProcessStatusKind::kInvalid; - } + HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast<UIntPtr>(kInterruptVectorTable); - rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server. - rtl_create_user_process(sched_idle_task, "LaunchSrv"); //! launchd - rtl_create_user_process(sched_idle_task, "SecSrv"); //! Login Server + HAL::IDTLoader idt_loader; + idt_loader.Load(idt_reg); HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); @@ -162,13 +152,6 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { NeFS::fs_init_nefs(); #endif - HAL::Register64 idt_reg; - idt_reg.Base = reinterpret_cast<UIntPtr>(kInterruptVectorTable); - - HAL::IDTLoader idt_loader; - - idt_loader.Load(idt_reg); - while (YES) ; } diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index d7663f4e..b711b833 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -35,10 +35,6 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { return; } - FB::fb_clear_video(); - - kBitMapCursor = 0UL; - #ifdef __NE_ARM64_EFI__ fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]); @@ -46,31 +42,19 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { handover_hdr->f_HardwareTables.f_ImageHandle); #endif + FB::fb_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. - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { - HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard; - HardwareThreadScheduler::The()[index].Leak()->Busy(NO); - } - - for (SizeT index = 0UL; index < UserProcessScheduler::The().TheCurrentTeam().AsArray().Count(); - ++index) { - UserProcessScheduler::The().TheCurrentTeam().AsArray()[index].Status = - ProcessStatusKind::kInvalid; - } - - rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server. - rtl_create_user_process(sched_idle_task, "LaunchSrv"); //! launchd - rtl_create_user_process(sched_idle_task, "SecSrv"); //! Login Server - Kernel::mp_init_cores(); while (YES) diff --git a/dev/kernel/NeKit/CxxAbi.h b/dev/kernel/NeKit/CxxAbi.h index 164a257d..4b7bf002 100644 --- a/dev/kernel/NeKit/CxxAbi.h +++ b/dev/kernel/NeKit/CxxAbi.h @@ -7,7 +7,7 @@ #include <NeKit/Defines.h> -#ifndef __TOOLCHAINKIT__ +#ifndef __NECTI__ #define kAtExitMacDestructors (128) @@ -17,10 +17,10 @@ struct atexit_func_entry_t { void* dso_handle; }; -typedef unsigned uarch_t; +typedef Kernel::UInt32 uarch_t; namespace cxxabiv1 { -typedef void* __guard; +typedef Kernel::SizeT* __guard; } -#endif // __GNUC__ +#endif // !__NECTI__ diff --git a/dev/kernel/NeKit/ErrorOr.h b/dev/kernel/NeKit/ErrorOr.h index b653e0ee..52f0d6a9 100644 --- a/dev/kernel/NeKit/ErrorOr.h +++ b/dev/kernel/NeKit/ErrorOr.h @@ -38,6 +38,8 @@ class ErrorOr final { return *this; } + T Value() const { return *mRef; } + Ref<T>& Leak() { return mRef; } Int32 Error() { return mId; } diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index 711ea588..6cebf26c 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -70,7 +70,7 @@ ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) { @param len the length of it. */ bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) { - if (len == 0 || !checksum) return false; + if (len == 0 || !checksum) return NO; Char chr = 0; diff --git a/dev/kernel/src/AsciiUtils.cc b/dev/kernel/src/AsciiUtils.cc index 24e4e220..cca3a368 100644 --- a/dev/kernel/src/AsciiUtils.cc +++ b/dev/kernel/src/AsciiUtils.cc @@ -8,7 +8,7 @@ namespace Kernel { -Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size); +Int32 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); Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) { @@ -45,7 +45,7 @@ const Char* rt_alloc_string(const Char* src) { return buffer; } -Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size) { +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); @@ -85,7 +85,7 @@ rt_set_memory(voidPtr src, UInt32 value, Size len) { #ifdef __NE_ENFORCE_DEPRECATED_WARNINGS [[deprecated("Use rt_copy_memory_safe instead")]] #endif -Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len) { +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); @@ -134,11 +134,15 @@ Bool rt_to_string(Char* str, UInt64 value, Int32 base) { str[j] = str[i - j - 1]; str[i - j - 1] = tmp; } + + return YES; #endif - return true; + return NO; } 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); @@ -152,6 +156,7 @@ VoidPtr rt_string_in_string(const Char* haystack, const Char* needle) { } Char* rt_string_has_char(Char* str, Char ch) { + if (!str) return nullptr; while (*str && *str != ch) ++str; return (*str == ch) ? str : nullptr; } @@ -166,7 +171,7 @@ EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) { return dst; } -EXTERN_C Kernel::Int32 strcmp(const char* a, const char* b) { +EXTERN_C Int32 strcmp(const char* a, const char* b) { return Kernel::rt_string_cmp(a, b, rt_string_len(a)); } diff --git a/dev/kernel/src/FS/Ext2+FileSystemParser.cc b/dev/kernel/src/FS/Ext2+FileSystemParser.cc index 80449ed9..318f83d6 100644 --- a/dev/kernel/src/FS/Ext2+FileSystemParser.cc +++ b/dev/kernel/src/FS/Ext2+FileSystemParser.cc @@ -6,7 +6,7 @@ #ifdef __FSKIT_INCLUDES_EXT2__ -#include <FSKit/Ext2.h> +#include <FSKit/Ext2+IFS.h> #include <FirmwareKit/EPM.h> #include <KernelKit/KPC.h> #include <KernelKit/ProcessScheduler.h> diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 174862a4..07c4a572 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -438,7 +438,7 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im } (Void)(kout << "ProcessID: " << number(process.ProcessId) << kendl); - (Void)(kout << "Name: " << process.Name << kendl); + (Void)(kout << "ProcesName: " << process.Name << kendl); return pid; } diff --git a/dev/kernel/src/UtfUtils.cc b/dev/kernel/src/UtfUtils.cc index 907632ad..e98b8306 100644 --- a/dev/kernel/src/UtfUtils.cc +++ b/dev/kernel/src/UtfUtils.cc @@ -37,7 +37,7 @@ Int32 urt_string_cmp(const Utf8Char* src, const Utf8Char* cmp, Size size) { return counter; } -Int urt_copy_memory(const VoidPtr src, VoidPtr dst, Size len) { +Int32 urt_copy_memory(const VoidPtr src, VoidPtr dst, Size len) { Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src); Utf8Char* dstChar = reinterpret_cast<Utf8Char*>(dst); diff --git a/dev/launch/.keep b/dev/launch/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/dev/launch/.keep diff --git a/dev/launch/LaunchKit/.keep b/dev/launch/LaunchKit/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/dev/launch/LaunchKit/.keep diff --git a/dev/launch/LaunchKit/LaunchKit.h b/dev/launch/LaunchKit/LaunchKit.h new file mode 100644 index 00000000..2fa9607b --- /dev/null +++ b/dev/launch/LaunchKit/LaunchKit.h @@ -0,0 +1,20 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + + ------------------------------------------- */ + +#pragma once + +#include <libSystem/SystemKit/System.h> + +/// @author Amlal El Mahrouss +/// @brief NeKernel Launch Kit. + +#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 LaunchHandle = VoidPtr; +using KernelStatus = SInt32; +} // namespace Launch diff --git a/dev/launch/ne_launch.json b/dev/launch/ne_launch.json new file mode 100644 index 00000000..e3d26a46 --- /dev/null +++ b/dev/launch/ne_launch.json @@ -0,0 +1,20 @@ +{ + "compiler_path": "x86_64-w64-mingw32-g++", + "compiler_std": "c++20", + "headers_path": ["../", "./"], + "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/dev/launch/obj/.keep b/dev/launch/obj/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/dev/launch/obj/.keep diff --git a/dev/launch/src/.keep b/dev/launch/src/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/dev/launch/src/.keep diff --git a/dev/launch/src/CRT0.S b/dev/launch/src/CRT0.S new file mode 100644 index 00000000..84a293e6 --- /dev/null +++ b/dev/launch/src/CRT0.S @@ -0,0 +1,18 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + + ------------------------------------------- */ + + .text + +.extern nelaunch_startup_fn +.globl _NeMain + +_NeMain: + push %rbp + movq %rsp, %rbp + callq nelaunch_startup_fn + popq %rbp + + retq diff --git a/dev/launch/src/LaunchSrv.cc b/dev/launch/src/LaunchSrv.cc new file mode 100644 index 00000000..f5c9ee3c --- /dev/null +++ b/dev/launch/src/LaunchSrv.cc @@ -0,0 +1,17 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + + ------------------------------------------- */ + +#include <LaunchKit/LaunchKit.h> +#include <libSystem/SystemKit/Err.h> + +/// @note This called by _NeMain from its own runtime. +extern "C" SInt32 nelaunch_startup_fn(Void) { + /// @todo Start LaunchServices.fwrk services, make the launcher manageable too (via mgmt.launch) + + NELAUNCH_INFO("Starting NeKernel services..."); + + return kErrorSuccess; +} diff --git a/dev/libDDK/DriverKit/ddk.h b/dev/libDDK/DriverKit/ddk.h index 254137f9..2e2dddf0 100644 --- a/dev/libDDK/DriverKit/ddk.h +++ b/dev/libDDK/DriverKit/ddk.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss 2025, all rights reserved. FILE: ddk.h PURPOSE: DDK Driver model base header. @@ -29,6 +29,8 @@ struct DDK_STATUS_STRUCT DDK_FINAL { 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** diff --git a/dev/libDDK/DriverKit/dki/contract.h b/dev/libDDK/DriverKit/dki/contract.h new file mode 100644 index 00000000..23884e02 --- /dev/null +++ b/dev/libDDK/DriverKit/dki/contract.h @@ -0,0 +1,32 @@ +/* ------------------------------------------- + + Copyright Amlal El Mahrouss 2025, all rights reserved. + + FILE: ddk.h + PURPOSE: Driver Kernel Interface Model base header. + + ------------------------------------------- */ + +#pragma once + +#include <CompilerKit/CompilerKit.h> +#include <DriverKit/macros.h> + +#define DKI_CONTRACT_IMPL : public ::Kernel::DKIContract + +/// @author Amlal El Mahrouss + +namespace Kernel::DKI { +class DKIContract { + public: + explicit DKIContract() = default; + virtual ~DKIContract() = default; + + NE_COPY_DEFAULT(DKIContract); + + virtual BOOL IsCastable() { return false; } + virtual BOOL IsActive() { return false; } + virtual VoidPtr Leak() { return nullptr; } + virtual Int32 Type() { return 0; } +}; +} // namespace Kernel::DKI diff --git a/dev/libDDK/src/ddk_dev.c b/dev/libDDK/src/ddk_dev.c index 32ec2442..d20684aa 100644 --- a/dev/libDDK/src/ddk_dev.c +++ b/dev/libDDK/src/ddk_dev.c @@ -11,7 +11,7 @@ /// @brief Open a new binary device from path. DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath) { - if (!devicePath) return nil; + if (nil == devicePath) return nil; return ke_call_dispatch("dk_open_dev", 1, (void*) devicePath, kstrlen(devicePath)); } @@ -19,7 +19,7 @@ DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath) { /// @brief Close any device. /// @param device valid device. DDK_EXTERN BOOL close(DDK_DEVICE_PTR device) { - if (!device) return NO; + if (nil == device) return NO; ke_call_dispatch("dk_close_dev", 1, device, sizeof(DDK_DEVICE)); return YES; diff --git a/dev/libDDK/src/ddk_io.c b/dev/libDDK/src/ddk_io.c index c6cdd457..825e82a7 100644 --- a/dev/libDDK/src/ddk_io.c +++ b/dev/libDDK/src/ddk_io.c @@ -1,7 +1,9 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + libDDK. + Copyright 2025 - Amlal El Mahrouss and NeKernel contributors. + File: ddk_io.c Purpose: DDK Text I/O. ------------------------------------------- */ @@ -9,6 +11,8 @@ #include <DriverKit/io.h> DDK_EXTERN void kputc(const char ch) { + if (!ch) return; + char assembled[2] = {0}; assembled[0] = ch; assembled[1] = 0; @@ -19,7 +23,7 @@ DDK_EXTERN void kputc(const char ch) { /// @brief print string to UART. /// @param message UART to transmit. DDK_EXTERN void kprint(const char* message) { - if (!message) return; + if (nil == message) return; if (*message == 0) return; size_t index = 0; diff --git a/dev/libDDK/src/ddk_kernel_call.c b/dev/libDDK/src/ddk_kernel_call.c index 1ac0a0aa..5976665b 100644 --- a/dev/libDDK/src/ddk_kernel_call.c +++ b/dev/libDDK/src/ddk_kernel_call.c @@ -12,8 +12,8 @@ #include <stdarg.h> /// @brief this is an internal call, do not use it. -DDK_EXTERN ATTRIBUTE(naked) void* __ke_call_dispatch(const int32_t name, int32_t cnt, void* data, - size_t sz); +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. diff --git a/dev/libDDK/src/ddk_kernel_call_dispatch.S b/dev/libDDK/src/ddk_kernel_call_dispatch.S index 7b7a26cb..a607fe40 100644 --- a/dev/libDDK/src/ddk_kernel_call_dispatch.S +++ b/dev/libDDK/src/ddk_kernel_call_dispatch.S @@ -21,10 +21,11 @@ __ke_call_dispatch: push rbp mov rbp, rsp + /* registers have already been pushed. */ + int kKernelCallTrapId pop rbp - ret #elif defined(__DDK_POWER64__) diff --git a/dev/libDDK/src/ddk_str.c b/dev/libDDK/src/ddk_str.c index 514cddc7..1e2fde19 100644 --- a/dev/libDDK/src/ddk_str.c +++ b/dev/libDDK/src/ddk_str.c @@ -23,6 +23,8 @@ DDK_EXTERN size_t kstrlen(const char* in) { } 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) { diff --git a/dev/libSystem/SystemKit/Syscall.h b/dev/libSystem/SystemKit/Syscall.h index a1505b46..35bfc6f8 100644 --- a/dev/libSystem/SystemKit/Syscall.h +++ b/dev/libSystem/SystemKit/Syscall.h @@ -14,22 +14,8 @@ 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); -inline UInt64 libsys_hash_64(const Char* path) { - if (!path || *path == 0) return 0; - - const UInt64 FNV_OFFSET_BASIS = 0xcbf29ce484222325ULL; - const UInt64 FNV_PRIME = 0x100000001b3ULL; - - UInt64 hash = FNV_OFFSET_BASIS; - - while (*path) { - hash ^= (Char) (*path++); - hash *= FNV_PRIME; - } - - return hash; -} +IMPORT_C UInt64 libsys_hash_64(const Char* path); #ifndef SYSCALL_HASH #define SYSCALL_HASH(str) libsys_hash_64(str) -#endif // !SYSCALL_HASH
\ No newline at end of file +#endif // !SYSCALL_HASH diff --git a/dev/libSystem/SystemKit/Verify.h b/dev/libSystem/SystemKit/Verify.h new file mode 100644 index 00000000..cbf85830 --- /dev/null +++ b/dev/libSystem/SystemKit/Verify.h @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + + File: Verify.h + Purpose: System Call Interface Verification Layer. + + ------------------------------------------- */ + +#pragma once + +#include <libSystem/SystemKit/System.h> + +namespace LibSystem::Detail { +/// @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 a mismatch!"); + return static_cast<R*>(ptr); +} +} // namespace LibSystem::Detail diff --git a/dev/libSystem/src/System.cc b/dev/libSystem/src/System.cc index 3870ff18..da9931fe 100644 --- a/dev/libSystem/src/System.cc +++ b/dev/libSystem/src/System.cc @@ -7,14 +7,9 @@ #include <libSystem/SystemKit/Err.h>
#include <libSystem/SystemKit/Syscall.h>
#include <libSystem/SystemKit/System.h>
+#include <libSystem/SystemKit/Verify.h>
-namespace Detail {
-template <typename T>
-static VoidPtr safe_void_cast(const T* ptr) {
- _rtl_assert(ptr, "safe void cast failed!");
- return static_cast<VoidPtr>(const_cast<T*>(ptr));
-}
-} // namespace Detail
+using namespace LibSystem;
IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) {
if (!expr) {
@@ -23,6 +18,29 @@ IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) { }
}
+/// @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;
+}
+
+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
@@ -41,8 +59,9 @@ IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input Si // 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);
+ 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) {
@@ -88,9 +107,11 @@ IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input Si IMPORT_C SInt64 MmStrLen(const Char* in) {
// strlen via pointer walk
- if (!in) return 0;
+ if (!in) return -kErrorInvalidData;
+
const Char* p = in;
while (*p) ++p;
+
return static_cast<SInt64>(p - in);
}
@@ -125,9 +146,8 @@ IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt }
IMPORT_C Ref IoOpenFile(_Input const Char* path, _Input const Char* drv_letter) {
- return static_cast<Ref>(libsys_syscall_arg_3(SYSCALL_HASH("IoOpenFile"),
- Detail::safe_void_cast(path),
- Detail::safe_void_cast(drv_letter)));
+ return static_cast<Ref>(libsys_syscall_arg_3(
+ SYSCALL_HASH("IoOpenFile"), Detail::sys_safe_cast(path), Detail::sys_safe_cast(drv_letter)));
}
IMPORT_C Void IoCloseFile(_Input Ref desc) {
@@ -163,7 +183,7 @@ IMPORT_C SInt32 PrintOut(_Input IORef desc, const Char* fmt, ...) { // if truncated, `needed` >= kBufferSz; we still send truncated buffer
auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("PrintOut"), static_cast<VoidPtr>(desc),
- Detail::safe_void_cast(buf));
+ Detail::sys_safe_cast(buf));
if (!ret_ptr) return -kErrorInvalidData;
diff --git a/dev/misc/BenchKit/HWChronometer.h b/dev/misc/BenchKit/HWChronometer.h index e232db7e..56e4f2af 100644 --- a/dev/misc/BenchKit/HWChronometer.h +++ b/dev/misc/BenchKit/HWChronometer.h @@ -14,7 +14,7 @@ struct HWChronoTraits; template <typename ChronoTraits = HWChronoTraits> class HWChrono; -/// @brief BenchKit chrono logic for x64. +/// @brief BenchKit chrono logic for x64/ARM64. struct HWChronoTraits final { private: STATIC UInt64 TickImpl_(void) { diff --git a/public/frameworks/LaunchHelpers.fwrk/.keep b/public/frameworks/LaunchHelpers.fwrk/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/.keep diff --git a/public/frameworks/LaunchHelpers.fwrk/LaunchHelpers.json b/public/frameworks/LaunchHelpers.fwrk/LaunchHelpers.json new file mode 100644 index 00000000..9ec17332 --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/LaunchHelpers.json @@ -0,0 +1,19 @@ +{ + "compiler_path": "clang++", + "compiler_std": "c++20", + "headers_path": [ + "./", + "../../../dev/kernel", + "../../../public/frameworks/", + "../../../dev/", + "./" + ], + "sources_path": [], + "output_name": "./dist/libLaunchHelpers.fwrk.dylib", + "cpp_macros": [ + "kSampleFWVersion=0x0100", + "kSampleFWVersionHighest=0x0100", + "kSampleFWVersionLowest=0x0100", + "__NE_SDK__" + ] +}
\ No newline at end of file diff --git a/public/frameworks/LaunchHelpers.fwrk/dist/.keep b/public/frameworks/LaunchHelpers.fwrk/dist/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/dist/.keep diff --git a/public/frameworks/LaunchHelpers.fwrk/headers/.keep b/public/frameworks/LaunchHelpers.fwrk/headers/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/headers/.keep diff --git a/public/frameworks/LaunchHelpers.fwrk/src/.keep b/public/frameworks/LaunchHelpers.fwrk/src/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/src/.keep diff --git a/public/frameworks/LaunchHelpers.fwrk/src/DylibMain.cc b/public/frameworks/LaunchHelpers.fwrk/src/DylibMain.cc new file mode 100644 index 00000000..99eebd26 --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/src/DylibMain.cc @@ -0,0 +1,5 @@ +#include <libSystem/SystemKit/System.h> + +SInt32 _DylibAttach(SInt32 argc, Char* argv[]) { + return EXIT_FAILURE; +}
\ No newline at end of file diff --git a/public/frameworks/LaunchHelpers.fwrk/xml/.keep b/public/frameworks/LaunchHelpers.fwrk/xml/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/xml/.keep diff --git a/public/frameworks/LaunchHelpers.fwrk/xml/app.xml b/public/frameworks/LaunchHelpers.fwrk/xml/app.xml new file mode 100644 index 00000000..6bc3a3f4 --- /dev/null +++ b/public/frameworks/LaunchHelpers.fwrk/xml/app.xml @@ -0,0 +1,2 @@ +<PropertyList> +<PLEntry Type="CFString" Name="LibraryName" Len="18" Value="LaunchHelpers.fwrk" /></PropertyList>
\ No newline at end of file diff --git a/public/manuals/nekernel/mgmt.hefs.util.man b/public/manuals/nekernel/mgmt.hefs.util.man new file mode 100644 index 00000000..3274f93a --- /dev/null +++ b/public/manuals/nekernel/mgmt.hefs.util.man @@ -0,0 +1,34 @@ +NAME + mgmt.hefs — HeFS Management utility command + +SYNOPSIS + mgmt.hefs [OPTIONS] + +DESCRIPTION + The `mgmt.hefs` command provides scheduling, execution, and remote orchestration + of a HeFS volume inside a System One environement. One might use this tool to + create, edit, and remove volumes from a disk. + + Usages include, but are not limited to: + - Schedule scripts or tasks for future execution. + - Verify device or filesystem integrity. + - Manage and automate remote NeKernel machines. + +OPTIONS + -v, --volume <DEVICE> Device input + -c, --create Create HeFS volume + -x, --xml <PLIST> Pass PropertyList to volume creation tool. + -t, --time <HH:MMAM/PM> Time to run the script + -d, --day <DAY> Day of the week (e.g., Mon, Tue, Wed) + -m, --month <MONTH> Month (e.g., Jan, Feb, Mar) + -y, --year <YYYY> Year to schedule task + -r, --remote <ADDRESS> Remote machine to manage (optional) + -v, --verify Run integrity checks only + -h, --help Display this help message + +EXAMPLES + mgmt.hefs -v /devices/disks0p0 -t 2:30PM -d Wed -m Apr -y 2026 --xml /xml/hefs.pxml + Schedules `/xml/hefs.pxml` to run at 2:30PM on Wednesday, April 2026. + +RELEASE + v1.0.0 — NeKernel.org diff --git a/public/tools/mgmt.launch/.keep b/public/tools/mgmt.launch/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/tools/mgmt.launch/.keep diff --git a/public/tools/mgmt.launch/dist/.keep b/public/tools/mgmt.launch/dist/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/tools/mgmt.launch/dist/.keep diff --git a/public/tools/mgmt.launch/mgmt.launch.json b/public/tools/mgmt.launch/mgmt.launch.json new file mode 100644 index 00000000..a181d745 --- /dev/null +++ b/public/tools/mgmt.launch/mgmt.launch.json @@ -0,0 +1,19 @@ +{ + "compiler_path": "clang++", + "compiler_std": "c++20", + "headers_path": [ + "./", + "../../../dev/kernel", + "../../../public/frameworks/", + "../../../dev/", + "./" + ], + "sources_path": [], + "output_name": "./dist/mgmt.launch", + "cpp_macros": [ + "kSampleFWVersion=0x0100", + "kSampleFWVersionHighest=0x0100", + "kSampleFWVersionLowest=0x0100", + "__NE_SDK__" + ] +}
\ No newline at end of file diff --git a/public/tools/mgmt.launch/src/.keep b/public/tools/mgmt.launch/src/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/tools/mgmt.launch/src/.keep diff --git a/public/tools/mgmt.launch/src/CommandLine.cc b/public/tools/mgmt.launch/src/CommandLine.cc new file mode 100644 index 00000000..6015988e --- /dev/null +++ b/public/tools/mgmt.launch/src/CommandLine.cc @@ -0,0 +1,5 @@ +#include <libSystem/SystemKit/System.h> + +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + return EXIT_FAILURE; +}
\ No newline at end of file diff --git a/public/tools/mgmt.launch/vendor/.keep b/public/tools/mgmt.launch/vendor/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/public/tools/mgmt.launch/vendor/.keep |
