diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-05-02 19:38:46 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-02 19:38:46 +0200 |
| commit | 997be16e5ac9a68d54882ab69529815860d62955 (patch) | |
| tree | 19d6129c2d776bb1edc5d4a7325e39ca176c3403 /dev/boot/src/BootThread.cc | |
| parent | 618104e74c195d7508a18450524f8ed7f9af8cc6 (diff) | |
| parent | b3b4b1ebdcd6adeac914869017c86d892b7a8ced (diff) | |
Merge pull request #28 from nekernel-org/dev
0.0.2
Diffstat (limited to 'dev/boot/src/BootThread.cc')
| -rw-r--r-- | dev/boot/src/BootThread.cc | 366 |
1 files changed, 177 insertions, 189 deletions
diff --git a/dev/boot/src/BootThread.cc b/dev/boot/src/BootThread.cc index 484c242d..ada864bb 100644 --- a/dev/boot/src/BootThread.cc +++ b/dev/boot/src/BootThread.cc @@ -1,18 +1,18 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include <BootKit/BootKit.h> #include <BootKit/BootThread.h> #include <BootKit/Support.h> -#include <BootKit/BootKit.h> #include <FirmwareKit/EFI/API.h> -#include <KernelKit/PEF.h> -#include <KernelKit/PE.h> -#include <KernelKit/MSDOS.h> #include <CFKit/Utils.h> +#include <KernelKit/MSDOS.h> +#include <KernelKit/PE.h> +#include <KernelKit/PEF.h> #include <modules/CoreGfx/TextGfx.h> /// @brief External boot services symbol. @@ -20,199 +20,187 @@ EXTERN EfiBootServices* BS; /// @note BootThread doesn't parse the symbols so doesn't nullify them, .bss is though. -namespace Boot -{ - EXTERN_C Int32 rt_jump_to_address(VoidPtr code, HEL::BootInfoHeader* handover, UInt8* stack); +namespace Boot { +EXTERN_C Int32 rt_jump_to_address(VoidPtr code, HEL::BootInfoHeader* handover, UInt8* stack); - BootThread::BootThread(VoidPtr blob) - : fStartAddress(nullptr), fBlob(blob) - { - // detect the format. - const Char* blob_bytes = reinterpret_cast<char*>(fBlob); +BootThread::BootThread(VoidPtr blob) : fStartAddress(nullptr), fBlob(blob) { + // detect the format. + const Char* blob_bytes = reinterpret_cast<char*>(fBlob); - BootTextWriter writer; + BootTextWriter writer; - if (!blob_bytes) - { - // failed to provide a valid pointer. - return; - } + if (!blob_bytes) { + // failed to provide a valid pointer. + return; + } - if (blob_bytes[0] == kMagMz0 && - blob_bytes[1] == kMagMz1) - { - LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header(blob_bytes); - LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header(blob_bytes); + if (blob_bytes[0] == kMagMz0 && blob_bytes[1] == kMagMz1) { + LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header(blob_bytes); + LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header(blob_bytes); - if (!header_ptr || !opt_header_ptr) - return; + if (!header_ptr || !opt_header_ptr) return; #ifdef __NE_AMD64__ - if (header_ptr->Machine != kPeMachineAMD64 || - header_ptr->Signature != kPeSignature) - { - writer.Write("BootZ: Not a PE32+ executable.\r"); - return; - } + if (header_ptr->Machine != kPeMachineAMD64 || header_ptr->Signature != kPeSignature) { + writer.Write("BootZ: Not a PE32+ executable.\r"); + return; + } #elif defined(__NE_ARM64__) - if (header_ptr->Machine != kPeMachineARM64 || - header_ptr->Signature != kPeSignature) - { - writer.Write("BootZ: Not a PE32+ executable.\r"); - return; - } -#endif // __NE_AMD64__ || __NE_ARM64__ - - writer.Write("BootZ: PE32+ executable detected (NeKernel Subsystem).\r"); - - auto numSecs = header_ptr->NumberOfSections; - - writer.Write("BootZ: Major Linker Ver: ").Write(opt_header_ptr->MajorLinkerVersion).Write("\r"); - writer.Write("BootZ: Minor Linker Ver: ").Write(opt_header_ptr->MinorLinkerVersion).Write("\r"); - writer.Write("BootZ: Major Subsystem Ver: ").Write(opt_header_ptr->MajorSubsystemVersion).Write("\r"); - writer.Write("BootZ: Minor Subsystem Ver: ").Write(opt_header_ptr->MinorSubsystemVersion).Write("\r"); - writer.Write("BootZ: Magic: ").Write(header_ptr->Signature).Write("\r"); - - EfiPhysicalAddress loadStartAddress = opt_header_ptr->ImageBase; - loadStartAddress += opt_header_ptr->BaseOfData; - - writer.Write("BootZ: Image base: ").Write(loadStartAddress).Write("\r"); - - fStack = new UInt8[mib_cast(16)]; - - if (!fStack) - { - writer.Write("BootZ: Unable to allocate stack.\r"); - return; - } - - LDR_SECTION_HEADER_PTR sectPtr = (LDR_SECTION_HEADER_PTR)(((Char*)opt_header_ptr) + header_ptr->SizeOfOptionalHeader); - - constexpr auto sectionForCode = ".text"; - constexpr auto sectionForBootZ = ".ldr"; - - for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) - { - LDR_SECTION_HEADER_PTR sect = §Ptr[sectIndex]; - - auto sz = sect->VirtualSize; - - if (sect->SizeOfRawData > 0) - sz = sect->SizeOfRawData; - - SetMem((VoidPtr)(loadStartAddress + sect->VirtualAddress), 0, sz); - - if (sect->SizeOfRawData > 0) - { - CopyMem((VoidPtr)(loadStartAddress + sect->VirtualAddress), - (VoidPtr)((UIntPtr)fBlob + sect->PointerToRawData), - sect->SizeOfRawData); - } - - if (StrCmp(sectionForCode, sect->Name) == 0) - { - fStartAddress = (VoidPtr)((UIntPtr)loadStartAddress + opt_header_ptr->AddressOfEntryPoint); - writer.Write("BootZ: Executable entry address: ").Write((UIntPtr)fStartAddress).Write("\r"); - } - else if (StrCmp(sectionForBootZ, sect->Name) == 0) - { - struct HANDOVER_INFORMATION_STUB - { - UInt64 HandoverMagic; - UInt32 HandoverType; - UInt32 HandoverPad; - UInt32 HandoverArch; - }* handover_struc = (struct HANDOVER_INFORMATION_STUB*)((UIntPtr)fBlob + sect->PointerToRawData); - - if (handover_struc->HandoverMagic != kHandoverMagic && - handover_struc->HandoverType != HEL::kTypeKernel) - { + if (header_ptr->Machine != kPeMachineARM64 || header_ptr->Signature != kPeSignature) { + writer.Write("BootZ: Not a PE32+ executable.\r"); + return; + } +#endif // __NE_AMD64__ || __NE_ARM64__ + + writer.Write("BootZ: PE32+ executable detected (NeKernel Subsystem).\r"); + + auto numSecs = header_ptr->NumberOfSections; + + writer.Write("BootZ: Major Linker Ver: ").Write(opt_header_ptr->MajorLinkerVersion).Write("\r"); + writer.Write("BootZ: Minor Linker Ver: ").Write(opt_header_ptr->MinorLinkerVersion).Write("\r"); + writer.Write("BootZ: Major Subsystem Ver: ") + .Write(opt_header_ptr->MajorSubsystemVersion) + .Write("\r"); + writer.Write("BootZ: Minor Subsystem Ver: ") + .Write(opt_header_ptr->MinorSubsystemVersion) + .Write("\r"); + writer.Write("BootZ: Magic: ").Write(header_ptr->Signature).Write("\r"); + + EfiPhysicalAddress loadStartAddress = opt_header_ptr->ImageBase; + loadStartAddress += opt_header_ptr->BaseOfData; + + writer.Write("BootZ: Image base: ").Write(loadStartAddress).Write("\r"); + + fStack = new UInt8[mib_cast(16)]; + + if (!fStack) { + writer.Write("BootZ: Unable to allocate stack.\r"); + return; + } + + LDR_SECTION_HEADER_PTR sectPtr = + (LDR_SECTION_HEADER_PTR) (((Char*) opt_header_ptr) + header_ptr->SizeOfOptionalHeader); + + constexpr auto sectionForCode = ".text"; + constexpr auto sectionForBootZ = ".ldr"; + + for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) { + LDR_SECTION_HEADER_PTR sect = §Ptr[sectIndex]; + + auto sz = sect->VirtualSize; + + if (sect->SizeOfRawData > 0) sz = sect->SizeOfRawData; + + SetMem((VoidPtr) (loadStartAddress + sect->VirtualAddress), 0, sz); + + if (sect->SizeOfRawData > 0) { + CopyMem((VoidPtr) (loadStartAddress + sect->VirtualAddress), + (VoidPtr) ((UIntPtr) fBlob + sect->PointerToRawData), sect->SizeOfRawData); + } + + if (StrCmp(sectionForCode, sect->Name) == 0) { + fStartAddress = + (VoidPtr) ((UIntPtr) loadStartAddress + opt_header_ptr->AddressOfEntryPoint); + writer.Write("BootZ: Executable entry address: ") + .Write((UIntPtr) fStartAddress) + .Write("\r"); + } else if (StrCmp(sectionForBootZ, sect->Name) == 0) { + struct HANDOVER_INFORMATION_STUB { + UInt64 HandoverMagic; + UInt32 HandoverType; + UInt32 HandoverPad; + UInt32 HandoverArch; + }* handover_struc = + (struct HANDOVER_INFORMATION_STUB*) ((UIntPtr) fBlob + sect->PointerToRawData); + + if (handover_struc->HandoverMagic != kHandoverMagic) { #ifdef __NE_AMD64__ - if (handover_struc->HandoverArch != HEL::kArchAMD64) - { - fb_render_string("BootZ: Not an handover header, bad CPU...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - } + if (handover_struc->HandoverArch != HEL::kArchAMD64) { + writer.Write("BootZ: Not an handover header, bad CPU...\r"); + } #elif defined(__NE_ARM64__) - if (handover_struc->HandoverArch != HEL::kArchARM64) - { - fb_render_string("BootZ: Not an handover header, bad CPU...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - } + if (handover_struc->HandoverArch != HEL::kArchARM64) { + writer.Write("BootZ: Not an handover header, bad CPU...\r"); + } #endif - fb_render_string("BootZ: Not an handover header...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - ::Boot::Stop(); - } - } - - writer.Write("BootZ: Raw offset: ").Write(sect->PointerToRawData).Write(" of ").Write(sect->Name).Write("\r"); - - CopyMem((VoidPtr)(loadStartAddress + sect->VirtualAddress), (VoidPtr)((UIntPtr)fBlob + sect->PointerToRawData), sect->SizeOfRawData); - } - } - else if (blob_bytes[0] == kPefMagic[0] && - blob_bytes[1] == kPefMagic[1] && - blob_bytes[2] == kPefMagic[2] && - blob_bytes[3] == kPefMagic[3]) - { - // ========================================= // - // PEF executable has been detected. - // ========================================= // - - fStartAddress = nullptr; - - writer.Write("BootZ: PEF executable detected, won't load it.\r"); - writer.Write("BootZ: note: PEF executables aren't supported for now.\r"); - } - else - { - writer.Write("BootZ: Invalid Executable.\r"); - } - } - - /// @note handover header has to be valid! - Int32 BootThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) - { - fHandover = handover; - - if (!fStartAddress) - { - return kEfiFail; - } - - if (!fHandover) - { - return kEfiFail; - } - - BootTextWriter writer; - - writer.Write("BootZ: Starting: ").Write(fBlobName).Write("\r"); - writer.Write("BootZ: Handover address: ").Write((UIntPtr)fHandover).Write("\r"); - - if (own_stack) - { - return rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); - } - else - { - return reinterpret_cast<HEL::HandoverProc>(fStartAddress)(fHandover); - } - - return kEfiFail; - } - - const Char* BootThread::GetName() - { - return fBlobName; - } - - Void BootThread::SetName(const Char* name) - { - CopyMem(fBlobName, name, StrLen(name)); - } - - bool BootThread::IsValid() - { - return fStartAddress != nullptr; - } -} // namespace Boot
\ No newline at end of file + writer.Write("BootZ: Not an handover header...\r"); + ::Boot::Stop(); + } + } + + writer.Write("BootZ: Raw offset: ") + .Write(sect->PointerToRawData) + .Write(" of ") + .Write(sect->Name) + .Write("\r"); + + CopyMem((VoidPtr) (loadStartAddress + sect->VirtualAddress), + (VoidPtr) ((UIntPtr) fBlob + sect->PointerToRawData), sect->SizeOfRawData); + } + } else if (blob_bytes[0] == kPefMagic[0] && blob_bytes[1] == kPefMagic[1] && + blob_bytes[2] == kPefMagic[2] && blob_bytes[3] == kPefMagic[3]) { + // ========================================= // + // PEF executable has been detected. + // ========================================= // + + fStartAddress = nullptr; + + writer.Write("BootZ: PEF executable detected, won't load it.\r"); + writer.Write("BootZ: note: PEF executables aren't supported for now.\r"); + } else { + writer.Write("BootZ: Invalid Executable.\r"); + } +} + +/// @note handover header has to be valid! +Int32 BootThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) { + fHandover = handover; + + if (!fStartAddress) { + return kEfiFail; + } + + if (!fHandover) { + return kEfiFail; + } + + BootTextWriter writer; + + writer.Write("BootZ: Starting: ").Write(fBlobName).Write("\r"); + writer.Write("BootZ: Handover address: ").Write((UIntPtr) fHandover).Write("\r"); + + if (own_stack) { + writer.Write("BootZ: Using it's own stack.\r"); + writer.Write("BootZ: Stack address: ").Write((UIntPtr) &fStack[mib_cast(16) - 1]).Write("\r"); + writer.Write("BootZ: Stack size: ").Write(mib_cast(16)).Write("\r"); + + auto ret = rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); + + // we don't need the stack anymore. + + delete[] fStack; + fStack = nullptr; + + return ret; + } else { + writer.Write("BootZ: Using Bootloader's stack.\r"); + + return reinterpret_cast<HEL::HandoverProc>(fStartAddress)(fHandover); + } + + return kEfiFail; +} + +const Char* BootThread::GetName() { + return fBlobName; +} + +Void BootThread::SetName(const Char* name) { + CopyMem(fBlobName, name, StrLen(name)); +} + +bool BootThread::IsValid() { + return fStartAddress != nullptr; +} +} // namespace Boot
\ No newline at end of file |
