From fb790b07aeba8e22e4190cf3e1834d11ecde6c96 Mon Sep 17 00:00:00 2001 From: Amlal Date: Fri, 25 Apr 2025 13:08:33 +0200 Subject: dev: better .clang-format, ran format command. Signed-off-by: Amlal --- dev/kernel/src/PEFCodeMgr.cc | 448 ++++++++++++++++++++----------------------- 1 file changed, 207 insertions(+), 241 deletions(-) (limited to 'dev/kernel/src/PEFCodeMgr.cc') diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc index 668dd916..7a75f386 100644 --- a/dev/kernel/src/PEFCodeMgr.cc +++ b/dev/kernel/src/PEFCodeMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,260 +9,226 @@ #include #include #include +#include #include #include -#include /// @brief PEF stack size symbol. #define kPefStackSizeSymbol "__PEFSizeOfReserveStack" -#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap" -#define kPefNameSymbol "__PEFProgramName" - -namespace Kernel -{ - namespace Detail - { - /***********************************************************************************/ - /// @brief Get the PEF platform signature according to the compiled architecture. - /***********************************************************************************/ - UInt32 ldr_get_platform(void) noexcept - { +#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap" +#define kPefNameSymbol "__PEFProgramName" + +namespace Kernel { +namespace Detail { + /***********************************************************************************/ + /// @brief Get the PEF platform signature according to the compiled architecture. + /***********************************************************************************/ + UInt32 ldr_get_platform(void) noexcept { #if defined(__NE_32X0__) - return kPefArch32x0; + return kPefArch32x0; #elif defined(__NE_64X0__) - return kPefArch64x0; + return kPefArch64x0; #elif defined(__NE_AMD64__) - return kPefArchAMD64; + return kPefArchAMD64; #elif defined(__NE_PPC64__) - return kPefArchPowerPC; + return kPefArchPowerPC; #elif defined(__NE_ARM64__) - return kPefArchARM64; + return kPefArchARM64; #else - return kPefArchInvalid; -#endif // __32x0__ || __64x0__ || __x86_64__ - } - } // namespace Detail - - /***********************************************************************************/ - /// @brief PEF loader constructor w/ blob. - /// @param blob file blob. - /***********************************************************************************/ - PEFLoader::PEFLoader(const VoidPtr blob) - : fCachedBlob(blob) - { - MUST_PASS(fCachedBlob); - fBad = false; - } - - /***********************************************************************************/ - /// @brief PEF loader constructor. - /// @param path the filesystem path. - /***********************************************************************************/ - PEFLoader::PEFLoader(const Char* path) - : fCachedBlob(nullptr), fFatBinary(false), fBad(false) - { - fFile.New(const_cast(path), kRestrictRB); - fPath = KStringBuilder::Construct(path).Leak(); - - auto kPefHeader = "PEF_CONTAINER"; - - fCachedBlob = fFile->Read(kPefHeader, mib_cast(16)); - - PEFContainer* container = reinterpret_cast(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; - } - - fBad = true; - - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - kout << "PEFLoader: warn: Executable format error!\r"; - - fCachedBlob = nullptr; - } - - /***********************************************************************************/ - /// @brief PEF destructor. - /***********************************************************************************/ - PEFLoader::~PEFLoader() - { - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - fFile.Delete(); - } - - /***********************************************************************************/ - /// @brief Finds the symbol according to it's name. - /// @param name name of symbol. - /// @param kind kind of symbol we want. - /***********************************************************************************/ - VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) - { - if (!fCachedBlob || fBad || !name) - return nullptr; - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - auto blob = fFile->Read(name, mib_cast(16)); - - PEFCommandHeader* container_header = reinterpret_cast(blob); - - constexpr auto cMangleCharacter = '$'; - const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; - - ErrorOr error_or_symbol; - - switch (kind) - { - case kPefCode: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[0]); // code symbol. - break; - } - case kPefData: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[1]); // data symbol. - break; - } - case kPefZero: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[2]); // block starting symbol. - break; - } - default: - return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were - // a user process. - } - - Char* unconst_symbol = const_cast(name); - - for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) - { - if (unconst_symbol[i] == ' ') - { - unconst_symbol[i] = cMangleCharacter; - } - } - - 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_delete_heap(blob); - return nullptr; - } - } - - Char* container_blob_value = new Char[container_header->Size]; - - rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size); - mm_delete_heap(blob); - - kout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; - - return container_blob_value; - } - } - } - - mm_delete_heap(blob); - return nullptr; - } - - /// @brief Finds the executable entrypoint. - /// @return - ErrorOr PEFLoader::FindStart() - { - if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) - return ErrorOr(sym); - - return ErrorOr(kErrorExecutable); - } - - /// @brief Tells if the executable is loaded or not. - /// @return - bool PEFLoader::IsLoaded() noexcept - { - return !fBad && fCachedBlob; - } - - const Char* PEFLoader::Path() - { - return fPath.Leak().CData(); - } - - const Char* PEFLoader::AsString() - { + return kPefArchInvalid; +#endif // __32x0__ || __64x0__ || __x86_64__ + } +} // namespace Detail + +/***********************************************************************************/ +/// @brief PEF loader constructor w/ blob. +/// @param blob file blob. +/***********************************************************************************/ +PEFLoader::PEFLoader(const VoidPtr blob) : fCachedBlob(blob) { + MUST_PASS(fCachedBlob); + fBad = false; +} + +/***********************************************************************************/ +/// @brief PEF loader constructor. +/// @param path the filesystem path. +/***********************************************************************************/ +PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false), fBad(false) { + fFile.New(const_cast(path), kRestrictRB); + fPath = KStringBuilder::Construct(path).Leak(); + + auto kPefHeader = "PEF_CONTAINER"; + + fCachedBlob = fFile->Read(kPefHeader, mib_cast(16)); + + PEFContainer* container = reinterpret_cast(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; + } + + fBad = true; + + if (fCachedBlob) mm_delete_heap(fCachedBlob); + + kout << "PEFLoader: warn: Executable format error!\r"; + + fCachedBlob = nullptr; +} + +/***********************************************************************************/ +/// @brief PEF destructor. +/***********************************************************************************/ +PEFLoader::~PEFLoader() { + if (fCachedBlob) mm_delete_heap(fCachedBlob); + + fFile.Delete(); +} + +/***********************************************************************************/ +/// @brief Finds the symbol according to it's name. +/// @param name name of symbol. +/// @param kind kind of symbol we want. +/***********************************************************************************/ +VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) { + if (!fCachedBlob || fBad || !name) return nullptr; + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + auto blob = fFile->Read(name, mib_cast(16)); + + PEFCommandHeader* container_header = reinterpret_cast(blob); + + constexpr auto cMangleCharacter = '$'; + const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; + + ErrorOr error_or_symbol; + + switch (kind) { + case kPefCode: { + error_or_symbol = KStringBuilder::Construct(cContainerKinds[0]); // code symbol. + break; + } + case kPefData: { + error_or_symbol = KStringBuilder::Construct(cContainerKinds[1]); // data symbol. + break; + } + case kPefZero: { + error_or_symbol = KStringBuilder::Construct(cContainerKinds[2]); // block starting symbol. + break; + } + default: + return nullptr; // prevent that from the kernel's mode perspective, let that happen if it + // were a user process. + } + + Char* unconst_symbol = const_cast(name); + + for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) { + if (unconst_symbol[i] == ' ') { + unconst_symbol[i] = cMangleCharacter; + } + } + + 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_delete_heap(blob); + return nullptr; + } + } + + Char* container_blob_value = new Char[container_header->Size]; + + rt_copy_memory((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value, + container_header->Size); + mm_delete_heap(blob); + + kout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; + + return container_blob_value; + } + } + } + + mm_delete_heap(blob); + return nullptr; +} + +/// @brief Finds the executable entrypoint. +/// @return +ErrorOr PEFLoader::FindStart() { + if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return ErrorOr(sym); + + return ErrorOr(kErrorExecutable); +} + +/// @brief Tells if the executable is loaded or not. +/// @return +bool PEFLoader::IsLoaded() noexcept { + return !fBad && fCachedBlob; +} + +const Char* PEFLoader::Path() { + return fPath.Leak().CData(); +} + +const Char* PEFLoader::AsString() { #ifdef __32x0__ - return "32x0 PEF executable."; + return "32x0 PEF executable."; #elif defined(__64x0__) - return "64x0 PEF executable."; + return "64x0 PEF executable."; #elif defined(__x86_64__) - return "x86_64 PEF executable."; + return "x86_64 PEF executable."; #elif defined(__aarch64__) - return "AARCH64 PEF executable."; + return "AARCH64 PEF executable."; #elif defined(__powerpc64__) - return "POWER64 PEF executable."; + return "POWER64 PEF executable."; #else - return "???? PEF executable."; -#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ - } - - const Char* PEFLoader::MIME() - { - return kPefApplicationMime; - } - - ErrorOr PEFLoader::GetBlob() - { - return ErrorOr{this->fCachedBlob}; - } - - namespace Utils - { - ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& process_kind) noexcept - { - auto errOrStart = exec.FindStart(); - - if (errOrStart.Error() != kErrorSuccess) - return kSchedInvalidPID; - - auto id = UserProcessScheduler::The().Spawn(reinterpret_cast(exec.FindSymbol(kPefNameSymbol, kPefData)), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); - - if (id != kSchedInvalidPID) - { - UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; - UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData); - UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData); - } - - return id; - } - } // namespace Utils -} // namespace Kernel + return "???? PEF executable."; +#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ +} + +const Char* PEFLoader::MIME() { + return kPefApplicationMime; +} + +ErrorOr PEFLoader::GetBlob() { + return ErrorOr{this->fCachedBlob}; +} + +namespace Utils { + ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& process_kind) noexcept { + auto errOrStart = exec.FindStart(); + + if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID; + + auto id = UserProcessScheduler::The().Spawn( + reinterpret_cast(exec.FindSymbol(kPefNameSymbol, kPefData)), + errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); + + if (id != kSchedInvalidPID) { + UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; + UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = + *(UIntPtr*) exec.FindSymbol(kPefStackSizeSymbol, kPefData); + UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = + *(UIntPtr*) exec.FindSymbol(kPefHeapSizeSymbol, kPefData); + } + + return id; + } +} // namespace Utils +} // namespace Kernel -- cgit v1.2.3 From 2ef7b73cff0d99d04e5091e98b3988532e2b1063 Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 1 May 2025 08:50:50 +0200 Subject: kernel: mmap the blob to VMAddress in PEFCodeMgr, alongside other fixes regarding memory leaks. Signed-off-by: Amlal --- dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc | 21 ++++--- dev/kernel/HALKit/AMD64/Processor.h | 2 +- dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 4 +- dev/kernel/HALKit/ARM64/Processor.h | 2 +- dev/kernel/KernelKit/IPEFDylibObject.h | 2 +- dev/kernel/KernelKit/LoaderInterface.h | 2 +- dev/kernel/KernelKit/PECodeMgr.h | 2 +- dev/kernel/KernelKit/PEF.h | 2 +- dev/kernel/KernelKit/PEFCodeMgr.h | 2 +- dev/kernel/src/PEFCodeMgr.cc | 84 ++++++++++++++++--------- tooling/mkfs.hefs.cc | 2 +- 11 files changed, 76 insertions(+), 49 deletions(-) (limited to 'dev/kernel/src/PEFCodeMgr.cc') diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc index 7a3e776f..4681b5e5 100644 --- a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc @@ -40,13 +40,14 @@ STATIC Void mmi_page_status(Detail::PTE* pte) { NE_UNUSED(pte); #ifdef __NE_VERBOSE_BITMAP__ - (Void)(kout << (pte->Present ? "Present" : "Not Present") << kendl); - (Void)(kout << (pte->Wr ? "W/R" : "Not W/R") << kendl); - (Void)(kout << (pte->Nx ? "NX" : "Not NX") << kendl); - (Void)(kout << (pte->User ? "User" : "Not User") << kendl); - (Void)(kout << (pte->Pcd ? "Not Cached" : "Cached") << kendl); - (Void)(kout << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl); - (Void)(kout << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled") << kendl); + (Void)(kout << "Flag: " << (pte->Present ? "Present" : "Not Present") << kendl); + (Void)(kout << "Flag: " << (pte->Wr ? "W/R" : "Not W/R") << kendl); + (Void)(kout << "Flag: " << (pte->Nx ? "NX" : "Not NX") << kendl); + (Void)(kout << "Flag: " << pte->User ? "User" : "Not User") << kendl); + (Void)(kout << "Flag: " << (pte->Pcd ? "Not Cached" : "Cached") << kendl); + (Void)(kout << "Flag: " << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl); + (Void)(kout << "Flag: " << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled") + << kendl); (Void)(kout << "Physical Address: " << hex_number(pte->PhysicalAddress) << kendl); #endif } @@ -56,7 +57,7 @@ STATIC Void mmi_page_status(Detail::PTE* pte) { /// @param virt a valid virtual address. /// @return Physical address. /***********************************************************************************/ -UIntPtr hal_get_phys_address(VoidPtr virt) { +UIntPtr mm_get_phys_address(VoidPtr virt) { const UInt64 kVMAddr = (UInt64) virt; const UInt64 kMask9Bits = 0x1FFULL; const UInt64 kPageOffsetMask = 0xFFFULL; @@ -101,7 +102,7 @@ UIntPtr hal_get_phys_address(VoidPtr virt) { /// @brief clflush+mfence helper function. /***********************************************************************************/ EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address) { - if (!virtual_address || !hal_get_phys_address(virtual_address)) return kErrorInvalidData; + if (!virtual_address || !mm_get_phys_address(virtual_address)) return kErrorInvalidData; asm volatile("clflush (%0)" : : "r"(virtual_address) : "memory"); asm volatile("mfence" ::: "memory"); @@ -117,6 +118,8 @@ EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address) { /// @return Status code of page manipulation process. /***********************************************************************************/ EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) { + if (physical_address == 0) return kErrorInvalidData; + const UInt64 kVMAddr = (UInt64) virtual_address; constexpr UInt64 kMask9 = 0x1FF; constexpr UInt64 kPageMask = 0xFFF; diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index d7d594d9..e1ce8718 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -179,7 +179,7 @@ inline Bool hal_has_msr() noexcept { return edx & (1 << 5); } -UIntPtr hal_get_phys_address(VoidPtr virtual_address); +UIntPtr mm_get_phys_address(VoidPtr virtual_address); /***********************************************************************************/ /// @brief Get Model specific register inside core. diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index d09fd71a..eba2f892 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -324,7 +324,7 @@ STATIC Bool drv_init_command_structures_ahci() { return NO; } - UIntPtr clb_phys = HAL::hal_get_phys_address(clb_mem); + UIntPtr clb_phys = HAL::mm_get_phys_address(clb_mem); kSATAHba->Ports[kSATAIndex].Clb = (UInt32) (clb_phys & 0xFFFFFFFF); kSATAHba->Ports[kSATAIndex].Clbu = (UInt32) (clb_phys >> 32); @@ -344,7 +344,7 @@ STATIC Bool drv_init_command_structures_ahci() { return NO; } - UIntPtr ct_phys = HAL::hal_get_phys_address(ct_mem); + UIntPtr ct_phys = HAL::mm_get_phys_address(ct_mem); header[i].Ctba = (UInt32) (ct_phys & 0xFFFFFFFF); header[i].Ctbau = (UInt32) (ct_phys >> 32); diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 38902627..1d9d2af2 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -36,7 +36,7 @@ enum { /// @return Status code of page manip. EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags); -EXTERN_C UIntPtr hal_get_phys_address(VoidPtr virtual_address); +EXTERN_C UIntPtr mm_get_phys_address(VoidPtr virtual_address); typedef UIntPtr Reg; typedef Register64 Register; diff --git a/dev/kernel/KernelKit/IPEFDylibObject.h b/dev/kernel/KernelKit/IPEFDylibObject.h index 4031bd85..42ed1830 100644 --- a/dev/kernel/KernelKit/IPEFDylibObject.h +++ b/dev/kernel/KernelKit/IPEFDylibObject.h @@ -62,7 +62,7 @@ class IPEFDylibObject final NE_DYLIB_OBJECT { if (symbol_name == nullptr || *symbol_name == 0) return nullptr; if (len > kPathLen || len < 1) return nullptr; - auto ret = reinterpret_cast(fLoader->FindSymbol(symbol_name, kind)); + auto ret = reinterpret_cast(fLoader->FindSymbol(symbol_name, kind).Leak().Leak()); if (!ret) { if (kind == kPefCode) return (VoidPtr) &__zka_pure_call; diff --git a/dev/kernel/KernelKit/LoaderInterface.h b/dev/kernel/KernelKit/LoaderInterface.h index 42046a53..f6a1b7e9 100644 --- a/dev/kernel/KernelKit/LoaderInterface.h +++ b/dev/kernel/KernelKit/LoaderInterface.h @@ -27,6 +27,6 @@ class LoaderInterface { virtual _Output const Char* MIME() = 0; virtual _Output const Char* Path() = 0; virtual _Output ErrorOr FindStart() = 0; - virtual _Output VoidPtr FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; + virtual _Output ErrorOr FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; }; } // namespace Kernel diff --git a/dev/kernel/KernelKit/PECodeMgr.h b/dev/kernel/KernelKit/PECodeMgr.h index 860f3426..05a2674c 100644 --- a/dev/kernel/KernelKit/PECodeMgr.h +++ b/dev/kernel/KernelKit/PECodeMgr.h @@ -55,7 +55,7 @@ class PE32Loader : public LoaderInterface { public: ErrorOr FindStart() override; - VoidPtr FindSymbol(const Char* name, Int32 kind) override; + ErrorOr FindSymbol(const Char* name, Int32 kind) override; ErrorOr GetBlob() override; public: diff --git a/dev/kernel/KernelKit/PEF.h b/dev/kernel/KernelKit/PEF.h index 03398b48..9381e491 100644 --- a/dev/kernel/KernelKit/PEF.h +++ b/dev/kernel/KernelKit/PEF.h @@ -98,7 +98,7 @@ typedef struct PEFCommandHeader final { UInt32 Flags; /* container flags */ UInt16 Kind; /* container kind */ UIntPtr Offset; /* content offset */ - UIntPtr VMAddress; /* VM offset */ + UIntPtr VMAddress; /* VM offset */ SizeT Size; /* content Size */ } PACKED PEFCommandHeader; diff --git a/dev/kernel/KernelKit/PEFCodeMgr.h b/dev/kernel/KernelKit/PEFCodeMgr.h index b3ca43d0..a637892f 100644 --- a/dev/kernel/KernelKit/PEFCodeMgr.h +++ b/dev/kernel/KernelKit/PEFCodeMgr.h @@ -42,7 +42,7 @@ class PEFLoader : public LoaderInterface { public: ErrorOr FindStart() override; - VoidPtr FindSymbol(const Char* name, Int32 kind) override; + ErrorOr FindSymbol(const Char* name, Int32 kind) override; ErrorOr GetBlob() override; public: diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc index 7a75f386..632d5baa 100644 --- a/dev/kernel/src/PEFCodeMgr.cc +++ b/dev/kernel/src/PEFCodeMgr.cc @@ -80,7 +80,7 @@ PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false) if (fCachedBlob) mm_delete_heap(fCachedBlob); - kout << "PEFLoader: warn: Executable format error!\r"; + kout << "PEFLoader: Warning: Executable format error!\r"; fCachedBlob = nullptr; } @@ -99,43 +99,44 @@ PEFLoader::~PEFLoader() { /// @param name name of symbol. /// @param kind kind of symbol we want. /***********************************************************************************/ -VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) { - if (!fCachedBlob || fBad || !name) return nullptr; +ErrorOr PEFLoader::FindSymbol(const Char* name, Int32 kind) { + if (!fCachedBlob || fBad || !name) return ErrorOr{kErrorInvalidData}; PEFContainer* container = reinterpret_cast(fCachedBlob); - auto blob = fFile->Read(name, mib_cast(16)); + auto blob = fFile->Read(name, sizeof(PEFCommandHeader)); PEFCommandHeader* container_header = reinterpret_cast(blob); - constexpr auto cMangleCharacter = '$'; - const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; + constexpr auto kMangleCharacter = '$'; + const Char* kContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; ErrorOr error_or_symbol; switch (kind) { case kPefCode: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[0]); // code symbol. + error_or_symbol = KStringBuilder::Construct(kContainerKinds[0]); // code symbol. break; } case kPefData: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[1]); // data symbol. + error_or_symbol = KStringBuilder::Construct(kContainerKinds[1]); // data symbol. break; } case kPefZero: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[2]); // block starting symbol. + error_or_symbol = KStringBuilder::Construct(kContainerKinds[2]); // block starting symbol. break; } default: - return nullptr; // prevent that from the kernel's mode perspective, let that happen if it - // were a user process. + return ErrorOr{kErrorInvalidData}; + ; // prevent that from the kernel's mode perspective, let that happen if it + // were a user process. } Char* unconst_symbol = const_cast(name); for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) { if (unconst_symbol[i] == ' ') { - unconst_symbol[i] = cMangleCharacter; + unconst_symbol[i] = kMangleCharacter; } } @@ -147,7 +148,7 @@ VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) { if (container_header->Cpu != Detail::ldr_get_platform()) { if (!this->fFatBinary) { mm_delete_heap(blob); - return nullptr; + return ErrorOr{kErrorInvalidData}; } } @@ -157,27 +158,36 @@ VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) { container_header->Size); mm_delete_heap(blob); - kout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; + kout << "PEFLoader: Information: Loaded stub: " << container_header->Name << "!\r"; - return container_blob_value; + auto ret = HAL::mm_map_page((VoidPtr) container_header->VMAddress, + (VoidPtr) HAL::mm_get_phys_address(container_blob_value), + HAL::kMMFlagsPresent | HAL::kMMFlagsUser); + + if (ret != kErrorSuccess) { + mm_delete_heap(container_blob_value); + return ErrorOr{kErrorInvalidData}; + } + + return ErrorOr{container_blob_value}; } } } mm_delete_heap(blob); - return nullptr; + return ErrorOr{kErrorInvalidData}; } /// @brief Finds the executable entrypoint. /// @return ErrorOr PEFLoader::FindStart() { - if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return ErrorOr(sym); + if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return sym; return ErrorOr(kErrorExecutable); } /// @brief Tells if the executable is loaded or not. -/// @return +/// @return Whether it's not bad and is cached. bool PEFLoader::IsLoaded() noexcept { return !fBad && fCachedBlob; } @@ -188,17 +198,17 @@ const Char* PEFLoader::Path() { const Char* PEFLoader::AsString() { #ifdef __32x0__ - return "32x0 PEF executable."; + return "32x0 PEF."; #elif defined(__64x0__) - return "64x0 PEF executable."; + return "64x0 PEF."; #elif defined(__x86_64__) - return "x86_64 PEF executable."; + return "x86_64 PEF."; #elif defined(__aarch64__) - return "AARCH64 PEF executable."; + return "AARCH64 PEF."; #elif defined(__powerpc64__) - return "POWER64 PEF executable."; + return "POWER64 PEF."; #else - return "???? PEF executable."; + return "???? PEF."; #endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ } @@ -216,16 +226,30 @@ namespace Utils { if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID; - auto id = UserProcessScheduler::The().Spawn( - reinterpret_cast(exec.FindSymbol(kPefNameSymbol, kPefData)), - errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); + auto symname = exec.FindSymbol(kPefNameSymbol, kPefData); + + if (!symname) { + symname = ErrorOr{(VoidPtr) rt_alloc_string("USER_PROCESS")}; + } + + auto id = + UserProcessScheduler::The().Spawn(reinterpret_cast(symname.Leak().Leak()), + errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); + + mm_delete_heap(symname.Leak().Leak()); if (id != kSchedInvalidPID) { + auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData); + + if (!symname) { + stacksym = ErrorOr{(VoidPtr) new UIntPtr(mib_cast(16))}; + } + UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = - *(UIntPtr*) exec.FindSymbol(kPefStackSizeSymbol, kPefData); - UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = - *(UIntPtr*) exec.FindSymbol(kPefHeapSizeSymbol, kPefData); + *(UIntPtr*) stacksym.Leak().Leak(); + + mm_delete_heap(stacksym.Leak().Leak()); } return id; diff --git a/tooling/mkfs.hefs.cc b/tooling/mkfs.hefs.cc index 4d7225fe..f19f1571 100644 --- a/tooling/mkfs.hefs.cc +++ b/tooling/mkfs.hefs.cc @@ -96,7 +96,7 @@ int main(int argc, char** argv) { bootNode.sectorSize = kSectorSize; bootNode.startIND = start_ind; bootNode.endIND = end_ind; - bootNode.indCount = 0UL; + bootNode.indCount = 0UL; bootNode.diskStatus = mkfs::hefs::kHeFSStatusUnlocked; std::memcpy(bootNode.magic, kHeFSMagic, kHeFSMagicLen - 1); -- cgit v1.2.3 From dc6c85c9344732a12f5e8f74e4cfc374b8bd391f Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 1 May 2025 12:07:58 +0200 Subject: kernel: scheduler and pef code mgr improvements. Signed-off-by: Amlal --- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 2 ++ dev/kernel/src/PEFCodeMgr.cc | 7 ++++++- dev/kernel/src/UserProcessScheduler.cc | 18 ++++++++++++++---- 3 files changed, 22 insertions(+), 5 deletions(-) (limited to 'dev/kernel/src/PEFCodeMgr.cc') diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 29244add..5de1b8e4 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -144,6 +144,8 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { team_index = 0U; } + kTeams[team_index].Id() = team_index; + while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])); timer.Wait(); diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc index 632d5baa..40a0cff9 100644 --- a/dev/kernel/src/PEFCodeMgr.cc +++ b/dev/kernel/src/PEFCodeMgr.cc @@ -12,6 +12,7 @@ #include #include #include +#include "KernelKit/UserProcessScheduler.h" /// @brief PEF stack size symbol. #define kPefStackSizeSymbol "__PEFSizeOfReserveStack" @@ -242,7 +243,11 @@ namespace Utils { auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData); if (!symname) { - stacksym = ErrorOr{(VoidPtr) new UIntPtr(mib_cast(16))}; + stacksym = ErrorOr{(VoidPtr) new UIntPtr(kSchedMaxStackSz)}; + } + + if ((*(volatile UIntPtr*)stacksym.Leak().Leak()) > kSchedMaxStackSz) { + *(volatile UIntPtr*)stacksym.Leak().Leak() = kSchedMaxStackSz; } UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 23ab22fa..5012e8a3 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -486,20 +486,30 @@ Bool UserProcessScheduler::HasMP() { /***********************************************************************************/ SizeT UserProcessScheduler::Run() noexcept { - SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many - //! things we have scheduled. - if (mTeam.mProcessCount < 1) { return 0UL; } + if (kCurrentlySwitching) + return 0UL; + kCurrentlySwitching = Yes; + SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many + //! things we have scheduled. + for (; process_index < mTeam.AsArray().Capacity(); ++process_index) { auto& process = mTeam.AsArray()[process_index]; - //! check if the process needs to be run. + //! Check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { + + if (process.StackSize > kSchedMaxStackSz) { + kout << "The process: " << process.Name << ", has not a valid stack size! Crashing it...\r"; + process.Crash(); + continue; + } + // Set current process header. this->CurrentProcess() = process; -- cgit v1.2.3 From 7b59d3e2fab595c920771368d33f7a42745cd5b1 Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 1 May 2025 16:44:37 +0200 Subject: kernel: HeFS: did progress on IND allocation. Signed-off-by: Amlal --- dev/kernel/src/FS/HeFS.cc | 82 ++-- dev/kernel/src/PEFCodeMgr.cc | 4 +- dev/kernel/src/UserProcessScheduler.cc | 4 +- tooling/mkfs.h | 8 +- tooling/mkfs.hefs.cc | 17 +- tooling/rang.h | 711 ++++++++++++++++----------------- 6 files changed, 411 insertions(+), 415 deletions(-) (limited to 'dev/kernel/src/PEFCodeMgr.cc') diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 89415ee5..0969d2a5 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -29,7 +29,8 @@ namespace Detail { /// @note This function is used to traverse the RB-Tree of the filesystem. /// @internal Internal filesystem use only. STATIC ATTRIBUTE(unused) _Output Void - hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start); + hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& start_ind, + Lba& start, const BOOL alloc_in_mind = NO); /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. @@ -74,19 +75,52 @@ namespace Detail { /// @param start The starting point of the traversal. /// @note This function is used to traverse the RB-Tree of the filesystem. /// @internal Internal filesystem use only. - STATIC ATTRIBUTE(unused) _Output Void - hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start) { - if (dir->fNext != 0) { - start = dir->fNext; - } else if (dir->fPrev != 0) { - start = dir->fPrev; - } else { - if (dir->fParent != 0) { - start = dir->fParent; + STATIC ATTRIBUTE(unused) Void + hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& ind_start, + Lba& start, const BOOL alloc_in_mind) { + if (!mnt || !dir) return; + + BOOL check_is_good = NO; + + while (YES) { + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + mnt->fInput(mnt->fPacket); + + if (dir->fNext != 0) { + if (check_is_good) break; + + start = dir->fNext; + + check_is_good = YES; + continue; } else if (dir->fPrev != 0) { - start = dir->fPrev; + if (check_is_good) break; + + start = dir->fPrev; + check_is_good = YES; + continue; } else { - start += kHeFSINDStartOffset; + if (dir->fParent != 0) { + if (check_is_good) break; + + start = dir->fParent; + check_is_good = YES; + continue; + } else if (dir->fPrev != 0) { + if (check_is_good) break; + + start = dir->fPrev; + check_is_good = YES; + continue; + } else { + if (!alloc_in_mind) break; + + if (start < 1) start = ind_start; + + start += kHeFSINDStartOffset; + } } } @@ -320,13 +354,13 @@ namespace Detail { } child += sizeof(HEFS_INDEX_NODE_DIRECTORY); - if (child < root->fStartIND || child > root->fEndIND) break; + if (child > root->fEndIND) break; } dirent->fColor = kHeFSRed; dirent->fChild = child; - if (child > root->fEndIND) dirent->fChild = root->fEndIND; + if (child > root->fEndIND) dirent->fChild = root->fStartIND; } for (SizeT index = 0UL; index < (kHeFSSliceCount * 2); index += 2) { @@ -358,7 +392,7 @@ namespace Detail { return YES; } - hefsi_traverse_tree(tmpdir, start); + hefsi_traverse_tree(tmpdir, mnt, root->fStartIND, start, YES); if (start > root->fEndIND || start == 0) break; } @@ -404,7 +438,7 @@ namespace Detail { } } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, mnt, root->fStartIND, start); if (start > root->fEndIND || start == 0) break; } } @@ -493,7 +527,7 @@ namespace Detail { } } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, mnt, root->fStartIND, start); if (start > root->fEndIND || start == 0) break; } } @@ -544,7 +578,7 @@ namespace Detail { } } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, mnt, root->fStartIND, start); if (start > root->fEndIND || start == 0) break; } @@ -632,7 +666,7 @@ namespace Detail { if (dir_parent->fNext == start) { hefsi_rotate_tree(start, mnt, YES); - hefsi_traverse_tree(dir_parent, start); + hefsi_traverse_tree(dir_parent, mnt, root->fStartIND, start); if (start > root->fEndIND || start == 0) break; @@ -658,7 +692,7 @@ namespace Detail { hefsi_rotate_tree(start, mnt, NO); - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, mnt, root->fStartIND, start); if (start > root->fEndIND || start == 0) break; } @@ -750,7 +784,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const SizeT dir_max = max_lba / 20; // 20% for directory metadata const SizeT inode_max = max_lba / 10; // 10% for inodes - root->fStartIND = drive->fLbaStart + kHeFSINDStartOffset; + root->fStartIND = drive->fLbaStart + kHeFSINDStartOffset + sizeof(HEFS_BOOT_NODE); root->fEndIND = root->fStartIND + dir_max; root->fStartIN = root->fEndIND + kHeFSINDStartOffset; @@ -799,7 +833,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input return NO; } - const Utf8Char* kFileMap[kHeFSPreallocateCount] = { + const Utf8Char kFileMap[kHeFSPreallocateCount][kHeFSFileNameLen] = { u8"/", u8"/boot", u8"/system", u8"/network", u8"/devices", u8"/media", u8"/vm", }; @@ -847,7 +881,9 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu urt_copy_memory((VoidPtr) dir, name, urt_string_len(dir) + 1); if (Detail::hefsi_allocate_index_node_directory(root, drive, name, flags)) { - Detail::hefsi_balance_filesystem(root, drive); + // todo: make it smarter for high-throughput. + if (root->fINDCount > 1024) Detail::hefsi_balance_filesystem(root, drive); + mm_delete_heap((VoidPtr) root); delete[] name; return YES; diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc index 40a0cff9..5da3a499 100644 --- a/dev/kernel/src/PEFCodeMgr.cc +++ b/dev/kernel/src/PEFCodeMgr.cc @@ -246,8 +246,8 @@ namespace Utils { stacksym = ErrorOr{(VoidPtr) new UIntPtr(kSchedMaxStackSz)}; } - if ((*(volatile UIntPtr*)stacksym.Leak().Leak()) > kSchedMaxStackSz) { - *(volatile UIntPtr*)stacksym.Leak().Leak() = kSchedMaxStackSz; + if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) { + *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz; } UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 5012e8a3..45a95b5b 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -490,8 +490,7 @@ SizeT UserProcessScheduler::Run() noexcept { return 0UL; } - if (kCurrentlySwitching) - return 0UL; + if (kCurrentlySwitching) return 0UL; kCurrentlySwitching = Yes; @@ -503,7 +502,6 @@ SizeT UserProcessScheduler::Run() noexcept { //! Check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { - if (process.StackSize > kSchedMaxStackSz) { kout << "The process: " << process.Name << ", has not a valid stack size! Crashing it...\r"; process.Crash(); diff --git a/tooling/mkfs.h b/tooling/mkfs.h index 650261db..7180b179 100644 --- a/tooling/mkfs.h +++ b/tooling/mkfs.h @@ -6,9 +6,9 @@ #pragma once +#include #include #include -#include /// @internal namespace mkfs { @@ -28,9 +28,9 @@ inline std::basic_string get_option(const std::basic_string& } inline auto console_out() -> std::ostream& { - std::ostream& conout = std::cout; - conout << rang::fg::red << "mkfs: " << rang::style::reset; + std::ostream& conout = std::cout; + conout << rang::fg::red << "mkfs: " << rang::style::reset; - return conout; + return conout; } } // namespace mkfs \ No newline at end of file diff --git a/tooling/mkfs.hefs.cc b/tooling/mkfs.hefs.cc index d9928858..23772023 100644 --- a/tooling/mkfs.hefs.cc +++ b/tooling/mkfs.hefs.cc @@ -16,10 +16,8 @@ static size_t kSectorSize = 512; int main(int argc, char** argv) { if (argc < 2) { - mkfs::console_out() << - "hefs: Usage: mkfs.hefs -L