diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-08-16 19:56:21 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-16 19:56:21 +0200 |
| commit | 1a32b9307357ac0fc9095e853b2b6d94f9fe62bb (patch) | |
| tree | f41f723659c8926e38182fbe062746d821ab487e | |
| parent | eb9df5eea339812513c25a8d3b2eeb03c633e7ac (diff) | |
| parent | b301047903b79560dce69085fc271a653a1eb4b6 (diff) | |
Merge pull request #55 from nekernel-org/dev
v0.0.4
177 files changed, 1858 insertions, 941 deletions
@@ -25,8 +25,8 @@ ne_bootz neoskrnl/neoskrnl.xcodeproj/project.xcworkspace/xcshareddata/ -tooling/dist/mkfs.* -tooling/dist/fsck.* +tools/dist/mkfs.* +tools/dist/fsck.* html/ latex/ diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 00000000..5725fd6a --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,25 @@ +# This CITATION.cff file was generated with cffinit. +# Visit https://bit.ly/cffinit to generate yours today! + +cff-version: 1.2.0 +title: NeKernel.org Operating System Kernel +message: The Operating System Kernel of NeKernel.org +type: software +authors: + - given-names: Amlal + family-names: El Mahrouss + email: aelmahrouss@acm.org +identifiers: + - type: url + value: 'https://nekernel.org' + description: NeKernel's website. +repository-code: 'https://github.com/nekernel-org/nekernel' +url: 'https://nekernel.org' +abstract: >- + This is NeKernel.org's Operating System Kernel, authored + by Amlal El Mahrouss. +keywords: + - kernel + - operating-system + - cpp +license: GPL-3.0 @@ -2,6 +2,6 @@ /dev/kernel/ @amlel-el-mahrouss
/dev/boot/ @amlel-el-mahrouss
/dev/ddk/ @amlel-el-mahrouss
-/dev/open_msg/ @amlel-el-mahrouss
-/dev/libSystem/ @amlel-el-mahrouss
-# some other parts (tooling, frameworks) need ownership too.
\ No newline at end of file +/dev/libMsg/ @0xf00sec
+/dev/libSystem/ @0xf00sec
+# some other parts (tools, frameworks) need ownership too.
\ No newline at end of file @@ -7,8 +7,8 @@ <b>Modern, Modular, and Secure Microkernel for Next-Generation Systems</b> </p> <p> - <a href="https://github.com/amlel-el-mahrouss/nekernel/actions/workflows/boot-pio.yml"><img src="https://github.com/amlel-el-mahrouss/nekernel/actions/workflows/boot-pio.yml/badge.svg" alt="CI"></a> - <a href="https://github.com/amlel-el-mahrouss/nekernel/actions/workflows/kernel-ahci.yml"><img src="https://github.com/amlel-el-mahrouss/nekernel/actions/workflows/kernel-ahci.yml/badge.svg" alt="CI"></a> + <a href="https://github.com/nekernel-org/nekernel/actions/workflows/boot-pio.yml"><img src="https://github.com/amlel-el-mahrouss/nekernel/actions/workflows/boot-pio.yml/badge.svg" alt="CI"></a> + <a href="https://github.com/nekernel-org/nekernel/actions/workflows/kernel-ahci.yml"><img src="https://github.com/amlel-el-mahrouss/nekernel/actions/workflows/kernel-ahci.yml/badge.svg" alt="CI"></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0-blue.svg" alt="License"></a> <img src="https://img.shields.io/badge/QEMU-Tested-success" alt="QEMU Tested"> </p> @@ -18,7 +18,7 @@ ## Overview -**NeKernel** is a modern, multi-platform microkernel designed for security, modularity, and performance. It features a custom VFS, advanced memory management, a flexible DDK (Driver Development Kit), and robust userland tooling. NeKernel is built for research, education, and next-generation OS development. +**NeKernel** is a modern, multi-platform microkernel designed for security, modularity, and performance. It features a custom VFS, advanced memory management, a flexible DDK (Driver Development Kit), and robust userland tools. NeKernel is built for research, education, and next-generation OS development. --- @@ -36,9 +36,9 @@ - **System Call Interface**: low-level syscall ABI, with a stable high-level SDK for user applications. System calls are routed through a syscall manager and abstracted by `libSystem`. -- **Security and Robustness**: kernel and tooling (bounds checks, safe memory copy/set, error codes). Kernel panics and error reporting for critical failures. No dynamic code loading in kernel space. +- **Security and Robustness**: kernel and tools (bounds checks, safe memory copy/set, error codes). Kernel panics and error reporting for critical failures. No dynamic code loading in kernel space. -- **Documentation and Specs**: Full LaTeX specifications for HeFS and NeFS, with on-disk structure diagrams and API documentation. Markdown docs for tooling and usage. +- **Documentation and Specs**: Full LaTeX specifications for HeFS and NeFS, with on-disk structure diagrams and API documentation. Markdown docs for tools and usage. - **Cross-Platform Boot Support**: Bootloader and platform code for AMD64 and ARM64, with handover and hardware abstraction layers. @@ -49,10 +49,10 @@ ## Getting Started ### **Requirements** -- [MINGW-W64](https://www.mingw-w64.org/) (cross-compiling) -- [CLANG](https://clang.llvm.org/) +- [MinGW](https://www.mingw-w64.org/) (cross-compiling) +- [Clang](https://clang.llvm.org/) - [NASM](https://nasm.us/) -- [BTB](https://github.com/nekernel-org/btb) (build system) +- [NeBuild](https://github.com/nekernel-org/nebuild) (build system) ### **Build & Run** @@ -88,7 +88,7 @@ cd nekernel ## Documentation -- [API Reference (Doxygen)](https://nekernel-org.github.io/docs/) +- [API Reference (Doxygen)](https://nekernel-org.github.io/doc/) - [Filesystem Specifications](docs/tex/) --- diff --git a/compile_flags.txt b/compile_flags.txt index 2005c689..828dc123 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -3,7 +3,7 @@ -Idev/user -Idev/boot -Idev/system_sdk --Idev/generic_kits +-Idev/misc -Idev/ddk -Ipublic/tools -Ipublic/tools/mk.app @@ -15,10 +15,11 @@ -Ipublic/tools/open -Ipublic/frameworks -Idev/boot/BootKit --Itooling/ +-Itools/ -I./ -std=c++20 -D__NE_AMD64__ +-D__NE_ARM64__ -D__NEOSKRNL__ -D__NE_ED__ -xc++ diff --git a/debug_ahci_x64.sh b/debug_ahci_x64.sh index 66121bb7..97ff57ee 100755 --- a/debug_ahci_x64.sh +++ b/debug_ahci_x64.sh @@ -11,6 +11,6 @@ cd ../boot make -f amd64-desktop.make all make -f amd64-desktop.make disk cd ../../ -./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root +./tools/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot make -f amd64-desktop.make run-efi-amd64-ahci
\ No newline at end of file diff --git a/debug_ata_x64.sh b/debug_ata_x64.sh index 6f40887b..b021c3ed 100755 --- a/debug_ata_x64.sh +++ b/debug_ata_x64.sh @@ -11,6 +11,6 @@ cd ../boot make -f amd64-desktop.make all make -f amd64-desktop.make disk cd ../../ -./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root +./tools/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot make -f amd64-desktop.make run-efi-amd64-ata-pio diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index 68e4b484..12a5861f 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -293,16 +293,16 @@ inline Boolean BDiskFormatFactory<BootDev>::Format(const Char* part_name) { CopyMem(gpt_part->Signature, reinterpret_cast<VoidPtr>(const_cast<Char*>(kMagicGPT)), StrLen(kMagicGPT)); - gpt_part->Revision = 0x00010000; + gpt_part->Revision = 0x00010000; gpt_part->HeaderSize = sizeof(GPT_PARTITION_TABLE); gpt_part->CRC32 = 0x00000000; - gpt_part->Reserved1 = 0x00000000; - gpt_part->LBAHeader = 0x00000000; - gpt_part->LBAAltHeader = 0x00000000; + gpt_part->Reserved1 = 0x00000000; + gpt_part->LBAHeader = 0x00000000; + gpt_part->LBAAltHeader = 0x00000000; gpt_part->FirstGPTEntry = 0x00000000; - gpt_part->LastGPTEntry = 0x00000000; + gpt_part->LastGPTEntry = 0x00000000; gpt_part->Guid.Data1 = 0x00000000; gpt_part->Guid.Data2 = 0x0000; @@ -312,10 +312,10 @@ inline Boolean BDiskFormatFactory<BootDev>::Format(const Char* part_name) { gpt_part->Revision = 0x00010000; - gpt_part->StartingLBA = 0x00000000; + gpt_part->StartingLBA = 0x00000000; gpt_part->NumPartitionEntries = 0x00000000; - gpt_part->SizeOfEntries = 0x00000000; - gpt_part->CRC32PartEntry = 0x00000000; + gpt_part->SizeOfEntries = 0x00000000; + gpt_part->CRC32PartEntry = 0x00000000; SetMem(gpt_part->Reserved2, 0, kSectorAlignGPT_PartTbl); diff --git a/dev/boot/BootKit/Device.h b/dev/boot/BootKit/Device.h index 6ae8cd6b..9a80e3c9 100644 --- a/dev/boot/BootKit/Device.h +++ b/dev/boot/BootKit/Device.h @@ -9,8 +9,7 @@ #include <modules/AHCI/AHCI.h> #include <modules/ATA/ATA.h> -using namespace Kernel; - +namespace Kernel { /// @brief Device type. class Device { public: @@ -33,3 +32,4 @@ class Device { typedef Device BootDevice; typedef Device NetworkDevice; typedef Device DiskDevice; +} // namespace Kernel
\ No newline at end of file diff --git a/dev/boot/modules/BootNet/BootNet.cc b/dev/boot/modules/BootNet/BootNet.cc index 8236dd0d..d8ea5799 100644 --- a/dev/boot/modules/BootNet/BootNet.cc +++ b/dev/boot/modules/BootNet/BootNet.cc @@ -12,8 +12,8 @@ #include <FirmwareKit/EFI/API.h> #include <modules/BootNet/BootNet.h> -STATIC EFI_GUID kEfiSimpleProtoGUID = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; -STATIC EFI_SIMPLE_NETWORK_PROTOCOL* kEfiProtocol = nullptr; +STATIC EFI_GUID kEfiSimpleProtoGUID = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; +STATIC EFI_SIMPLE_NETWORK_PROTOCOL* kEfiProtocol = nullptr; STATIC Void bootnet_read_ip_packet(BOOTNET_INTERNET_HEADER inet, BOOTNET_INTERNET_HEADER** inet_out); diff --git a/dev/boot/modules/BootNet/BootNet.h b/dev/boot/modules/BootNet/BootNet.h index 0b319387..3e876d09 100644 --- a/dev/boot/modules/BootNet/BootNet.h +++ b/dev/boot/modules/BootNet/BootNet.h @@ -9,4 +9,4 @@ #pragma once -#include <FirmwareKit/CoreBoot/BootNet.h> +#include <FirmwareKit/NeBoot/BootNet.h> diff --git a/dev/boot/src/BootSupport.cc b/dev/boot/src/BootSupport.cc index ce824e0f..4bf3e68a 100644 --- a/dev/boot/src/BootSupport.cc +++ b/dev/boot/src/BootSupport.cc @@ -18,6 +18,69 @@ /// @param dst destination pointer. /// @param byte value to fill in. /// @param len length of of src. +EXTERN_C VoidPtr memnset(void* dst, int byte, long long unsigned int len, + long long unsigned int dst_size) { + if (!dst || len > dst_size) { + // For now, we return nullptr or an error status. + return nullptr; + } + unsigned char* p = (unsigned char*) dst; + unsigned char val = (unsigned char) byte; + for (size_t i = 0UL; i < len; ++i) { + p[i] = val; + } + return dst; +} + +/// @brief memcpy definition in C++. +/// @param dst destination pointer. +/// @param src source pointer. +/// @param len length of of src. +EXTERN_C VoidPtr memncpy(void* dst, const void* src, long long unsigned int len, + long long unsigned int dst_size) { + if (!dst || !src || len > dst_size) { + // Similar to memset, this is a critical failure. + return nullptr; + } + unsigned char* d = (unsigned char*) dst; + const unsigned char* s = (const unsigned char*) src; + for (size_t i = 0UL; i < len; ++i) { + d[i] = s[i]; + } + return dst; +} + +/// @brief strlen definition in C++. +EXTERN_C size_t strnlen(const char* whatToCheck, size_t max_len) { + size_t len = 0; + while (len < max_len && whatToCheck[len] != '\0') { + ++len; + } + return len; +} + +/// @brief strcmp definition in C++. +EXTERN_C int strncmp(const char* whatToCheck, const char* whatToCheckRight, size_t max_len) { + size_t i = 0; + while (i < max_len && whatToCheck[i] == whatToCheckRight[i]) { + if (whatToCheck[i] == '\0') return 0; + ++i; + } + if (i == max_len) { + return 0; + } + return (unsigned char) whatToCheck[i] - (unsigned char) whatToCheckRight[i]; +} + +/// @brief something specific to the Microsoft's ABI, When the stack grows too big. +EXTERN_C void ___chkstk_ms(void) {} + +/// @note GCC expects them to be here. + +/// @brief memset definition in C++. +/// @param dst destination pointer. +/// @param byte value to fill in. +/// @param len length of of src. EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) { for (size_t i = 0UL; i < len; ++i) { ((int*) dst)[i] = byte; @@ -62,7 +125,4 @@ EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) { return len; } -/// @brief something specific to the Microsoft's ABI, When the stack grows too big. -EXTERN_C void ___chkstk_ms(void) {} - #endif diff --git a/dev/boot/src/BootThread.cc b/dev/boot/src/BootThread.cc index c477d659..377e6e3a 100644 --- a/dev/boot/src/BootThread.cc +++ b/dev/boot/src/BootThread.cc @@ -105,6 +105,12 @@ BootThread::BootThread(VoidPtr blob) : fStartAddress(nullptr), fBlob(blob) { writer.Write("BootZ: Executable entry address: ") .Write((UIntPtr) fStartAddress) .Write("\r"); + + /// @note .text region shall be marked as executable on ARM. + +#ifdef __NE_ARM64__ + +#endif } else if (StrCmp(sectionForBootZ, sect->Name) == 0) { struct HANDOVER_INFORMATION_STUB { UInt64 HandoverMagic; diff --git a/dev/boot/src/HEL/AMD64/BootATA.cc b/dev/boot/src/HEL/AMD64/BootATA.cc index 25810222..e5e0d8c2 100644 --- a/dev/boot/src/HEL/AMD64/BootATA.cc +++ b/dev/boot/src/HEL/AMD64/BootATA.cc @@ -88,8 +88,7 @@ ATAInit_Retry: /// fetch serial info /// model, speed, number of sectors... - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); @@ -115,15 +114,14 @@ Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { boot_ata_wait_io(IO); @@ -149,15 +147,14 @@ Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { boot_ata_wait_io(IO); diff --git a/dev/boot/src/HEL/ARM64/BootCB.S b/dev/boot/src/HEL/ARM64/BootCB.S index 3b0e1737..d52c1dcf 100644 --- a/dev/boot/src/HEL/ARM64/BootCB.S +++ b/dev/boot/src/HEL/ARM64/BootCB.S @@ -4,7 +4,7 @@ ------------------------------------------- */ -#ifdef __NE_COREBOOT__ +#ifdef __NE_NEBOOT__ .section .boot_hdr .align 4 @@ -37,4 +37,4 @@ bootloader_start: bl bootloader_main ret -#endif // __NE_COREBOOT__
\ No newline at end of file +#endif // __NE_NEBOOT__
\ No newline at end of file diff --git a/dev/boot/src/HEL/ARM64/BootPlatform.cc b/dev/boot/src/HEL/ARM64/BootPlatform.cc index 9dd03afe..683245fb 100644 --- a/dev/boot/src/HEL/ARM64/BootPlatform.cc +++ b/dev/boot/src/HEL/ARM64/BootPlatform.cc @@ -13,8 +13,7 @@ using namespace Boot; EXTERN_C void rt_halt() { - while (Yes) - ; + while (Yes); } EXTERN_C void rt_cli() {} diff --git a/dev/boot/src/New+Delete.cc b/dev/boot/src/New+Delete.cc index d4d5dfed..f7ad2898 100644 --- a/dev/boot/src/New+Delete.cc +++ b/dev/boot/src/New+Delete.cc @@ -17,8 +17,7 @@ void* operator new(size_t sz) { void* buf = nullptr; - while (BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf) != kEfiOk) - ; + while (BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf) != kEfiOk); return buf; } diff --git a/dev/ddk/DDKKit/ddk.h b/dev/ddk/DriverKit/ddk.h index 888219c6..254137f9 100644 --- a/dev/ddk/DDKKit/ddk.h +++ b/dev/ddk/DriverKit/ddk.h @@ -9,7 +9,7 @@ #pragma once -#include <DDKKit/macros.h> +#include <DriverKit/macros.h> struct DDK_STATUS_STRUCT; struct DDK_OBJECT_MANIFEST; @@ -35,12 +35,12 @@ struct DDK_STATUS_STRUCT DDK_FINAL { /// @param dat data argument pointer. /// @param sz sz of whole data argument pointer. /// @return result of call -DDK_EXTERN void* ke_call(const char* name, int32_t cnt, void* dat, size_t sz); +DDK_EXTERN void* ke_call_dispatch(const char* name, int32_t cnt, void* dat, size_t sz); /// @brief add a system call. /// @param slot system call slot id. /// @param slotFn, syscall slot. -DDK_EXTERN void ke_add_syscall(const int32_t slot, void (*slotFn)(void* a0)); +DDK_EXTERN void ke_set_syscall(const int32_t slot, void (*slotFn)(void* a0)); /// @brief Allocates an heap ptr. /// @param sz size of the allocated struct/type. @@ -65,10 +65,10 @@ DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* na DDK_EXTERN void* ke_set_obj(const int32_t slot, const struct DDK_OBJECT_MANIFEST* ddk_pr); /// @brief The highest API version of the DDK. -DDK_EXTERN int32_t kApiVersionHighest; +DDK_EXTERN uint32_t kApiVersionHighest; /// @brief The lowest API version of the DDK. -DDK_EXTERN int32_t kApiVersionLowest; +DDK_EXTERN uint32_t kApiVersionLowest; /// @brief API version in BCD. -DDK_EXTERN int32_t kApiVersion; +DDK_EXTERN uint32_t kApiVersion; diff --git a/dev/ddk/DDKKit/dev.h b/dev/ddk/DriverKit/dev.h index 59fb48b5..adb1c1d0 100644 --- a/dev/ddk/DDKKit/dev.h +++ b/dev/ddk/DriverKit/dev.h @@ -9,7 +9,7 @@ #pragma once -#include <DDKKit/ddk.h> +#include <DriverKit/ddk.h> struct _DDK_DEVICE; diff --git a/dev/ddk/DDKKit/io.h b/dev/ddk/DriverKit/io.h index 28396608..805696e6 100644 --- a/dev/ddk/DDKKit/io.h +++ b/dev/ddk/DriverKit/io.h @@ -8,7 +8,7 @@ #pragma once -#include <DDKKit/str.h> +#include <DriverKit/str.h> /// @brief print character into UART. DDK_EXTERN void kputc(const char ch); diff --git a/dev/ddk/DDKKit/macros.h b/dev/ddk/DriverKit/macros.h index 9b7b3d50..9b7b3d50 100644 --- a/dev/ddk/DDKKit/macros.h +++ b/dev/ddk/DriverKit/macros.h diff --git a/dev/ddk/DDKKit/net.h b/dev/ddk/DriverKit/net.h index ea85dee7..63f89367 100644 --- a/dev/ddk/DDKKit/net.h +++ b/dev/ddk/DriverKit/net.h @@ -9,7 +9,7 @@ #pragma once -#include <DDKKit/macros.h> +#include <DriverKit/macros.h> struct DDK_NET_MANIFEST; diff --git a/dev/ddk/DDKKit/str.h b/dev/ddk/DriverKit/str.h index fbf6506d..b2c0ce72 100644 --- a/dev/ddk/DDKKit/str.h +++ b/dev/ddk/DriverKit/str.h @@ -8,7 +8,7 @@ #pragma once -#include <DDKKit/ddk.h> +#include <DriverKit/ddk.h> /// @brief DDK equivalent of POSIX's string.h /// @file str.h diff --git a/dev/ddk/docs/SPECIFICATION_DDK.md b/dev/ddk/docs/SPECIFICATION_DDK.md index 57710d1f..d7d333d3 100644 --- a/dev/ddk/docs/SPECIFICATION_DDK.md +++ b/dev/ddk/docs/SPECIFICATION_DDK.md @@ -5,7 +5,7 @@ =================================== - Programming Language: C/C++ -- Build System: Make/BTB +- Build System: Make/NeBuild - Purpose: Driver Tool Kit, which you link against ddk.sys =================================== diff --git a/dev/ddk/src/ddk_rt_cxx.cc b/dev/ddk/src/ddk_abi_cxx.cc index 3d57e2b9..fc590c0e 100644 --- a/dev/ddk/src/ddk_rt_cxx.cc +++ b/dev/ddk/src/ddk_abi_cxx.cc @@ -1,12 +1,14 @@ /* ------------------------------------------- + DDK Copyright Amlal El Mahrouss. - Purpose: DDK C++ runtime. + Author: Amlal El Mahrouss + Purpose: DDK C++ ABI. ------------------------------------------- */ -#include <DDKKit/ddk.h> +#include <DriverKit/ddk.h> void* operator new(size_t sz) { return ::kalloc(sz); diff --git a/dev/ddk/src/ddk_alloc.c b/dev/ddk/src/ddk_alloc.c index 0b428b15..08527f4d 100644 --- a/dev/ddk/src/ddk_alloc.c +++ b/dev/ddk/src/ddk_alloc.c @@ -6,7 +6,7 @@ ------------------------------------------- */ -#include <DDKKit/ddk.h> +#include <DriverKit/ddk.h> /** \brief Allocates a new heap on the Kernel's side. @@ -16,7 +16,7 @@ DDK_EXTERN void* kalloc(size_t sz) { if (!sz) ++sz; - void* ptr = ke_call("mm_alloc_ptr", 1, &sz, sizeof(size_t)); + void* ptr = ke_call_dispatch("mm_alloc_ptr", 1, &sz, sizeof(size_t)); return ptr; } @@ -28,5 +28,5 @@ DDK_EXTERN void* kalloc(size_t sz) { DDK_EXTERN void kfree(void* ptr) { if (!ptr) return; - ke_call("mm_free_ptr", 1, ptr, 0); + ke_call_dispatch("mm_free_ptr", 1, ptr, 0); } diff --git a/dev/ddk/src/ddk_dev.c b/dev/ddk/src/ddk_dev.c index 4cd7dcdd..32ec2442 100644 --- a/dev/ddk/src/ddk_dev.c +++ b/dev/ddk/src/ddk_dev.c @@ -6,14 +6,14 @@ ------------------------------------------- */ -#include <DDKKit/dev.h> -#include <DDKKit/str.h> +#include <DriverKit/dev.h> +#include <DriverKit/str.h> /// @brief Open a new binary device from path. DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath) { if (!devicePath) return nil; - return ke_call("dk_open_dev", 1, (void*) devicePath, kstrlen(devicePath)); + return ke_call_dispatch("dk_open_dev", 1, (void*) devicePath, kstrlen(devicePath)); } /// @brief Close any device. @@ -21,6 +21,6 @@ DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath) { DDK_EXTERN BOOL close(DDK_DEVICE_PTR device) { if (!device) return NO; - ke_call("dk_close_dev", 1, device, sizeof(DDK_DEVICE)); + ke_call_dispatch("dk_close_dev", 1, device, sizeof(DDK_DEVICE)); return YES; } diff --git a/dev/ddk/src/ddk_io.c b/dev/ddk/src/ddk_io.c index ba6d4e55..c6cdd457 100644 --- a/dev/ddk/src/ddk_io.c +++ b/dev/ddk/src/ddk_io.c @@ -6,14 +6,14 @@ ------------------------------------------- */ -#include <DDKKit/io.h> +#include <DriverKit/io.h> DDK_EXTERN void kputc(const char ch) { char assembled[2] = {0}; assembled[0] = ch; assembled[1] = 0; - ke_call("ke_put_string", 1, assembled, 1); + ke_call_dispatch("ke_put_string", 1, assembled, 1); } /// @brief print string to UART. diff --git a/dev/ddk/src/ddk_kernel_call.c b/dev/ddk/src/ddk_kernel_call.c index b5c494f7..1ac0a0aa 100644 --- a/dev/ddk/src/ddk_kernel_call.c +++ b/dev/ddk/src/ddk_kernel_call.c @@ -1,36 +1,56 @@ /* ------------------------------------------- + DDK Copyright Amlal El Mahrouss. - Purpose: DDK Kernel call. + Author: Amlal El Mahrouss + Purpose: DDK kernel dispatch system. ------------------------------------------- */ -#include <DDKKit/ddk.h> +#include <DriverKit/ddk.h> #include <stdarg.h> /// @brief this is an internal call, do not use it. -DDK_EXTERN ATTRIBUTE(naked) void* ke_call_dispatch(const char* name, int32_t cnt, void* data, - size_t sz); +DDK_EXTERN ATTRIBUTE(naked) void* __ke_call_dispatch(const int32_t name, int32_t cnt, void* data, + size_t sz); +/// @brief This function hashes the path into a FNV symbol. +/// @param path the path to hash. +/// @retval 0 symbol wasn't hashed. +/// @retval > 0 hashed symbol. +static uint64_t ddk_fnv_64(const char* path) { + if (path == nil || *path == 0) return 0; -/// @brief Interupt Kernel and call it's RPC. -/// @param KernelRpcName RPC name + const uint64_t kFnvOffsetBase = 0xcbf29ce484222325ULL; + const uint64_t kFnvPrime64 = 0x100000001b3ULL; + + uint64_t hash = kFnvOffsetBase; + + while (*path) { + hash ^= (char) (*path++); + hash *= kFnvPrime64; + } + + return hash; +} + +/// @brief Interrupt Kernel and call it's RPC. +/// @param name RPC name /// @param cnt number of elements in **data** pointer. /// @param data data pointer. /// @param sz The size of the whole data pointer. /// @retval void* Kernel call was successful. /// @retval nil Kernel call failed, call KernelLastError(void) -DDK_EXTERN void* ke_call(const char* name, int32_t cnt, void* data, size_t sz) { - if (!name || *name == 0 || cnt == 0) return nil; - - return ke_call_dispatch(name, cnt, data, sz); +DDK_EXTERN void* ke_call_dispatch(const char* name, int32_t cnt, void* data, size_t sz) { + if (name == nil || *name == 0 || data == nil || cnt == 0) return nil; + return __ke_call_dispatch(ddk_fnv_64(name), cnt, data, sz); } /// @brief Add system call. /// @param slot system call slot /// @param slotFn, syscall slot. -DDK_EXTERN void ke_add_syscall(const int slot, void (*slotFn)(void* a0)) { - ke_call("ke_add_syscall", slot, slotFn, 1); +DDK_EXTERN void ke_set_syscall(const int slot, void (*slotFn)(void* a0)) { + ke_call_dispatch("ke_set_syscall", slot, slotFn, 1); } /// @brief Get a Kernel object. @@ -39,7 +59,7 @@ DDK_EXTERN void ke_add_syscall(const int slot, void (*slotFn)(void* a0)) { /// @return Object manifest. DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name) { struct DDK_OBJECT_MANIFEST* manifest = - (struct DDK_OBJECT_MANIFEST*) ke_call("cf_get_kobj", slot, (void*) name, 1); + (struct DDK_OBJECT_MANIFEST*) ke_call_dispatch("cfkit_get_kobj", slot, (void*) name, 1); if (!manifest) return nil; @@ -52,5 +72,5 @@ DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* na /// @param ddk_pr pointer to a object's DDK_OBJECT_MANIFEST. /// @return property's object. DDK_EXTERN void* ke_set_obj(const int slot, const struct DDK_OBJECT_MANIFEST* ddk_pr) { - return ke_call("cf_set_kobj", slot, (void*) ddk_pr, 1); + return ke_call_dispatch("cfkit_set_kobj", slot, (void*) ddk_pr, 1); } diff --git a/dev/ddk/src/ddk_kernel_call_dispatch.S b/dev/ddk/src/ddk_kernel_call_dispatch.S index 9b32d0c2..c66d9d49 100644 --- a/dev/ddk/src/ddk_kernel_call_dispatch.S +++ b/dev/ddk/src/ddk_kernel_call_dispatch.S @@ -3,7 +3,7 @@ compiler: gnu */ -.globl ke_call_dispatch +.globl __ke_call_dispatch .text @@ -13,7 +13,7 @@ #if defined(__DDK_AMD64__) /* args rcx, rdx, r8, r9 */ -ke_call_dispatch: +__ke_call_dispatch: int $0x33 ret diff --git a/dev/ddk/src/ddk_str.c b/dev/ddk/src/ddk_str.c index d50a5d03..514cddc7 100644 --- a/dev/ddk/src/ddk_str.c +++ b/dev/ddk/src/ddk_str.c @@ -2,11 +2,11 @@ Copyright Amlal El Mahrouss. - Purpose: DDK Strings. + Purpose: DDK String API. ------------------------------------------- */ -#include <DDKKit/str.h> +#include <DriverKit/str.h> DDK_EXTERN size_t kstrlen(const char* in) { if (in == nil) return 0; diff --git a/dev/ddk/src/ddk_ver.c b/dev/ddk/src/ddk_ver.c index b2370b23..9be3134e 100644 --- a/dev/ddk/src/ddk_ver.c +++ b/dev/ddk/src/ddk_ver.c @@ -2,11 +2,11 @@ Copyright Amlal El Mahrouss.
- Purpose: DDK version symbols.
+ Purpose: DDK version system.
------------------------------------------- */
-#include <DDKKit/ddk.h>
+#include <DriverKit/ddk.h>
#ifndef kDDKVersionHighest
#define kDDKVersionHighest 1
@@ -20,6 +20,6 @@ #define kDDKVersion 1
#endif // !kDDKVersion
-int32_t kApiVersionHighest = kDDKVersionHighest;
-int32_t kApiVersionLowest = kDDKVersionLowest;
-int32_t kApiVersion = kDDKVersion;
+uint32_t kApiVersionHighest = kDDKVersionHighest;
+uint32_t kApiVersionLowest = kDDKVersionLowest;
+uint32_t kApiVersion = kDDKVersion;
diff --git a/dev/kernel/ArchKit/ArchKit.h b/dev/kernel/ArchKit/ArchKit.h index a9dca240..37793370 100644 --- a/dev/kernel/ArchKit/ArchKit.h +++ b/dev/kernel/ArchKit/ArchKit.h @@ -77,9 +77,19 @@ struct HAL_DISPATCH_ENTRY final { operator bool() { return fHooked; } }; +typedef Kernel::Void (*rt_kerncall_proc)(Kernel::SizeT, Kernel::VoidPtr, Kernel::SizeT); + +struct HAL_KERNEL_DISPATCH_ENTRY final { + Kernel::UInt64 fHash; + Kernel::Bool fHooked; + rt_kerncall_proc fProc; + + operator bool() { return fHooked; } +}; + inline Kernel::Array<HAL_DISPATCH_ENTRY, kMaxDispatchCallCount> kSysCalls; -inline Kernel::Array<HAL_DISPATCH_ENTRY, kMaxDispatchCallCount> kKernCalls; +inline Kernel::Array<HAL_KERNEL_DISPATCH_ENTRY, kMaxDispatchCallCount> kKernCalls; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ diff --git a/dev/kernel/DmaKit/DmaPool.h b/dev/kernel/DmaKit/DmaPool.h index ada8299e..99f43725 100644 --- a/dev/kernel/DmaKit/DmaPool.h +++ b/dev/kernel/DmaKit/DmaPool.h @@ -23,7 +23,11 @@ #define kNeDMAPoolSize (0x1000000) #endif +#ifdef __GNUC__ #define kNeDMABestAlign __BIGGEST_ALIGNMENT__ +#else +#define kNeDMABestAlign (8) +#endif namespace Kernel { /// @brief DMA pool base pointer, here we're sure that AHCI or whatever tricky standard sees it. @@ -37,7 +41,7 @@ inline const UInt8* kDmaPoolEnd = (UInt8*) (kNeDMAPoolStart + kNeDMAPoolSize); /***********************************************************************************/ inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) { if (!size) { - return nullptr; + ++size; } /// Check alignement according to architecture. @@ -69,7 +73,7 @@ inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) { inline Void rtl_dma_free(SizeT size) { if (!size) return; - auto ptr = (UInt8*) (kDmaPoolPtr - size); + auto ptr = (kDmaPoolPtr - size); if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) { err_global_get() = kErrorDmaExhausted; @@ -98,4 +102,4 @@ inline Void rtl_dma_flush(VoidPtr ptr, SizeT size_buffer) { HAL::mm_memory_fence((VoidPtr) ((UInt8*) ptr + buf_idx)); } } -} // namespace Kernel
\ No newline at end of file +} // namespace Kernel diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 845ef467..bb4e3dc0 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -259,7 +259,7 @@ inline UInt32 hefs_hour_get(ATime raw_atime) noexcept { /// @return the minute value.
/// @note The minute is stored in the lower 8 bits of the ATime value.
inline UInt32 hefs_minute_get(ATime raw_atime) noexcept {
- return (raw_atime) &0xFF;
+ return (raw_atime) & 0xFF;
}
inline constexpr UInt32 kHeFSBaseYear = 1970;
@@ -379,10 +379,10 @@ class HeFileSystemParser final { ~HeFileSystemParser() = default;
public:
- HeFileSystemParser(const HeFileSystemParser&) = delete;
+ HeFileSystemParser(const HeFileSystemParser&) = delete;
HeFileSystemParser& operator=(const HeFileSystemParser&) = delete;
- HeFileSystemParser(HeFileSystemParser&&) = delete;
+ HeFileSystemParser(HeFileSystemParser&&) = delete;
HeFileSystemParser& operator=(HeFileSystemParser&&) = delete;
public:
diff --git a/dev/kernel/FirmwareKit/EFI/EFI.h b/dev/kernel/FirmwareKit/EFI/EFI.h index 97e3ad01..9b22f5b6 100644 --- a/dev/kernel/FirmwareKit/EFI/EFI.h +++ b/dev/kernel/FirmwareKit/EFI/EFI.h @@ -57,7 +57,7 @@ typedef Char16 EfiChar16Type; /// @brief Core Handle Kind /// Self is like NT's Win32 HANDLE type. typedef struct EfiHandle { -} * EfiHandlePtr; +}* EfiHandlePtr; /* UEFI uses wide characters by default. */ typedef WideChar EfiCharType; @@ -239,63 +239,85 @@ typedef struct EfiTableHeader { UInt32 Reserved; } EfiTableHeader; -#define EFI_ACPI_TABLE_PROTOCOL_GUID \ - { \ - 0xffe06bdd, 0x6107, 0x46a6, { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c } \ +#define EFI_ACPI_TABLE_PROTOCOL_GUID \ + { \ + 0xffe06bdd, 0x6107, 0x46a6, { \ + 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c \ + } \ } -#define EFI_LOAD_FILE_PROTOCOL_GUID \ - { \ - 0x56EC3091, 0x954C, 0x11d2, { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ +#define EFI_LOAD_FILE_PROTOCOL_GUID \ + { \ + 0x56EC3091, 0x954C, 0x11d2, { \ + 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ } -#define EFI_LOAD_FILE2_PROTOCOL_GUID \ - { \ - 0x4006c0c1, 0xfcb3, 0x403e, { 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \ +#define EFI_LOAD_FILE2_PROTOCOL_GUID \ + { \ + 0x4006c0c1, 0xfcb3, 0x403e, { \ + 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d \ + } \ } -#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ - { \ - 0x5B1B31A1, 0x9562, 0x11d2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { \ + 0x5B1B31A1, 0x9562, 0x11d2, { \ + 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B \ + } \ } -#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ - { \ - 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \ +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + { \ + 0x9042a9de, 0x23dc, 0x4a38, { \ + 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a \ + } \ } -#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \ - { \ - 0xA19832B9, 0xAC25, 0x11D3, { 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ +#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \ + { \ + 0xA19832B9, 0xAC25, 0x11D3, { \ + 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d \ + } \ } #define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION 0x00010000 -#define EFI_IP4_PROTOCOL_GUID \ - { \ - 0x41d94cd2, 0x35b6, 0x455a, { 0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd } \ +#define EFI_IP4_PROTOCOL_GUID \ + { \ + 0x41d94cd2, 0x35b6, 0x455a, { \ + 0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd \ + } \ } #define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ - { \ - 0x0964e5b22, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { \ + 0x0964e5b22, 0x6459, 0x11d2, { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ } -#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } \ +#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0xbc62157e, 0x3e33, 0x4fec, { \ + 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf \ + } \ } -#define EFI_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0x9576e91, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ +#define EFI_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0x9576e91, 0x6d3f, 0x11d2, { \ + 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ } -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ - { \ - 0x0964e5b22, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { \ + 0x0964e5b22, 0x6459, 0x11d2, { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ } typedef UInt64(EfiImageUnload)(EfiHandlePtr ImageHandle); @@ -351,17 +373,17 @@ typedef struct { typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_TRANSMIT)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This, IN UInt32 HeaderSize, IN UInt32 BufferSize, - IN Void* Buffer, - IN EfiMacAddress* SrcAddr OPTIONAL, + IN Void* Buffer, + IN EfiMacAddress* SrcAddr OPTIONAL, IN EfiMacAddress* DestAddr OPTIONAL, - IN UInt16* Protocol OPTIONAL); + IN UInt16* Protocol OPTIONAL); typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_RECEIVE)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This, - OUT UInt32* HeaderSize OPTIONAL, + OUT UInt32* HeaderSize OPTIONAL, IN OUT UInt32* BufferSize, OUT Void* Buffer, - OUT EfiMacAddress* SrcAddr OPTIONAL, + OUT EfiMacAddress* SrcAddr OPTIONAL, OUT EfiMacAddress* DestAddr OPTIONAL, - OUT UInt16* Protocol OPTIONAL); + OUT UInt16* Protocol OPTIONAL); typedef struct EFI_SIMPLE_NETWORK_PROTOCOL { UInt64 Revision; @@ -506,9 +528,11 @@ typedef struct EFI_GUID EFI_FINAL { * Protocol stuff... */ -#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ - { \ - 0x387477c1, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ +#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ + { \ + 0x387477c1, 0x69c7, 0x11d2, { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ } /** some helpers */ @@ -607,7 +631,7 @@ typedef struct { } EfiInputKey; typedef EfiStatusType(EFI_API* EfiInputReadKey)(IN EfiSimpleTextInputProtocol* This, - OUT EfiInputKey* Key); + OUT EfiInputKey* Key); typedef EfiStatusType(EFI_API* EfiInputReset)(IN EfiSimpleTextInputProtocol* This, IN Boolean ExtendedChk); @@ -665,7 +689,7 @@ typedef struct EfiSystemTable { struct { EFI_GUID VendorGUID; VoidPtr VendorTable; - } * ConfigurationTable; + }* ConfigurationTable; } EfiSystemTable; #define kEfiOk 0 @@ -726,9 +750,11 @@ enum { #define EFI_EXTRA_DESCRIPTOR_SIZE 8 -#define EFI_MP_SERVICES_PROTOCOL_GUID \ - { \ - 0x3fdda605, 0xa76e, 0x4f46, { 0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08 } \ +#define EFI_MP_SERVICES_PROTOCOL_GUID \ + { \ + 0x3fdda605, 0xa76e, 0x4f46, { \ + 0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08 \ + } \ } #define PROCESSOR_AS_BSP_BIT 0x00000001 @@ -825,9 +851,11 @@ typedef struct EfiTime { UInt8 Pad2; } EfiTime; -#define EFI_FILE_INFO_GUID \ - { \ - 0x09576e92, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ +#define EFI_FILE_INFO_GUID \ + { \ + 0x09576e92, 0x6d3f, 0x11d2, { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ } struct EfiFileInfo EFI_FINAL { @@ -896,8 +924,8 @@ typedef EfiStatusType EFI_API (*EfiMpServicesStartupThisAP)( IN Void* ProcedureArgument OPTIONAL, OUT Boolean* Finished OPTIONAL); typedef EfiStatusType EFI_API (*EfiMpServicesDisableThisAP)(IN struct _EfiMpServicesProtocol* Self, - IN UInt32 ProcessorNumber, - IN Boolean EnableAP, + IN UInt32 ProcessorNumber, + IN Boolean EnableAP, IN UInt32* HealthFlag OPTIONAL); typedef EfiStatusType EFI_API (*EfiMpServicesWhoAmI)(IN struct _EfiMpServicesProtocol* Self, diff --git a/dev/kernel/FirmwareKit/EPM.h b/dev/kernel/FirmwareKit/EPM.h index 05291929..dcab3607 100644 --- a/dev/kernel/FirmwareKit/EPM.h +++ b/dev/kernel/FirmwareKit/EPM.h @@ -97,11 +97,13 @@ struct PACKED EPM_PART_BLOCK { ///! @brief Use in boot block version field. enum { - kEPMInvalid = 0x00, - kEPMGeneric = 0xcf, /// @brief Generic OS - kEPMLinux = 0x8f, /// @brief Linux on EPM - kEPMBSD = 0x9f, /// @brief Berkeley Soft. Distribution - kEPMNeKernel = 0x1f, /// @brief NeKernel. + kEPMInvalid = 0x00, + kEPMGeneric = 0xcf, /// @brief Generic OS + kEPMLinux = 0x8f, /// @brief Linux on EPM. + kEPMBSD = 0x9f, /// @brief BSD on EPM. + kEPMNeKernel = 0x1f, /// @brief NeKernel. + kEPMVMKernel = 0x2f, /// @brief VMKernel. + /// @note ... the rest is reserved for future OSes. kEPMInvalidOS = 0xff, }; diff --git a/dev/kernel/FirmwareKit/CoreBoot/BootNet.h b/dev/kernel/FirmwareKit/NeBoot/BootNet.h index 3ed11363..3ed11363 100644 --- a/dev/kernel/FirmwareKit/CoreBoot/BootNet.h +++ b/dev/kernel/FirmwareKit/NeBoot/BootNet.h diff --git a/dev/kernel/FirmwareKit/CoreBoot/NS.h b/dev/kernel/FirmwareKit/NeBoot/NS.h index 06197fcd..a4d6a251 100644 --- a/dev/kernel/FirmwareKit/CoreBoot/NS.h +++ b/dev/kernel/FirmwareKit/NeBoot/NS.h @@ -6,5 +6,5 @@ #pragma once -#include <FirmwareKit/CoreBoot/BootNet.h> -#include <FirmwareKit/CoreBoot/CoreBoot.h>
\ No newline at end of file +#include <FirmwareKit/NeBoot/BootNet.h> +#include <FirmwareKit/NeBoot/NeBoot.h>
\ No newline at end of file diff --git a/dev/kernel/FirmwareKit/CoreBoot/CoreBoot.h b/dev/kernel/FirmwareKit/NeBoot/NeBoot.h index 9e756a70..621b3b64 100644 --- a/dev/kernel/FirmwareKit/CoreBoot/CoreBoot.h +++ b/dev/kernel/FirmwareKit/NeBoot/NeBoot.h @@ -8,14 +8,14 @@ #include <NeKit/Defines.h> -namespace Firmware::Detail::CoreBoot { +namespace Firmware::Detail::NeBoot { using namespace Kernel; -struct COREBOOT_LINEAR_EXEC; +struct NEBOOT_LINEAR_EXEC; /// @brief Linear Executable Header /// @author Amlal El Mahrouss -struct ATTRIBUTE(aligned(4)) COREBOOT_LINEAR_EXEC { +struct ATTRIBUTE(aligned(4)) NEBOOT_LINEAR_EXEC { const Char fMagic[2]; // magic number const Char fName[10]; // operating system name const UInt32 fRevision; // firmware revision @@ -31,4 +31,4 @@ struct ATTRIBUTE(aligned(4)) COREBOOT_LINEAR_EXEC { UIntPtr fMBCIStructureVersion; // MBCI structure version. #endif }; -} // namespace Firmware::Detail::CoreBoot +} // namespace Firmware::Detail::NeBoot diff --git a/dev/kernel/GfxKit/FB.h b/dev/kernel/GfxKit/FB.h index 14f0393c..28f3a20c 100644 --- a/dev/kernel/GfxKit/FB.h +++ b/dev/kernel/GfxKit/FB.h @@ -6,8 +6,7 @@ #pragma once -#include <modules/CoreGfx/CoreGfx.h> -#include <modules/CoreGfx/TextGfx.h> +#include <KernelKit/DeviceMgr.h> namespace Kernel { class FBDeviceInterface; @@ -47,7 +46,7 @@ class FBDeviceInterface NE_DEVICE<FBDevicePacket*> { const Char* Name() const override; public: - FBDeviceInterface& operator<<(FBDevicePacket* Data) override; - FBDeviceInterface& operator>>(FBDevicePacket* Data) override; + FBDeviceInterface& operator<<(FBDevicePacket* dat) override; + FBDeviceInterface& operator>>(FBDevicePacket* dat) override; }; } // namespace Kernel diff --git a/dev/kernel/src/CxxAbi-AMD64.cc b/dev/kernel/HALKit/AMD64/CxxAbi.cc index 30c8306e..cd135abc 100644 --- a/dev/kernel/src/CxxAbi-AMD64.cc +++ b/dev/kernel/HALKit/AMD64/CxxAbi.cc @@ -4,8 +4,6 @@ ------------------------------------------- */ -#ifdef __NE_AMD64__ - #include <KernelKit/DebugOutput.h> #include <KernelKit/KPC.h> #include <KernelKit/UserProcessScheduler.h> @@ -78,5 +76,3 @@ EXTERN_C void __cxa_guard_abort(__guard* g) { (void) g; } } // namespace cxxabiv1 - -#endif // ifdef __NE_AMD64__ diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index aeaeff52..64f146f3 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -32,10 +32,9 @@ #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/CoreGfx/TextGfx.h> -/// @note: _hal_switch_context is internal - /////////////////////////////////////////////////////////////////////////////////////// +/// @note: _hal_switch_context is internal. /// @brief The **HAL** namespace. /////////////////////////////////////////////////////////////////////////////////////// @@ -45,15 +44,15 @@ struct HAL_APIC_MADT; struct HAL_HARDWARE_THREAD; struct HAL_HARDWARE_THREAD final { - HAL::StackFramePtr mFramePtr; - ProcessID mThreadID{0}; + StackFramePtr mFramePtr; + ProcessID mThreadID{0}; }; -EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame); +EXTERN_C Void sched_jump_to_task(StackFramePtr stack_frame); -STATIC HAL_APIC_MADT* kMADTBlock = nullptr; -STATIC Bool kSMPAware = false; -STATIC Int64 kSMPCount = 0; +STATIC HAL_APIC_MADT* kSMPBlock = nullptr; +STATIC Bool kSMPAware = false; +STATIC Int64 kSMPCount = 0; EXTERN_C UIntPtr kApicBaseAddress; @@ -70,6 +69,7 @@ struct HAL_APIC_MADT final SDT_OBJECT { UInt8 List[1]; // Records List }; +/// @brief Local APIC Descriptor Table. struct LAPIC final { UInt8 Type; UInt8 Length; @@ -113,17 +113,19 @@ EXTERN_C HAL::StackFramePtr mp_get_current_task(ThreadID thrdid) { /***********************************************************************************/ EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ThreadID thrdid) { - if (thrdid > kSMPCount) return NO; if (!stack_frame) return NO; - kHWThread[thrdid].mFramePtr = stack_frame; - - HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); + if (thrdid > kSMPCount) return NO; if (!kSMPAware) { sched_jump_to_task(kHWThread[thrdid].mFramePtr); + + return YES; } + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); + kHWThread[thrdid].mFramePtr = stack_frame; + return YES; } @@ -158,11 +160,11 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { return; } - kRawMADT = pwr.Leak().Leak(); - kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT); - kSMPAware = NO; + kRawMADT = pwr.Leak().Leak(); + kSMPBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT); + kSMPAware = NO; - if (kMADTBlock) { + if (kSMPBlock) { kSMPInterrupt = 0; kSMPCount = 0; @@ -189,8 +191,8 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { controller.Write(LAPIC_REG_TIMER_LVT, 0x20 | (1 << 17)); controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000); - volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kMADTBlock->List); - volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length; + volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kSMPBlock->List); + volatile UInt8* end_ptr = ((UInt8*) kSMPBlock) + kSMPBlock->Length; while (entry_ptr < end_ptr) { UInt8 type = *entry_ptr; diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc index be6d0af5..0c2d0960 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc @@ -61,8 +61,7 @@ EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { hal_idt_send_eoi(32); - while (kIsRunning) - ; + while (kIsRunning); kIsRunning = YES; @@ -148,8 +147,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash, /// @brief Enter Kernel call from assembly (libDDK only). /// @param stack the stack pushed from assembly routine. /// @return nothing. -EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, - Kernel::UIntPtr rdx_kerncall_arg) { +EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt, + Kernel::UIntPtr arg, Kernel::SizeT sz) { hal_idt_send_eoi(51); if (!Kernel::kRootUser) return; @@ -159,7 +158,7 @@ EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) { if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) { if (kKernCalls[i].fProc) { - (kKernCalls[i].fProc)((Kernel::VoidPtr) rdx_kerncall_arg); + (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz); } } } diff --git a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc index f9749946..56d46a15 100644 --- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc +++ b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc @@ -30,10 +30,11 @@ Void IDTLoader::Load(Register64& idt) { volatile UIntPtr** ptr_ivt = (volatile UIntPtr**) idt.Base; for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) { - Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector; - Detail::kInterruptVectorTable[idt_indx].Ist = 0; - Detail::kInterruptVectorTable[idt_indx].TypeAttributes = kInterruptGate; - Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr) ptr_ivt[idt_indx] & 0xFFFF); + Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector; + Detail::kInterruptVectorTable[idt_indx].Ist = 0; + Detail::kInterruptVectorTable[idt_indx].TypeAttributes = + kKernelInterruptId ? kUserInterruptGate : kInterruptGate; + Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr) ptr_ivt[idt_indx] & 0xFFFF); Detail::kInterruptVectorTable[idt_indx].OffsetMid = (((UIntPtr) ptr_ivt[idt_indx] >> 16) & 0xFFFF); Detail::kInterruptVectorTable[idt_indx].OffsetHigh = diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 446a1e85..c7a87b13 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -14,7 +14,7 @@ #include <KernelKit/Timer.h> #include <NetworkKit/IPC.h> #include <StorageKit/AHCI.h> -#include <generic_kits/BenchKit/X64Chrono.h> +#include <misc/BenchKit/X64Chrono.h> #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/CoreGfx/TextGfx.h> @@ -43,6 +43,11 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { kKernelVM = kHandoverHeader->f_PageStart; + if (!kKernelVM) { + MUST_PASS(kKernelVM); + return kEfiFail; + } + hal_write_cr3(kKernelVM); /************************************** */ @@ -163,7 +168,6 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { idt_loader.Load(idt_reg); - while (YES) - ; + while (YES); } #endif // ifndef __NE_MODULAR_KERNEL_COMPONENTS__ diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgr.cc b/dev/kernel/HALKit/AMD64/HalPagingMgr.cc index 048cb7c2..ced4f268 100644 --- a/dev/kernel/HALKit/AMD64/HalPagingMgr.cc +++ b/dev/kernel/HALKit/AMD64/HalPagingMgr.cc @@ -117,9 +117,12 @@ EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address) { /// @param flags the flags to put on the page. /// @return Status code of page manipulation process. /***********************************************************************************/ -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) { +EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, + UInt32 level) { if (physical_address == 0) return kErrorInvalidData; + NE_UNUSED(level); /// @todo support PML4, and PDPT levels. + const UInt64 kVMAddr = (UInt64) virtual_address; constexpr UInt64 kMask9 = 0x1FF; constexpr UInt64 kPageMask = 0xFFF; diff --git a/dev/kernel/HALKit/AMD64/HalTimer.cc b/dev/kernel/HALKit/AMD64/HalTimer.cc index 13573880..22876a96 100644 --- a/dev/kernel/HALKit/AMD64/HalTimer.cc +++ b/dev/kernel/HALKit/AMD64/HalTimer.cc @@ -61,11 +61,8 @@ HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) { // if not enabled yet.
if (!(*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) & (1 << 0))) {
*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) |
- (1 << 0); // enable timer
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) |
- (1 << 3); // one shot conf
+ *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) | (1 << 0) |
+ (1 << 3); // enable timer & one shot conf
}
}
@@ -80,18 +77,21 @@ HardwareTimer::~HardwareTimer() { BOOL HardwareTimer::Wait() noexcept {
if (fWaitFor < 1) return NO;
+ if (fWaitFor > 1'000'000) return NO; // max 1000s = 16 minutes
- UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue));
+ UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer));
UInt64 femtoseconds_per_tick = (hpet_cap >> 32);
if (femtoseconds_per_tick == 0) return NO;
volatile UInt64* timer = (volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue);
- UInt64 now = *timer;
- UInt64 prev = now + (fWaitFor / femtoseconds_per_tick);
+ UInt64 now = *timer;
+
+ UInt64 fs_wait = fWaitFor * 1'000'000'000'000ULL;
+ UInt64 stop_at = now + (fs_wait / femtoseconds_per_tick);
- while (*timer < (prev)) asm volatile("pause");
+ while (*timer < (stop_at)) asm volatile("pause");
return YES;
}
diff --git a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc index 3ccbfa24..be27915a 100644 --- a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc +++ b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc @@ -13,10 +13,9 @@ using namespace Kernel::HAL; STATIC UInt16 kRTLIOBase = 0xFFFF; -STATIC BOOL kTXEnabled = NO; - -STATIC UInt32 kRXOffset = 0UL; +STATIC BOOL kTXRXEnabled = NO; +STATIC UInt32 kRXOffset = 0UL; STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500; STATIC UInt8* kRXUpperLayer = nullptr; @@ -26,8 +25,8 @@ STATIC UInt8* kRXBuffer = nullptr; ///@brief RTL8139 Init routine. /***********************************************************************************/ -EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { - if (kTXEnabled) return; +EXTERN_C BOOL rtl_init_nic_rtl8139(UInt16 io_base) noexcept { + if (kTXRXEnabled) return NO; kRTLIOBase = io_base; @@ -49,8 +48,7 @@ EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { } if (timeout <= 0x1000) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "RTL8139: Reset failed"); - return; + return NO; } rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRXBuffer); @@ -61,16 +59,21 @@ EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { rt_out16(io_base + 0x3C, 0x0005); - kTXEnabled = YES; + kTXRXEnabled = YES; + + return YES; } /***********************************************************************************/ /// @brief RTL8139 I/O interrupt handler. +/// @param rsp stack pointer. /// @note This function is called when the device interrupts to retrieve network data. /***********************************************************************************/ -EXTERN_C void rtl_rtl8139_interrupt_handler() { - if (kRTLIOBase == 0xFFFF) return; +EXTERN_C Void rtl_rtl8139_interrupt_handler(UIntPtr rsp) { + if (kRTLIOBase == 0xFFFF || kRTLIOBase == 0) return; + + NE_UNUSED(rsp); UInt16 status = rt_in16(kRTLIOBase + 0x3E); rt_out16(kRTLIOBase + 0x3E, status); @@ -111,4 +114,16 @@ EXTERN_C void rtl_rtl8139_interrupt_handler() { EXTERN_C UInt8* rtl_rtl8139_get_upper_layer() { return kRXUpperLayer; -}
\ No newline at end of file +} + +/***********************************************************************************/ +/// @brief RTL8139 set upper layer function +/// @param layer the upper layer. +/***********************************************************************************/ + +EXTERN_C BOOL rtl_rtl8139_set_upper_layer(UInt8* layer) { + if (!layer) return NO; + kRXUpperLayer = layer; + + return YES; +} diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h index 079acde4..cf297632 100644 --- a/dev/kernel/HALKit/AMD64/Paging.h +++ b/dev/kernel/HALKit/AMD64/Paging.h @@ -57,7 +57,9 @@ namespace Detail { PageEnable = 31, }; - inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); } + inline UInt8 control_register_cast(ControlRegisterBits reg) { + return static_cast<UInt8>(reg); + } } // namespace Detail auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr; diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index 80dc7a1d..99f857b1 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -47,6 +47,7 @@ #define IsLevelTriggered(FLG) (FLG & 8) #define kInterruptGate (0x8E) +#define kUserInterruptGate (0xEE) #define kTrapGate (0xEF) #define kTaskGate (0b10001100) #define kIDTSelector (0x08) @@ -245,7 +246,8 @@ class LAPICDmaWrapper final { /// @param phys_addr point to physical address. /// @param flags the flags to put on the page. /// @return Status code of page manip. -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags); +EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, + UInt32 level = 2); EXTERN_C UInt8 rt_in8(UInt16 port); EXTERN_C UInt16 rt_in16(UInt16 port); diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index cd41480a..3363e809 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -136,7 +136,7 @@ template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept { if (sector_sz == 0) { - kout << "Invalid sector size.\r"; + kout << "ahci: Invalid sector size.\r"; err_global_get() = kErrorDisk; return; } @@ -144,7 +144,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz lba /= sector_sz; if (!buffer || size_buffer == 0) { - kout << "Invalid buffer for AHCI I/O.\r"; + kout << "ahci: Invalid buffer for AHCI I/O.\r"; err_global_get() = kErrorDisk; return; } @@ -157,7 +157,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz while (slot == ~0UL) { if (timeout > kTimeout) { - kout << "No free command slot found, AHCI disk is busy!\r"; + kout << "ahci: No free command slot found, AHCI disk is busy!\r"; err_global_get() = kErrorDisk; return; @@ -217,7 +217,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz command_table->Prdt[prdt_index - 1].Ie = YES; if (bytes_remaining > 0) { - kout << "Warning: AHCI PRDT overflow, cannot map full buffer.\r"; + kout << "ahci: AHCI PRDT overflow, cannot map full buffer.\r"; err_global_get() = kErrorDisk; rtl_dma_free(size_buffer); @@ -262,7 +262,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz while (YES) { if (timeout > kTimeout) { - kout << "Disk hangup!\r"; + kout << "ahci: disk-hangup, corrupted-disk.\r"; err_global_get() = kErrorDiskIsCorrupted; rtl_dma_free(size_buffer); @@ -277,7 +277,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz rtl_dma_flush(ptr, size_buffer); if (kSATAHba->Is & kSATAErrTaskFile) { - kout << "AHCI Task File Error during I/O.\r"; + kout << "ahci: Task File Error during I/O.\r"; rtl_dma_free(size_buffer); err_global_get() = kErrorDiskIsCorrupted; @@ -293,9 +293,8 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz if ((kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) == 0) { goto ahci_io_end; } else { - kout << "Warning: Disk still busy after command completion!\r"; - while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) - ; + kout << "ahci: Disk still busy after command completion!\r"; + while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)); } ahci_io_end: @@ -308,13 +307,15 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz @brief Gets the number of sectors inside the drive. @return Sector size in bytes. */ -STATIC ATTRIBUTE(unused) SizeT drv_get_sector_count_ahci() { +STATIC ATTRIBUTE(unused) +SizeT drv_get_sector_count_ahci() { return kSATASectorCount; } /// @brief Get the drive size. /// @return Disk size in bytes. -STATIC ATTRIBUTE(unused) SizeT drv_get_size_ahci() { +STATIC ATTRIBUTE(unused) +SizeT drv_get_size_ahci() { return drv_std_get_sector_count() * kAHCISectorSize; } diff --git a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc index 39efb7d3..4688203f 100644 --- a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc @@ -105,7 +105,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz - 1) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); @@ -123,8 +123,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine - while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; + while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01); rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine @@ -147,7 +146,7 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz - 1)) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); @@ -163,8 +162,7 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS rt_out8(IO + 0x00, 0x09); // Start DMA engine - while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; + while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01); rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc index 6fccbdfa..9c5b3931 100644 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc @@ -83,8 +83,7 @@ ATAInit_Retry: rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); /// fetch serial info /// model, speed, number of sectors... @@ -117,15 +116,14 @@ Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sect rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { drv_pio_std_wait_io(IO); @@ -149,15 +147,14 @@ Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sec rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { drv_pio_std_wait_io(IO); diff --git a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc index e58fb782..17a60515 100644 --- a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc +++ b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc @@ -9,7 +9,7 @@ using namespace Kernel; -/// @brief Send APM command to it's IO space. +/// @brief Send APM command to its IO space. /// @param base_dma the IO base port. /// @param cmd the command. /// @return status code. diff --git a/dev/kernel/src/CxxAbi-ARM64.cc b/dev/kernel/HALKit/ARM64/CxxAbi.cc index e91eb958..964fc2f4 100644 --- a/dev/kernel/src/CxxAbi-ARM64.cc +++ b/dev/kernel/HALKit/ARM64/CxxAbi.cc @@ -4,8 +4,6 @@ ------------------------------------------- */ -#ifdef __NE_ARM64__ - #include <KernelKit/DebugOutput.h> #include <KernelKit/KPC.h> #include <NeKit/CxxAbi.h> @@ -87,5 +85,3 @@ EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) { } EXTERN_C Kernel::Int _tls_index = 0UL; - -#endif // ifdef __NE_ARM64__ diff --git a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc index 61a82314..63a42de8 100644 --- a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc +++ b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc @@ -11,16 +11,16 @@ #include <SignalKit/Signals.h> EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip); - EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void); +EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void); -EXTERN_C BOOL kEndOfInterrupt; +EXTERN_C BOOL kEndOfInterrupt; EXTERN_C UInt8 kEndOfInterruptVector; STATIC BOOL kIsRunning = NO; /// @note This is managed by the system software. STATIC void hal_int_send_eoi(UInt8 vector) { - kEndOfInterrupt = YES; + kEndOfInterrupt = YES; kEndOfInterruptVector = vector; } @@ -56,8 +56,7 @@ EXTERN_C void int_handle_scheduler(Kernel::UIntPtr rsp) { hal_int_send_eoi(32); - while (kIsRunning) - ; + while (kIsRunning); kIsRunning = YES; @@ -143,10 +142,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash, /// @brief Enter Kernel call from assembly (libDDK only). /// @param stack the stack pushed from assembly routine. /// @return nothing. -EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, - Kernel::UIntPtr rdx_kerncall_arg) { - hal_int_send_eoi(51); - +EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt, + Kernel::UIntPtr arg, Kernel::SizeT sz) { if (!Kernel::kRootUser) return; if (Kernel::kCurrentUser != Kernel::kRootUser) return; if (!Kernel::kCurrentUser->IsSuperUser()) return; @@ -154,7 +151,7 @@ EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) { if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) { if (kKernCalls[i].fProc) { - (kKernCalls[i].fProc)((Kernel::VoidPtr) rdx_kerncall_arg); + (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz); } } } diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index 20bd3d8a..d8e6843b 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -71,7 +71,6 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { Kernel::mp_init_cores(); - while (YES) - ; + while (YES); } #endif
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc index faad6778..b7b0c10e 100644 --- a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc +++ b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc @@ -13,16 +13,74 @@ namespace Kernel::HAL { typedef UInt32 PageTableIndex; +EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address) { + if (!virtual_address) return 0; + + UInt64 ttbr0_val = 0; + + asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val)); + volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val); + + UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF; + UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF; + UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF; + + if (!l1_table[l1_idx]) return 0; + + volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL); + + if (!l2_table[l2_idx]) return 0; + + volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL); + + if (!l3_table[l3_idx]) return 0; + + return (l3_table[l3_idx] & ~0xFFFUL); +} + /// @brief Maps or allocates a page from virtual_address. /// @param virtual_address a valid virtual address. /// @param phys_addr point to physical address. /// @param flags the flags to put on the page. /// @return Status code of page manipulation process. -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) { - if (!virtual_address || !flags) return kErrorInvalidData; +EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, + UInt32 level) { + if (!virtual_address || !flags || !physical_address) return kErrorInvalidData; + + UInt64 ttbr0_val = 0; + + asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val)); + volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val); + + UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF; + UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF; + UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF; + + if (!l1_table[l1_idx]) return kErrorInvalidData; + + volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL); + + if (!l2_table[l2_idx]) return kErrorInvalidData; + + volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL); + + l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; - NE_UNUSED(physical_address); + switch (level) { + case 2: { + l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + case 1: { + l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + case 0: { + l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + } - return kErrorSuccess; + return kErrorInvalidData; } } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h index 5001871b..be9fb116 100644 --- a/dev/kernel/HALKit/ARM64/Paging.h +++ b/dev/kernel/HALKit/ARM64/Paging.h @@ -86,14 +86,16 @@ namespace Detail { PageEnable = 31, }; - inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); } + inline UInt8 control_register_cast(ControlRegisterBits reg) { + return static_cast<UInt8>(reg); + } } // namespace Detail struct PDE_4KB final { PTE_4KB ALIGN(kPageAlign) fEntries[kPageMax]; }; -auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr; +auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr; auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 068b798d..68fe736c 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -36,7 +36,8 @@ enum { /// @param phys_addr point to physical address. /// @param flags the flags to put on the page. /// @return Status code of page manip. -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags); +EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, + UInt32 level = 2); EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address); diff --git a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc index daa26e53..6059e3be 100644 --- a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc @@ -10,8 +10,7 @@ namespace Kernel::Detail { STATIC void mp_hang_fn(void) { - while (YES) - ; + while (YES); } } // namespace Kernel::Detail diff --git a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc index 31d4a62e..e6fdddfb 100644 --- a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc @@ -13,8 +13,7 @@ using namespace Kernel; namespace Kernel {
namespace Detail {
STATIC void mp_hang_fn(void) {
- while (YES)
- ;
+ while (YES);
}
} // namespace Detail
diff --git a/dev/kernel/KernelKit/BinaryMutex.h b/dev/kernel/KernelKit/BinaryMutex.h index 45d4bd8d..f2c15af0 100644 --- a/dev/kernel/KernelKit/BinaryMutex.h +++ b/dev/kernel/KernelKit/BinaryMutex.h @@ -24,16 +24,16 @@ class BinaryMutex final { bool Unlock() noexcept; public: - BOOL WaitForProcess(const Int16& sec) noexcept; + BOOL WaitForProcess(const UInt32& sec) noexcept; public: - bool Lock(USER_PROCESS& process); - bool LockOrWait(USER_PROCESS& process, TimerInterface* timer); + bool Lock(USER_PROCESS* process); + bool LockOrWait(USER_PROCESS* process, TimerInterface* timer); public: NE_COPY_DEFAULT(BinaryMutex) private: - USER_PROCESS& fLockingProcess; + USER_PROCESS* fLockingProcess{nullptr}; }; } // namespace Kernel diff --git a/dev/kernel/KernelKit/CodeMgr.h b/dev/kernel/KernelKit/CodeMgr.h index 072ba4d5..c733bc47 100644 --- a/dev/kernel/KernelKit/CodeMgr.h +++ b/dev/kernel/KernelKit/CodeMgr.h @@ -18,6 +18,10 @@ #include <KernelKit/PECodeMgr.h> #include <KernelKit/PEFCodeMgr.h> +/// @file CodeMgr.h +/// @brief Code Manager header file. +/// @author Amlal El Mahrouss (amlal@nekernel.org) + namespace Kernel { /// @brief Main process entrypoint. typedef void (*rtl_main_kind)(void); diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h index c06ef92c..a7908b7d 100644 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -9,13 +9,17 @@ #include <NeKit/Defines.h> #include <NeKit/ErrorOr.h> +/// @file CoreProcessScheduler.h +/// @brief Core Process Scheduler header file. +/// @author Amlal El Mahrouss (amlal@nekernel.org) + #define kSchedMinMicroTime (AffinityKind::kStandard) #define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (32U) #define kSchedTeamCount (256U) -#define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ -#define kSchedMaxStackSz (kib_cast(8)) /* maximum stack size */ +#define kSchedMaxMemoryLimit (gib_cast(128)) /* max physical memory limit */ +#define kSchedMaxStackSz (kib_cast(8)) /* maximum stack size */ #define kSchedNameLen (128U) @@ -32,19 +36,23 @@ template <typename T> struct PROCESS_HEAP_TREE; template <typename T> +struct PROCESS_SPECIAL_TREE; + +template <typename T> struct PROCESS_FILE_TREE; enum { kInvalidTreeKind = 0U, kRedTreeKind = 100U, kBlackTreeKind = 101U, - kTreeKindCount = 2U, + kTreeKindCount = 3U, }; template <typename T> struct PROCESS_HEAP_TREE { - static constexpr auto kPtr = true; - static constexpr auto kFD = false; + static constexpr auto kHeap = true; + static constexpr auto kFile = false; + static constexpr auto kSpecial = false; T Entry{nullptr}; SizeT EntrySize{0UL}; @@ -69,8 +77,9 @@ struct PROCESS_HEAP_TREE { template <typename T> struct PROCESS_FILE_TREE { - static constexpr auto kPtr = false; - static constexpr auto kFD = true; + static constexpr auto kHeap = false; + static constexpr auto kFile = true; + static constexpr auto kSpecial = false; T Entry{nullptr}; SizeT EntrySize{0UL}; @@ -81,6 +90,7 @@ struct PROCESS_FILE_TREE { struct PROCESS_FILE_TREE<T>* Parent { nullptr }; + struct PROCESS_FILE_TREE<T>* Child { nullptr }; @@ -88,6 +98,7 @@ struct PROCESS_FILE_TREE { struct PROCESS_FILE_TREE<T>* Prev { nullptr }; + struct PROCESS_FILE_TREE<T>* Next { nullptr }; @@ -106,8 +117,6 @@ enum class ProcessSubsystem : Int32 { kProcessSubsystemCount = 4, }; -typedef UInt64 PTime; - /***********************************************************************************/ //! @brief Local Process identifier. /***********************************************************************************/ @@ -170,7 +179,8 @@ inline bool operator>=(AffinityKind lhs, AffinityKind rhs) { return lhs_int >= rhs_int; } -using ProcessTime = UInt64; +using PTime = UInt64; +using ProcessTime = PTime; using PID = Int64; /***********************************************************************************/ @@ -180,7 +190,7 @@ enum class ProcessLevelRing : Int32 { kRingStdUser = 1, kRingSuperUser = 2, kRingGuestUser = 5, - kRingCount = 5, + kRingCount = 3, }; /***********************************************************************************/ @@ -200,8 +210,8 @@ struct PROCESS_IMAGE final { friend class UserProcessScheduler; - ImagePtr fCode; - ImagePtr fBlob; + ImagePtr fCode{}; + ImagePtr fBlob{}; public: Bool HasCode() const { return this->fCode != nullptr; } diff --git a/dev/kernel/KernelKit/DebugOutput.h b/dev/kernel/KernelKit/DebugOutput.h index de3bc997..992d1ca7 100644 --- a/dev/kernel/KernelKit/DebugOutput.h +++ b/dev/kernel/KernelKit/DebugOutput.h @@ -12,7 +12,7 @@ #include <NeKit/Stream.h> #include <NeKit/Utils.h> -#define kDebugUnboundPort 0x0FEED +#define kDebugPort (51820U) #define kDebugMag0 'K' #define kDebugMag1 'D' @@ -27,7 +27,7 @@ namespace Kernel { class TerminalDevice; class DTraceDevice; -class DebugDevice; +class NeDebugDevice; class Utf8TerminalDevice; inline TerminalDevice end_line(); @@ -180,17 +180,9 @@ inline TerminalDevice get_console_in(Char* buf) { return self; } -inline constexpr SizeT kDebugTypeLen = 256U; +inline constexpr SizeT kDebugCmdLen = 256U; -typedef Char rt_debug_type[kDebugTypeLen]; - -/// @brief KDBG's packet header. -class KernelDebugHeader final { - public: - Int16 fPort; - Int16 fPortKind; - rt_debug_type fPortBlob; -}; +typedef Char rt_debug_cmd[kDebugCmdLen]; inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) { src = number(num); diff --git a/dev/kernel/KernelKit/DriveMgr.h b/dev/kernel/KernelKit/DriveMgr.h index 4a530deb..69df1cec 100644 --- a/dev/kernel/KernelKit/DriveMgr.h +++ b/dev/kernel/KernelKit/DriveMgr.h @@ -7,6 +7,10 @@ #ifndef INC_DRIVE_MANAGER_H #define INC_DRIVE_MANAGER_H +/// @file DriveMgr.h +/// @brief Drive Manager. +/// @author Amlal El Mahrouss (amlal@nekernel.org) + #include <CompilerKit/CompilerKit.h> #include <KernelKit/DebugOutput.h> #include <KernelKit/DeviceMgr.h> diff --git a/dev/kernel/KernelKit/FileMgr.h b/dev/kernel/KernelKit/FileMgr.h index 13eeabdf..f925a96c 100644 --- a/dev/kernel/KernelKit/FileMgr.h +++ b/dev/kernel/KernelKit/FileMgr.h @@ -4,6 +4,7 @@ File: FileMgr.h Purpose: Kernel file manager. + Author: Amlal El Mahrouss (amlal@nekernel.org) ------------------------------------------- */ @@ -21,7 +22,11 @@ #ifndef INC_FILEMGR_H #define INC_FILEMGR_H -//! Include filesystems that neoskrnl supports. +/// @file FileMgr.h +/// @brief File Manager. +/// @author Amlal El Mahrouss (amlal@nekernel.org) + +//! Include filesystems that NeKernel supports. #include <FSKit/Ext2.h> #include <FSKit/HeFS.h> #include <FSKit/NeFS.h> @@ -48,11 +53,6 @@ #define rtl_node_cast(PTR) reinterpret_cast<Kernel::NodePtr>(PTR) -/** - @note Refer to first enum. -*/ -#define kFileOpsCount (4U) - #define kFileMimeGeneric "ne-application-kind/all" /** @brief invalid position. (n-pos) */ @@ -65,10 +65,10 @@ enum { kFileReadAll = 101, kFileReadChunk = 102, kFileWriteChunk = 103, - kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1, // File flags (HFS+, NeFS specific) kFileFlagRsrc = 104, kFileFlagData = 105, + kFileIOCnt = (kFileFlagData - kFileWriteAll) + 1, }; typedef VoidPtr NodePtr; @@ -284,12 +284,10 @@ class FileStream final { this->fFileRestrict != kFileMgrRestrictReadBinary) return nullptr; - NE_UNUSED(sz); - auto man = FSClass::GetMounted(); if (man) { - VoidPtr ret = man->Read(name, fFile, kFileReadAll, 0); + VoidPtr ret = man->Read(name, fFile, kFileReadAll, sz); return ret; } @@ -394,6 +392,7 @@ inline FileStream<Encoding, Class>::FileStream(const Encoding* path, const Encod template <typename Encoding, typename Class> inline FileStream<Encoding, Class>::~FileStream() { mm_free_ptr(fFile); + fFile = nullptr; } } // namespace Kernel diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index 76327a93..168a0cc1 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -100,7 +100,7 @@ class HardwareThreadScheduler final : public ISchedulable { public: Ref<HardwareThread*> operator[](SizeT idx); bool operator!() noexcept; - operator bool() noexcept; + operator bool() noexcept; Bool IsUser() override { return Yes; } diff --git a/dev/kernel/KernelKit/KPC.h b/dev/kernel/KernelKit/KPC.h index a3b13de6..794197e2 100644 --- a/dev/kernel/KernelKit/KPC.h +++ b/dev/kernel/KernelKit/KPC.h @@ -65,6 +65,9 @@ inline constexpr KPCError kErrorFileLocked = 64; inline constexpr KPCError kErrorDiskIsTooTiny = 65; inline constexpr KPCError kErrorDmaExhausted = 66; inline constexpr KPCError kErrorOutOfBitMapMemory = 67; +inline constexpr KPCError kErrorTimeout = 68; +inline constexpr KPCError kErrorAccessDenied = 69; +inline constexpr KPCError kErrorUnavailable = 70; /// Generic errors. inline constexpr KPCError kErrorUnimplemented = -1; diff --git a/dev/kernel/KernelKit/KernelTaskScheduler.h b/dev/kernel/KernelKit/KernelTaskScheduler.h index 57b83ccb..c0879769 100644 --- a/dev/kernel/KernelKit/KernelTaskScheduler.h +++ b/dev/kernel/KernelKit/KernelTaskScheduler.h @@ -15,6 +15,12 @@ #include <KernelKit/LockDelegate.h> namespace Kernel { +class KernelTaskHelper; + +typedef PID KID; + +/// @brief Equivalent of USER_PROCESS, but for kernel tasks. +/// @author Amlal class KERNEL_TASK final { public: Char Name[kSchedNameLen] = {"KERNEL_TASK"}; @@ -23,5 +29,18 @@ class KERNEL_TASK final { UInt8* StackReserve{nullptr}; SizeT StackSize{kSchedMaxStackSz}; PROCESS_IMAGE Image{}; + /// @brief a KID is a Kernel Identification Descriptor, it is used to find a task running within + /// the kernel. + KID Kid{0}; +}; + +/// @brief Equivalent of UserProcessHelper, but for kernel tasks. +/// @author Amlal +class KernelTaskHelper final { + public: + STATIC Bool Switch(HAL::StackFramePtr frame_ptr, PID new_kid); + STATIC Bool CanBeScheduled(const KERNEL_TASK& process); + STATIC ErrorOr<PID> TheCurrentKID(); + STATIC SizeT StartScheduling(); }; } // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/LoaderInterface.h b/dev/kernel/KernelKit/LoaderInterface.h index 1f9b1e56..ed7d8364 100644 --- a/dev/kernel/KernelKit/LoaderInterface.h +++ b/dev/kernel/KernelKit/LoaderInterface.h @@ -23,9 +23,9 @@ class LoaderInterface { public: virtual _Output ErrorOr<VoidPtr> GetBlob() = 0; - virtual _Output const Char* AsString() = 0; - virtual _Output const Char* MIME() = 0; - virtual _Output const Char* Path() = 0; + virtual _Output const Char* AsString() = 0; + virtual _Output const Char* MIME() = 0; + virtual _Output const Char* Path() = 0; virtual _Output ErrorOr<VoidPtr> FindStart() = 0; virtual _Output ErrorOr<VoidPtr> FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; }; diff --git a/dev/kernel/KernelKit/LockDelegate.h b/dev/kernel/KernelKit/LockDelegate.h index b5977c92..a8c36de7 100644 --- a/dev/kernel/KernelKit/LockDelegate.h +++ b/dev/kernel/KernelKit/LockDelegate.h @@ -11,10 +11,10 @@ namespace Kernel { enum { - kLockInvalid = 0, - kLockDone = 200, - kLockTimedOut, - kLockCount = 3, + kLockInvalid = 0, + kLockDone = 200, + kLockTimedOut = 300, + kLockCount = 3, }; /// @brief Lock condition pointer. diff --git a/dev/kernel/KernelKit/PCI/DMA.h b/dev/kernel/KernelKit/PCI/DMA.h index 7e7d3f0c..c4e3b61a 100644 --- a/dev/kernel/KernelKit/PCI/DMA.h +++ b/dev/kernel/KernelKit/PCI/DMA.h @@ -47,7 +47,7 @@ class DMAWrapper final { T* Get(UIntPtr off = 0); public: - operator bool(); + operator bool(); bool operator!(); public: diff --git a/dev/kernel/KernelKit/PEF.h b/dev/kernel/KernelKit/PEF.h index c28c8f8c..fd39392e 100644 --- a/dev/kernel/KernelKit/PEF.h +++ b/dev/kernel/KernelKit/PEF.h @@ -11,19 +11,19 @@ ------------------------------------------- */ -#ifndef KERNELKIT_PEF_H -#define KERNELKIT_PEF_H +#ifndef __KERNELKIT_PEF_H__ +#define __KERNELKIT_PEF_H__ #include <CompilerKit/CompilerKit.h> #include <KernelKit/LoaderInterface.h> #include <NeKit/Defines.h> -#define kPefMagic "Joy!" -#define kPefMagicFat "yoJ!" +#define kPefMagic "Open" +#define kPefMagicFat "nepO" #define kPefMagicLen (5) -#define kPefVersion (4) +#define kPefVersion (0x0500) #define kPefNameLen (256U) /* not mandatory, only for non fork based filesystems. */ @@ -54,15 +54,15 @@ enum { kPefArch32x0, /* 32x0. ISA */ kPefArchPowerPC, kPefArchARM64, - kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1, + kPefArchCount = (kPefArchARM64 - kPefArchIntel86S) + 1, kPefArchInvalid = 0xFF, }; enum { + kPefSubArchGeneric, kPefSubArchAMD = 200, kPefSubArchIntel, kPefSubArchARM, - kPefSubArchGeneric, kPefSubArchIBM, }; @@ -98,16 +98,19 @@ typedef struct PEFCommandHeader final { UInt32 Flags; /* container flags */ UInt16 Kind; /* container kind */ UIntPtr Offset; /* content offset */ - UIntPtr VMAddress; /* VM offset */ - SizeT Size; /* content Size */ + SizeT OffsetSize; /* offset size (physical size inside the file) */ + UIntPtr VMAddress; /* Virtual Address */ + SizeT VMSize; /* Virtual Size */ } PACKED PEFCommandHeader; enum { + kPefInvalid = 0x0, kPefCode = 0xC, kPefData = 0xD, kPefZero = 0xE, kPefLinkerID = 0x1, + kPefCount = 4, }; } // namespace Kernel -#endif /* ifndef KERNELKIT_PEF_H */ +#endif /* ifndef __KERNELKIT_PEF_H__ */ diff --git a/dev/kernel/KernelKit/PEFCodeMgr.h b/dev/kernel/KernelKit/PEFCodeMgr.h index 18041f8f..d61aa863 100644 --- a/dev/kernel/KernelKit/PEFCodeMgr.h +++ b/dev/kernel/KernelKit/PEFCodeMgr.h @@ -7,6 +7,10 @@ #ifndef _INC_CODE_MANAGER_PEF_H_ #define _INC_CODE_MANAGER_PEF_H_ +/// @file PEFCodeMgr.h +/// @brief PEF Code Manager header file. +/// @author Amlal El Mahrouss (amlal@nekernel.org) + #include <KernelKit/FileMgr.h> #include <KernelKit/PEF.h> #include <NeKit/ErrorOr.h> @@ -59,8 +63,8 @@ class PEFLoader : public LoaderInterface { Ref<KString> fPath; VoidPtr fCachedBlob; - bool fFatBinary; - bool fBad; + BOOL fFatBinary{}; + BOOL fBad{}; }; namespace Utils { diff --git a/dev/kernel/KernelKit/Semaphore.h b/dev/kernel/KernelKit/Semaphore.h index a1b5ecad..f73f36ed 100644 --- a/dev/kernel/KernelKit/Semaphore.h +++ b/dev/kernel/KernelKit/Semaphore.h @@ -6,10 +6,105 @@ #pragma once +/// @author Amlal El Mahrouss +/// @file Semaphore.h +/// @brief Semaphore structure and functions for synchronization in the kernel. + #include <CompilerKit/CompilerKit.h> #include <KernelKit/Timer.h> #include <NeKit/Defines.h> +#define kSemaphoreOwnerIndex (0U) +#define kSemaphoreCountIndex (1U) + +#define kSemaphoreCount (2U) + +#define kSemaphoreIncrementOwner(sem) (sem[kSemaphoreOwnerIndex]++) +#define kSemaphoreDecrementOwner(sem) (sem[kSemaphoreOwnerIndex]--) + namespace Kernel { -typedef Int64 Semaphore; +/// @brief Semaphore structure used for synchronization. +typedef UInt64 SemaphoreArr[kSemaphoreCount]; + +/// @brief Checks if the semaphore is valid. +inline BOOL rtl_sem_is_valid(const SemaphoreArr& sem, UInt64 owner = 0) { + return sem[kSemaphoreOwnerIndex] == owner && sem[kSemaphoreCountIndex] > 0; +} + +/// @brief Releases the semaphore, resetting its owner and count. +/// @param sem +/// @return +inline BOOL rtl_sem_release(SemaphoreArr& sem) { + sem[kSemaphoreOwnerIndex] = 0; + sem[kSemaphoreCountIndex] = 0; + + return TRUE; +} + +/// @brief Initializes the semaphore with an owner and a count of zero. +/// @param sem the semaphore array to use. +/// @param owner the owner to set, could be anything identifitable. +/// @return +inline BOOL rtl_sem_acquire(SemaphoreArr& sem, UInt64 owner) { + if (!owner) { + err_global_get() = kErrorInvalidData; + return FALSE; // Invalid owner + } + + sem[kSemaphoreOwnerIndex] = owner; + sem[kSemaphoreCountIndex] = 0; + + return TRUE; +} + +/// @brief Waits for the semaphore to be available, blocking until it is. +/// @param sem +/// @param timeout +/// @param condition condition pointer. +/// @return +inline BOOL rtl_sem_wait(SemaphoreArr& sem, UInt64 owner, UInt64 timeout, + BOOL* condition = nullptr) { + if (!rtl_sem_is_valid(sem, owner)) { + return FALSE; + } + + if (timeout <= 0) { + err_global_get() = kErrorTimeout; + + return FALSE; + } + + if (!condition || *condition) { + if (sem[kSemaphoreCountIndex] == 0) { + err_global_get() = kErrorUnavailable; + return FALSE; + } + + err_global_get() = kErrorSuccess; + sem[kSemaphoreCountIndex]--; + + return TRUE; + } + + HardwareTimer timer(timeout); + BOOL ret = timer.Wait(); + + if (ret) { + if (!condition || *condition) { + if (sem[kSemaphoreCountIndex] == 0) { + err_global_get() = kErrorUnavailable; + return FALSE; + } + + err_global_get() = kErrorSuccess; + sem[kSemaphoreCountIndex]--; + + return TRUE; + } + } + + err_global_get() = kErrorTimeout; + + return FALSE; // Failed to acquire semaphore +} } // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/ThreadLocalStorage.h b/dev/kernel/KernelKit/ThreadLocalStorage.h index 1b8e4821..47ff526c 100644 --- a/dev/kernel/KernelKit/ThreadLocalStorage.h +++ b/dev/kernel/KernelKit/ThreadLocalStorage.h @@ -10,24 +10,24 @@ #include <NeKit/Defines.h> #include <NeKit/ErrorOr.h> -///! @brief Thread Local Storage for neoskrnl. +///! @brief Thread Local Storage for NeKernel. -#define kCookieMag0Idx 0 -#define kCookieMag1Idx 1 -#define kCookieMag2Idx 2 +#define kCookieMag0Idx (0U) +#define kCookieMag1Idx (1U) +#define kCookieMag2Idx (2U) -#define kCookieMag0 'Z' +#define kCookieMag0 'N' #define kCookieMag1 'K' -#define kCookieMag2 'A' +#define kCookieMag2 'O' -#define kTLSCookieLen (3U) +#define kCookieMagLen (3U) struct THREAD_INFORMATION_BLOCK; /// @brief Thread Information Block. /// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64) struct PACKED THREAD_INFORMATION_BLOCK final { - Kernel::Char Cookie[kTLSCookieLen]{0}; //! Thread Magic Number. + Kernel::Char Cookie[kCookieMagLen]{0}; //! Thread Magic Number. Kernel::VoidPtr UserData{nullptr}; //! Thread Information Record (User defined canary structure) }; diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 5bc5b8d2..3dae178a 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -62,7 +62,7 @@ class USER_PROCESS final { }; USER_PROCESS_SIGNAL Signal; - PROCESS_FILE_TREE<UInt32*>* FileTree{nullptr}; + PROCESS_FILE_TREE<VoidPtr>* FileTree{nullptr}; PROCESS_HEAP_TREE<VoidPtr>* HeapTree{nullptr}; UserProcessTeam* ParentTeam; @@ -93,7 +93,10 @@ class USER_PROCESS final { /***********************************************************************************/ Void Crash(); - Bool SpawnDylib(); + /***********************************************************************************/ + ///! @brief Spawns a dynamic library handle if dylib. + /***********************************************************************************/ + Bool InitDylib(); /***********************************************************************************/ ///! @brief Exits the app. @@ -189,7 +192,7 @@ class UserProcessScheduler final : public ISchedulable { NE_MOVE_DELETE(UserProcessScheduler) public: - operator bool(); + operator bool(); bool operator!(); public: diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index df35e037..0605a5e0 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -17,7 +17,7 @@ namespace Kernel { /***********************************************************************************/ -/** @brief Free pointer from usage. */ +/** @brief Free pointer/file from usage. */ /***********************************************************************************/ template <typename T> diff --git a/dev/kernel/NeKit/Crc32.h b/dev/kernel/NeKit/Crc32.h index 8988f828..0fc35134 100644 --- a/dev/kernel/NeKit/Crc32.h +++ b/dev/kernel/NeKit/Crc32.h @@ -16,7 +16,7 @@ #define kCrcCnt (256) namespace Kernel { -UInt32 ke_calculate_crc32(const Char* crc, Int32 len) noexcept; +UInt32 ke_calculate_crc32(const VoidPtr crc, Int32 len) noexcept; } // namespace Kernel #endif // !CRC32_H diff --git a/dev/kernel/NeKit/Macros.h b/dev/kernel/NeKit/Macros.h index b46ffaa8..e80e2e47 100644 --- a/dev/kernel/NeKit/Macros.h +++ b/dev/kernel/NeKit/Macros.h @@ -16,7 +16,7 @@ #endif #ifndef kib_cast -#define kib_cast(X) (Kernel::UInt64)((X) *1024) +#define kib_cast(X) (Kernel::UInt64)((X) * 1024) #endif #ifndef MIB diff --git a/dev/kernel/NeKit/OwnPtr.h b/dev/kernel/NeKit/OwnPtr.h index 674f9ff3..f5ff4b54 100644 --- a/dev/kernel/NeKit/OwnPtr.h +++ b/dev/kernel/NeKit/OwnPtr.h @@ -50,7 +50,7 @@ class OwnPtr final { Ref<T> AsRef() { return Ref<T>(fCls); } - operator bool() { return fCls; } + operator bool() { return fCls; } bool operator!() { return !fCls; } private: diff --git a/dev/kernel/NeKit/Ref.h b/dev/kernel/NeKit/Ref.h index 4d343bc5..46e94f88 100644 --- a/dev/kernel/NeKit/Ref.h +++ b/dev/kernel/NeKit/Ref.h @@ -29,7 +29,7 @@ class Ref final { return *this; } - NE_COPY_DEFAULT(Ref); + NE_COPY_DEFAULT(Ref) public: T operator->() const { return fClass; } diff --git a/dev/kernel/NeKit/Utils.h b/dev/kernel/NeKit/Utils.h index 43526fc8..11566008 100644 --- a/dev/kernel/NeKit/Utils.h +++ b/dev/kernel/NeKit/Utils.h @@ -1,4 +1,3 @@ - /* ------------------------------------------- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. @@ -29,6 +28,10 @@ Int rt_to_lower(Int c); voidPtr rt_string_in_string(const Char* in, const Char* needle); char* rt_string_has_char(Char* str, Char chr); +// Safe memory functions +Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size); +voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size); + /// UNICODE API Int urt_string_cmp(const Char* src, const Char* cmp, Size len); diff --git a/dev/kernel/NetworkKit/IPC.h b/dev/kernel/NetworkKit/IPC.h index 0dd8a1f1..d14356c0 100644 --- a/dev/kernel/NetworkKit/IPC.h +++ b/dev/kernel/NetworkKit/IPC.h @@ -57,6 +57,12 @@ enum { constexpr inline auto kIPCMsgSize = 6094U; +enum { + kIPCLockInvalid, + kIPCLockFree = 1, + kIPCLockUsed = 2, +}; + /// @brief IPC connection header, message cannot be greater than 6K. typedef struct IPC_MSG final { UInt32 IpcHeaderMagic; // cRemoteHeaderMagic @@ -68,7 +74,7 @@ typedef struct IPC_MSG final { UInt32 IpcMsg; UInt32 IpcMsgSz; UInt8 IpcData[kIPCMsgSize]; - + UInt32 IpcLock; /// @brief Passes the message to target, could be anything, HTTP packet, JSON or whatever. static Bool Pass(IPC_MSG* self, IPC_MSG* target) noexcept; } PACKED IPC_MSG; diff --git a/dev/kernel/amd64-ci.make b/dev/kernel/amd64-ci.make index c728b29c..f21efca4 100644 --- a/dev/kernel/amd64-ci.make +++ b/dev/kernel/amd64-ci.make @@ -1,6 +1,6 @@ ################################################## # (c) Amlal El Mahrouss, all rights reserved. -# This is the neoskrnl's makefile. +# This is the NeKernel's makefile. ################################################## CXX = x86_64-w64-mingw32-g++ @@ -42,7 +42,7 @@ error: @echo "=== ERROR ===" @echo "=> Use a specific target." -MOVEALL=./MoveAll.X64.sh +MOVEALL=./move-all-x64.sh WINDRES=x86_64-w64-mingw32-windres .PHONY: nekernel-amd64-epm diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make index 21488782..36b0f18e 100644 --- a/dev/kernel/amd64-desktop.make +++ b/dev/kernel/amd64-desktop.make @@ -1,6 +1,6 @@ ################################################## # (c) Amlal El Mahrouss, all rights reserved. -# This is the neoskrnl's makefile. +# This is the NeKernel's makefile. ################################################## CXX = x86_64-w64-mingw32-g++ @@ -44,7 +44,7 @@ error: @echo "=== ERROR ===" @echo "=> Use a specific target." -MOVEALL=./MoveAll.X64.sh +MOVEALL=./move-all-x64.sh WINDRES=x86_64-w64-mingw32-windres .PHONY: nekernel-amd64-epm diff --git a/dev/kernel/arm64-desktop.make b/dev/kernel/arm64-desktop.make index 423391af..e83e1db8 100644 --- a/dev/kernel/arm64-desktop.make +++ b/dev/kernel/arm64-desktop.make @@ -30,7 +30,7 @@ error: @echo "=== ERROR ===" @echo "=> Use a specific target." -MOVEALL=./MoveAll.ARM64.sh +MOVEALL=./move-all-aarch64.sh .PHONY: nekernel-arm64-epm nekernel-arm64-epm: clean diff --git a/dev/kernel/MoveAll.ARM64.sh b/dev/kernel/move-all-aarch64.sh index 35e0909e..35e0909e 100755 --- a/dev/kernel/MoveAll.ARM64.sh +++ b/dev/kernel/move-all-aarch64.sh diff --git a/dev/kernel/MoveAll.X64.sh b/dev/kernel/move-all-x64.sh index 1c135d06..1c135d06 100755 --- a/dev/kernel/MoveAll.X64.sh +++ b/dev/kernel/move-all-x64.sh diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index 8cc11cad..01f30500 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -10,12 +10,11 @@ #include <modules/ACPI/ACPIFactoryInterface.h> namespace Kernel { -constexpr STATIC const auto kMinACPIVer = 1; +constexpr STATIC const auto kMinACPIVer = 1U; /// @brief Finds a descriptor table inside ACPI XSDT. ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) { - MUST_PASS(this->fRsdp); - + if (this->fRsdp) return ErrorOr<voidPtr>{kErrorInvalidData}; if (!signature) return ErrorOr<voidPtr>{-kErrorInvalidData}; if (*signature == 0) return ErrorOr<voidPtr>{-kErrorInvalidData}; @@ -33,7 +32,7 @@ ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) { if (num < 1) { /// stop here, we should have entries... ke_panic(RUNTIME_CHECK_ACPI); - return ErrorOr<voidPtr>{-1}; + return ErrorOr<voidPtr>{-kErrorInvalidData}; } this->fEntries = num; @@ -62,7 +61,7 @@ ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) { } } - return ErrorOr<voidPtr>{-1}; + return ErrorOr<voidPtr>{-kErrorInvalidData}; } /*** diff --git a/dev/kernel/src/AsciiUtils.cc b/dev/kernel/src/AsciiUtils.cc index bfc56aec..66a4aaef 100644 --- a/dev/kernel/src/AsciiUtils.cc +++ b/dev/kernel/src/AsciiUtils.cc @@ -8,8 +8,8 @@ namespace Kernel { -STATIC Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size); -STATIC voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size); +Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size); +voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size); Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) { for (Size i = 0; i < size; ++i) { @@ -45,7 +45,7 @@ const Char* rt_alloc_string(const Char* src) { return buffer; } -STATIC Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size) { +Int 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); @@ -58,7 +58,7 @@ STATIC Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size ds return static_cast<Int>(len); } -STATIC voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size) { +voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size) { if (!dst || len > dst_size) return nullptr; auto p = reinterpret_cast<UInt8*>(dst); UInt8 v = static_cast<UInt8>(value & 0xFF); @@ -73,8 +73,7 @@ Void rt_zero_memory(voidPtr pointer, Size len) { #ifdef __NE_ENFORCE_DEPRECATED_WARNINGS [[deprecated("Use rt_set_memory_safe instead")]] #endif -voidPtr -rt_set_memory(voidPtr src, UInt32 value, Size len) { +voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) { if (!src) return nullptr; auto p = reinterpret_cast<UInt8*>(src); UInt8 v = static_cast<UInt8>(value & 0xFF); @@ -156,26 +155,18 @@ Char* rt_string_has_char(Char* str, Char ch) { return (*str == ch) ? str : nullptr; } -Int32 rt_strcmp(const Char* a, const Char* b) { - Size i = 0; - while (a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) { - ++i; - } - return static_cast<Int32>(static_cast<UInt8>(a[i]) - static_cast<UInt8>(b[i])); -} - -// @uses the deprecated version callers should ensure 'len' is valid. -extern "C" void* memset(void* dst, int c, long long unsigned int len) { - return Kernel::rt_set_memory(dst, c, static_cast<Size>(len)); +EXTERN_C void* memset(void* dst, int c, long long unsigned int len) { + return Kernel::rt_set_memory_safe(dst, c, static_cast<Size>(len), static_cast<Size>(len)); } -extern "C" void* memcpy(void* dst, const void* src, long long unsigned int len) { - Kernel::rt_copy_memory(const_cast<void*>(src), dst, static_cast<Size>(len)); +EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) { + Kernel::rt_copy_memory_safe(const_cast<void*>(src), dst, static_cast<Size>(len), + static_cast<Size>(len)); return dst; } -extern "C" Kernel::Int32 strcmp(const char* a, const char* b) { - return Kernel::rt_strcmp(a, b); +EXTERN_C Kernel::Int32 strcmp(const char* a, const char* b) { + return Kernel::rt_string_cmp(a, b, rt_string_len(a)); } } // namespace Kernel diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc index bbf7a477..9bfb89d9 100644 --- a/dev/kernel/src/BinaryMutex.cc +++ b/dev/kernel/src/BinaryMutex.cc @@ -11,10 +11,10 @@ namespace Kernel { /***********************************************************************************/ /// @brief Unlocks the binary mutex. /***********************************************************************************/ + Bool BinaryMutex::Unlock() noexcept { - if (fLockingProcess.Status == ProcessStatusKind::kRunning) { - fLockingProcess = USER_PROCESS(); - fLockingProcess.Status = ProcessStatusKind::kFrozen; + if (fLockingProcess->Status == ProcessStatusKind::kRunning) { + fLockingProcess = nullptr; return Yes; } @@ -25,7 +25,8 @@ Bool BinaryMutex::Unlock() noexcept { /***********************************************************************************/ /// @brief Locks process in the binary mutex. /***********************************************************************************/ -Bool BinaryMutex::Lock(USER_PROCESS& process) { + +Bool BinaryMutex::Lock(USER_PROCESS* process) { if (!process || this->IsLocked()) return No; this->fLockingProcess = process; @@ -36,14 +37,16 @@ Bool BinaryMutex::Lock(USER_PROCESS& process) { /***********************************************************************************/ /// @brief Checks if process is locked. /***********************************************************************************/ + Bool BinaryMutex::IsLocked() const { - return this->fLockingProcess.Status == ProcessStatusKind::kRunning; + return this->fLockingProcess->Status == ProcessStatusKind::kRunning; } /***********************************************************************************/ /// @brief Try lock or wait. /***********************************************************************************/ -Bool BinaryMutex::LockOrWait(USER_PROCESS& process, TimerInterface* timer) { + +Bool BinaryMutex::LockOrWait(USER_PROCESS* process, TimerInterface* timer) { if (timer == nullptr) return No; this->Lock(process); @@ -57,7 +60,8 @@ Bool BinaryMutex::LockOrWait(USER_PROCESS& process, TimerInterface* timer) { /// @brief Wait for process **sec** until we check if it's free. /// @param sec seconds. /***********************************************************************************/ -BOOL BinaryMutex::WaitForProcess(const Int16& sec) noexcept { + +BOOL BinaryMutex::WaitForProcess(const UInt32& sec) noexcept { HardwareTimer hw_timer(rtl_milliseconds(sec)); hw_timer.Wait(); diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc index df678d41..22737dbe 100644 --- a/dev/kernel/src/BitMapMgr.cc +++ b/dev/kernel/src/BitMapMgr.cc @@ -19,6 +19,8 @@ #define kBitMapSizeIdx (1U) #define kBitMapUsedIdx (2U) +///! @author Amlal El Mahrouss (amlal@nekernel.org) + namespace Kernel { namespace HAL { namespace Detail { diff --git a/dev/kernel/src/Crc32.cc b/dev/kernel/src/Crc32.cc index fddcb095..46a1d940 100644 --- a/dev/kernel/src/Crc32.cc +++ b/dev/kernel/src/Crc32.cc @@ -49,11 +49,13 @@ UInt32 kChecksumPolys[kCrcCnt] = { /// @param in the data to compute. /// @param len the length of the data. /// @return CRC32 of **in**. -UInt32 ke_calculate_crc32(const Char* in, Int32 len) noexcept { - if (!in || *in == 0) return ~0; +UInt32 ke_calculate_crc32(const VoidPtr inp, Int32 len) noexcept { + if (!inp) return ~0; UInt32 crc = 0xffffffff; + Char* in = static_cast<Char*>(inp); + while ((len--) > 0) crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF]; return ~crc; diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index b7c181c8..9f107e97 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -15,7 +15,8 @@ /***********************************************************************************/ /// @file DriveMgr.cc -/// @brief Drive Manager of kernel. +/// @brief Drive Manager of NeKernel. +///! @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ namespace Kernel { diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index 39f8c0a1..344369d5 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -89,6 +89,8 @@ namespace Detail { /// @param path the directory path. /// @return The hashed path. STATIC UInt64 hefsi_hash_64(const Utf8Char* path) { + if (!path || *path == 0) return 0; + const UInt64 FNV_OFFSET_BASIS = 0xcbf29ce484222325ULL; const UInt64 FNV_PRIME = 0x100000001b3ULL; @@ -798,11 +800,11 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input c return NO; } - rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); urt_copy_memory((VoidPtr) vol_name, boot->fVolName, urt_string_len(vol_name) + 1); - rt_copy_memory((VoidPtr) kHeFSMagic, boot->fMagic, kHeFSMagicLen - 1); + rt_copy_memory_safe((VoidPtr) kHeFSMagic, boot->fMagic, kHeFSMagicLen - 1, sizeof(boot->fMagic)); if (mnt->fLbaStart > mnt->fLbaEnd) { err_global_get() = kErrorDiskIsCorrupted; @@ -906,8 +908,8 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt, HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) mm_alloc_ptr(sizeof(HEFS_BOOT_NODE), Yes, No); - rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); mnt->fPacket.fPacketLba = mnt->fLbaStart; mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); @@ -992,8 +994,8 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc return NO; } - rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); mnt->fPacket.fPacketLba = mnt->fLbaStart; mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); @@ -1078,8 +1080,8 @@ _Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input co return NO; } - rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); mnt->fPacket.fPacketLba = mnt->fLbaStart; mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); diff --git a/dev/kernel/src/FS/NeFS+FileSystemParser.cc b/dev/kernel/src/FS/NeFS+FileSystemParser.cc index 18595e9f..7b9ebcd6 100644 --- a/dev/kernel/src/FS/NeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/NeFS+FileSystemParser.cc @@ -154,8 +154,8 @@ _Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) { /// @return the newly found fork. /***********************************************************************************/ _Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUCT* catalog, - _Input const Char* name, - _Input Boolean is_data) { + _Input const Char* name, + _Input Boolean is_data) { if (!catalog || !name) return nullptr; auto& drive = kMountpoint.A(); @@ -167,8 +167,8 @@ _Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUC drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&local_buf); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); if (auto res = fs_ifs_read(&kMountpoint, drive, this->mDriveIndex); res) { switch (res) { @@ -190,7 +190,7 @@ _Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUC if (KStringBuilder::Equals(local_buf.ForkName, name) && KStringBuilder::Equals(local_buf.CatalogName, catalog->Name)) { auto result = new NEFS_FORK_STRUCT(); - rt_copy_memory(&local_buf, result, sizeof(NEFS_FORK_STRUCT)); + rt_copy_memory_safe(&local_buf, result, sizeof(NEFS_FORK_STRUCT), sizeof(NEFS_FORK_STRUCT)); return result; } @@ -217,7 +217,7 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char /// @param kind the catalog kind. /// @return catalog pointer. /***********************************************************************************/ -_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name, +_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name, _Input const Int32& flags, _Input const Int32& kind) { kout << "CreateCatalog(*...*)\r"; @@ -249,7 +249,7 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char } Char* parent_name = (Char*) mm_alloc_ptr(nameLen + 1, Yes, No); - rt_copy_memory(const_cast<Char*>(name), parent_name, nameLen + 1); + rt_copy_memory_safe(const_cast<Char*>(name), parent_name, nameLen + 1, nameLen + 1); if (nameLen < 2) { mm_free_ptr(parent_name); @@ -312,13 +312,14 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char --i; if (kind == kNeFSCatalogKindDir) --i; while (name[i] != '/') --i; - rt_copy_memory((VoidPtr) (name + i), (VoidPtr) child_catalog->Name, rt_string_len(name) - i); + rt_copy_memory_safe((VoidPtr) (name + i), (VoidPtr) child_catalog->Name, rt_string_len(name) - i, + kNeFSCatalogNameLen); NEFS_CATALOG_STRUCT temporary_catalog{}; Lba start_free = out_lba; - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf_part_block); @@ -380,13 +381,15 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char delete catalog; NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT(); - rt_copy_memory(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT)); + rt_copy_memory_safe(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT), + sizeof(NEFS_CATALOG_STRUCT)); delete child_catalog; return found_catalog; } else if ((temporary_catalog.Flags & kNeFSFlagCreated) && KStringBuilder::Equals(temporary_catalog.Name, name)) { - rt_copy_memory(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT)); + rt_copy_memory_safe(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT), + sizeof(NEFS_CATALOG_STRUCT)); delete catalog; return child_catalog; } @@ -411,8 +414,8 @@ bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const I // verify disk. drive->fVerify(drive->fPacket); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/nefs-packet"), sizeof(drive->fPacket.fPacketMime)); if (!drive->fPacket.fPacketGood) { err_global_get() = kErrorDiskIsCorrupted; return false; @@ -430,9 +433,10 @@ bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const I if (rt_string_cmp(kNeFSIdent, part_block->Ident, kNeFSIdentLen) == 0) return true; const auto kNeFSUntitledHD = part_name; - rt_copy_memory((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen); - rt_copy_memory((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName, - rt_string_len(kNeFSUntitledHD)); + rt_copy_memory_safe((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen, + sizeof(part_block->Ident)); + rt_copy_memory_safe((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName, + rt_string_len(kNeFSUntitledHD), sizeof(part_block->PartitionName)); SizeT sectorCount = drv_std_get_sector_count(); SizeT sectorSize = drive->fSectorSz; @@ -513,9 +517,9 @@ bool NeFileSystemParser::WriteCatalog(_Input const Char* catalog_name, Bool is_r auto buf = new UInt8[size_of_data]; rt_set_memory(buf, 0, size_of_data); - rt_copy_memory(data, buf, size_of_data); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory_safe(data, buf, size_of_data, size_of_data); + rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT(); NEFS_FORK_STRUCT prev_fork{}; @@ -577,8 +581,8 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* NEFS_ROOT_PARTITION_BLOCK part{}; auto& drive = kMountpoint.A(); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part); drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; @@ -607,7 +611,8 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* return nullptr; } NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT(); - rt_copy_memory(&tmp, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT)); + rt_copy_memory_safe(&tmp, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT), + sizeof(NEFS_CATALOG_STRUCT)); out_lba = cursor; return catalog_ptr; } @@ -619,7 +624,8 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search) { Char parent_name[kNeFSCatalogNameLen] = {0}; SizeT nameLen = rt_string_len(catalog_name); - rt_copy_memory(const_cast<Char*>(catalog_name), parent_name, nameLen + 1); + rt_copy_memory_safe(const_cast<Char*>(catalog_name), parent_name, nameLen + 1, + kNeFSCatalogNameLen); SizeT indexReverseCopy = nameLen - 1; if (parent_name[indexReverseCopy] == NeFileSystemHelper::Separator()) { @@ -727,8 +733,8 @@ _Output Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_nam catalog->Flags &= (~kNeFSFlagCreated); catalog->Flags |= kNeFSFlagDeleted; - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); drive.fPacket.fPacketLba = out_lba; drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(catalog); @@ -795,8 +801,8 @@ VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* cata } auto* fs_buf = new NEFS_FORK_STRUCT(); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); NEFS_FORK_STRUCT* fs_fork_data = nullptr; while (dataForkLba >= kNeFSCatalogStartAddress) { diff --git a/dev/kernel/src/FileMgr.cc b/dev/kernel/src/FileMgr.cc index e000965f..faed9ae1 100644 --- a/dev/kernel/src/FileMgr.cc +++ b/dev/kernel/src/FileMgr.cc @@ -10,6 +10,7 @@ /***********************************************************************************/ /// @file FileMgr.cc //! @brief File System Manager API. +///! @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ namespace Kernel { diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc index d1d4eeca..a24fba72 100644 --- a/dev/kernel/src/IPEFDylibObject.cc +++ b/dev/kernel/src/IPEFDylibObject.cc @@ -35,6 +35,7 @@ using namespace Kernel; /***********************************************************************************/ /// @file IPEFDylibObject.cc /// @brief PEF's Dylib runtime. +///! @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ /***********************************************************************************/ diff --git a/dev/kernel/src/IndexableProperty.cc b/dev/kernel/src/IndexableProperty.cc index 1d2a1ce8..251d6645 100644 --- a/dev/kernel/src/IndexableProperty.cc +++ b/dev/kernel/src/IndexableProperty.cc @@ -6,6 +6,8 @@ #include <CompilerKit/CompilerKit.h> #include <FSKit/IndexableProperty.h> +#include <NeKit/KString.h> +#include <NeKit/KernelPanic.h> #include <NeKit/MutableArray.h> #include <NeKit/Utils.h> @@ -16,13 +18,21 @@ namespace Kernel { namespace Indexer { - Index& IndexableProperty::Leak() noexcept { return fIndex; } + Index& IndexableProperty::Leak() noexcept { + return fIndex; + } - Void IndexableProperty::AddFlag(Int16 flag) { fFlags |= flag; } + Void IndexableProperty::AddFlag(Int16 flag) { + fFlags |= flag; + } - Void IndexableProperty::RemoveFlag(Int16 flag) { fFlags &= flag; } + Void IndexableProperty::RemoveFlag(Int16 flag) { + fFlags &= flag; + } - Int16 IndexableProperty::HasFlag(Int16 flag) { return fFlags & flag; } + Int16 IndexableProperty::HasFlag(Int16 flag) { + return fFlags & flag; + } /// @brief Index a file into the indexer instance. /// @param filename filesystem path to access. @@ -32,7 +42,8 @@ namespace Indexer { Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) { if (!indexer.HasFlag(kIndexerClaimed)) { indexer.AddFlag(kIndexerClaimed); - rt_copy_memory((VoidPtr) indexer.Leak().Path, (VoidPtr) filename, filenameLen); + rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(filename)), + (VoidPtr) indexer.Leak().Path, filenameLen, kIndexerCatalogNameLength); (Void)(kout << "FSKit: Indexed new file: " << filename << kendl); } diff --git a/dev/kernel/src/Network/IPAddr.cc b/dev/kernel/src/Network/IPAddr.cc index b341af8f..ec7d8a35 100644 --- a/dev/kernel/src/Network/IPAddr.cc +++ b/dev/kernel/src/Network/IPAddr.cc @@ -88,19 +88,23 @@ ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4) { bool IPFactory::IpCheckVersion4(const Char* ip) { if (!ip) return NO; - Int32 cnter = 0; + Int32 cnter = 0; + Int32 dot_cnter = 0; for (SizeT base = 0; base < rt_string_len(ip); ++base) { if (ip[base] == '.') { cnter = 0; + ++dot_cnter; } else { - if (!rt_is_alnum(ip[base])) return false; - if (cnter == 3) return false; + if (!rt_is_alnum(ip[base])) return NO; + if (cnter == 3) return NO; ++cnter; } } - return true; + if (dot_cnter != 3) return NO; + + return YES; } } // namespace Kernel diff --git a/dev/kernel/src/Network/IPCMsg.cc b/dev/kernel/src/Network/IPCMsg.cc index cff19cfa..9abefcef 100644 --- a/dev/kernel/src/Network/IPCMsg.cc +++ b/dev/kernel/src/Network/IPCMsg.cc @@ -87,6 +87,8 @@ Bool ipc_construct_packet(_Output IPC_MSG** pckt_in) { (*pckt_in)->IpcFrom.UserProcessID = 0; (*pckt_in)->IpcFrom.UserProcessTeam = 0; + (*pckt_in)->IpcLock = kIPCLockFree; + return Yes; } @@ -103,7 +105,19 @@ Bool IPC_MSG::Pass(IPC_MSG* src, IPC_MSG* target) noexcept { if (src->IpcMsgSz > target->IpcMsgSz) return No; if (target->IpcMsgSz > src->IpcMsgSz) return No; - rt_copy_memory(src->IpcData, target->IpcData, src->IpcMsgSz); + UInt32 timeout = 0U; + + while ((target->IpcLock % kIPCLockUsed) != 0) { + if (timeout > 100000U) { + return No; + } + } + + ++target->IpcLock; + + rt_copy_memory_safe(src->IpcData, target->IpcData, src->IpcMsgSz, kIPCMsgSize); + + --target->IpcLock; return Yes; } diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc index ed72473f..c0caeb5b 100644 --- a/dev/kernel/src/PEFCodeMgr.cc +++ b/dev/kernel/src/PEFCodeMgr.cc @@ -1,9 +1,11 @@ /* ------------------------------------------- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss & NeKernel contributors, all rights reserved. ------------------------------------------- */ +#include <ArchKit/ArchKit.h> #include <KernelKit/DebugOutput.h> #include <KernelKit/HeapMgr.h> #include <KernelKit/PEFCodeMgr.h> @@ -12,6 +14,11 @@ #include <NeKit/KString.h> #include <NeKit/KernelPanic.h> #include <NeKit/OwnPtr.h> +#include <NeKit/Utils.h> + +/// @author Amlal El Mahrouss (amlal@nekernel.org) +/// @brief PEF backend for the Code Manager. +/// @file PEFCodeMgr.cc /// @brief PEF stack size symbol. #define kPefStackSizeSymbol "__PEFSizeOfReserveStack" @@ -23,7 +30,7 @@ namespace Detail { /***********************************************************************************/ /// @brief Get the PEF platform signature according to the compiled architecture. /***********************************************************************************/ - UInt32 ldr_get_platform(void) noexcept { + static UInt32 ldr_get_platform(void) noexcept { #if defined(__NE_32X0__) return kPefArch32x0; #elif defined(__NE_64X0__) @@ -57,30 +64,34 @@ PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false) fFile.New(const_cast<Char*>(path), kRestrictRB); fPath = KStringBuilder::Construct(path).Leak(); - auto kPefHeader = "PEF_CONTAINER"; + constexpr auto kPefHeader = "PEF_CONTAINER"; - fCachedBlob = fFile->Read(kPefHeader, mib_cast(16)); + /// @note zero here means that the FileMgr will read every container header inside the file. + fCachedBlob = fFile->Read(kPefHeader, 0UL); PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob); - if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] && - container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] && - container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4] && - container->Abi == kPefAbi) { - return; - } else if (container->Magic[4] == kPefMagic[0] && container->Magic[3] == kPefMagic[1] && - container->Magic[2] == kPefMagic[2] && container->Magic[1] == kPefMagic[3] && - container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) { - /// This is a fat binary. - this->fFatBinary = true; - return; + if (container->Abi == kPefAbi && + container->Count >= + 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */ + if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] && + container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] && + container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4]) { + return; + } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] && + container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] && + container->Magic[4] == kPefMagicFat[4]) { + /// This is a fat binary, treat it as such. + this->fFatBinary = true; + return; + } } fBad = true; if (fCachedBlob) mm_free_ptr(fCachedBlob); - kout << "PEFLoader: Warning: Executable format error!\r"; + kout << "PEFLoader: warning: exec format error!\r"; fCachedBlob = nullptr; } @@ -102,14 +113,26 @@ PEFLoader::~PEFLoader() { ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) { if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData}; + auto blob = fFile->Read(name, sizeof(PEFCommandHeader)); + + if (!blob) return ErrorOr<VoidPtr>{kErrorInvalidData}; + PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob); - auto blob = fFile->Read(name, sizeof(PEFCommandHeader)); + if (!container) return ErrorOr<VoidPtr>{kErrorInvalidData}; + + PEFCommandHeader* command_header = reinterpret_cast<PEFCommandHeader*>(blob); - PEFCommandHeader* container_header = reinterpret_cast<PEFCommandHeader*>(blob); + if (command_header->VMSize < 1 || command_header->VMAddress == 0) + return ErrorOr<VoidPtr>{kErrorInvalidData}; - constexpr auto kMangleCharacter = '$'; - const Char* kContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; + /// fat binary check. + if (command_header->Cpu != container->Cpu && !this->fFatBinary) { + return ErrorOr<VoidPtr>{kErrorInvalidData}; + } + + const auto kMangleCharacter = '$'; + const Char* kContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; ErrorOr<KString> error_or_symbol; @@ -128,8 +151,8 @@ ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) { } default: return ErrorOr<VoidPtr>{kErrorInvalidData}; - ; // prevent that from the kernel's mode perspective, let that happen if it - // were a user process. + // prevent that from the kernel's mode perspective, let that happen if it + // were a user process. } Char* unconst_symbol = const_cast<Char*>(name); @@ -142,35 +165,50 @@ ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) { error_or_symbol.Leak().Leak() += name; - for (SizeT index = 0; index < container->Count; ++index) { - if (KStringBuilder::Equals(container_header->Name, error_or_symbol.Leak().Leak().CData())) { - if (container_header->Kind == kind) { - if (container_header->Cpu != Detail::ldr_get_platform()) { - if (!this->fFatBinary) { - mm_free_ptr(blob); - return ErrorOr<VoidPtr>{kErrorInvalidData}; - } + if (KStringBuilder::Equals(command_header->Name, error_or_symbol.Leak().Leak().CData())) { + if (command_header->Kind == kind) { + if (command_header->Cpu != Detail::ldr_get_platform()) { + if (!this->fFatBinary) { + mm_free_ptr(blob); + blob = nullptr; + + return ErrorOr<VoidPtr>{kErrorInvalidData}; } + } + + Char* container_blob_value = new Char[command_header->VMSize]; + + rt_copy_memory_safe((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value, + command_header->VMSize, command_header->VMSize); - Char* container_blob_value = new Char[container_header->Size]; + mm_free_ptr(blob); - rt_copy_memory((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value, - container_header->Size); - mm_free_ptr(blob); + kout << "PEFLoader: info: Loaded stub: " << command_header->Name << "!\r"; - kout << "PEFLoader: Information: Loaded stub: " << container_header->Name << "!\r"; + Int32 ret = 0; + SizeT pages_count = (command_header->VMSize + kPageSize - 1) / kPageSize; - auto ret = HAL::mm_map_page((VoidPtr) container_header->VMAddress, - (VoidPtr) HAL::mm_get_page_addr(container_blob_value), - HAL::kMMFlagsPresent | HAL::kMMFlagsUser); + for (SizeT i_vm{}; i_vm < pages_count; ++i_vm) { + ret = HAL::mm_map_page( + (VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)), + (VoidPtr) (HAL::mm_get_page_addr(container_blob_value) + (i_vm * kPageSize)), + HAL::kMMFlagsPresent | HAL::kMMFlagsUser); if (ret != kErrorSuccess) { - mm_free_ptr(container_blob_value); + /// We set the VMAddress to nullptr, if the mapping fail here. + for (SizeT i_vm_unmap{}; i_vm_unmap < i_vm; ++i_vm_unmap) { + ret = HAL::mm_map_page((VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)), + nullptr, HAL::kMMFlagsPresent | HAL::kMMFlagsUser); + } + + delete[] container_blob_value; + container_blob_value = nullptr; + return ErrorOr<VoidPtr>{kErrorInvalidData}; } - - return ErrorOr<VoidPtr>{container_blob_value}; } + + return ErrorOr<VoidPtr>{container_blob_value}; } } @@ -198,17 +236,17 @@ const Char* PEFLoader::Path() { const Char* PEFLoader::AsString() { #ifdef __32x0__ - return "32x0 PEF."; + return "32x0 PEF"; #elif defined(__64x0__) - return "64x0 PEF."; + return "64x0 PEF"; #elif defined(__x86_64__) - return "x86_64 PEF."; + return "x86_64 PEF"; #elif defined(__aarch64__) - return "AARCH64 PEF."; + return "AARCH64 PEF"; #elif defined(__powerpc64__) - return "POWER64 PEF."; + return "POWER64 PEF"; #else - return "???? PEF."; + return "???? PEF"; #endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ } @@ -232,7 +270,7 @@ namespace Utils { symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS")}; } - auto id = + ProcessID id = UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); @@ -241,7 +279,7 @@ namespace Utils { if (id != kSchedInvalidPID) { auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData); - if (!symname) { + if (!stacksym) { stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)}; } diff --git a/dev/kernel/src/PageMgr.cc b/dev/kernel/src/PageMgr.cc index e78f4908..2aa2a79c 100644 --- a/dev/kernel/src/PageMgr.cc +++ b/dev/kernel/src/PageMgr.cc @@ -47,7 +47,7 @@ Bool PTEWrapper::Reclaim() { } /// @brief Request a PTE. -/// @param Rw r/w? +/// @param Rw Is it read write? or is it read only? /// @param User user mode? /// @param ExecDisable disable execution on page? /// @return diff --git a/dev/kernel/src/Semaphore.cc b/dev/kernel/src/Semaphore.cc new file mode 100644 index 00000000..acbbb57f --- /dev/null +++ b/dev/kernel/src/Semaphore.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <KernelKit/Semaphore.h>
\ No newline at end of file diff --git a/dev/kernel/src/SoftwareTimer.cc b/dev/kernel/src/SoftwareTimer.cc index 535bec9e..52087931 100644 --- a/dev/kernel/src/SoftwareTimer.cc +++ b/dev/kernel/src/SoftwareTimer.cc @@ -7,6 +7,7 @@ #include <KernelKit/Timer.h> /// @brief SoftwareTimer class, meant to be generic. +///! @author Amlal El Mahrouss (amlal@nekernel.org) using namespace Kernel; diff --git a/dev/kernel/src/ThreadLocalStorage.cc b/dev/kernel/src/ThreadLocalStorage.cc index 03a71f1a..f54eeaab 100644 --- a/dev/kernel/src/ThreadLocalStorage.cc +++ b/dev/kernel/src/ThreadLocalStorage.cc @@ -16,6 +16,7 @@ /// @bugs: 0 /// @file ThreadLocalStorage.cc /// @brief NeKernel Thread Local Storage. +///! @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ using namespace Kernel; diff --git a/dev/kernel/src/Timer.cc b/dev/kernel/src/Timer.cc index 826be99a..6539f1a9 100644 --- a/dev/kernel/src/Timer.cc +++ b/dev/kernel/src/Timer.cc @@ -9,6 +9,7 @@ ///! BUGS: 0 ///! @file Timer.cc ///! @brief Software Timer implementation +///! @author Amlal El Mahrouss (amlal@nekernel.org) using namespace Kernel; diff --git a/dev/kernel/src/UserMgr.cc b/dev/kernel/src/UserMgr.cc index 8eade85e..8e4ba540 100644 --- a/dev/kernel/src/UserMgr.cc +++ b/dev/kernel/src/UserMgr.cc @@ -13,8 +13,11 @@ #include <KernelKit/FileMgr.h> #include <KernelKit/HeapMgr.h> #include <KernelKit/KPC.h> +#include <KernelKit/ThreadLocalStorage.h> #include <KernelKit/UserMgr.h> +#include <NeKit/KString.h> #include <NeKit/KernelPanic.h> +#include <NeKit/Utils.h> #define kStdUserType (0xEE) #define kSuperUserType (0xEF) @@ -30,8 +33,8 @@ namespace Detail { /// \return the hashed password //////////////////////////////////////////////////////////// STATIC UInt64 user_fnv_generator(const Char* password, User* user) { - if (!password || !user) return 1; - if (*password == 0) return 1; + if (!password || !user) return 0; + if (*password == 0) return 0; kout << "user_fnv_generator: Hashing user password...\r"; @@ -47,7 +50,7 @@ namespace Detail { kout << "user_fnv_generator: Hashed user password.\r"; - return 0; + return hash; } } // namespace Detail @@ -56,14 +59,16 @@ namespace Detail { //////////////////////////////////////////////////////////// User::User(const Int32& sel, const Char* user_name) : mUserRing((UserRingKind) sel) { MUST_PASS(sel >= 0); - rt_copy_memory((VoidPtr) user_name, this->mUserName, rt_string_len(user_name)); + rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name), + kMaxUserNameLen); } //////////////////////////////////////////////////////////// /// @brief User ring constructor. //////////////////////////////////////////////////////////// User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) { - rt_copy_memory((VoidPtr) user_name, this->mUserName, rt_string_len(user_name)); + rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name), + kMaxUserNameLen); } //////////////////////////////////////////////////////////// diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index eff53745..45957c7b 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -20,6 +20,7 @@ #include <KernelKit/KPC.h> #include <KernelKit/ProcessScheduler.h> #include <NeKit/KString.h> +#include <NeKit/Utils.h> #include <SignalKit/Signals.h> ///! BUGS: 0 @@ -39,8 +40,9 @@ USER_PROCESS::~USER_PROCESS() = default; Void USER_PROCESS::Crash() { if (this->Status != ProcessStatusKind::kRunning) return; + this->Status = ProcessStatusKind::kKilled; + (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl); - this->Exit(-kErrorProcessFault); } /***********************************************************************************/ @@ -83,7 +85,8 @@ Void USER_PROCESS::Wake(Bool should_wakeup) { /** @param tree The tree to calibrate */ /***********************************************************************************/ -STATIC PROCESS_HEAP_TREE<VoidPtr>* sched_try_go_upper_ptr_tree(PROCESS_HEAP_TREE<VoidPtr>* tree) { +template <typename T> +STATIC T* sched_try_go_upper_ptr_tree(T* tree) { if (!tree) { return nullptr; } @@ -104,7 +107,7 @@ STATIC PROCESS_HEAP_TREE<VoidPtr>* sched_try_go_upper_ptr_tree(PROCESS_HEAP_TREE } /***********************************************************************************/ -/** @brief Allocate pointer to heap tree. */ +/** @brief Allocate pointer to heap/file tree. */ /***********************************************************************************/ ErrorOr<VoidPtr> USER_PROCESS::New(SizeT sz, SizeT pad_amount) { @@ -119,7 +122,7 @@ ErrorOr<VoidPtr> USER_PROCESS::New(SizeT sz, SizeT pad_amount) { hal_write_cr3(vm_register); #else - auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount); + auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount); #endif if (!this->HeapTree) { @@ -231,23 +234,24 @@ const AffinityKind& USER_PROCESS::GetAffinity() noexcept { /** @brief Free heap tree. */ /***********************************************************************************/ -STATIC Void sched_free_ptr_tree(PROCESS_HEAP_TREE<VoidPtr>* memory_ptr_list) { +template <typename T> +STATIC Void sched_free_ptr_tree(T* tree) { // Deleting memory lists. Make sure to free all of them. - while (memory_ptr_list) { - if (memory_ptr_list->Entry) { - MUST_PASS(mm_free_ptr(memory_ptr_list->Entry)); + while (tree) { + if (tree->Entry) { + MUST_PASS(mm_free_ptr(tree->Entry)); } - auto next = memory_ptr_list->Next; + auto next = tree->Next; if (next->Child) sched_free_ptr_tree(next->Child); - memory_ptr_list->Child = nullptr; + tree->Child = nullptr; - mm_free_ptr(memory_ptr_list); + mm_free_ptr(tree); - memory_ptr_list = nullptr; - memory_ptr_list = next; + tree = nullptr; + tree = next; } } @@ -271,6 +275,9 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { sched_free_ptr_tree(this->HeapTree); this->HeapTree = nullptr; + sched_free_ptr_tree(this->FileTree); + this->FileTree = nullptr; + #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ hal_write_cr3(pd); #endif @@ -314,10 +321,10 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { } /***********************************************************************************/ -/// @brief Add dylib to process. +/// @brief Add dylib to the process object. /***********************************************************************************/ -Bool USER_PROCESS::SpawnDylib() { +Bool USER_PROCESS::InitDylib() { // React according to the process's kind. switch (this->Kind) { case USER_PROCESS::kExecutableDylibKind: { @@ -340,7 +347,6 @@ Bool USER_PROCESS::SpawnDylib() { (Void)(kout << "Unknown process kind: " << hex_number(this->Kind) << kendl); this->Crash(); - return NO; return NO; } @@ -379,7 +385,8 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im return -kErrorProcessFault; } - rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, len); + rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, len, + kSchedNameLen); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ process.VMRegister = kKernelVM; @@ -419,6 +426,17 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im process.PTime = 0; process.RTime = 0; + if (!process.FileTree) { + process.FileTree = new PROCESS_FILE_TREE<VoidPtr>(); + + if (!process.FileTree) { + process.Crash(); + return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory); + } + + /// @todo File Tree allocation and dispose methods (amlal) + } + (Void)(kout << "PID: " << number(process.ProcessId) << kendl); (Void)(kout << "Name: " << process.Name << kendl); diff --git a/dev/kernel/src/UserProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc index dd21ac49..73ba7285 100644 --- a/dev/kernel/src/UserProcessTeam.cc +++ b/dev/kernel/src/UserProcessTeam.cc @@ -7,6 +7,7 @@ /***********************************************************************************/ /// @file UserProcessTeam.cc /// @brief Process teams implementation. +/// @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ #include <KernelKit/UserProcessScheduler.h> diff --git a/dev/kernel/src/UtfUtils.cc b/dev/kernel/src/UtfUtils.cc index ae17aed7..a5c03b85 100644 --- a/dev/kernel/src/UtfUtils.cc +++ b/dev/kernel/src/UtfUtils.cc @@ -6,6 +6,8 @@ #include <NeKit/Utils.h> +/// @author Amlal El Mahrouss (amlal@nekernel.org) + namespace Kernel { Size urt_string_len(const Utf8Char* str) { SizeT len{0}; diff --git a/dev/generic_kits/.keep b/dev/libMsg/.keep index e69de29b..e69de29b 100644 --- a/dev/generic_kits/.keep +++ b/dev/libMsg/.keep diff --git a/dev/libMsg/MsgKit/Network.h b/dev/libMsg/MsgKit/Network.h new file mode 100644 index 00000000..7dd56877 --- /dev/null +++ b/dev/libMsg/MsgKit/Network.h @@ -0,0 +1,9 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include <libMsg/MsgKit/Server.h>
\ No newline at end of file diff --git a/dev/libMsg/MsgKit/Server.h b/dev/libMsg/MsgKit/Server.h new file mode 100644 index 00000000..4fa73ccc --- /dev/null +++ b/dev/libMsg/MsgKit/Server.h @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#ifdef __cplusplus +#include <public/frameworks/CoreFoundation.fwrk/headers/String.h> +#else +#include <libSystem/SystemKit/System.h> +#endif + +/// @author Amlal El Mahrouss +/// @brief libMsg LISP system. + +struct LIBMSG_EXPR; + +/// @brief an expression chain of LibMSG. +struct LIBMSG_EXPR final { +#ifdef __cplusplus + CF::CFString* l_key{nullptr}; + CF::CFString* l_value{nullptr}; +#else + VoidPtr l_key{nullptr}; + VoidPtr l_value{nullptr}; +#endif + + LIBMSG_EXPR* l_head{nullptr}; + LIBMSG_EXPR* l_tail{nullptr}; + LIBMSG_EXPR* l_child{nullptr}; +}; + +/// @brief Function type for LibMSG lisp. +typedef Void (*libmsg_func_t)(LIBMSG_EXPR* self, VoidPtr arg, SizeT arg_size); + +IMPORT_C Void libmsg_init_library(libmsg_func_t* funcs, SizeT cnt); +IMPORT_C UInt32 libmsg_close_library(Void); +IMPORT_C UInt32 libmsg_eval_expr(struct LIBMSG_EXPR* head); diff --git a/dev/open_msg/.keep b/dev/libMsg/obj/.keep index e69de29b..e69de29b 100644 --- a/dev/open_msg/.keep +++ b/dev/libMsg/obj/.keep diff --git a/dev/open_msg/script/window_client.json b/dev/libMsg/script/window_client.json index 4c8a21ba..4c8a21ba 100644 --- a/dev/open_msg/script/window_client.json +++ b/dev/libMsg/script/window_client.json diff --git a/dev/open_msg/obj/.keep b/dev/libMsg/src/.keep index e69de29b..e69de29b 100644 --- a/dev/open_msg/obj/.keep +++ b/dev/libMsg/src/.keep diff --git a/dev/libSystem/SystemKit/Jail.h b/dev/libSystem/SystemKit/Jail.h index 998173f9..c23942c5 100644 --- a/dev/libSystem/SystemKit/Jail.h +++ b/dev/libSystem/SystemKit/Jail.h @@ -9,7 +9,8 @@ #include <libSystem/SystemKit/System.h> /// @file Jail.h -/// @brief NeKernel Jail System +/// @author Amlal El Mahrouss +/// @brief NeKernel Jail System, part of OpenEnclave. struct JAIL_INFO; struct JAIL; @@ -19,4 +20,17 @@ struct JAIL_INFO { SInt32 fParentID; SInt32 fJailHash; SInt64 fACL; -};
\ No newline at end of file +}; + +/// @brief Jail information (we grab a JAIL from JailGetCurrent()) +struct JAIL { + struct JAIL_INFO* fServer; + struct JAIL_INFO* fClient; + SInt32 fJailHash; + SInt32 fParentID; + SInt64 fACL; +}; + +/// @brief Get the current jail +/// @return Pointer to the current jail structure, or NULL if not in a jail +IMPORT_C struct JAIL* JailGetCurrent(Void); diff --git a/dev/libSystem/SystemKit/Macros.h b/dev/libSystem/SystemKit/Macros.h index 2bdeff9d..25bc77ba 100644 --- a/dev/libSystem/SystemKit/Macros.h +++ b/dev/libSystem/SystemKit/Macros.h @@ -94,7 +94,7 @@ typedef nullPtr NullPtr; #endif #ifndef kib_cast -#define kib_cast(X) (UInt64)((X) *1024) +#define kib_cast(X) (UInt64)((X) * 1024) #endif #ifndef MIB diff --git a/dev/libSystem/SystemKit/Syscall.h b/dev/libSystem/SystemKit/Syscall.h index 436665ae..a1505b46 100644 --- a/dev/libSystem/SystemKit/Syscall.h +++ b/dev/libSystem/SystemKit/Syscall.h @@ -9,11 +9,27 @@ #include <libSystem/SystemKit/System.h> #include <cstdarg> -#ifndef SYSCALL_HASH -#define SYSCALL_HASH(str) (UInt64) str -#endif // !SYSCALL_HASH - IMPORT_C VoidPtr libsys_syscall_arg_1(SizeT id); IMPORT_C VoidPtr libsys_syscall_arg_2(SizeT id, VoidPtr arg1); IMPORT_C VoidPtr libsys_syscall_arg_3(SizeT id, VoidPtr arg1, VoidPtr arg3); IMPORT_C VoidPtr libsys_syscall_arg_4(SizeT id, VoidPtr arg1, VoidPtr arg3, VoidPtr arg4); + +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; +} + +#ifndef SYSCALL_HASH +#define SYSCALL_HASH(str) libsys_hash_64(str) +#endif // !SYSCALL_HASH
\ No newline at end of file diff --git a/dev/libSystem/SystemKit/System.h b/dev/libSystem/SystemKit/System.h index 421868ae..f46fe523 100644 --- a/dev/libSystem/SystemKit/System.h +++ b/dev/libSystem/SystemKit/System.h @@ -12,6 +12,10 @@ Purpose: System Call Interface. #include <libSystem/SystemKit/Macros.h>
+/// @brief TTY device path.
+#define kPrintDevicePath "/devices/tty{}"
+#define kCDDevicePath "/devices/dvd{}"
+
// ------------------------------------------------------------------------------------------ //
/// @brief Types API.
// ------------------------------------------------------------------------------------------ //
@@ -309,8 +313,6 @@ IMPORT_C SInt32 PwrSendCode(_Output SInt32& code); // CD-ROM API.
// ------------------------------------------------------------------------------------------ //
-#define kCDDevicePath "/devices/dvd{}"
-
IMPORT_C IORef CdOpenTray(Void);
IMPORT_C SInt32 CdEjectDrive(_Input IORef cdrom);
@@ -321,8 +323,6 @@ IMPORT_C SInt32 CdCloseTray(Void); // TTY API.
// ------------------------------------------------------------------------------------------ //
-#define kPrintDevicePath "/devices/tty{}"
-
IMPORT_C SInt32 PrintOut(IORef file /* nullptr to direct to stdout */, const Char* fmt, ...);
IMPORT_C SInt32 PrintIn(IORef file /* nullptr to direct to stdout */, const Char* fmt, ...);
diff --git a/dev/libSystem/docs/SPECIFICATION_SYSCALLS.md b/dev/libSystem/docs/SPECIFICATION_SYSCALLS.md index b4b11c8c..89f61498 100644 --- a/dev/libSystem/docs/SPECIFICATION_SYSCALLS.md +++ b/dev/libSystem/docs/SPECIFICATION_SYSCALLS.md @@ -3,7 +3,7 @@ =================================== - **Programming Language**: C / C++ -- **Build System**: Make / BTB (Build the Build) +- **Build System**: Make / NeBuild - **Purpose**: System Call Interface (SCI) for NeKernel =================================== diff --git a/dev/libSystem/src/System.cc b/dev/libSystem/src/System.cc new file mode 100644 index 00000000..3870ff18 --- /dev/null +++ b/dev/libSystem/src/System.cc @@ -0,0 +1,173 @@ +/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <libSystem/SystemKit/Err.h>
+#include <libSystem/SystemKit/Syscall.h>
+#include <libSystem/SystemKit/System.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
+
+IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) {
+ if (!expr) {
+ PrintOut(nullptr, "Assertion failed: %s\r", origin);
+ libsys_syscall_arg_1(SYSCALL_HASH("_rtl_debug_break"));
+ }
+}
+
+// memmove-style copy
+IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len) {
+ // handles overlap, prefers 64-bit word copies when aligned
+ if (!len || !dest || !src) return nullptr;
+
+ auto s = static_cast<const UInt8*>(src);
+ auto d = static_cast<UInt8*>(dest);
+
+ if (d == s) return dest;
+
+ // decide direction
+ if (d > s && d < s + len) {
+ const UInt8* rs = s + len;
+ UInt8* rd = d + len;
+
+ // try 64-bit aligned backward copy
+ if (len >= sizeof(UInt64) && (reinterpret_cast<UIntPtr>(rs) % sizeof(UInt64) == 0) &&
+ (reinterpret_cast<UIntPtr>(rd) % sizeof(UInt64) == 0)) {
+ auto rsw = reinterpret_cast<const UInt64*>(rs);
+ auto rdw = reinterpret_cast<UInt64*>(rd);
+ SizeT words = len / sizeof(UInt64);
+
+ for (SizeT i = 0; i < words; ++i) {
+ rdw[-1 - static_cast<SizeT>(i)] = rsw[-1 - static_cast<SizeT>(i)];
+ }
+
+ SizeT rem = len % sizeof(UInt64);
+ for (SizeT i = 0; i < rem; ++i) {
+ rd[-1 - i] = rs[-1 - i];
+ }
+ } else {
+ // byte-wise backward
+ for (SizeT i = 0; i < len; ++i) {
+ rd[-1 - i] = rs[-1 - i];
+ }
+ }
+ } else {
+ // try 64-bit aligned forward copy
+ if (len >= sizeof(UInt64) && (reinterpret_cast<UIntPtr>(s) % sizeof(UInt64) == 0) &&
+ (reinterpret_cast<UIntPtr>(d) % sizeof(UInt64) == 0)) {
+ auto sw = reinterpret_cast<const UInt64*>(s);
+ auto dw = reinterpret_cast<UInt64*>(d);
+ SizeT words = len / sizeof(UInt64);
+
+ for (SizeT i = 0; i < words; ++i) {
+ dw[i] = sw[i];
+ }
+
+ SizeT rem = len % sizeof(UInt64);
+ const SizeT offset = words * sizeof(UInt64);
+ for (SizeT i = 0; i < rem; ++i) {
+ d[offset + i] = s[offset + i];
+ }
+ } else {
+ for (SizeT i = 0; i < len; ++i) {
+ d[i] = s[i];
+ }
+ }
+ }
+
+ return dest;
+}
+
+IMPORT_C SInt64 MmStrLen(const Char* in) {
+ // strlen via pointer walk
+ if (!in) return 0;
+ const Char* p = in;
+ while (*p) ++p;
+ return static_cast<SInt64>(p - in);
+}
+
+IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt8 value) {
+ if (!len || !dest) return nullptr;
+
+ auto d = static_cast<UInt8*>(dest);
+
+ if (len >= sizeof(UInt64) && (reinterpret_cast<UIntPtr>(d) % sizeof(UInt64)) == 0) {
+ UInt64 pattern = static_cast<UInt64>(value);
+ pattern |= (pattern << 8);
+ pattern |= (pattern << 16);
+ pattern |= (pattern << 32);
+
+ auto dw = reinterpret_cast<UInt64*>(d);
+ SizeT words = len / sizeof(UInt64);
+
+ for (SizeT i = 0; i < words; ++i) {
+ dw[i] = pattern;
+ }
+
+ SizeT rem = len % sizeof(UInt64);
+ const SizeT offset = words * sizeof(UInt64);
+ for (SizeT i = 0; i < rem; ++i) {
+ d[offset + i] = value;
+ }
+ } else {
+ for (SizeT i = 0; i < len; ++i) d[i] = value;
+ }
+
+ return dest;
+}
+
+IMPORT_C Ref IoOpenFile(_Input const Char* path, _Input const Char* drv_letter) {
+ return static_cast<Ref>(libsys_syscall_arg_3(SYSCALL_HASH("IoOpenFile"),
+ Detail::safe_void_cast(path),
+ Detail::safe_void_cast(drv_letter)));
+}
+
+IMPORT_C Void IoCloseFile(_Input Ref desc) {
+ libsys_syscall_arg_2(SYSCALL_HASH("IoCloseFile"), static_cast<VoidPtr>(desc));
+}
+
+IMPORT_C UInt64 IoSeekFile(_Input Ref desc, _Input UInt64 off) {
+ auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("IoSeekFile"), static_cast<VoidPtr>(desc),
+ reinterpret_cast<VoidPtr>(&off));
+
+ if (!ret_ptr) return ~0UL;
+
+ auto ret = static_cast<volatile UInt64*>(ret_ptr);
+ UInt64 result = *ret;
+ MUST_PASS(result != ~0UL);
+ return result;
+}
+
+IMPORT_C UInt64 IoTellFile(_Input Ref desc) {
+ auto ret_ptr = libsys_syscall_arg_2(SYSCALL_HASH("IoTellFile"), static_cast<VoidPtr>(desc));
+ if (!ret_ptr) return ~0UL;
+ auto ret = static_cast<volatile UInt64*>(ret_ptr);
+ return *ret;
+}
+
+IMPORT_C SInt32 PrintOut(_Input IORef desc, const Char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+
+ auto buf = StrFmt(fmt, args);
+
+ va_end(args);
+
+ // if truncated, `needed` >= kBufferSz; we still send truncated buffer
+ auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("PrintOut"), static_cast<VoidPtr>(desc),
+ Detail::safe_void_cast(buf));
+
+ if (!ret_ptr) return -kErrorInvalidData;
+
+ auto ret = static_cast<const volatile SInt32*>(ret_ptr);
+
+ return *ret;
+}
diff --git a/dev/libSystem/src/SystemAPI.cc b/dev/libSystem/src/SystemAPI.cc deleted file mode 100644 index d0682830..00000000 --- a/dev/libSystem/src/SystemAPI.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* -------------------------------------------
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
-
-------------------------------------------- */
-
-#include <libSystem/SystemKit/Syscall.h>
-#include <libSystem/SystemKit/System.h>
-
-/// @file SystemAPI.cc
-/// @brief System wide API for NeKernel.
-
-IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len) {
- if (!len || !dest || !src) {
- return nullptr;
- }
-
- for (SizeT i = 0; i < len; i++) {
- ((Char*) dest)[i] = ((Char*) src)[i];
- }
-
- return dest;
-}
-
-IMPORT_C SInt64 MmStrLen(const Char* in) {
- if (!in) return 0;
-
- SizeT len{0};
-
- do {
- ++len;
- } while (in[len] != '\0');
-
- return len;
-}
-
-IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt8 value) {
- if (!len || !dest) {
- return nullptr;
- }
-
- for (SizeT i = 0; i < len; i++) {
- ((Char*) dest)[i] = value;
- }
-
- return dest;
-}
-
-IMPORT_C Ref IoOpenFile(_Input const Char* path, _Input const Char* drv_letter) {
- return (Ref) libsys_syscall_arg_3(SYSCALL_HASH('IoOpenFile'),
- reinterpret_cast<VoidPtr>(const_cast<Char*>(path)),
- reinterpret_cast<VoidPtr>(const_cast<Char*>(drv_letter)));
-}
-
-IMPORT_C Void IoCloseFile(_Input Ref desc) {
- libsys_syscall_arg_2(2, desc);
-}
-
-IMPORT_C UInt64 IoSeekFile(_Input Ref desc, _Input UInt64 off) {
- auto ret = (volatile UInt64*) libsys_syscall_arg_3(
- SYSCALL_HASH('IoSeekFile'), reinterpret_cast<VoidPtr>(desc), reinterpret_cast<VoidPtr>(&off));
-
- MUST_PASS((*ret) != ~0UL);
- return *ret;
-}
-
-IMPORT_C UInt64 IoTellFile(_Input Ref desc) {
- auto ret = (volatile UInt64*) libsys_syscall_arg_2(SYSCALL_HASH('IoTellFile'),
- reinterpret_cast<VoidPtr>(desc));
- return *ret;
-}
-
-IMPORT_C SInt32 PrintOut(_Input IORef desc, const char* fmt, ...) {
- va_list args;
-
- va_start(args, fmt);
-
- auto ret = (volatile UInt64*) libsys_syscall_arg_4(
- SYSCALL_HASH('PrintOut'), reinterpret_cast<VoidPtr>(desc),
- reinterpret_cast<VoidPtr>(const_cast<Char*>(fmt)), args);
-
- va_end(args);
-
- return *ret;
-}
-
-IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) {
- if (!expr) {
- PrintOut(nullptr, "Assertion failed: %s\r", origin);
- PrintOut(nullptr, "Origin: %s\r", origin);
-
- libsys_syscall_arg_1(SYSCALL_HASH('_rtl_debug_break'));
- }
-}
diff --git a/dev/open_msg/src/.keep b/dev/misc/.keep index e69de29b..e69de29b 100644 --- a/dev/open_msg/src/.keep +++ b/dev/misc/.keep diff --git a/dev/generic_kits/BenchKit/Chrono.h b/dev/misc/BenchKit/Chrono.h index 394f16fd..3a82a94e 100644 --- a/dev/generic_kits/BenchKit/Chrono.h +++ b/dev/misc/BenchKit/Chrono.h @@ -10,6 +10,11 @@ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. #include <CompilerKit/CompilerKit.h> #include <NeKit/Defines.h> +/// @author Amlal El Mahrouss +/// @brief BenchKit Chrono contract. + +#define BENCHKIT_INTERFACE : public ::Kernel::ChronoInterface + namespace Kernel { class ChronoInterface; @@ -19,13 +24,17 @@ class ChronoInterface { ChronoInterface() = default; virtual ~ChronoInterface() = default; - NE_COPY_DEFAULT(ChronoInterface); + NE_COPY_DEFAULT(ChronoInterface) - virtual void Start() = 0; - virtual void Stop() = 0; - virtual void Reset() = 0; + virtual Void Start() = 0; + virtual Void Stop() = 0; + virtual Void Reset() = 0; virtual UInt64 GetElapsedTime() const = 0; }; } // namespace Kernel +namespace BenchKit { +using namespace Kernel; +} + #endif // BENCHKIT_CHRONO_H diff --git a/dev/generic_kits/BenchKit/X64Chrono.h b/dev/misc/BenchKit/X64Chrono.h index 229146cb..728e7d60 100644 --- a/dev/generic_kits/BenchKit/X64Chrono.h +++ b/dev/misc/BenchKit/X64Chrono.h @@ -6,7 +6,7 @@ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. #pragma once -#include <generic_kits/BenchKit/Chrono.h> +#include <misc/BenchKit/Chrono.h> #if defined(__NE_AMD64__) @@ -14,11 +14,13 @@ namespace Kernel { class X64Chrono; struct X64ChronoTraits; +/// @brief BenchKit chrono logic for x64. struct X64ChronoTraits { private: STATIC UInt64 TickImpl_(void) { UInt64 a = 0, d = 0; - __asm__ volatile("rdtsc" : "=a"(a), "=d"(d)); + + asm volatile("rdtsc" : "=a"(a), "=d"(d)); return (d << 32) | a; } @@ -26,19 +28,19 @@ struct X64ChronoTraits { }; /// @brief X86_64 hardware chrono implementation using the `rdtsc` instruction. -class X64Chrono : public ChronoInterface { +class X64Chrono BENCHKIT_INTERFACE { public: X64Chrono() = default; ~X64Chrono() override = default; - NE_COPY_DEFAULT(X64Chrono); + NE_COPY_DEFAULT(X64Chrono) public: - void Start() override { fStart = X64ChronoTraits::TickImpl_(); } + Void Start() override { fStart = X64ChronoTraits::TickImpl_(); } - void Stop() override { fStop = X64ChronoTraits::TickImpl_(); } + Void Stop() override { fStop = X64ChronoTraits::TickImpl_(); } - void Reset() override { + Void Reset() override { fStart = 0; fStop = 0; } @@ -46,8 +48,8 @@ class X64Chrono : public ChronoInterface { UInt64 GetElapsedTime() const override { return fStop - fStart; } private: - UInt64 fStart = 0; - UInt64 fStop = 0; + UInt64 fStart{}; + UInt64 fStop{}; }; } // namespace Kernel diff --git a/dev/modules/Power/PowerFactory.h b/dev/modules/Power/PowerFactory.h index b7c13280..ba3a8da6 100644 --- a/dev/modules/Power/PowerFactory.h +++ b/dev/modules/Power/PowerFactory.h @@ -27,6 +27,6 @@ class PowerFactory { public: Bool Shutdown() { return NO; }; // shutdown - Void Reboot(){}; // soft-reboot + Void Reboot() {}; // soft-reboot }; } // namespace Kernel
\ No newline at end of file diff --git a/dev/open_msg/MsgKit/Server.h b/dev/open_msg/MsgKit/Server.h deleted file mode 100644 index 54183472..00000000 --- a/dev/open_msg/MsgKit/Server.h +++ /dev/null @@ -1,22 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include <NeKit/KString.h> -#include <NeKit/MutableArray.h> - -struct OPENMSG_EXPR; - -struct OPENMSG_EXPR { - Kernel::KString* l_head; - Kernel::MutableArray<OPENMSG_EXPR> l_args; -}; - -typedef Kernel::Void (*openmsg_func_t)(OPENMSG_EXPR* arg); - -EXTERN_C Kernel::Void openmsg_init_library(openmsg_func_t* funcs, Kernel::SizeT cnt); -EXTERN_C Kernel::UInt32 openmsg_close_library(Kernel::Void); diff --git a/docs/tex/NOTICE.md b/docs/tex/NOTICE.md new file mode 100644 index 00000000..5d6eb03f --- /dev/null +++ b/docs/tex/NOTICE.md @@ -0,0 +1,5 @@ +# Notice for LaTeX documents. + +## Recommended Tool + +`pdflatex` is recommended for this matter, although you are free to use other tools. diff --git a/docs/tex/binary_mutex.tex b/docs/tex/binary_mutex.tex new file mode 100644 index 00000000..9b8a1c40 --- /dev/null +++ b/docs/tex/binary_mutex.tex @@ -0,0 +1,77 @@ +\documentclass{article} +\usepackage{graphicx} +\usepackage{hyperref} + +\title{BinaryMutex: Technical Documentation} +\author{Amlal El Mahrouss} +\date{\today} + +\begin{document} + +\maketitle + +\section{Abstract} + +{The BinaryMutex is a core component of NeKernel (NeKernel/VMKernel) based systems. The pattern excludes other acquirers to own the USER\_PROCESS that is currently being hold. Thus the acquiree is the USER\_PROCESS itself} + +\section{Overview} + +{The BinaryMutex comes from the need to make sure that no race conditions occurs in kernel code. Most of those race conditions happens in process handling code. Thus the design of the BinaryMutex (which holds a process handle to it)} + +\begin{verbatim} +BinaryMutex mux; +mux.Lock(process); + +// Say we want to interact with the process itself on this thread, +we can then make sure that no race condition happens by using: +constexpr auto kSecondsMax = 5; +while (mux.WaitForProcess(kSecondsMax)); + +// finally do our task now. + +process.DoFoo(); +\end{verbatim} + +\section{Implementation} + +The source implementation consists of this simple C++ class: + +\begin{verbatim} +class BinaryMutex final { + public: + explicit BinaryMutex() = default; + ~BinaryMutex() = default; + + public: + bool IsLocked() const; + bool Unlock() noexcept; + + public: + BOOL WaitForProcess(const UInt32& sec) noexcept; + + public: + bool Lock(USER_PROCESS* process); + bool LockOrWait(USER_PROCESS* process, TimerInterface* timer); + + public: + NE_COPY_DEFAULT(BinaryMutex) + + private: + USER_PROCESS* fLockingProcess; +}; +\end{verbatim} + +\section{Conclusion} + +{This design pattern is useful for systems that need to make sure that a process isn't tampered by concurrent usages. +Thus its existence in VMKernel and NeKernel.} + +\section{References} + +{NeKernel}: \href{https://github.com/nekernel-org/nekernel}{NeKernel} + +{VMKernel}: \href{https://snu.systems/specs/vmkernel}{VMKernel} + +{BinaryMutex}: \href{https://github.com/nekernel-org/nekernel/blob/dev/dev/kernel/KernelKit/BinaryMutex.h}{BinaryMutex} + +\end{document} diff --git a/docs/tex/core_process_scheduler.tex b/docs/tex/core_process_scheduler.tex new file mode 100644 index 00000000..b99232bb --- /dev/null +++ b/docs/tex/core_process_scheduler.tex @@ -0,0 +1,130 @@ +\documentclass{article} +\usepackage{graphicx} +\usepackage{hyperref} + +\title{CoreProcessScheduler: Technical Documentation} +\author{Amlal El Mahrouss} +\date{\today} + +\begin{document} + +\maketitle + +\section{Abstract} + +{The CoreProcessScheduler governs how the scheduling backend and policy of the kernel works, It is the common gateway for schedulers inside NeKernel based systems.} + +\section{Overview} + +{The CoreProcessScheduler (now referred as CPS) serves as the intermediate foundal between the scheduler backend and kernel.} {It takes care of process life-cycle management, team-based process grouping, and affinity-based CPU based allocation to mention the least.} + +\section{The Affinity System} + +{Processes are given CPU time affinity hints using an affinity kind type, these hints help the scheduler run or adjust the current process.} + +\subsection{Sample Code \#1} + +{The following sample is C++ code.} {The smaller the value, the more critical the process.} + +\begin{verbatim} +enum class AffinityKind : Int32 { + kRealTime = 100, + kVeryHigh = 150, + kHigh = 200, + kStandard = 1000, + kLowUsage = 1500, + kVeryLowUsage = 2000, +}; +\end{verbatim} + +\section{The Team System} + +{The team system holds process metadata for the backend scheduler to run on. It holds methods and fields for backend specific operations.} {One implementation of such team is the UserProcessTeam object inside NeKernel.} + +\subsection{Sample Code \#2} + +{The following sample is used to hold team metadata.} {This is part of the NeKernel source tree.} + +\begin{verbatim} +class UserProcessTeam final { + public: + explicit UserProcessTeam(); + ~UserProcessTeam() = default; + + NE_COPY_DEFAULT(UserProcessTeam) + + Array<USER_PROCESS, kSchedProcessLimitPerTeam>& AsArray(); + Ref<USER_PROCESS>& AsRef(); + ProcessID& Id() noexcept; + + public: + USER_PROCESS_ARRAY mProcessList; + USER_PROCESS_REF mCurrentProcess; + ProcessID mTeamId{0}; + ProcessID mProcessCur{0}; +}; + +\end{verbatim} + +\section{The Process Image System} + +{The process image container is a design pattern made to contain process data and metadata, its purpose comes from the lack of mainstream operating systems of such ability to hold metadata.} + +{This approach helps separate concerns and give modularity to the system, as the image and process structure are not mixed together.} + +\subsection{Sample Code \#3} + +{The following sample is a C++ container used to hold process data and metadata.} {This is part of the NeKernel source tree.} + +\begin{verbatim} +struct PROCESS_IMAGE final { + explicit PROCESS_IMAGE() = default; + + private: + friend USER_PROCESS; + friend KERNEL_TASK; + + friend class UserProcessScheduler; + + ImagePtr fCode; + ImagePtr fBlob; + + public: + Bool HasCode() const { return this->fCode != nullptr; } + + Bool HasImage() const { return this->fBlob != nullptr; } + + ErrorOr<ImagePtr> LeakImage() { + if (this->fCode) { + return ErrorOr<ImagePtr>{this->fCode}; + } + + return ErrorOr<ImagePtr>{kErrorInvalidData}; + } + + ErrorOr<ImagePtr> LeakBlob() { + if (this->fBlob) { + return ErrorOr<ImagePtr>{this->fBlob}; + } + + return ErrorOr<ImagePtr>{kErrorInvalidData}; + } +}; + +\end{verbatim} + +\section{Conclusion} + +{The CoreProcessScheduler is a piece of systems design with robust design and useful cases, although useful in desktop/server cases, It may not be suited for every other tasks.} + +{And while one scheduler backend (such as the UserProcessScheduler) takes care of user process scheduling and fairness, the CoreProcessScheduler takes care of the foundation for those systems.} + +\section{References} + +{NeKernel}: \href{https://github.com/nekernel-org/nekernel}{NeKernel} + +{VMKernel}: \href{https://snu.systems/specs/vmkernel}{VMKernel} + +{CoreProcessScheduler C++ Header}: \href{https://github.com/nekernel-org/nekernel/blob/dev/dev/kernel/KernelKit/CoreProcessScheduler.h}{CoreProcessScheduler} + +\end{document} diff --git a/docs/tex/hefs.tex b/docs/tex/hefs.tex index c947710f..1656e5a9 100644 --- a/docs/tex/hefs.tex +++ b/docs/tex/hefs.tex @@ -4,9 +4,9 @@ \usepackage{longtable} \usepackage{listings} \geometry{margin=1in} -\title{HeFS Filesystem Specification (v1.3)} +\title{HeFS: Hight-throughput extended File System} \author{Amlal El Mahrouss} -\date{2025} +\date{\today} \begin{document} diff --git a/docs/tex/mbci.tex b/docs/tex/mini_bus_controller_interface.tex index 71907376..ba2381b7 100644 --- a/docs/tex/mbci.tex +++ b/docs/tex/mini_bus_controller_interface.tex @@ -7,7 +7,7 @@ \geometry{margin=1in} \title{MBCI: Mini Bus Controller Interface Specification} \author{Amlal El Mahrouss} -\date{2025} +\date{\today} \begin{document} diff --git a/docs/tex/nefs.tex b/docs/tex/nefs.tex index 37e43d13..7f2fdd84 100644 --- a/docs/tex/nefs.tex +++ b/docs/tex/nefs.tex @@ -21,9 +21,9 @@ showstringspaces=false } -\title{NeFS: New Extended File System Specification} +\title{NeFS: New Extended File System} \author{Amlal El Mahrouss} -\date{2025} +\date{\today} \begin{document} diff --git a/modules_ahci_x64.sh b/modules_ahci_x64.sh index eadce549..89d5f60b 100755 --- a/modules_ahci_x64.sh +++ b/modules_ahci_x64.sh @@ -5,7 +5,7 @@ # 04/05/25: Improve and fix script. cd dev/boot/modules/SysChk -btb amd64-ahci-epm.json +nebuild amd64-ahci-epm.json cd ../ cd BootNet -btb amd64.json
\ No newline at end of file +nebuild amd64.json
\ No newline at end of file diff --git a/modules_pio_x64.sh b/modules_pio_x64.sh index b091704e..bc1153ba 100755 --- a/modules_pio_x64.sh +++ b/modules_pio_x64.sh @@ -5,7 +5,7 @@ # 04/05/25: Improve and fix script. cd dev/boot/modules/SysChk -btb amd64-pio-epm.json +nebuild amd64-pio-epm.json cd ../ cd BootNet -btb amd64.json
\ No newline at end of file +nebuild amd64.json
\ No newline at end of file diff --git a/public/frameworks/CoreFoundation.fwrk/CoreFoundation.json b/public/frameworks/CoreFoundation.fwrk/CoreFoundation.json index 076b35ae..39e6b480 100644 --- a/public/frameworks/CoreFoundation.fwrk/CoreFoundation.json +++ b/public/frameworks/CoreFoundation.fwrk/CoreFoundation.json @@ -15,7 +15,8 @@ "kCFVersion=0x0100", "kCFVersionHighest=0x0100", "kCFVersionLowest=0x0100", - "__NE_AMD64__" + "__NE_AMD64__", + "__CF_64BIT__" ] }
\ No newline at end of file diff --git a/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h b/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h index 500ad544..8396a3e8 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h @@ -25,7 +25,7 @@ struct CFPoint; struct CFRect; struct CFColor; -#ifndef __LP64__ +#ifndef __CF_64BIT__ typedef SInt32 CFInteger; typedef float CFReal; #else diff --git a/public/frameworks/CoreFoundation.fwrk/headers/String.h b/public/frameworks/CoreFoundation.fwrk/headers/String.h index c28c05cd..80b68536 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/String.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/String.h @@ -14,5 +14,10 @@ class CFString; class CFString final CF_OBJECT { public: + CFString() = default; + ~CFString() = default; + + CFString(const CFString&) = delete; + CFString& operator=(const CFString&) = delete; }; } // namespace CF
\ No newline at end of file diff --git a/public/frameworks/DiskImage.fwrk/headers/DiskImage.h b/public/frameworks/DiskImage.fwrk/headers/DiskImage.h index 53348f3e..4a18b079 100644 --- a/public/frameworks/DiskImage.fwrk/headers/DiskImage.h +++ b/public/frameworks/DiskImage.fwrk/headers/DiskImage.h @@ -39,6 +39,7 @@ struct DI_DISK_IMAGE { SInt32 block_cnt = 0; SizeT disk_sz = kDIMinDiskSz; Char out_name[kDIOutNameLen] = kDIDefaultOutputName; + SInt32 fs_version = 0UL; }; /// @brief Format with an EPM partition. diff --git a/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc b/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc index a1182e64..83b52905 100644 --- a/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc +++ b/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc @@ -17,7 +17,7 @@ /// @return Status code upon completion. SInt32 DI::DIFormatPartitionEPM(struct DI_DISK_IMAGE& img) noexcept { if (!img.sector_sz || (img.sector_sz % 512 != 0)) return kDIFailureStatus; - + if (!img.fs_version) return kDIFailureStatus; if (*img.out_name == 0 || *img.disk_name == 0) return kDIFailureStatus; struct ::EPM_PART_BLOCK block {}; @@ -27,10 +27,11 @@ SInt32 DI::DIFormatPartitionEPM(struct DI_DISK_IMAGE& img) noexcept { block.Version = kEPMRevisionBcd; block.LbaStart = sizeof(struct ::EPM_PART_BLOCK); block.LbaEnd = img.disk_sz - block.LbaStart; - block.FsVersion = kNeFSVersionInteger; + block.FsVersion = img.fs_version; ::MmCopyMemory(block.Name, (VoidPtr) img.disk_name, ::MmStrLen(img.disk_name)); - ::MmCopyMemory(block.Magic, (VoidPtr) kEPMMagic86, ::MmStrLen(kEPMMagic86)); + + ::MmCopyMemory(block.Magic, (VoidPtr) kEPMMagic, ::MmStrLen(kEPMMagic)); IORef handle = IoOpenFile(img.out_name, nullptr); diff --git a/public/frameworks/KernelTest.fwrk/headers/KernelTest.h b/public/frameworks/KernelTest.fwrk/headers/KernelTest.h index 04e90964..70b1b9b3 100644 --- a/public/frameworks/KernelTest.fwrk/headers/KernelTest.h +++ b/public/frameworks/KernelTest.fwrk/headers/KernelTest.h @@ -11,21 +11,25 @@ /// @brief Kernel Test Framework. /// @file KernelTest.h -#define KT_TEST_VERSION_BCD (0x0001) -#define KT_TEST_VERSION "v0.0.1-kerneltest" +#define KT_TEST_VERSION_BCD (0x0002) +#define KT_TEST_VERSION "v0.0.2-kerneltest" #define KT_TEST_FAILURE (1) #define KT_TEST_SUCCESS (0) -#define KT_DECL_TEST(NAME, FN) \ - class KT_##NAME final { \ - public: \ - void Run(); \ - const char* ToString(); \ - }; \ - inline void KT_##NAME::Run() { MUST_PASS(FN() == true); } \ - inline const char* KT_##NAME::ToString() { return #FN; } +#define KT_DECL_TEST(NAME, FN) \ + class KT_##NAME final { \ + public: \ + Kernel::Void Run(); \ + const Kernel::Char* ToString(); \ + }; \ + inline Kernel::Void KT_##NAME::Run() { \ + MUST_PASS(FN() == true); \ + } \ + inline const Kernel::Char* KT_##NAME::ToString() { \ + return #FN; \ + } KT_DECL_TEST(ALWAYS_BREAK, []() -> bool { return false; }); KT_DECL_TEST(ALWAYS_GOOD, []() -> bool { return true; });
\ No newline at end of file diff --git a/public/frameworks/KernelTest.fwrk/src/UnitTests.cc b/public/frameworks/KernelTest.fwrk/src/UnitTests.cc new file mode 100644 index 00000000..07e7b129 --- /dev/null +++ b/public/frameworks/KernelTest.fwrk/src/UnitTests.cc @@ -0,0 +1,17 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <public/frameworks/KernelTest.fwrk/headers/KernelTest.h> + +EXTERN_C Kernel::Void KT_TestBreak() { + KT_ALWAYS_BREAK brk; + brk.Run(); +} + +EXTERN_C Kernel::Void KT_TestGood() { + KT_ALWAYS_GOOD good; + good.Run(); +}
\ No newline at end of file diff --git a/public/frameworks/OpenMSG.fwrk/src/DylibMain.cc b/public/frameworks/OpenMSG.fwrk/src/DylibMain.cc deleted file mode 100644 index 99eebd26..00000000 --- a/public/frameworks/OpenMSG.fwrk/src/DylibMain.cc +++ /dev/null @@ -1,5 +0,0 @@ -#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/OpenMSG.fwrk/xml/app.xml b/public/frameworks/OpenMSG.fwrk/xml/app.xml deleted file mode 100644 index 6a46e598..00000000 --- a/public/frameworks/OpenMSG.fwrk/xml/app.xml +++ /dev/null @@ -1,2 +0,0 @@ -<PropertyList> -<PLEntry Type="CFString" Name="LibraryName" Len="12" Value="OpenMSG.fwrk" /></PropertyList>
\ No newline at end of file diff --git a/public/manuals/nekernel/mgmt.util.man b/public/manuals/nekernel/mgmt.util.man index 1c46002b..7f1bbba3 100644 --- a/public/manuals/nekernel/mgmt.util.man +++ b/public/manuals/nekernel/mgmt.util.man @@ -29,4 +29,4 @@ EXAMPLES Schedules `pgp-update.script` to run at 2:30PM on Wednesday, April 2026. RELEASE - System One — NeKernel
\ No newline at end of file + v1.0.0 — NeKernel.org
\ No newline at end of file diff --git a/public/manuals/nekernel/mgmt.util.man.html b/public/manuals/nekernel/mgmt.util.man.html deleted file mode 100644 index 6f1ddc13..00000000 --- a/public/manuals/nekernel/mgmt.util.man.html +++ /dev/null @@ -1,85 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>mgmt Manual Page</title> - <style> - body { - font-family: monospace; - background-color: #f4f4f4; - padding: 2em; - color: #222; - } - - h1, - h2 { - border-bottom: 1px solid #aaa; - } - - code { - background: #eee; - padding: 0.2em 0.4em; - border-radius: 4px; - } - - section { - margin-bottom: 2em; - } - </style> -</head> - -<body> - <h1>mgmt</h1> - <section> - <h2>NAME</h2> - <p><strong>mgmt</strong> — Management utility command</p> - </section> - - <section> - <h2>SYNOPSIS</h2> - <p><code>mgmt [OPTIONS]</code></p> - </section> - - <section> - <h2>DESCRIPTION</h2> - <p> - The <code>mgmt</code> command provides scheduling, execution, and remote orchestration - capabilities within the System One operating environment. It serves as the main task - and maintenance utility for NeKernel deployments. - </p> - <ul> - <li>Schedule scripts or tasks for future execution.</li> - <li>Verify device or filesystem integrity.</li> - <li>Manage and automate remote NeKernel machines.</li> - </ul> - </section> - - <section> - <h2>OPTIONS</h2> - <ul> - <li><code>-s, --script <FILE></code>: Script to execute</li> - <li><code>-t, --time <HH:MMAM/PM></code>: Time to run the script</li> - <li><code>-d, --day <DAY></code>: Day of the week (e.g., Mon, Tue, Wed)</li> - <li><code>-m, --month <MONTH></code>: Month (e.g., Jan, Feb, Mar)</li> - <li><code>-y, --year <YYYY></code>: Year to schedule task</li> - <li><code>-r, --remote <ADDRESS></code>: Remote machine to manage (optional)</li> - <li><code>-v, --verify</code>: Run integrity checks only</li> - <li><code>-h, --help</code>: Display this help message</li> - </ul> - </section> - - <section> - <h2>EXAMPLES</h2> - <pre><code>mgmt -s pgp-update.script -t 2:30PM -d Wed -m Apr -y 2026</code></pre> - <p>Schedules <code>pgp-update.script</code> to run at 2:30PM on Wednesday, April 2026.</p> - </section> - - <section> - <h2>RELEASE</h2> - <p>System One — NeKernel</p> - </section> -</body> - -</html>
\ No newline at end of file diff --git a/public/tools/diutil/vendor/Dialogs.h b/public/tools/diutil/vendor/Dialogs.h index 84e239f5..ce50b811 100644 --- a/public/tools/diutil/vendor/Dialogs.h +++ b/public/tools/diutil/vendor/Dialogs.h @@ -175,7 +175,7 @@ namespace internal { #elif __EMSCRIPTEN__ void start(int exit_code); #else - void start_process(std::vector<std::string> const& command); + void start_process(std::vector<std::string> const& command); #endif ~executor(); @@ -490,10 +490,10 @@ inline settings::settings(bool resync) { #if _WIN32 flags(flag::is_vista) = internal::is_vista(); #elif !__APPLE__ - flags(flag::has_zenity) = check_program("zenity"); + flags(flag::has_zenity) = check_program("zenity"); flags(flag::has_matedialog) = check_program("matedialog"); - flags(flag::has_qarma) = check_program("qarma"); - flags(flag::has_kdialog) = check_program("kdialog"); + flags(flag::has_qarma) = check_program("qarma"); + flags(flag::has_kdialog) = check_program("kdialog"); // If multiple helpers are available, try to default to the best one if (flags(flag::has_zenity) && flags(flag::has_kdialog)) { @@ -540,7 +540,7 @@ inline bool settings::check_program(std::string const& program) { (void) program; return false; #else - int exit_code = -1; + int exit_code = -1; internal::executor async; async.start_process({"/bin/sh", "-c", "which " + program}); async.result(&exit_code); @@ -604,7 +604,7 @@ inline std::string path::home() { if (size_max != -1) len = size_t(size_max); #endif std::vector<char> buf(len); - struct passwd pwd, *result; + struct passwd pwd, *result; if (getpwuid_r(getuid(), &pwd, buf.data(), buf.size(), &result) == 0) return result->pw_dir; #endif return "/"; @@ -717,7 +717,7 @@ inline void internal::executor::start_process(std::vector<std::string> const& co } close(in[1]); - m_fd = out[0]; + m_fd = out[0]; auto flags = fcntl(m_fd, F_GETFL); fcntl(m_fd, F_SETFL, flags | O_NONBLOCK); @@ -753,7 +753,7 @@ inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) // FIXME: do something (void) timeout; #else - char buf[BUFSIZ]; + char buf[BUFSIZ]; ssize_t received = read(m_fd, buf, BUFSIZ); // Flawfinder: ignore if (received > 0) { m_stdout += std::string(buf, received); @@ -764,7 +764,7 @@ inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) // (this happens when the calling application handles or ignores SIG_CHLD) and results in // waitpid() failing with ECHILD. Otherwise we assume the child is running and we sleep for // a little while. - int status; + int status; pid_t child = waitpid(m_pid, &status, WNOHANG); if (child != m_pid && (child >= 0 || errno != ECHILD)) { // FIXME: this happens almost always at first iteration @@ -782,8 +782,7 @@ inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) inline void internal::executor::stop() { // Loop until the user closes the dialog - while (!ready()) - ; + while (!ready()); } // dll implementation @@ -879,11 +878,11 @@ inline std::vector<std::string> internal::dialog::desktop_helper() const { #if __APPLE__ return {"osascript"}; #else - return {flags(flag::has_zenity) ? "zenity" + return {flags(flag::has_zenity) ? "zenity" : flags(flag::has_matedialog) ? "matedialog" - : flags(flag::has_qarma) ? "qarma" - : flags(flag::has_kdialog) ? "kdialog" - : "echo"}; + : flags(flag::has_qarma) ? "qarma" + : flags(flag::has_kdialog) ? "kdialog" + : "echo"}; #endif } @@ -1125,9 +1124,9 @@ inline internal::file_dialog::file_dialog(type in_type, std::string const& title // Split the pattern list to check whether "*" is in there; if it // is, we have to disable filters because there is no mechanism in // OS X for the user to override the filter. - std::regex sep("\\s+"); - std::string filter_list; - bool has_filter = true; + std::regex sep("\\s+"); + std::string filter_list; + bool has_filter = true; std::sregex_token_iterator iter(patterns.begin(), patterns.end(), sep, -1); std::sregex_token_iterator end; for (; iter != end; ++iter) { @@ -1236,7 +1235,7 @@ inline std::vector<std::string> internal::file_dialog::vector_result() { return m_vector_result; #else std::vector<std::string> ret; - auto result = m_async->result(); + auto result = m_async->result(); for (;;) { // Split result along newline characters auto i = result.find('\n'); @@ -1569,7 +1568,7 @@ inline message::message(std::string const& title, std::string const& text, if_cancel = button::ok; break; } - m_mappings[1] = if_cancel; + m_mappings[1] = if_cancel; m_mappings[256] = if_cancel; // XXX: I think this was never correct script += " with icon "; switch (_icon) { @@ -1656,7 +1655,7 @@ inline message::message(std::string const& title, std::string const& text, if (_choice == choice::yes_no_cancel) flag += "cancel"; command.push_back(flag); if (_choice == choice::yes_no || _choice == choice::yes_no_cancel) { - m_mappings[0] = button::yes; + m_mappings[0] = button::yes; m_mappings[256] = button::no; } } diff --git a/public/frameworks/OpenMSG.fwrk/.keep b/public/tools/mgmt.oe/.keep index e69de29b..e69de29b 100644 --- a/public/frameworks/OpenMSG.fwrk/.keep +++ b/public/tools/mgmt.oe/.keep diff --git a/public/frameworks/OpenMSG.fwrk/OpenMSG.json b/public/tools/mgmt.oe/mgmt.oe.json index 4bda8798..b4e9d586 100644 --- a/public/frameworks/OpenMSG.fwrk/OpenMSG.json +++ b/public/tools/mgmt.oe/mgmt.oe.json @@ -9,7 +9,7 @@ "./" ], "sources_path": [], - "output_name": "./dist/libOpenMSG.fwrk.dylib", + "output_name": "./dist/mgmt.oe", "cpp_macros": [ "kSampleFWVersion=0x0100", "kSampleFWVersionHighest=0x0100", diff --git a/public/frameworks/OpenMSG.fwrk/headers/.keep b/public/tools/mgmt.oe/src/.keep index e69de29b..e69de29b 100644 --- a/public/frameworks/OpenMSG.fwrk/headers/.keep +++ b/public/tools/mgmt.oe/src/.keep diff --git a/public/tools/mgmt.oe/src/CommandLine.cc b/public/tools/mgmt.oe/src/CommandLine.cc new file mode 100644 index 00000000..3a0c192d --- /dev/null +++ b/public/tools/mgmt.oe/src/CommandLine.cc @@ -0,0 +1,30 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <libSystem/SystemKit/Jail.h> +#include <libSystem/SystemKit/System.h> + +/// @author Amlal El Mahrouss +/// @brief OpenEnclave management tool + +static JAIL* kJailSrv = nullptr; + +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + LIBSYS_UNUSED(argc); + LIBSYS_UNUSED(argv); + + kJailSrv = ::JailGetCurrent(); + + MUST_PASS(kJailSrv); + + ::PrintOut(nullptr, "%s", "mgmt.oe: OpenEnclave Management Tool."); + + /// @note JailGetCurrent returns client as nullptr if we're not that client (we'll not be able to + /// access the jail then) + if (kJailSrv->fClient == nullptr) return EXIT_FAILURE; + + return EXIT_FAILURE; +}
\ No newline at end of file diff --git a/public/frameworks/OpenMSG.fwrk/src/.keep b/public/tools/mgmt.oe/vendor/.keep index e69de29b..e69de29b 100644 --- a/public/frameworks/OpenMSG.fwrk/src/.keep +++ b/public/tools/mgmt.oe/vendor/.keep diff --git a/release_ahci_x64.sh b/release_ahci_x64.sh index d585e74e..f081c774 100755 --- a/release_ahci_x64.sh +++ b/release_ahci_x64.sh @@ -8,6 +8,6 @@ cd ../boot make -f amd64-desktop.make all make -f amd64-desktop.make disk cd ../../ -./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root +./tools/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot make -f amd64-desktop.make run-efi-amd64-ahci
\ No newline at end of file diff --git a/release_ata_x64.sh b/release_ata_x64.sh index c0a0e01e..d69e3d3f 100755 --- a/release_ata_x64.sh +++ b/release_ata_x64.sh @@ -8,6 +8,6 @@ cd ../boot make -f amd64-desktop.make all make -f amd64-desktop.make disk cd ../../ -./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root +./tools/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot make -f amd64-desktop.make run-efi-amd64-ata-pio
\ No newline at end of file diff --git a/setup_x64_project.sh b/setup_x64_project.sh index fd5edf7c..da74a332 100755 --- a/setup_x64_project.sh +++ b/setup_x64_project.sh @@ -8,9 +8,9 @@ cd dev/libSystem cd src make libsys_asm_io_x64 cd .. -btb libSystem.json +nebuild libSystem.json cd ../ddk -btb ddk.json +nebuild ddk.json cd ../boot make -f amd64-desktop.make efi make -f amd64-desktop.make epm-img diff --git a/tooling/dist/.keep b/tooling/dist/.keep deleted file mode 100644 index e69de29b..00000000 --- a/tooling/dist/.keep +++ /dev/null diff --git a/tooling/fsck.hefs.cc b/tooling/fsck.hefs.cc deleted file mode 100644 index 37dfbdd7..00000000 --- a/tooling/fsck.hefs.cc +++ /dev/null @@ -1,21 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#include <tooling/hefs.h> -#include <tooling/mkfs.h> -#include <cstdlib> - -int main(int argc, char** argv) { - if (argc < 2) { - mkfs::console_out() << "fsck: hefs: usage: fsck.hefs i <input_device>" - << "\n"; - return EXIT_FAILURE; - } - - (void) (argv); - - return EXIT_SUCCESS; -}
\ No newline at end of file diff --git a/tooling/manual.py b/tooling/manual.py deleted file mode 100644 index 8298559b..00000000 --- a/tooling/manual.py +++ /dev/null @@ -1,9 +0,0 @@ -#! /usr/bin/env python3 -# -*- coding: utf-8 -*- - -import sys, os - -if __name__ == "__main__": - if len(sys.argv) != 2: - print("Usage: manual.py <manual_path>") - sys.exit(os.EX_CONFIG) diff --git a/tooling/mkfs.h b/tooling/mkfs.h deleted file mode 100644 index 7180b179..00000000 --- a/tooling/mkfs.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include <tooling/rang.h> -#include <iostream> -#include <string> - -/// @internal -namespace mkfs { -/// @brief Helper function to get the option value from command line arguments. -template <typename CharType> -inline std::basic_string<CharType> get_option(const std::basic_string<CharType>& args, - const std::basic_string<CharType>& option) { - size_t pos = args.find(option + CharType('=')); - - if (pos != std::string::npos) { - size_t start = pos + option.length() + 1; - size_t end = args.find(' ', start); - return args.substr(start, end - start); - } - - return std::basic_string<CharType>{}; -} - -inline auto console_out() -> std::ostream& { - std::ostream& conout = std::cout; - conout << rang::fg::red << "mkfs: " << rang::style::reset; - - return conout; -} -} // namespace mkfs
\ No newline at end of file diff --git a/public/frameworks/OpenMSG.fwrk/xml/.keep b/tools/dist/.keep index e69de29b..e69de29b 100644 --- a/public/frameworks/OpenMSG.fwrk/xml/.keep +++ b/tools/dist/.keep diff --git a/tools/fsck.hefs.cc b/tools/fsck.hefs.cc new file mode 100644 index 00000000..eb6a66d8 --- /dev/null +++ b/tools/fsck.hefs.cc @@ -0,0 +1,74 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <tools/libmkfs/hefs.h> +#include <tools/libmkfs/mkfs.h> +#include <cstdlib> +#include <fstream> + +static uint16_t kNumericalBase = 10; + +int main(int argc, char** argv) { + if (argc < 2) { + mkfs::console_out() << "fsck: hefs: usage: fsck.hefs -i=<input_device> -o=<origin>" << "\n"; + return EXIT_FAILURE; + } + + auto args = mkfs::detail::build_args(argc, argv); + + auto opt_disk = mkfs::get_option<char>(args, "-i"); + + auto origin = mkfs::get_option<char>(args, "-o"); + + if (opt_disk.empty()) { + mkfs::console_out() << "fsck: hefs: error: HeFS is empty! Exiting..." << "\n"; + return EXIT_FAILURE; + } + + auto out_origin = 0L; + + if (!mkfs::detail::parse_signed(origin, out_origin, kNumericalBase)) { + mkfs::console_out() << "hefs: error: Invalid -o <dec> argument.\n"; + return EXIT_FAILURE; + } + + std::ifstream output_device(opt_disk, std::ios::binary); + + if (!output_device.good()) { + mkfs::console_out() << "hefs: error: Unable to open output device: " << opt_disk << "\n"; + return EXIT_FAILURE; + } + + output_device.seekg(out_origin); + + if (!output_device.good()) { + mkfs::console_out() << "hefs: error: Failed seek to origin.\n"; + return EXIT_FAILURE; + } + + mkfs::hefs::BootNode boot_node; + + std::memset(&boot_node, 0, sizeof(boot_node)); + + output_device.read(reinterpret_cast<char*>(&boot_node), sizeof(boot_node)); + + if (strncmp(boot_node.magic, kHeFSMagic, kHeFSMagicLen) != 0 || boot_node.sectorCount < 1 || + boot_node.sectorSize < kMkFsSectorSz) { + mkfs::console_out() << "hefs: error: Device is not an HeFS disk: " << opt_disk << "\n"; + return EXIT_FAILURE; + } + + if (boot_node.badSectors > kMkFsMaxBadSectors) { + mkfs::console_out() << "hefs: error: HeFS disk has too much bad sectors: " << opt_disk << "\n"; + return EXIT_FAILURE; + } + + mkfs::console_out() << "hefs: HeFS partition is is healthy, exiting...\n"; + + output_device.close(); + + return EXIT_SUCCESS; +}
\ No newline at end of file diff --git a/tooling/fsck.hefs.json b/tools/fsck.hefs.json index d6ff4b0f..d6ff4b0f 100644 --- a/tooling/fsck.hefs.json +++ b/tools/fsck.hefs.json diff --git a/tooling/hefs.h b/tools/libmkfs/hefs.h index d0da516b..52bb3086 100644 --- a/tooling/hefs.h +++ b/tools/libmkfs/hefs.h @@ -62,6 +62,7 @@ enum { kHeFSFlagsDevice, kHeFSFlagsCount = 7 }; + // Time type using ATime = std::uint64_t; diff --git a/tools/libmkfs/mkfs.h b/tools/libmkfs/mkfs.h new file mode 100644 index 00000000..6e242293 --- /dev/null +++ b/tools/libmkfs/mkfs.h @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include <tools/rang.h> +#include <iostream> +#include <sstream> +#include <string> + +#define kMkFsSectorSz (512U) +#define kMkFsMaxBadSectors (128U) + +/// @internal +namespace mkfs { + +namespace detail { + /// @internal + /// @brief GB‐to‐byte conversion (use multiplication, not XOR). + inline constexpr size_t gib_cast(uint32_t gb) { + return static_cast<size_t>(gb) * 1024ULL * 1024ULL * 1024ULL; + } + + inline bool parse_decimal(const std::string& opt, unsigned long long& out) { + if (opt.empty()) return false; + char* endptr = nullptr; + unsigned long long val = std::strtoull(opt.c_str(), &endptr, 10); + if (endptr == opt.c_str() || *endptr != '\0') return false; + out = val; + return true; + } + + inline bool parse_signed(const std::string& opt, long& out, int base = 10) { + out = 0L; + + if (opt.empty()) return true; + + char* endptr = nullptr; + long val = std::strtol(opt.c_str(), &endptr, base); + auto err = errno; + + if (err == ERANGE || err == EINVAL) return false; + if (endptr == opt.c_str() || *endptr != '\0') return false; + + out = val; + return true; + } + + inline std::string build_args(int argc, char** argv) { + std::string combined; + for (int i = 1; i < argc; ++i) { + combined += argv[i]; + combined += ' '; + } + return combined; + } +} // namespace detail + +/// @brief Helper function to get the option value from command line arguments. +template <typename CharType> +inline std::basic_string<CharType> get_option(const std::basic_string<CharType>& args, + const std::basic_string<CharType>& option) { + size_t pos = args.find(option + CharType('=')); + + if (pos != std::string::npos) { + size_t start = pos + option.length() + 1; + size_t end = args.find(' ', start); + return args.substr(start, end - start); + } + + return std::basic_string<CharType>{}; +} + +inline auto console_out() -> std::ostream& { + std::ostream& conout = std::cout; + conout << rang::fg::red << "mkfs: " << rang::style::reset; + + return conout; +} +} // namespace mkfs
\ No newline at end of file diff --git a/tooling/mk_app.py b/tools/mk_app.py index 7f7cef17..7f7cef17 100755..100644 --- a/tooling/mk_app.py +++ b/tools/mk_app.py diff --git a/tooling/mk_fwrk.py b/tools/mk_fwrk.py index b2ef99ff..b2ef99ff 100755..100644 --- a/tooling/mk_fwrk.py +++ b/tools/mk_fwrk.py diff --git a/tools/mk_htman.py b/tools/mk_htman.py new file mode 100644 index 00000000..e865f7c5 --- /dev/null +++ b/tools/mk_htman.py @@ -0,0 +1,41 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys, os + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("INFO: mk_htman.py <manual_path>") + sys.exit(os.EX_CONFIG) + + manual_path = sys.argv[1] + if not os.path.exists(manual_path): + print(f"ERROR: Manual path '{manual_path}' does not exist.") + sys.exit(os.EX_NOINPUT) + + if os.path.isdir(manual_path): + print(f"ERROR: Manual path '{manual_path}' is a directory.") + sys.exit(os.EX_NOTDIR) + + if not manual_path.endswith('.man'): + print(f"ERROR: Manual path '{manual_path}' must end with '.man'") + sys.exit(os.EX_DATAERR) + + try: + with open(manual_path, 'r') as file: + content = file.read() + if not content.strip(): + print(f"ERROR: Manual file '{manual_path}' is empty.") + sys.exit(os.EX_DATAERR) + html_content = f"<html><head><title>NeKernel Manual: {manual_path}</title></head><body><pre>{content}</pre></body></html>" + + html_path = manual_path.replace('.man', '.html') + + with open(html_path, 'w') as html_file: + html_file.write(html_content) + except IOError as e: + print(f"ERROR: Could not read manual file '{manual_path}': {e}") + sys.exit(os.EX_IOERR) + + print(f"INFO: Wrote manual '{manual_path}' to HTML.") + sys.exit(os.EX_OK) diff --git a/tooling/mk_img.py b/tools/mk_img.py index 28af22e3..f0fa0609 100755 --- a/tooling/mk_img.py +++ b/tools/mk_img.py @@ -4,7 +4,7 @@ import os import sys import subprocess -import glob +import glob as file_glob def copy_to_fat(image_path, source_dir): if not os.path.isfile(image_path): @@ -16,11 +16,11 @@ def copy_to_fat(image_path, source_dir): sys.exit(1) try: - files_to_copy = glob.glob(os.path.join(source_dir, "*")) - + files_to_copy = file_glob.glob(os.path.join(source_dir, "*")) + if not files_to_copy: - print(f"Warning: No files found in {source_dir}. Nothing to copy.") - return + print(f"Warning: No files found in {source_dir}, nothing to copy.") + sys.exit(1) command = ["mcopy", "-spm", "-i", image_path] + files_to_copy + ["::"] subprocess.run(command, check=True) diff --git a/tooling/mkfs.hefs.cc b/tools/mkfs.hefs.cc index 3960fa5e..9f70b78f 100644 --- a/tooling/mkfs.hefs.cc +++ b/tools/mkfs.hefs.cc @@ -4,53 +4,19 @@ ------------------------------------------- */ -#include <tooling/hefs.h> -#include <tooling/mkfs.h> +#include <tools/libmkfs/hefs.h> +#include <tools/libmkfs/mkfs.h> #include <algorithm> #include <cstdlib> #include <cstring> #include <fstream> #include <limits> -namespace detail { -/// @internal -/// @brief GB‐to‐byte conversion (use multiplication, not XOR). -static constexpr size_t gib_cast(uint32_t gb) { - return static_cast<size_t>(gb) * 1024ULL * 1024ULL * 1024ULL; -} -} // namespace detail - -static size_t kDiskSize = detail::gib_cast(4UL); +static size_t kDiskSize = mkfs::detail::gib_cast(4UL); static uint16_t kVersion = kHeFSVersion; static std::u8string kLabel; -static size_t kSectorSize = 512; - -static bool parse_decimal(const std::string& opt, unsigned long long& out) { - if (opt.empty()) return false; - char* endptr = nullptr; - unsigned long long val = std::strtoull(opt.c_str(), &endptr, 10); - if (endptr == opt.c_str() || *endptr != '\0') return false; - out = val; - return true; -} - -static bool parse_signed(const std::string& opt, long& out, int base = 10) { - if (opt.empty()) return false; - char* endptr = nullptr; - long val = std::strtol(opt.c_str(), &endptr, base); - if (endptr == opt.c_str() || *endptr != '\0' || val < 0) return false; - out = val; - return true; -} - -static std::string build_args(int argc, char** argv) { - std::string combined; - for (int i = 1; i < argc; ++i) { - combined += argv[i]; - combined += ' '; - } - return combined; -} +static size_t kSectorSize = 512; +static uint16_t kNumericalBase = 10; int main(int argc, char** argv) { if (argc < 2) { @@ -62,7 +28,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - std::string args = build_args(argc, argv); + std::string args = mkfs::detail::build_args(argc, argv); auto output_path = mkfs::get_option<char>(args, "-o"); if (output_path.empty()) { @@ -72,7 +38,7 @@ int main(int argc, char** argv) { auto opt_s = mkfs::get_option<char>(args, "-s"); long parsed_s = 0; - if (!parse_signed(opt_s, parsed_s, 10) || parsed_s == 0) { + if (!mkfs::detail::parse_signed(opt_s, parsed_s, kNumericalBase) || parsed_s == 0) { mkfs::console_out() << "hefs: error: Invalid sector size \"" << opt_s << "\". Must be a positive integer.\n"; return EXIT_FAILURE; @@ -98,7 +64,7 @@ int main(int argc, char** argv) { auto opt_S = mkfs::get_option<char>(args, "-S"); unsigned long long gb = 0; - if (!parse_decimal(opt_S, gb) || gb == 0ULL) { + if (!mkfs::detail::parse_decimal(opt_S, gb) || gb == 0ULL) { mkfs::console_out() << "hefs: error: Invalid disk size \"" << opt_S << "\". Must be a positive integer.\n"; return EXIT_FAILURE; @@ -121,28 +87,33 @@ int main(int argc, char** argv) { long start_block = 0, end_block = 0; long start_in = 0, end_in = 0; - if (!parse_signed(opt_b, start_ind, 16)) { - mkfs::console_out() << "hefs: error: Invalid -b <hex> argument.\n"; + if (!mkfs::detail::parse_signed(opt_b, start_ind, kNumericalBase)) { + mkfs::console_out() << "hefs: error: Invalid -b <dec> argument.\n"; return EXIT_FAILURE; } - if (!parse_signed(opt_e, end_ind, 16) || end_ind <= start_ind) { - mkfs::console_out() << "hefs: error: Invalid or out-of-range -e <hex> argument.\n"; + + if (!mkfs::detail::parse_signed(opt_e, end_ind, kNumericalBase) || end_ind <= start_ind) { + mkfs::console_out() << "hefs: error: Invalid or out-of-range -e <dec> argument.\n"; return EXIT_FAILURE; } - if (!parse_signed(opt_bs, start_block, 16)) { - mkfs::console_out() << "hefs: error: Invalid -bs <hex> argument.\n"; + + if (!mkfs::detail::parse_signed(opt_bs, start_block, kNumericalBase)) { + mkfs::console_out() << "hefs: error: Invalid -bs <dec> argument.\n"; return EXIT_FAILURE; } - if (!parse_signed(opt_be, end_block, 16) || end_block <= start_block) { - mkfs::console_out() << "hefs: error: Invalid or out-of-range -be <hex> argument.\n"; + + if (!mkfs::detail::parse_signed(opt_be, end_block, kNumericalBase) || end_block <= start_block) { + mkfs::console_out() << "hefs: error: Invalid or out-of-range -be <dec> argument.\n"; return EXIT_FAILURE; } - if (!parse_signed(opt_is, start_in, 16)) { - mkfs::console_out() << "hefs: error: Invalid -is <hex> argument.\n"; + + if (!mkfs::detail::parse_signed(opt_is, start_in, kNumericalBase)) { + mkfs::console_out() << "hefs: error: Invalid -is <dec> argument.\n"; return EXIT_FAILURE; } - if (!parse_signed(opt_ie, end_in, 16) || end_in <= start_in) { - mkfs::console_out() << "hefs: error: Invalid or out-of-range -ie <hex> argument.\n"; + + if (!mkfs::detail::parse_signed(opt_ie, end_in, kNumericalBase) || end_in <= start_in) { + mkfs::console_out() << "hefs: error: Invalid or out-of-range -ie <dec> argument.\n"; return EXIT_FAILURE; } @@ -153,6 +124,7 @@ int main(int argc, char** argv) { } std::ofstream output_device(output_path, std::ios::binary); + if (!output_device.good()) { mkfs::console_out() << "hefs: error: Unable to open output device: " << output_path << "\n"; return EXIT_FAILURE; @@ -161,22 +133,24 @@ int main(int argc, char** argv) { mkfs::hefs::BootNode boot_node; std::memset(&boot_node, 0, sizeof(boot_node)); - boot_node.version = kVersion; - boot_node.diskKind = mkfs::hefs::kHeFSHardDrive; - boot_node.encoding = mkfs::hefs::kHeFSEncodingFlagsUTF8; - boot_node.diskSize = kDiskSize; - boot_node.sectorSize = kSectorSize; - boot_node.startIND = static_cast<size_t>(start_ind) + sizeof(mkfs::hefs::BootNode); - boot_node.endIND = static_cast<size_t>(end_ind); - boot_node.startIN = static_cast<size_t>(start_in); - boot_node.endIN = static_cast<size_t>(end_in); - boot_node.startBlock = static_cast<size_t>(start_block); - boot_node.endBlock = static_cast<size_t>(end_block); - boot_node.indCount = 0UL; - boot_node.diskStatus = mkfs::hefs::kHeFSStatusUnlocked; + boot_node.version = kVersion; + boot_node.diskKind = mkfs::hefs::kHeFSHardDrive; + boot_node.encoding = mkfs::hefs::kHeFSEncodingFlagsUTF8; + boot_node.diskSize = kDiskSize; + boot_node.sectorSize = kSectorSize; + boot_node.sectorCount = kDiskSize / kSectorSize; + boot_node.startIND = static_cast<size_t>(start_ind) + sizeof(mkfs::hefs::BootNode); + boot_node.endIND = static_cast<size_t>(end_ind); + boot_node.startIN = static_cast<size_t>(start_in); + boot_node.endIN = static_cast<size_t>(end_in); + boot_node.startBlock = static_cast<size_t>(start_block); + boot_node.endBlock = static_cast<size_t>(end_block); + boot_node.indCount = 0UL; + boot_node.diskStatus = mkfs::hefs::kHeFSStatusUnlocked; static_assert(sizeof(boot_node.magic) >= kHeFSMagicLen, "BootNode::magic too small to hold kHeFSMagicLen"); + std::memset(boot_node.magic, 0, sizeof(boot_node.magic)); size_t magic_copy = (sizeof(boot_node.magic) < kHeFSMagicLen - 1) ? sizeof(boot_node.magic) : (kHeFSMagicLen - 1); @@ -184,12 +158,16 @@ int main(int argc, char** argv) { boot_node.magic[magic_copy] = 0; constexpr size_t vol_slots = kHeFSPartNameLen; + std::memset(boot_node.volumeName, 0, sizeof(boot_node.volumeName)); + size_t label_units = std::min(kLabel.size(), vol_slots - 1); + for (size_t i = 0; i < label_units; ++i) { - boot_node.volumeName[i] = static_cast<char16_t>(kLabel[i]); + boot_node.volumeName[i] = static_cast<char8_t>(kLabel[i]); } - boot_node.volumeName[label_units] = 0; + + boot_node.volumeName[label_units] = 0U; output_device.seekp(static_cast<std::streamoff>(start_ind)); if (!output_device.good()) { @@ -214,5 +192,6 @@ int main(int argc, char** argv) { output_device.close(); mkfs::console_out() << "hefs: info: Wrote filesystem to output device: " << output_path << "\n"; + return EXIT_SUCCESS; } diff --git a/tooling/mkfs.hefs.json b/tools/mkfs.hefs.json index d29b7f73..d29b7f73 100644 --- a/tooling/mkfs.hefs.json +++ b/tools/mkfs.hefs.json diff --git a/tooling/rang.h b/tools/rang.h index 5d1c68ef..5d1c68ef 100644 --- a/tooling/rang.h +++ b/tools/rang.h |
