summaryrefslogtreecommitdiffhomepage
path: root/Private
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-02 16:34:04 +0100
committerAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-02 16:34:04 +0100
commite1e6032cfa5d0c55424d5badd65bfd186a44ab93 (patch)
treee593f96b052d90bf88a53d86aafb66e71aad560b /Private
parent800977c96cd64b3beeccaa7d373daed3987b1c2a (diff)
Bootloader: successfully loaded PE into memory!
Signed-off-by: Amlal El Mahrouss <amlalelmahrouss@icloud.com>
Diffstat (limited to 'Private')
-rw-r--r--Private/EFIKit/EFI.hxx104
-rw-r--r--Private/NewBoot/BootKit/BootKit.hxx3
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx59
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx10
4 files changed, 124 insertions, 52 deletions
diff --git a/Private/EFIKit/EFI.hxx b/Private/EFIKit/EFI.hxx
index 6ea95b0d..c830b30f 100644
--- a/Private/EFIKit/EFI.hxx
+++ b/Private/EFIKit/EFI.hxx
@@ -19,6 +19,10 @@
using namespace HCore;
+#ifndef EPI_API
+#define EFI_API __attribute__((stdcall))
+#endif // ifndef EPI_API
+
// Forwar decls
struct EfiTableHeader;
@@ -28,10 +32,13 @@ struct EfiDevicePathProtocol;
struct EfiBootServices;
struct EfiMemoryDescriptor;
struct EfiSystemTable;
+struct EfiGUID;
+struct EfiFileDevicePathProtocol;
+struct EfiHandle;
/// @brief Core Handle Type
/// This is like NT's Win32 HANDLE type.
-typedef struct {
+typedef struct EfiHandle {
} *EfiHandlePtr;
/* UEFI uses wide characters by default. */
@@ -42,21 +49,26 @@ typedef WideChar EfiCharType;
/// that the boot manager is attempting to load FilePath as a boot selection. If
/// FALSE, then FilePath must match an exact file to be loaded.
-typedef UInt64 (*EfiTextString)(struct EfiSimpleTextOutputProtocol *This,
- const WideChar *OutputString);
+typedef UInt64(EFI_API *EfiTextString)(struct EfiSimpleTextOutputProtocol *This,
+ const WideChar *OutputString);
+
+typedef UInt64(EFI_API *EfiTextAttrib)(struct EfiSimpleTextOutputProtocol *This,
+ const WideChar Attribute);
-typedef UInt64 (*EfiTextAttrib)(struct EfiSimpleTextOutputProtocol *This,
- const WideChar Attribute);
+typedef UInt64(EFI_API *EfiTextClear)(struct EfiSimpleTextOutputProtocol *This);
-typedef UInt64 (*EfiTextClear)(struct EfiSimpleTextOutputProtocol *This);
+typedef UInt64(EFI_API *EfiLoadFile)(EfiLoadFileProtocol *This,
+ EfiFileDevicePathProtocol *FilePath,
+ Boolean BootPolicy, UInt32 *BufferSize,
+ Void *Buffer);
-typedef UInt64 (*EfiLoadFile)(EfiLoadFileProtocol *This,
- EfiDevicePathProtocol *FilePath,
- Boolean BootPolicy, UInt32 *BufferSize,
- Void *Buffer);
+typedef UInt64(EFI_API *EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf,
+ SizeT Length);
+typedef UInt64(EFI_API *EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length);
-typedef UInt64 (*EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf, SizeT Length);
-typedef UInt64 (*EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length);
+typedef UInt64(EFI_API *EfiLocateDevicePath)(EfiGUID *Protocol,
+ EfiDevicePathProtocol **DevicePath,
+ EfiHandlePtr Device);
/// EFI pool helpers, taken from iPXE.
@@ -192,13 +204,13 @@ typedef struct EfiMemoryDescriptor {
UInt64 Attribute;
} EfiMemoryDescriptor;
-typedef UInt64 (*EfiAllocatePool)(EfiMemoryType PoolType, UInt32 Size,
- VoidPtr *Buffer);
+typedef UInt64(EFI_API *EfiAllocatePool)(EfiMemoryType PoolType, UInt32 Size,
+ VoidPtr *Buffer);
-typedef UInt64 (*EfiFreePool)(VoidPtr Buffer);
+typedef UInt64(EFI_API *EfiFreePool)(VoidPtr Buffer);
-typedef UInt64 (*EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize,
- UInt32 *CrcOut);
+typedef UInt64(EFI_API *EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize,
+ UInt32 *CrcOut);
/**
@brief Present in every header, used to identify a UEFI structure.
@@ -227,6 +239,13 @@ typedef struct EfiTableHeader {
#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { \
+ 0x0964e5b22, 0x6459, 0x11d2, { \
+ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ } \
+ }
+
#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \
{ \
0xbc62157e, 0x3e33, 0x4fec, { \
@@ -265,26 +284,29 @@ typedef struct EfiLoadFileProtocol {
typedef struct EfiDevicePathProtocol {
UInt8 Type;
UInt8 SubType;
- UInt8 LengthData[2];
+ UInt8 Length[2];
} EfiDevicePathProtocol;
typedef struct EfiFileDevicePathProtocol {
- UInt8 Type;
- UInt8 SubType;
- UInt8 LengthData[2];
+ EfiDevicePathProtocol Proto;
+
+ ///
+ /// File Path of this struct
+ ///
WideChar Path[kPathLen];
} EfiFileDevicePathProtocol;
typedef UInt64 EfiPhysicalAddress;
typedef UIntPtr EfiVirtualAddress;
-typedef UInt64 (*EfiExitBootServices)(VoidPtr ImageHandle, UInt32 MapKey);
+typedef UInt64(EFI_API *EfiExitBootServices)(VoidPtr ImageHandle,
+ UInt32 MapKey);
-typedef UInt64 (*EfiAllocatePages)(EfiAllocateType AllocType,
- EfiMemoryType MemType,
- EfiPhysicalAddress *Memory);
+typedef UInt64(EFI_API *EfiAllocatePages)(EfiAllocateType AllocType,
+ EfiMemoryType MemType,
+ EfiPhysicalAddress *Memory);
-typedef UInt64 (*EfiFreePages)(EfiPhysicalAddress *Memory, UInt32 Pages);
+typedef UInt64(EFI_API *EfiFreePages)(EfiPhysicalAddress *Memory, UInt32 Pages);
/**
* @brief GUID type, something you can also find in CFKit.
@@ -308,13 +330,15 @@ typedef struct EfiGUID {
#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
-typedef UInt64 (*EfiLocateProtocol)(EfiGUID *Protocol, VoidPtr Registration,
- VoidPtr *Interface);
+typedef UInt64(EFI_API *EfiLocateProtocol)(EfiGUID *Protocol,
+ VoidPtr Registration,
+ VoidPtr *Interface);
-typedef UInt64 (*EfiOpenProtocol)(EfiHandlePtr Handle, EfiGUID *Guid,
- VoidPtr *Interface, EfiHandlePtr AgentHandle,
- EfiHandlePtr ControllerHandle,
- UInt32 Attributes);
+typedef UInt64(EFI_API *EfiOpenProtocol)(EfiHandlePtr Handle, EfiGUID *Guid,
+ VoidPtr *Interface,
+ EfiHandlePtr AgentHandle,
+ EfiHandlePtr ControllerHandle,
+ UInt32 Attributes);
/**
@name EfiBootServices
@@ -343,7 +367,7 @@ typedef struct EfiBootServices {
VoidPtr Reserved;
UIntPtr RegisterProtocolNotify;
UIntPtr LocateHandle;
- UIntPtr LocateDevicePath;
+ EfiLocateDevicePath LocateDevicePath;
UIntPtr InstallConfigurationTable;
UIntPtr LoadImage;
UIntPtr StartImage;
@@ -432,13 +456,13 @@ typedef struct EfiIPV6 {
#endif // __x86_64
enum {
- kEFIHwDevicePath = 0x1,
- kEFIAcpiDevicePath,
- kEFIMessaingDevicePath,
- kEFIMediaDevicePath,
- kEFIBiosBootPath,
- kEFIEndOfPath,
- kEFICount,
+ kEFIHwDevicePath = 0x01,
+ kEFIAcpiDevicePath = 0x02,
+ kEFIMessaingDevicePath = 0x03,
+ kEFIMediaDevicePath = 0x04,
+ kEFIBiosBootPath = 0x05,
+ kEFIEndOfPath = 0x06,
+ kEFICount = 6,
};
#endif // __EFI__
diff --git a/Private/NewBoot/BootKit/BootKit.hxx b/Private/NewBoot/BootKit/BootKit.hxx
index b0dbccd5..bbe2332e 100644
--- a/Private/NewBoot/BootKit/BootKit.hxx
+++ b/Private/NewBoot/BootKit/BootKit.hxx
@@ -15,6 +15,7 @@
#pragma once
#include <BootKit/Arch/ATA.hxx>
+#include <EFIKit/EFI.hxx>
#include <NewKit/Defines.hpp>
using namespace HCore;
@@ -63,7 +64,7 @@ class BFileReader final {
explicit BFileReader(const CharacterType *path);
~BFileReader() = default;
- HCore::VoidPtr ReadAll();
+ HCore::VoidPtr ReadAll(SizeT &size);
enum {
kOperationOkay,
diff --git a/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx b/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx
index 600a8fcc..b45e661f 100644
--- a/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/AMD64-BootKit.cxx
@@ -11,6 +11,9 @@
#include <EFIKit/Api.hxx>
#include <FSKit/NewFS.hxx>
+#include "EFIKit/EFI.hxx"
+#include "NewKit/Macros.hpp"
+
/// bugs 0
/////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -89,7 +92,7 @@ BTextWriter &BTextWriter::WriteCharacter(CharacterType c) {
BFileReader::BFileReader(const CharacterType *path) {
if (path != nullptr) {
SizeT index = 0UL;
- for (; path[index] != L'0'; ++index) {
+ for (; path[index] != L'\0'; ++index) {
mPath[index] = path[index];
}
@@ -99,21 +102,61 @@ BFileReader::BFileReader(const CharacterType *path) {
/**
@brief this reads all of the buffer.
+@param size, new buffer size.
*/
-HCore::VoidPtr BFileReader::ReadAll() {
+HCore::VoidPtr BFileReader::ReadAll(SizeT &size) {
BTextWriter writer;
writer.WriteString(L"*** BFileReader::ReadAll: Reading ")
.WriteString(mPath)
.WriteString(L" *** \r\n");
- EfiFileDevicePathProtocol loadFile{0};
- loadFile.LengthData[0] = 0xFF;
- loadFile.LengthData[1] = 0;
+ 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 = KIB(350);
+ VoidPtr buf = nullptr;
+
+ BS->AllocatePool(EfiLoaderCode, bufSz, &buf);
+
+ if (!buf) return nullptr;
- loadFile.Type = kEFIMediaDevicePath;
- loadFile.SubType = 0; // from all drives.
+ EfiFileDevicePathProtocol filePath{0};
+ filePath.Proto.Length[0] = (sizeof(EfiDevicePathProtocol));
+ filePath.Proto.Length[1] = (sizeof(EfiDevicePathProtocol) + kPathLen) >> 8;
- BCopyMem(loadFile.Path, mPath, kPathLen);
+ filePath.Proto.Type = kEFIMediaDevicePath;
+ filePath.Proto.SubType = kEFIMediaDevicePath; // from all drives.
+
+ BCopyMem(filePath.Path, mPath, kPathLen);
+
+ auto err = loadFile->LoadFile(loadFile, &filePath, false, (UInt32 *)&bufSz,
+ (VoidPtr *)&buf);
+
+ size = bufSz;
+
+ if (buf) {
+ writer.WriteString(L"HCoreLdr: Loaded: ")
+ .WriteString(mPath)
+ .WriteString(L"\r\n");
+ } else {
+ writer.WriteString(L"HCoreLdr: Error: ")
+ .WriteString(mPath)
+ .WriteString(L" , EFI-Code: ")
+ .WriteCharacter(err + 48)
+ .WriteString(L"\r\n");
+ }
+
+ return buf;
+ }
return nullptr;
}
diff --git a/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx b/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx
index 256c7feb..7d179e42 100644
--- a/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/AMD64-Main.cxx
@@ -7,6 +7,7 @@
* ========================================================
*/
+#include "EFIKit/EFI.hxx"
#define __BOOTLOADER__ 1
#include <BootKit/BootKit.hxx>
@@ -26,10 +27,13 @@ EFI_EXTERN_C int EfiMain(EfiHandlePtr ImageHandle,
UInt64 mapKey = 0;
- BFileReader reader(L"\\Root\\System\\HCoreKrnl.exe\0");
- auto blob = reader.ReadAll();
+ BFileReader reader(L"EFI\\BOOT\\HCoreKrnl.exe");
- if (!blob)
+ SizeT sz = 0UL;
+
+ auto blob = reader.ReadAll(sz);
+
+ if (!blob || sz < 1)
KeRuntimeStop(L"HCoreLdr_NoSuchKernel",
L"Couldn't find HCoreKrnl.exe! Aborting...");