From d3f87b1b84d355ad72366ced5d7e5a43207226c0 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 7 Sep 2025 23:29:48 +0200 Subject: feat: kernel: startup sequence fix, and new mgmt.hefs manual. wip: LaunchKit for the `ne_launch` program. Signed-off-by: Amlal El Mahrouss --- dev/launch/LaunchKit/LaunchKit.h | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 dev/launch/LaunchKit/LaunchKit.h (limited to 'dev/launch/LaunchKit/LaunchKit.h') diff --git a/dev/launch/LaunchKit/LaunchKit.h b/dev/launch/LaunchKit/LaunchKit.h new file mode 100644 index 00000000..95d91e09 --- /dev/null +++ b/dev/launch/LaunchKit/LaunchKit.h @@ -0,0 +1,9 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + + ------------------------------------------- */ + +#pragma once + +#include -- cgit v1.2.3 From e55f246042a12955200e20abe406b26ab02b94fa Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 9 Sep 2025 11:38:39 +0200 Subject: feat: launch: Working on LaunchKit's implementation. Signed-off-by: Amlal El Mahrouss --- .gitignore | 3 +++ dev/launch/LaunchKit/LaunchKit.h | 9 +++++++++ dev/launch/ne_launch.json | 20 ++++++++++++++++++++ dev/launch/src/LaunchSrv.cc | 5 +++-- 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 dev/launch/ne_launch.json (limited to 'dev/launch/LaunchKit/LaunchKit.h') diff --git a/.gitignore b/.gitignore index 1144fd7a..329688e2 100644 --- a/.gitignore +++ b/.gitignore @@ -137,6 +137,9 @@ local.properties # Locally stored "Eclipse launch configurations" # *.launch +# NeKernel Launch +ne_launch + # PyDev specific (Python IDE for Eclipse) *.pydevproject diff --git a/dev/launch/LaunchKit/LaunchKit.h b/dev/launch/LaunchKit/LaunchKit.h index 95d91e09..1a134e8f 100644 --- a/dev/launch/LaunchKit/LaunchKit.h +++ b/dev/launch/LaunchKit/LaunchKit.h @@ -7,3 +7,12 @@ #pragma once #include + +/// @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) + +using LaunchHandle = VoidPtr; +using KernelStatus = SInt32; diff --git a/dev/launch/ne_launch.json b/dev/launch/ne_launch.json new file mode 100644 index 00000000..38379de9 --- /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"], + "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/src/LaunchSrv.cc b/dev/launch/src/LaunchSrv.cc index 8c302c6d..40027f65 100644 --- a/dev/launch/src/LaunchSrv.cc +++ b/dev/launch/src/LaunchSrv.cc @@ -5,11 +5,12 @@ ------------------------------------------- */ #include +#include SInt32 _NeMain(Void) { - PrintOut(nullptr, "%s", "NeKernel Launcher\n"); + /// @todo Start LaunchServices.fwrk services, make the launcher manageable too (via mgmt.launch) - /// @todo Start LaunchServices.fwrk, make the launcher manageable too (via mgmt.launch) + NELAUNCH_INFO("Starting services..."); return kErrorSuccess; } -- cgit v1.2.3 From b1e3dac861c0d6c28bdb7768d7f96f19456e9ad0 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 9 Sep 2025 21:28:04 +0200 Subject: feat:! ddk/dki, ne_launch, ifs: Big architectural changes and improvements. Signed-off-by: Amlal El Mahrouss --- dev/kernel/FSKit/Ext2+IFS.h | 140 +++++++++++++++++++++++++++++ dev/kernel/FSKit/Ext2IFS.h | 135 ---------------------------- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 2 +- dev/kernel/HALKit/ARM64/HalKernelMain.cc | 2 +- dev/kernel/src/FS/Ext2+FileSystemParser.cc | 2 +- dev/launch/LaunchKit/LaunchKit.h | 2 + dev/launch/ne_launch.json | 2 +- dev/launch/src/CRT0.S | 17 ++++ dev/launch/src/LaunchSrv.cc | 5 +- dev/libDDK/DriverKit/cpp/object.hpp | 16 ---- dev/libDDK/DriverKit/dki/contract.h | 32 +++++++ dev/libSystem/src/System.cc | 15 +++- 12 files changed, 210 insertions(+), 160 deletions(-) create mode 100644 dev/kernel/FSKit/Ext2+IFS.h delete mode 100644 dev/kernel/FSKit/Ext2IFS.h create mode 100644 dev/launch/src/CRT0.S delete mode 100644 dev/libDDK/DriverKit/cpp/object.hpp create mode 100644 dev/libDDK/DriverKit/dki/contract.h (limited to 'dev/launch/LaunchKit/LaunchKit.h') 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 +#include +#include +#include +#include +#include +#include + +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(buffer); + pkt.fPacketSize = size; + pkt.fPacketLba = lba; + drv->fOutput(pkt); + return pkt.fPacketGood; +} + +inline Kernel::ErrorOr ext2_load_superblock(Ext2Context* ctx) { + if (!ctx || !ctx->drive) return Kernel::ErrorOr(Kernel::kErrorInvalidData); + + auto buf = Kernel::mm_alloc_ptr(sizeof(EXT2_SUPER_BLOCK), true, false); + if (!buf) return Kernel::ErrorOr(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(Kernel::kErrorDisk); + } + + auto sb = reinterpret_cast(buf); + if (sb->fMagic != kExt2FSMagic) { + Kernel::mm_free_ptr(buf); + return Kernel::ErrorOr(Kernel::kErrorInvalidData); + } + + ctx->superblock = sb; + return Kernel::ErrorOr(sb); +} + +// Load inode +inline Kernel::ErrorOr ext2_load_inode(Ext2Context* ctx, Kernel::UInt32 inodeNumber) { + if (!ctx || !ctx->superblock) return Kernel::ErrorOr(Kernel::kErrorInvalidData); + + auto nodePtr = Kernel::mm_alloc_ptr(sizeof(Ext2Node), true, false); + if (!nodePtr) return Kernel::ErrorOr(Kernel::kErrorHeapOutOfMemory); + + auto ext2Node = reinterpret_cast(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(Kernel::kErrorDisk); + } + + ext2Node->cursor = 0; + return Kernel::ErrorOr(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/Ext2IFS.h b/dev/kernel/FSKit/Ext2IFS.h deleted file mode 100644 index 2550cfea..00000000 --- a/dev/kernel/FSKit/Ext2IFS.h +++ /dev/null @@ -1,135 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -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(buffer); - pkt.fPacketSize = size; - pkt.fPacketLba = lba; - drv->fOutput(pkt); - return pkt.fPacketGood; -} - -// Load superblock -inline Kernel::ErrorOr ext2_load_superblock(Context* ctx) { - if (!ctx || !ctx->drive) return Kernel::ErrorOr(Kernel::kErrorInvalidData); - - auto buf = Kernel::mm_alloc_ptr(sizeof(EXT2_SUPER_BLOCK), true, false); - if (!buf) return Kernel::ErrorOr(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(Kernel::kErrorDisk); - } - - auto sb = reinterpret_cast(buf); - if (sb->fMagic != kExt2FSMagic) { - Kernel::mm_free_ptr(buf); - return Kernel::ErrorOr(Kernel::kErrorInvalidData); - } - - ctx->superblock = sb; - return Kernel::ErrorOr(sb); -} - -// Load inode -inline Kernel::ErrorOr ext2_load_inode(Context* ctx, Kernel::UInt32 inodeNumber) { - if (!ctx || !ctx->superblock) return Kernel::ErrorOr(Kernel::kErrorInvalidData); - - auto nodePtr = Kernel::mm_alloc_ptr(sizeof(Ext2Node), true, false); - if (!nodePtr) return Kernel::ErrorOr(Kernel::kErrorHeapOutOfMemory); - - auto ext2Node = reinterpret_cast(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(Kernel::kErrorDisk); - } - - ext2Node->cursor = 0; - return Kernel::ErrorOr(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/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 16670f5c..6f4d7e0a 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -119,7 +119,7 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { kGDTArray[4].fBaseHigh = 0; FB::fb_clear_video(); - + // Load memory descriptors. HAL::Register64 gdt_reg; diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index 240b3ac8..b711b833 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -48,7 +48,7 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { /* INITIALIZE BIT MAP. */ /************************************** */ - kBitMapCursor = 0UL; + kBitMapCursor = 0UL; kKernelBitMpSize = kHandoverHeader->f_BitMapSize; kKernelBitMpStart = reinterpret_cast( reinterpret_cast(kHandoverHeader->f_BitMapStart)); 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 +#include #include #include #include diff --git a/dev/launch/LaunchKit/LaunchKit.h b/dev/launch/LaunchKit/LaunchKit.h index 1a134e8f..2fa9607b 100644 --- a/dev/launch/LaunchKit/LaunchKit.h +++ b/dev/launch/LaunchKit/LaunchKit.h @@ -14,5 +14,7 @@ #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 index 38379de9..e3d26a46 100644 --- a/dev/launch/ne_launch.json +++ b/dev/launch/ne_launch.json @@ -2,7 +2,7 @@ "compiler_path": "x86_64-w64-mingw32-g++", "compiler_std": "c++20", "headers_path": ["../", "./"], - "sources_path": ["src/*.cc"], + "sources_path": ["src/*.cc", "src/*.S"], "output_name": "ne_launch", "compiler_flags": [ "-ffreestanding", diff --git a/dev/launch/src/CRT0.S b/dev/launch/src/CRT0.S new file mode 100644 index 00000000..ffc7398a --- /dev/null +++ b/dev/launch/src/CRT0.S @@ -0,0 +1,17 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + + ------------------------------------------- */ + + .text + +.extern nelaunch_startup_fn + +_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 index 40027f65..f5c9ee3c 100644 --- a/dev/launch/src/LaunchSrv.cc +++ b/dev/launch/src/LaunchSrv.cc @@ -7,10 +7,11 @@ #include #include -SInt32 _NeMain(Void) { +/// @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 services..."); + NELAUNCH_INFO("Starting NeKernel services..."); return kErrorSuccess; } diff --git a/dev/libDDK/DriverKit/cpp/object.hpp b/dev/libDDK/DriverKit/cpp/object.hpp deleted file mode 100644 index 3bf52657..00000000 --- a/dev/libDDK/DriverKit/cpp/object.hpp +++ /dev/null @@ -1,16 +0,0 @@ -/* ------------------------------------------- - - Copyright Amlal El Mahrouss 2025, all rights reserved. - - FILE: ddk.h - PURPOSE: DDK Driver model base header. - - ------------------------------------------- */ - -#pragma once - -#include - -#define DK_INTERFACE_IMPL : public ::DKInterface - -class DKInterface; 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 +#include + +#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/libSystem/src/System.cc b/dev/libSystem/src/System.cc index ba848a18..2215c4d8 100644 --- a/dev/libSystem/src/System.cc +++ b/dev/libSystem/src/System.cc @@ -40,6 +40,12 @@ IMPORT_C UInt64 libsys_hash_64(const Char* path) { return hash; } +IMPORT_C Char* StrFmt(const Char* fmt, ...) { + if (!fmt || *fmt == 0) return const_cast("(null)"); + + return const_cast(""); +} + // 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 @@ -58,8 +64,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(rs) % sizeof(UInt64) == 0) && (reinterpret_cast(rd) % sizeof(UInt64) == 0)) { - auto rsw = reinterpret_cast(rs); - auto rdw = reinterpret_cast(rd); + auto rsw = reinterpret_cast(rs); + auto rdw = reinterpret_cast(rd); + SizeT words = len / sizeof(UInt64); for (SizeT i = 0; i < words; ++i) { @@ -105,9 +112,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(p - in); } -- cgit v1.2.3