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 --- 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 +- 6 files changed, 222 insertions(+), 217 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 (limited to 'Boot') 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 -- cgit v1.2.3