diff options
| author | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-03 10:07:06 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-03 10:07:06 +0100 |
| commit | bb83659cf509f659cf1dd2e4ad239a32ad9ce119 (patch) | |
| tree | 9ed0cd541fd4ad7738ea3b3a5c108f9f6e32cadc /Private/NewBoot/Source | |
| parent | 275c162c7c270499408ee4cbdd8f24b6d0240117 (diff) | |
WiP: See below.
- GetDevicePathSize
- IsDevicePathValid
- DuplicateDevicePath
- Fix kernel build on MinGW-gcc.
- Will also work on kernel disk bootstrap drivers (ATA, NVME).
- Add compile_flags.txt for drivers to lint correctly.
Signed-off-by: Amlal El Mahrouss <amlalelmahrouss@icloud.com>
Diffstat (limited to 'Private/NewBoot/Source')
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx | 102 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx | 9 | ||||
| -rw-r--r-- | Private/NewBoot/Source/Utils.cxx | 174 | ||||
| -rw-r--r-- | Private/NewBoot/Source/makefile | 2 |
4 files changed, 191 insertions, 96 deletions
diff --git a/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx b/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx index 328e7bc9..8db6ae16 100644 --- a/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx +++ b/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx @@ -60,6 +60,9 @@ HCore::SizeT BSetMem(CharacterType *src, const CharacterType byte, ///////////////////////////////////////////////////////////////////////////////////////////////////////// +/** +@brief puts wrapper over EFI. +*/ BTextWriter &BTextWriter::WriteString(const CharacterType *str) { if (*str == 0 || !str) return *this; @@ -69,7 +72,7 @@ BTextWriter &BTextWriter::WriteString(const CharacterType *str) { } /** -@brief putc wrapper over VGA. +@brief putc wrapper over EFI. */ BTextWriter &BTextWriter::WriteCharacter(CharacterType c) { EfiCharType str[2]; @@ -80,13 +83,13 @@ BTextWriter &BTextWriter::WriteCharacter(CharacterType c) { return *this; } -///////////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// /*** @brief File Reader constructor. */ -BFileReader::BFileReader(const CharacterType *path) { +BImageReader::BImageReader(const CharacterType *path) { if (path != nullptr) { SizeT index = 0UL; for (; path[index] != L'\0'; ++index) { @@ -101,97 +104,16 @@ BFileReader::BFileReader(const CharacterType *path) { @brief this reads all of the buffer. @param size, new buffer size. */ -HCore::VoidPtr BFileReader::ReadAll(SizeT &size) { +HCore::VoidPtr BImageReader::Fetch(SizeT &size) { BTextWriter writer; - writer.WriteString(L"*** BFileReader::ReadAll: Reading ") + writer.WriteString(L"*** BImageReader::Fetch: Fetching... ") .WriteString(mPath) .WriteString(L" *** \r\n"); - EfiHandlePtr handleFile = nullptr; - EfiLoadFileProtocol *loadFile = nullptr; - - EfiGUID loadFileGUID = EfiGUID(EFI_LOAD_FILE_PROTOCOL_GUID); - - BS->LocateProtocol(&loadFileGUID, nullptr, (VoidPtr *)&loadFile); - - if (loadFile) { - writer.WriteString(L"HCoreLdr: Loading: ") - .WriteString(mPath) - .WriteString(L"\r\n"); - - UInt32 *bufSz = nullptr; - VoidPtr buf = nullptr; - - BS->AllocatePool(EfiLoaderCode, sizeof(UInt32), (VoidPtr *)&bufSz); - *bufSz = KIB(324); - - if (!bufSz) { - return nullptr; - } - - BS->AllocatePool(EfiLoaderCode, *bufSz, &buf); - - if (!buf) { - BS->FreePool(bufSz); - bufSz = nullptr; - - return nullptr; - } - - EfiFileDevicePathProtocol filePath{0}; - - filePath.Proto.Length[0] = sizeof(EfiDevicePathProtocol) + BStrLen(mPath); - filePath.Proto.Length[1] = 0; - - filePath.Proto.Type = kEFIMediaDevicePath; - filePath.Proto.SubType = kEFIMediaDevicePath; // from all drives. - - BCopyMem(filePath.Path, mPath, BStrLen(mPath)); - - auto err = loadFile->LoadFile(loadFile, &filePath, true, bufSz, buf); - - size = *bufSz; - - if (err == kEfiOk) { - writer.WriteString(L"HCoreLdr: Loaded: ") - .WriteString(mPath) - .WriteString(L"\r\n"); - } else { - BS->FreePool(buf); - buf = nullptr; - - switch (err) { - case 2: { - writer.WriteString(L"HCoreLdr: Error: ") - .WriteString(mPath) - .WriteString(L", EFI-Code: Invalid-Parameter") - .WriteString(L"\r\n"); - - break; - } - case 14: { - writer.WriteString(L"HCoreLdr: Error: ") - .WriteString(mPath) - .WriteString(L", EFI-Code: Not-Found") - .WriteString(L"\r\n"); - - break; - } - default: { - writer.WriteString(L"HCoreLdr: Error: ") - .WriteString(mPath) - .WriteString(L", EFI-Code: Unknown-Error") - .WriteString(L"\r\n"); - - break; - } - } - } - - BS->FreePool(bufSz); - bufSz = nullptr; + EfiLoadImageProtocol *proto = nullptr; + EfiGUID guidImg = EfiGUID(EFI_LOADED_IMAGE_PROTOCOL_GUID); - return buf; + if (BS->LocateProtocol(&guidImg, nullptr, (VoidPtr *)&proto) == kEfiOk) { } return nullptr; diff --git a/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx b/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx index d7583873..c2631a6f 100644 --- a/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx +++ b/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx @@ -17,7 +17,7 @@ EFI_EXTERN_C int EfiMain(EfiHandlePtr ImageHandle, EfiSystemTable* SystemTable) { - KeInitEFI(SystemTable); + InitEFI(SystemTable); BTextWriter writer; @@ -27,11 +27,10 @@ EFI_EXTERN_C int EfiMain(EfiHandlePtr ImageHandle, UInt64 mapKey = 0; - BFileReader reader(L"HCoreKrnl.exe"); + BImageReader img(L"HCoreKrnl.exe"); SizeT sz = 0UL; - - PEImagePtr blob = (PEImagePtr)reader.ReadAll(sz); + PEImagePtr blob = (PEImagePtr)img.Fetch(sz); if (!blob || sz < 1) KeRuntimeStop(L"HCoreLdr_NoSuchKernel", L"Couldn't find HCoreKrnl.exe!"); @@ -40,11 +39,11 @@ EFI_EXTERN_C int EfiMain(EfiHandlePtr ImageHandle, if (blob[0] == kMagMz0 && blob[1] == kMagMz1) { writer.WriteString(L"HCoreLdr: Running HCoreKrnl.exe...\r\n"); + /// Load Image here } else { KeRuntimeStop(L"HCoreLdr_NotPE", L"Not a PE file! Aborting..."); } - EFI::ExitBootServices(SystemTable, mapKey, ImageHandle); EFI::Stop(); return kEfiOk; diff --git a/Private/NewBoot/Source/Utils.cxx b/Private/NewBoot/Source/Utils.cxx new file mode 100644 index 00000000..c51a87d6 --- /dev/null +++ b/Private/NewBoot/Source/Utils.cxx @@ -0,0 +1,174 @@ +/* + * ======================================================== + * + * NewBoot + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <BootKit/BootKit.hxx> +#include <EFIKit/Api.hxx> +#include <EFIKit/EFI.hxx> + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// @brief External EFI code for completeness. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace Detail { +const EfiDevicePathProtocol mUefiDevicePathLibEndDevicePath = { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + {sizeof(EfiDevicePathProtocol), 0}}; + +EfiDevicePathProtocol *UefiDevicePathLibAppendDevicePath( + const EfiDevicePathProtocol *FirstDevicePath, + const EfiDevicePathProtocol *SecondDevicePath) { + SizeT Size; + SizeT Size1; + SizeT Size2; + EfiDevicePathProtocol *NewDevicePath; + EfiDevicePathProtocol *DevicePath2; + + // + // If there's only 1 path, just duplicate it. + // + if (FirstDevicePath == nullptr) { + return DuplicateDevicePath((SecondDevicePath != nullptr) + ? SecondDevicePath + : &mUefiDevicePathLibEndDevicePath); + } + + if (SecondDevicePath == nullptr) { + return DuplicateDevicePath(FirstDevicePath); + } + + if (!IsDevicePathValid(FirstDevicePath, 0) || + !IsDevicePathValid(SecondDevicePath, 0)) { + return nullptr; + } + + // + // Allocate space for the combined device path. It only has one end node of + // length EFI_DEVICE_PATH_PROTOCOL. + // + Size1 = GetDevicePathSize(FirstDevicePath); + Size2 = GetDevicePathSize(SecondDevicePath); + Size = Size1 + Size2 - sizeof(EfiDevicePathProtocol); + + BS->AllocatePool(EfiLoaderData, Size, (VoidPtr *)&NewDevicePath); + + if (NewDevicePath != NULL) { + BCopyMem((CharacterType *)NewDevicePath, (CharacterType *)FirstDevicePath, + Size1); + // + // Over write FirstDevicePath EndNode and do the copy + // + DevicePath2 = + (EfiDevicePathProtocol *)((Char *)NewDevicePath + + (Size1 - sizeof(EfiDevicePathProtocol))); + BCopyMem((CharacterType *)DevicePath2, (CharacterType *)SecondDevicePath, + Size2); + } + + return NewDevicePath; +} + +EfiDevicePathProtocol *AppendDevicePath( + EfiDevicePathProtocol *FirstDevicePath, + EfiDevicePathProtocol *SecondDevicePath) { + return UefiDevicePathLibAppendDevicePath(FirstDevicePath, SecondDevicePath); +} + +EfiDevicePathProtocol *EFI_API DevicePathFromHandle(EfiHandlePtr Handle) { + EfiDevicePathProtocol *DevicePath; + UInt64 Status; + + EfiGUID guid = EfiGUID(EFI_DEVICE_PATH_PROTOCOL_GUID); + + Status = BS->HandleProtocol(Handle, &guid, (VoidPtr *)&DevicePath); + if (Status != kEfiOk) { + DevicePath = nullptr; + } + + return DevicePath; +} + +UInt16 ReadUnaligned16(UInt16 *Buffer) { + // ASSERT (Buffer != NULL); + return *Buffer; +} + +UInt16 WriteUnaligned16(UInt16 *Buffer, UInt16 Value) { + // ASSERT (Buffer != NULL); + + return *Buffer = Value; +} + +UInt16 EFI_API SetDevicePathNodeLength(Void *Node, UInt32 Length) { + // ASSERT(Node != nullptr); + // ASSERT((Length >= sizeof(EfiDevicePathProtocol)) && (Length < KIB(64))); + return WriteUnaligned16( + (UInt16 *)&((EfiDevicePathProtocol *)(Node))->Length[0], + (UInt16)(Length)); +} + +Void EFI_API SetDevicePathEndNode(Void *Node) { + // ASSERT(Node != NULL); + BCopyMem((CharacterType *)Node, + (CharacterType *)&mUefiDevicePathLibEndDevicePath, + sizeof(mUefiDevicePathLibEndDevicePath)); +} + +UInt32 EFI_API DevicePathNodeLength(const Void *Node) { + // ASSERT(Node != NULL); + return ReadUnaligned16( + (UInt16 *)&((EfiDevicePathProtocol *)(Node))->Length[0]); +} + +EfiDevicePathProtocol *EFI_API NextDevicePathNode(Void *Node) { + // ASSERT (Node != NULL); + return (EfiDevicePathProtocol *)((UInt8 *)(Node) + + DevicePathNodeLength(Node)); +} + +EfiDevicePathProtocol *EFI_API FileDevicePath(EfiHandlePtr Device, + CharacterType *FileName) { + SizeT Size; + EfiFileDevicePathProtocol *FilePath; + EfiDevicePathProtocol *DevicePath; + EfiDevicePathProtocol *FileDevicePath; + + DevicePath = nullptr; + + Size = BStrLen(FileName); + BS->AllocatePool( + EfiLoaderData, + Size + sizeof(EfiFileDevicePathProtocol) + sizeof(EfiDevicePathProtocol), + (VoidPtr *)&FileDevicePath); + + if (FileDevicePath != nullptr) { + FilePath = (EfiFileDevicePathProtocol *)FileDevicePath; + FilePath->Proto.Type = kEFIMediaDevicePath; + FilePath->Proto.SubType = kEFIMediaDevicePath; + + BCopyMem(FilePath->Path, FileName, Size); + + SetDevicePathNodeLength(&FilePath->Proto, + Size + sizeof(EfiFileDevicePathProtocol)); + + SetDevicePathEndNode(NextDevicePathNode(&FilePath->Proto)); + + if (Device != nullptr) { + DevicePath = DevicePathFromHandle(Device); + } + + DevicePath = AppendDevicePath(DevicePath, FileDevicePath); + BS->FreePool(FileDevicePath); + } + + return DevicePath; +} +} // namespace Detail diff --git a/Private/NewBoot/Source/makefile b/Private/NewBoot/Source/makefile index 0f679772..04b39516 100644 --- a/Private/NewBoot/Source/makefile +++ b/Private/NewBoot/Source/makefile @@ -14,7 +14,7 @@ invalid-recipe: .PHONY: bootloader-amd64 bootloader-amd64: - $(CC_GNU) $(FLAG_GNU) HEL/AMD64/*.cxx + $(CC_GNU) $(FLAG_GNU) HEL/AMD64/*.cxx *.cxx $(LD_GNU) *.o -e efi_main -filealign:16 -shared --subsystem=10 -ffreestanding -o HCoreLdr.exe cp HCoreLdr.exe CDROM/EFI/BOOT/BOOTX64.EFI cp ../../HCoreKrnl.exe CDROM/EFI/BOOT/HCoreKrnl.exe |
