From df8393cebbae61ed7686be17a28d80c657f49b7e Mon Sep 17 00:00:00 2001 From: Amlal EL Mahrouss Date: Thu, 8 Aug 2024 14:19:42 +0200 Subject: [IMP] Code cleanup and improvements of the bootloader, still trying to figure what is going wrong on the kernel's DLL. Signed-off-by: Amlal EL Mahrouss --- Boot/BootKit/KernelLoader.hxx | 43 +++++++++ Boot/BootKit/ProgramLoader.hxx | 43 --------- Boot/Sources/HEL/AMD64/BootMain.cxx | 6 +- Boot/Sources/HEL/AMD64/New+Delete.cxx | 7 ++ Boot/Sources/KernelLoader.cxx | 169 ++++++++++++++++++++++++++++++++++ Boot/Sources/ProgramLoader.cxx | 151 ------------------------------ Boot/Sources/Root/bootloader.json | 5 - 7 files changed, 222 insertions(+), 202 deletions(-) create mode 100644 Boot/BootKit/KernelLoader.hxx delete mode 100644 Boot/BootKit/ProgramLoader.hxx create mode 100644 Boot/Sources/KernelLoader.cxx delete mode 100644 Boot/Sources/ProgramLoader.cxx delete mode 100644 Boot/Sources/Root/bootloader.json (limited to 'Boot') diff --git a/Boot/BootKit/KernelLoader.hxx b/Boot/BootKit/KernelLoader.hxx new file mode 100644 index 00000000..3c98a238 --- /dev/null +++ b/Boot/BootKit/KernelLoader.hxx @@ -0,0 +1,43 @@ +/* ------------------------------------------- + + 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/ProgramLoader.hxx b/Boot/BootKit/ProgramLoader.hxx deleted file mode 100644 index 09fff89b..00000000 --- a/Boot/BootKit/ProgramLoader.hxx +++ /dev/null @@ -1,43 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - -------------------------------------------- */ - -#pragma once - -#include -#include -#include - -namespace Boot -{ - using namespace Kernel; - - class ProgramLoader; - - /// @brief Program loader class - /// @package nl.zeta.boot.api - class ProgramLoader final - { - public: - explicit ProgramLoader() = delete; - ~ProgramLoader() = default; - - explicit ProgramLoader(Kernel::VoidPtr blob); - - ProgramLoader& operator=(const ProgramLoader&) = default; - ProgramLoader(const ProgramLoader&) = default; - - void Start(HEL::HandoverInformationHeader* handover); - const char* GetName(); - void SetName(const char* name); - bool IsValid(); - - private: - Char fBlobName[255]; - Char* fStackPtr{nullptr}; - 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 8647d00e..0e2be7ac 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. @@ -205,7 +205,7 @@ EFI_EXTERN_C EFI_API Int Main(EfiHandlePtr ImageHandle, readerKernel.ReadAll(0); - Boot::ProgramLoader* loader = nullptr; + Boot::KernelLoader* loader = nullptr; // ------------------------------------------ // // If we succeed in reading the blob, then execute it. @@ -213,7 +213,7 @@ EFI_EXTERN_C EFI_API Int Main(EfiHandlePtr ImageHandle, if (readerKernel.Blob()) { - loader = new Boot::ProgramLoader(readerKernel.Blob()); + loader = new Boot::KernelLoader(readerKernel.Blob()); loader->SetName("\"newoskrnl.dll\" (64-bit SMP DLL)"); } diff --git a/Boot/Sources/HEL/AMD64/New+Delete.cxx b/Boot/Sources/HEL/AMD64/New+Delete.cxx index b651f091..7039f478 100644 --- a/Boot/Sources/HEL/AMD64/New+Delete.cxx +++ b/Boot/Sources/HEL/AMD64/New+Delete.cxx @@ -44,6 +44,13 @@ void operator delete(void* buf) BS->FreePool(buf); } +/// @brief Deletes the object. +/// @param buf the object. +void operator delete[](void* buf) +{ + BS->FreePool(buf); +} + /// @brief Deletes the object (array specific). /// @param buf the object. /// @param size it's size. diff --git a/Boot/Sources/KernelLoader.cxx b/Boot/Sources/KernelLoader.cxx new file mode 100644 index 00000000..02fa97e4 --- /dev/null +++ b/Boot/Sources/KernelLoader.cxx @@ -0,0 +1,169 @@ +/* ------------------------------------------- + + 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*)(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/ProgramLoader.cxx b/Boot/Sources/ProgramLoader.cxx deleted file mode 100644 index 3b24d97b..00000000 --- a/Boot/Sources/ProgramLoader.cxx +++ /dev/null @@ -1,151 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Technologies - -------------------------------------------- */ - -#include -#include -#include - -#include -#include -#include -#include - -EXTERN_C -{ -#include -} - -extern EfiBootServices* BS; - -namespace Boot -{ - EXTERN_C Int32 rt_jump_to_address(HEL::HandoverProc baseCode, HEL::HandoverInformationHeader* handover, Char* stackPointer); - - ProgramLoader::ProgramLoader(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); - - 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 = ".start"; - - for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) - { - ExecSectionHeaderPtr sect = §Ptr[sectIndex]; - - if (StrCmp(sectionForCode, sect->mName) == 0) - { - fStartAddress = (VoidPtr)((UIntPtr)loadStartAddress + sect->mVirtualAddress); - writer.Write("newosldr: Start Address: ").Write((UIntPtr)fStartAddress).Write("\r"); - } - - 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); - } - - // ================================ // - // Allocate stack. - // ================================ // - fStackPtr = new Char[optHdr->mSizeOfStackReserve]; - } - 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 ProgramLoader::Start(HEL::HandoverInformationHeader* handover) - { - BTextWriter writer; - - if (!handover) - { - writer.Write("newosldr: Exec format error.\r"); - return; - } - - HEL::HandoverProc err_fn = [](HEL::HandoverInformationHeader* rcx) -> void { - BTextWriter writer; - writer.Write("newosldr: Exec format error, Thread has been aborted.\r"); - - EFI::ThrowError(L"Exec-Format-Error", L"Format doesn't match (Thread aborted)."); - }; - - if (!fStartAddress) - { - err_fn(handover); - } - - reinterpret_cast(fStartAddress)(handover); - err_fn(handover); - } - - const Char* ProgramLoader::GetName() - { - return fBlobName; - } - - Void ProgramLoader::SetName(const Char* name) - { - CopyMem(fBlobName, name, StrLen(name)); - } - - bool ProgramLoader::IsValid() - { - return fStartAddress != nullptr; - } -} // namespace Boot diff --git a/Boot/Sources/Root/bootloader.json b/Boot/Sources/Root/bootloader.json deleted file mode 100644 index ebfcf320..00000000 --- a/Boot/Sources/Root/bootloader.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "newoskrnl.dll": "krnldll", - "ZKA/fonts.json": "rsrc", - "ZKA/cmd.json": "cmdline" -} -- cgit v1.2.3