summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
Diffstat (limited to 'dev')
-rw-r--r--dev/boot/amd64-desktop.make6
-rw-r--r--dev/kernel/FSKit/Ext2+IFS.h140
-rw-r--r--dev/kernel/FSKit/Ext2.h202
-rw-r--r--dev/kernel/FSKit/Ext2IFS.h133
-rw-r--r--dev/kernel/HALKit/AMD64/CxxAbi.cc15
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc13
-rw-r--r--dev/kernel/HALKit/AMD64/HalKernelMain.cc39
-rw-r--r--dev/kernel/HALKit/ARM64/HalKernelMain.cc22
-rw-r--r--dev/kernel/NeKit/CxxAbi.h8
-rw-r--r--dev/kernel/NeKit/ErrorOr.h2
-rw-r--r--dev/kernel/src/ACPIFactoryInterface.cc2
-rw-r--r--dev/kernel/src/AsciiUtils.cc15
-rw-r--r--dev/kernel/src/FS/Ext2+FileSystemParser.cc2
-rw-r--r--dev/kernel/src/UserProcessScheduler.cc2
-rw-r--r--dev/kernel/src/UtfUtils.cc2
-rw-r--r--dev/launch/.keep0
-rw-r--r--dev/launch/LaunchKit/.keep0
-rw-r--r--dev/launch/LaunchKit/LaunchKit.h20
-rw-r--r--dev/launch/ne_launch.json20
-rw-r--r--dev/launch/obj/.keep0
-rw-r--r--dev/launch/src/.keep0
-rw-r--r--dev/launch/src/CRT0.S18
-rw-r--r--dev/launch/src/LaunchSrv.cc17
-rw-r--r--dev/libDDK/DriverKit/ddk.h4
-rw-r--r--dev/libDDK/DriverKit/dki/contract.h32
-rw-r--r--dev/libDDK/src/ddk_dev.c4
-rw-r--r--dev/libDDK/src/ddk_io.c8
-rw-r--r--dev/libDDK/src/ddk_kernel_call.c4
-rw-r--r--dev/libDDK/src/ddk_kernel_call_dispatch.S3
-rw-r--r--dev/libDDK/src/ddk_str.c2
-rw-r--r--dev/libSystem/SystemKit/Syscall.h18
-rw-r--r--dev/libSystem/SystemKit/Verify.h40
-rw-r--r--dev/libSystem/src/System.cc48
-rw-r--r--dev/misc/BenchKit/HWChronometer.h2
34 files changed, 492 insertions, 351 deletions
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) {