From 7efcf975fe61b2d20d2379f6151b6cdd99391dff Mon Sep 17 00:00:00 2001 From: Amlal EL Mahrouss Date: Tue, 13 Aug 2024 13:00:12 +0200 Subject: [IMP] Add WIP Thread scheduler inside kernel DLL. [META] PE loader: Fix uneven macros inside PE.hxx. [FIX] Add more checks to Thread loader inside bootloader for PE32+ [IMP] Refactor KernelLoader to Thread inside loader EXE. Signed-off-by: Amlal EL Mahrouss --- .vscode/c_cpp_properties.json | 1 + Boot/BootKit/KernelLoader.hxx | 43 --------- Boot/BootKit/Thread.hxx | 42 +++++++++ Boot/Sources/HEL/AMD64/BootMain.cxx | 6 +- Boot/Sources/KernelLoader.cxx | 169 ---------------------------------- Boot/Sources/Thread.cxx | 175 ++++++++++++++++++++++++++++++++++++ Boot/amd64-efi.make | 4 +- Kernel/FirmwareKit/EFI/API.hxx | 10 +-- Kernel/KernelKit/PE.hxx | 4 +- Kernel/Sources/ThreadScheduler.cxx | 5 ++ SCIKit/ReadMe.md | 3 + SCIKit/SCIBase.hxx | 41 +++++---- SCIKit/scm.internal.inl | 6 +- 13 files changed, 265 insertions(+), 244 deletions(-) delete mode 100644 Boot/BootKit/KernelLoader.hxx create mode 100644 Boot/BootKit/Thread.hxx delete mode 100644 Boot/Sources/KernelLoader.cxx create mode 100644 Boot/Sources/Thread.cxx create mode 100644 Kernel/Sources/ThreadScheduler.cxx create mode 100644 SCIKit/ReadMe.md diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index b2e339e6..c15cd223 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -39,6 +39,7 @@ "__EFI_x86_64__", "__ATA_PIO__", "__NEWOS_AMD64__", + "__NEWOSLDR__", "__DEBUG__" ], "cStandard": "c17", diff --git a/Boot/BootKit/KernelLoader.hxx b/Boot/BootKit/KernelLoader.hxx deleted file mode 100644 index 3c98a238..00000000 --- a/Boot/BootKit/KernelLoader.hxx +++ /dev/null @@ -1,43 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Boot -{ - using namespace Kernel; - - class KernelLoader; - - /// @brief Program loader class - /// @package nl.zeta.boot.api - class KernelLoader final - { - public: - explicit KernelLoader() = delete; - ~KernelLoader() = default; - - explicit KernelLoader(Kernel::VoidPtr blob); - - KernelLoader& operator=(const KernelLoader&) = default; - KernelLoader(const KernelLoader&) = default; - - void Start(HEL::HandoverInformationHeader* handover); - const char* GetName(); - void SetName(const char* name); - bool IsValid(); - - private: - Char fBlobName[255]; - Char* fHeapForProgram{nullptr}; - VoidPtr fStartAddress{nullptr}; - VoidPtr fBlob{nullptr}; - }; -} // namespace Boot diff --git a/Boot/BootKit/Thread.hxx b/Boot/BootKit/Thread.hxx new file mode 100644 index 00000000..6303eb35 --- /dev/null +++ b/Boot/BootKit/Thread.hxx @@ -0,0 +1,42 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace Boot +{ + using namespace Kernel; + + class Thread; + + /// @brief Program loader class + /// @package nl.zeta.boot.api + class Thread final + { + public: + explicit Thread() = delete; + ~Thread() = default; + + explicit Thread(Kernel::VoidPtr blob); + + Thread& operator=(const Thread&) = default; + Thread(const Thread&) = default; + + void Start(HEL::HandoverInformationHeader* handover); + const char* GetName(); + void SetName(const char* name); + bool IsValid(); + + private: + Char fBlobName[255] = { "Boot Thread" }; + VoidPtr fStartAddress{nullptr}; + VoidPtr fBlob{nullptr}; + }; +} // namespace Boot diff --git a/Boot/Sources/HEL/AMD64/BootMain.cxx b/Boot/Sources/HEL/AMD64/BootMain.cxx index f35c13ff..ffbab88a 100644 --- a/Boot/Sources/HEL/AMD64/BootMain.cxx +++ b/Boot/Sources/HEL/AMD64/BootMain.cxx @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include // make the compiler shut up. @@ -223,7 +223,7 @@ EFI_EXTERN_C EFI_API Int Main(EfiHandlePtr ImageHandle, readerKernel.ReadAll(0); - Boot::KernelLoader* loader = nullptr; + Boot::Thread* loader = nullptr; // ------------------------------------------ // // If we succeed in reading the blob, then execute it. @@ -231,7 +231,7 @@ EFI_EXTERN_C EFI_API Int Main(EfiHandlePtr ImageHandle, if (readerKernel.Blob()) { - loader = new Boot::KernelLoader(readerKernel.Blob()); + loader = new Boot::Thread(readerKernel.Blob()); loader->SetName("\"newoskrnl.dll\" (64-bit SMP DLL)"); } diff --git a/Boot/Sources/KernelLoader.cxx b/Boot/Sources/KernelLoader.cxx deleted file mode 100644 index aaabddc3..00000000 --- a/Boot/Sources/KernelLoader.cxx +++ /dev/null @@ -1,169 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - -------------------------------------------- */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -EXTERN_C -{ -#include -} - -#define kHOTypeKernel 100 - -EXTERN EfiBootServices* BS; - -namespace Boot -{ - KernelLoader::KernelLoader(VoidPtr blob) - : fBlob(blob), fStartAddress(nullptr) - { - // detect the format. - const Char* firstBytes = reinterpret_cast(fBlob); - - BTextWriter writer; - - if (!firstBytes) - { - // failed to provide a valid pointer. - return; - } - - if (firstBytes[0] == kMagMz0 && - firstBytes[1] == kMagMz1) - { - writer.Write("newosldr: PE32+ executable detected.\r"); - - ExecHeaderPtr hdrPtr = ldr_find_exec_header(firstBytes); - ExecOptionalHeaderPtr optHdr = ldr_find_opt_exec_header(firstBytes); - - if (hdrPtr->mMachine != 0x8664 && - hdrPtr->mSignature != 0x20b) - { - return; - } - - auto numSecs = hdrPtr->mNumberOfSections; - - writer.Write("newosldr: Major Linker Ver: ").Write(optHdr->mMajorLinkerVersion).Write("\r"); - writer.Write("newosldr: Minor Linker Ver: ").Write(optHdr->mMinorLinkerVersion).Write("\r"); - writer.Write("newosldr: Major Subsystem Ver: ").Write(optHdr->mMajorSubsystemVersion).Write("\r"); - writer.Write("newosldr: Minor Subsystem Ver: ").Write(optHdr->mMinorSubsystemVersion).Write("\r"); - writer.Write("newosldr: Magic: ").Write(hdrPtr->mSignature).Write("\r"); - - constexpr auto cPageSize = 512; - - EfiPhysicalAddress loadStartAddress = optHdr->mImageBase; - loadStartAddress += optHdr->mBaseOfData; - - writer.Write("newosldr: ImageBase: ").Write(loadStartAddress).Write("\r"); - - auto numPages = optHdr->mSizeOfImage / cPageSize; - BS->AllocatePages(AllocateAddress, EfiLoaderData, numPages, &loadStartAddress); - - ExecSectionHeaderPtr sectPtr = (ExecSectionHeaderPtr)(((Char*)optHdr) + hdrPtr->mSizeOfOptionalHeader); - - constexpr auto sectionForCode = ".text"; - constexpr auto sectionForNewLdr = ".ldr"; - - for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) - { - ExecSectionHeaderPtr sect = §Ptr[sectIndex]; - - if (StrCmp(sectionForCode, sect->mName) == 0) - { - fStartAddress = (VoidPtr)((UIntPtr)loadStartAddress + optHdr->mAddressOfEntryPoint); - writer.Write("newosldr: Start Address: ").Write((UIntPtr)fStartAddress).Write("\r"); - } - else if (StrCmp(sectionForNewLdr, sect->mName) == 0) - { - struct HANDOVER_INFORMATION_STUB - { - UInt64 HandoverMagic; - UInt32 HandoverType; - - }* structHandover = (struct HANDOVER_INFORMATION_STUB*)((UIntPtr)fBlob + sect->mPointerToRawData); - - if (structHandover->HandoverMagic != kHandoverMagic || - structHandover->HandoverType != kHOTypeKernel) - { - cg_write_text("NEWOSLDR: INVALID HANDOVER IMAGE! ABORTING...", 40, 10, RGB(0x00, 0x00, 0x00)); - EFI::Stop(); - } - } - - writer.Write("newosldr: offset ").Write(sect->mPointerToRawData).Write(" of ").Write(sect->mName).Write("\r"); - - SetMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), 0, sect->mSizeOfRawData); - CopyMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), (VoidPtr)((UIntPtr)fBlob + sect->mPointerToRawData), sect->mSizeOfRawData); - } - } - else if (firstBytes[0] == kPefMagic[0] && - firstBytes[1] == kPefMagic[1] && - firstBytes[2] == kPefMagic[2] && - firstBytes[3] == kPefMagic[3]) - { - // ========================================= // - // PEF executable detected. - // ========================================= // - - fStartAddress = nullptr; - writer.Write("newosldr: PEF executable detected.\r"); - } - else - { - writer.Write("newosldr: Invalid executable.\r"); - } - } - - /// @note handover header has to be valid! - Void KernelLoader::Start(HEL::HandoverInformationHeader* handover) - { - BTextWriter writer; - - if (!handover) - { - writer.Write("newosldr: Exec format error.\r"); - return; - } - - HEL::HandoverProc err_fn = [](HEL::HandoverInformationHeader* rcx) -> void { - cg_write_text("NEWOSLDR: INVALID IMAGE! ABORTING...", 40, 10, RGB(0x00, 0x00, 0x00)); - EFI::Stop(); - }; - - if (!fStartAddress) - { - err_fn(handover); - } - - reinterpret_cast(fStartAddress)(handover); - err_fn(handover); - } - - const Char* KernelLoader::GetName() - { - return fBlobName; - } - - Void KernelLoader::SetName(const Char* name) - { - CopyMem(fBlobName, name, StrLen(name)); - } - - bool KernelLoader::IsValid() - { - return fStartAddress != nullptr; - } -} // namespace Boot diff --git a/Boot/Sources/Thread.cxx b/Boot/Sources/Thread.cxx new file mode 100644 index 00000000..51d10fda --- /dev/null +++ b/Boot/Sources/Thread.cxx @@ -0,0 +1,175 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies + +------------------------------------------- */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +EXTERN_C +{ +#include +} + +#define kHOTypeKernel 100 + +EXTERN EfiBootServices* BS; + +namespace Boot +{ + Thread::Thread(VoidPtr blob) + : fBlob(blob), fStartAddress(nullptr) + { + // detect the format. + const Char* firstBytes = reinterpret_cast(fBlob); + + BTextWriter writer; + + if (!firstBytes) + { + // failed to provide a valid pointer. + return; + } + + if (firstBytes[0] == kMagMz0 && + firstBytes[1] == kMagMz1) + { + ExecHeaderPtr hdrPtr = ldr_find_exec_header(firstBytes); + ExecOptionalHeaderPtr optHdr = ldr_find_opt_exec_header(firstBytes); + + if (hdrPtr->mMachine != kPeMachineAMD64 || + hdrPtr->mSignature != kPeMagic) + { + writer.Write("newosldr: Not a PE32+ executable.\r"); + return; + } + + if (optHdr->mSubsystem != kNewOSSubsystem) + { + writer.Write("newosldr: Not a New OS executable.\r"); + return; + } + + writer.Write("newosldr: PE32+ executable detected (New OS Subsystem).\r"); + + auto numSecs = hdrPtr->mNumberOfSections; + + writer.Write("newosldr: Major Linker Ver: ").Write(optHdr->mMajorLinkerVersion).Write("\r"); + writer.Write("newosldr: Minor Linker Ver: ").Write(optHdr->mMinorLinkerVersion).Write("\r"); + writer.Write("newosldr: Major Subsystem Ver: ").Write(optHdr->mMajorSubsystemVersion).Write("\r"); + writer.Write("newosldr: Minor Subsystem Ver: ").Write(optHdr->mMinorSubsystemVersion).Write("\r"); + writer.Write("newosldr: Magic: ").Write(hdrPtr->mSignature).Write("\r"); + + constexpr auto cPageSize = 512; + + EfiPhysicalAddress loadStartAddress = optHdr->mImageBase; + loadStartAddress += optHdr->mBaseOfData; + + writer.Write("newosldr: ImageBase: ").Write(loadStartAddress).Write("\r"); + + auto numPages = optHdr->mSizeOfImage / cPageSize; + BS->AllocatePages(AllocateAddress, EfiLoaderData, numPages, &loadStartAddress); + + ExecSectionHeaderPtr sectPtr = (ExecSectionHeaderPtr)(((Char*)optHdr) + hdrPtr->mSizeOfOptionalHeader); + + constexpr auto sectionForCode = ".text"; + constexpr auto sectionForNewLdr = ".ldr"; + + for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) + { + ExecSectionHeaderPtr sect = §Ptr[sectIndex]; + + if (StrCmp(sectionForCode, sect->mName) == 0) + { + fStartAddress = (VoidPtr)((UIntPtr)loadStartAddress + optHdr->mAddressOfEntryPoint); + writer.Write("newosldr: Start Address: ").Write((UIntPtr)fStartAddress).Write("\r"); + } + else if (StrCmp(sectionForNewLdr, sect->mName) == 0) + { + struct HANDOVER_INFORMATION_STUB + { + UInt64 HandoverMagic; + UInt32 HandoverType; + }* structHandover = (struct HANDOVER_INFORMATION_STUB*)((UIntPtr)fBlob + sect->mPointerToRawData); + + if (structHandover->HandoverMagic != kHandoverMagic || + structHandover->HandoverType != kHOTypeKernel) + { + cg_write_text("NEWOSLDR: INVALID HANDOVER IMAGE! ABORTING...", 40, 10, RGB(0x00, 0x00, 0x00)); + EFI::Stop(); + } + } + + writer.Write("newosldr: offset ").Write(sect->mPointerToRawData).Write(" of ").Write(sect->mName).Write("\r"); + + SetMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), 0, sect->mSizeOfRawData); + CopyMem((VoidPtr)(loadStartAddress + sect->mVirtualAddress), (VoidPtr)((UIntPtr)fBlob + sect->mPointerToRawData), sect->mSizeOfRawData); + } + } + else if (firstBytes[0] == kPefMagic[0] && + firstBytes[1] == kPefMagic[1] && + firstBytes[2] == kPefMagic[2] && + firstBytes[3] == kPefMagic[3]) + { + // ========================================= // + // PEF executable detected. + // ========================================= // + + fStartAddress = nullptr; + writer.Write("newosldr: PEF executable detected.\r"); + } + else + { + writer.Write("newosldr: Invalid executable.\r"); + } + } + + /// @note handover header has to be valid! + Void Thread::Start(HEL::HandoverInformationHeader* handover) + { + BTextWriter writer; + + if (!handover) + { + writer.Write("newosldr: Exec format error.\r"); + return; + } + + HEL::HandoverProc err_fn = [](HEL::HandoverInformationHeader* rcx) -> void { + cg_write_text("NEWOSLDR: INVALID IMAGE! ABORTING...", 40, 10, RGB(0x00, 0x00, 0x00)); + EFI::Stop(); + }; + + if (!fStartAddress) + { + err_fn(handover); + } + + reinterpret_cast(fStartAddress)(handover); + err_fn(handover); + } + + const Char* Thread::GetName() + { + return fBlobName; + } + + Void Thread::SetName(const Char* name) + { + CopyMem(fBlobName, name, StrLen(name)); + } + + bool Thread::IsValid() + { + return fStartAddress != nullptr; + } +} // namespace Boot diff --git a/Boot/amd64-efi.make b/Boot/amd64-efi.make index ef2dae46..5bd422c4 100644 --- a/Boot/amd64-efi.make +++ b/Boot/amd64-efi.make @@ -45,8 +45,8 @@ REM_FLAG=-f FLAG_ASM=-f win64 FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -mno-red-zone -D__NEWOSKRNL__ -D__NEWOSLDR__ \ - -DEFI_FUNCTION_WRAPPER -I./ -I../Vendor -I../Kernel -c -nostdlib -fno-rtti -fno-exceptions \ - -std=c++20 -D__HAVE_MAHROUSS_APIS__ -D__NEWOS_AMD64__ -D__MAHROUSS__ -D__BOOTLOADER__ -I../ + -DEFI_FUNCTION_WRAPPER -I./ -I../Vendor -I../Kernel -I../ -c -nostdlib -fno-rtti -fno-exceptions \ + -std=c++20 -D__HAVE_MAHROUSS_APIS__ -D__NEWOS_AMD64__ -D__MAHROUSS__ BOOT_LOADER=newosldr.exe KERNEL=newoskrnl.dll diff --git a/Kernel/FirmwareKit/EFI/API.hxx b/Kernel/FirmwareKit/EFI/API.hxx index 1466bdd1..7d06cf12 100644 --- a/Kernel/FirmwareKit/EFI/API.hxx +++ b/Kernel/FirmwareKit/EFI/API.hxx @@ -12,6 +12,8 @@ #include #include +#define kNewOSSubsystem 17 + #ifdef __NEWOSLDR__ // forward decl. class BTextWriter; @@ -65,7 +67,7 @@ Bascially frees everything we have in the EFI side. inline UInt32 Platform() noexcept { - return kPEMachineAMD64; + return kPeMachineAMD64; } /*** @@ -105,12 +107,10 @@ inline void InitEFI(EfiSystemTable* SystemTable) noexcept ST->ConOut->EnableCursor(ST->ConOut, false); } -#ifdef __BOOTLOADER__ +#ifdef __NEWOSLDR__ #include -#endif // ifdef __BOOTLOADER__ - -#define kNewOSSubsystem 17 +#endif // ifdef __NEWOSLDR__ #endif /* ifndef __EFI_API__ */ diff --git a/Kernel/KernelKit/PE.hxx b/Kernel/KernelKit/PE.hxx index 2931410f..9d30fd8e 100644 --- a/Kernel/KernelKit/PE.hxx +++ b/Kernel/KernelKit/PE.hxx @@ -21,8 +21,8 @@ #define kMagPE32 0x010b #define kMagPE64 0x020b -#define kPEMachineAMD64 0x8664 -#define kPEMachineARM64 0xaa64 +#define kPeMachineAMD64 0x8664 +#define kPeMachineARM64 0xaa64 typedef struct ExecHeader final { diff --git a/Kernel/Sources/ThreadScheduler.cxx b/Kernel/Sources/ThreadScheduler.cxx new file mode 100644 index 00000000..b2d0b934 --- /dev/null +++ b/Kernel/Sources/ThreadScheduler.cxx @@ -0,0 +1,5 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies + +------------------------------------------- */ \ No newline at end of file diff --git a/SCIKit/ReadMe.md b/SCIKit/ReadMe.md new file mode 100644 index 00000000..b5f76a9f --- /dev/null +++ b/SCIKit/ReadMe.md @@ -0,0 +1,3 @@ +# Official SCM implementation for New OS + +Read the specs for + information... \ No newline at end of file diff --git a/SCIKit/SCIBase.hxx b/SCIKit/SCIBase.hxx index c685a081..8bc09afe 100644 --- a/SCIKit/SCIBase.hxx +++ b/SCIKit/SCIBase.hxx @@ -12,6 +12,8 @@ Purpose: SCIKit foundation header. #define IMPORT_CXX extern "C++" #define IMPORT_C extern "C" +#define OBJECT_PATH "\\::\\OBJDLL\\" + typedef bool Bool; typedef void UInt0; @@ -63,8 +65,8 @@ public: UnknownInterface(const UnknownInterface&) = default; virtual SInt32 Release() = 0; - virtual void DecrementRef() = 0; - virtual UnknownInterface* IncrementRef() = 0; + virtual void RemoveRef() = 0; + virtual UnknownInterface* AddRef() = 0; virtual VoidPtr QueryInterface(UUID* p_uuid) = 0; }; @@ -82,8 +84,27 @@ public: }; #endif +// ------------------------------------------------------------------------------------------ // +/// @note Handle types. +// ------------------------------------------------------------------------------------------ // + +typedef VoidPtr NEW_OBJECT; + +typedef NEW_OBJECT DLL_OBJECT; +typedef NEW_OBJECT IO_OBJECT; +typedef NEW_OBJECT COMP_OBJECT; + +// ------------------------------------------------------------------------------------------ // + +// ------------------------------------------------------------------------------------------ // /// @note Part of NK loader API. +// ------------------------------------------------------------------------------------------ // + +/// @brief Get function which is part of the DLL. +/// @param symbol the symbol to look for +/// @param dll_handle the DLL handle. +/// @return the proc pointer. IMPORT_C VoidPtr RtlGetDLLProc(const char* symbol, VoidPtr dll_handle); /// @brief Open DLL handle. @@ -113,21 +134,7 @@ IMPORT_C UInt0 RtlCloseFile(UInt64 file_desc); /// @brief Installs the TIB and GIB inside the current process. /// @param none /// @return > 0 error ocurred or already present, = 0 success. -IMPORT_C UInt32 RtlInstallTIB(UInt0); - -/// @brief Asks for the process's own framebuffer. (Not a GPU one) -/// @param flags -/// @param fb_ptr -/// @param fb_out_sz -/// @return -IMPORT_C UInt32 RtlRequestFB(SInt32* type, VoidPtr* fb_ptr, SizeT* fb_out_sz); - -enum -{ - eFBGPU, - eFBCPU, - eFBInvalid, -}; +IMPORT_C UInt32 RtlInstallInfoBlocks(UInt0); /// @brief Allocate new SCM object. /// @tparam TCLS the class type. diff --git a/SCIKit/scm.internal.inl b/SCIKit/scm.internal.inl index 96210889..8a5a85fa 100644 --- a/SCIKit/scm.internal.inl +++ b/SCIKit/scm.internal.inl @@ -34,8 +34,8 @@ public: UnknownInterface(const UnknownInterface&) = default; virtual SInt32 Release() = 0; - virtual void DecrementRef() = 0; - virtual UnknownInterface* IncrementRef() = 0; + virtual void RemoveRef() = 0; + virtual UnknownInterface* AddRef() = 0; virtual VoidPtr QueryInterface(UUID* p_uuid) = 0; }; @@ -78,7 +78,7 @@ public: virtual EventListenerInterface& operator +=(FnSign arg) { - this->AddEvent(arg); + this->AddEventListener(arg); return *this; } }; -- cgit v1.2.3