[BOOT] Create input parameters structures.

This commit is contained in:
Quinn Stephens 2024-06-06 09:40:58 -04:00
parent 42369f91ee
commit be6f37b4dc
6 changed files with 433 additions and 7 deletions

View File

@ -17,6 +17,27 @@ Abstract:
#define _BOOTMGR_H #define _BOOTMGR_H
#include <nt.h> #include <nt.h>
#include "efi.h"
//
// Set machine type.
//
#if defined(__x86_64__)
#define BOOT_MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
#elif defined(__i386__)
#define BOOT_MACHINE_TYPE IMAGE_FILE_MACHINE_I386
#endif
//
// No address translation.
//
#define BOOT_TRANSLATION_TYPE 0
//
// Use EFI page size.
//
#define PAGE_SIZE EFI_PAGE_SIZE
#define PAGE_SHIFT EFI_PAGE_SHIFT
#define BOOT_INPUT_PARAMETERS_SIGNATURE 0x50504120544f4f42 /* "BOOT APP" */ #define BOOT_INPUT_PARAMETERS_SIGNATURE 0x50504120544f4f42 /* "BOOT APP" */
#define BOOT_INPUT_PARAMETERS_VERSION 2 #define BOOT_INPUT_PARAMETERS_VERSION 2
@ -24,8 +45,82 @@ Abstract:
typedef struct { typedef struct {
ULONGLONG Signature; ULONGLONG Signature;
ULONG Version; ULONG Version;
ULONG Size;
//
// Machine information.
//
ULONG MachineType;
ULONG TranslationType;
//
// Image information.
//
PVOID ImageBase;
ULONG ImageSize;
//
// Offsets to ancillary structures.
//
ULONG MemoryInfoOffset;
ULONG ApplicationEntryOffset;
ULONG BootDeviceOffset;
ULONG FirmwareDataOffset;
ULONG ReturnDataOffset;
ULONG PlatformDataOffset;
} BOOT_INPUT_PARAMETERS, *PBOOT_INPUT_PARAMETERS; } BOOT_INPUT_PARAMETERS, *PBOOT_INPUT_PARAMETERS;
#define BOOT_APPLICATION_ENTRY_SIGNATURE 0x544e4550415442
typedef struct {
ULONGLONG Signature;
} BOOT_APPLICATION_ENTRY, *PBOOT_APPLICATION_ENTRY;
#define BOOT_MEMORY_INFO_VERSION 1
typedef struct {
ULONG Version;
ULONG MdlOffset;
ULONG DescriptorCount;
ULONG DescriptorSize;
ULONG BasePageOffset;
} BOOT_MEMORY_INFO, *PBOOT_MEMORY_INFO;
#define MEMORY_FLAG_CACHE_WB 0x08
#define MEMORY_TYPE_BOOT_APPLICATION 0xd0000002
typedef struct {
LIST_ENTRY ListEntry;
ULONGLONG BasePage;
ULONG Pages;
ULONG Flags;
ULONG Type;
} BOOT_MEMORY_DESCRIPTOR, *PBOOT_MEMORY_DESCRIPTOR;
#define BOOT_FIRMWARE_DATA_VERSION 2
typedef struct {
ULONG Version;
ULONG Reserved;
EFI_HANDLE ImageHandle;
EFI_SYSTEM_TABLE *SystemTable;
} BOOT_FIRMWARE_DATA, *PBOOT_FIRMWARE_DATA;
#define BOOT_RETURN_DATA_VERSION 1
typedef struct {
ULONG Version;
NTSTATUS Status;
ULONG Flags;
} BOOT_RETURN_DATA, *PBOOT_RETURN_DATA;
typedef struct {
ULONG Size;
} BOOT_DEVICE, *PBOOT_DEVICE;
NTSTATUS NTSTATUS
BmMain ( BmMain (
IN PBOOT_INPUT_PARAMETERS InputParameters IN PBOOT_INPUT_PARAMETERS InputParameters

View File

@ -107,6 +107,22 @@ typedef struct {
#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 #define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION #define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION
typedef
EFI_STATUS
(EFIAPI *EFI_ALLOCATE_PAGES) (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *Memory
);
typedef
EFI_STATUS
(EFIAPI *EFI_FREE_PAGES) (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN Pages
);
typedef typedef
EFI_STATUS EFI_STATUS
(EFIAPI *EFI_HANDLE_PROTOCOL) ( (EFIAPI *EFI_HANDLE_PROTOCOL) (
@ -121,8 +137,8 @@ typedef struct _EFI_BOOT_SERVICES {
EFI_HANDLE RaiseTPL; EFI_HANDLE RaiseTPL;
EFI_HANDLE RestoreTPL; EFI_HANDLE RestoreTPL;
EFI_HANDLE AllocatePages; EFI_ALLOCATE_PAGES AllocatePages;
EFI_HANDLE FreePages; EFI_FREE_PAGES FreePages;
EFI_HANDLE GetMemoryMap; EFI_HANDLE GetMemoryMap;
EFI_HANDLE AllocatePool; EFI_HANDLE AllocatePool;
EFI_HANDLE FreePool; EFI_HANDLE FreePool;

View File

@ -146,4 +146,35 @@ typedef union ULARGE_INTEGER {
#define FIELD_OFFSET(type, field) ((ULONG)__builtin_offsetof(type, field)) #define FIELD_OFFSET(type, field) ((ULONG)__builtin_offsetof(type, field))
#endif #endif
//
// Alignment helpers.
//
#define ALIGN_DOWN(x, a) ((x) & ~((a) - 1))
#define ALIGN_UP(x, a) ALIGN_DOWN((x) + (a) - 1, a)
//
// Doubly-linked list entry.
//
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *ForwardLink;
struct _LIST_ENTRY *BackLink;
} LIST_ENTRY, *PLIST_ENTRY;
//
// Runtime library definitions.
//
PVOID
RtlCopyMemory (
PVOID Destination,
CONST PVOID Source,
ULONG Length
);
PVOID
RtlZeroMemory (
PVOID Destination,
ULONG Length
);
#endif #endif

View File

@ -17,6 +17,80 @@ Abstract:
#include "efi.h" #include "efi.h"
UCHAR EfiInitScratch[2048]; UCHAR EfiInitScratch[2048];
const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
const EFI_GUID EfiDevicePathProtocol = DEVICE_PATH_PROTOCOL;
VOID
EfiInitpCreateApplicationEntry (
IN EFI_SYSTEM_TABLE *SystemTable,
IN OUT PBOOT_APPLICATION_ENTRY Entry,
IN ULONG BufferSize,
IN EFI_DEVICE_PATH *DevicePath,
IN EFI_DEVICE_PATH *FilePath,
IN PWCHAR LoadOptions,
IN ULONG LoadOptionsSize,
OUT PULONG BufferUsed,
OUT PBOOT_DEVICE *Device
)
/*++
Routine Description:
Creates an application entry structure for the boot application.
Arguments:
SystemTable - Pointer to the EFI system table.
Entry - A buffer to put the entry in.
BufferSize - The amount of available space in the buffer.
DevicePath - The device path for the application.
FilePath - The file path for the application.
LoadOptions - Firmware load options string.
LoadOptionsSize - Length of the string pointed to by LoadOptions.
BufferUsed - Returns the amount of buffer space used by the routine.
Device - Returns a pointer to the device the application was loaded from.
Return Value:
None.
--*/
{
//
// Require enough space for the application entry.
//
if (BufferSize < sizeof(BOOT_APPLICATION_ENTRY)) {
*BufferUsed = 0;
return;
}
//
// Set up application entry structure.
//
RtlZeroMemory(Entry, sizeof(BOOT_APPLICATION_ENTRY));
Entry->Signature = BOOT_APPLICATION_ENTRY_SIGNATURE;
//
// TODO: This routine is not fully implemented.
//
(VOID)SystemTable;
(VOID)DevicePath;
(VOID)FilePath;
(VOID)LoadOptions;
(VOID)LoadOptionsSize;
(VOID)Device;
*BufferUsed = sizeof(BOOT_APPLICATION_ENTRY);
}
PBOOT_INPUT_PARAMETERS PBOOT_INPUT_PARAMETERS
EfiInitCreateInputParameters ( EfiInitCreateInputParameters (
@ -44,17 +118,131 @@ Return Value:
{ {
ULONG ScratchUsed = 0; ULONG ScratchUsed = 0;
ULONG ApplicationEntrySize = 0;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS BadPageAddress;
EFI_LOADED_IMAGE *LoadedImage;
EFI_DEVICE_PATH *DevicePath;
PBOOT_INPUT_PARAMETERS InputParameters; PBOOT_INPUT_PARAMETERS InputParameters;
PBOOT_MEMORY_INFO MemoryInfo;
PBOOT_MEMORY_DESCRIPTOR MemoryDescriptor;
PBOOT_DEVICE BootDevice;
PBOOT_FIRMWARE_DATA FirmwareData;
PBOOT_RETURN_DATA ReturnData;
(VOID)ImageHandle; //
(VOID)SystemTable; // Page 0x102 may be broken on some machines.
// It is mapped here so that it does not get used.
//
BadPageAddress = 0x102 << PAGE_SHIFT;
SystemTable->BootServices->AllocatePages(AllocateAddress, EfiLoaderData, 1, &BadPageAddress);
//
// Get boot manager image information.
//
Status = SystemTable->BootServices->HandleProtocol(
ImageHandle,
(EFI_GUID*)&EfiLoadedImageProtocol,
(VOID**)&LoadedImage
);
if (Status != EFI_SUCCESS) {
return NULL;
}
//
// Get boot manager image device path.
//
Status = SystemTable->BootServices->HandleProtocol(
LoadedImage->DeviceHandle,
(EFI_GUID*)&EfiDevicePathProtocol,
(VOID**)&DevicePath
);
if (Status != EFI_SUCCESS) {
return NULL;
}
//
// Create input parameters structure.
//
InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]); InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS);
InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE; InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE;
InputParameters->Version = BOOT_INPUT_PARAMETERS_VERSION; InputParameters->Version = BOOT_INPUT_PARAMETERS_VERSION;
ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS); InputParameters->MachineType = BOOT_MACHINE_TYPE;
InputParameters->TranslationType = BOOT_TRANSLATION_TYPE;
InputParameters->ImageBase = LoadedImage->ImageBase;
InputParameters->ImageSize = LoadedImage->ImageSize;
/* TODO: Create additional parameter structures */ //
// Create memory info structure.
//
InputParameters->MemoryInfoOffset = ScratchUsed;
MemoryInfo = (PBOOT_MEMORY_INFO)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_MEMORY_INFO);
MemoryInfo->Version = BOOT_MEMORY_INFO_VERSION;
MemoryInfo->MdlOffset = sizeof(BOOT_MEMORY_INFO);
MemoryInfo->DescriptorCount = 1;
MemoryInfo->DescriptorSize = sizeof(BOOT_MEMORY_DESCRIPTOR);
MemoryInfo->BasePageOffset = FIELD_OFFSET(BOOT_MEMORY_DESCRIPTOR, BasePage);
//
// Create a memory descriptor for the boot manager image.
//
MemoryDescriptor = (PBOOT_MEMORY_DESCRIPTOR)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_MEMORY_DESCRIPTOR);
MemoryDescriptor->BasePage = (UINTN)InputParameters->ImageBase >> PAGE_SHIFT;
MemoryDescriptor->Pages = ALIGN_UP(InputParameters->ImageSize, PAGE_SIZE) >> PAGE_SHIFT;
MemoryDescriptor->Flags = MEMORY_FLAG_CACHE_WB;
MemoryDescriptor->Type = MEMORY_TYPE_BOOT_APPLICATION;
//
// Create an application entry for the boot application.
//
InputParameters->ApplicationEntryOffset = ScratchUsed;
EfiInitpCreateApplicationEntry(
SystemTable,
(PBOOT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]),
sizeof(EfiInitScratch) - ScratchUsed,
DevicePath,
LoadedImage->FilePath,
LoadedImage->LoadOptions,
LoadedImage->LoadOptionsSize,
&ApplicationEntrySize,
&BootDevice
);
ScratchUsed += ApplicationEntrySize;
//
// Copy application device to scratch area.
//
InputParameters->BootDeviceOffset = ScratchUsed;
if (BootDevice != NULL) {
RtlCopyMemory(&EfiInitScratch[ScratchUsed], BootDevice, BootDevice->Size);
ScratchUsed += BootDevice->Size;
} else {
RtlZeroMemory(&EfiInitScratch[ScratchUsed], sizeof(BOOT_DEVICE));
ScratchUsed += sizeof(BOOT_DEVICE);
}
//
// Create firmware data structure.
//
InputParameters->FirmwareDataOffset = ScratchUsed;
FirmwareData = (PBOOT_FIRMWARE_DATA)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_FIRMWARE_DATA);
FirmwareData->Version = BOOT_FIRMWARE_DATA_VERSION;
FirmwareData->Reserved = 0;
FirmwareData->ImageHandle = ImageHandle;
FirmwareData->SystemTable = SystemTable;
//
// Create return data structure.
//
InputParameters->ReturnDataOffset = ScratchUsed;
ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_RETURN_DATA);
ReturnData->Version = BOOT_RETURN_DATA_VERSION;
InputParameters->Size = ScratchUsed;
return InputParameters; return InputParameters;
} }

View File

@ -15,6 +15,16 @@ Abstract:
#include "bootlib.h" #include "bootlib.h"
//
// Total size of required structures.
//
#define MIN_INPUT_PARAMETERS_SIZE ( \
sizeof(BOOT_INPUT_PARAMETERS) + \
sizeof(BOOT_MEMORY_INFO) + \
sizeof(BOOT_FIRMWARE_DATA) + \
sizeof(BOOT_RETURN_DATA) \
)
NTSTATUS NTSTATUS
InitializeLibrary ( InitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters, IN PBOOT_INPUT_PARAMETERS InputParameters,
@ -45,7 +55,9 @@ Return Value:
// //
// Verify input parameters structure. // Verify input parameters structure.
// //
if (InputParameters == NULL || InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE) { if (InputParameters == NULL ||
InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE ||
InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }

84
BOOT/ENVIRON/LIB/rtl.c Normal file
View File

@ -0,0 +1,84 @@
/*++
Copyright (c) 2024, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
rtl.c
Abstract:
Runtime library routines.
--*/
#include <nt.h>
PVOID
RtlCopyMemory (
PVOID Destination,
CONST PVOID Source,
ULONG Length
)
/*++
Routine Description:
Copies a block of memory from Source to Destination.
Arguments:
Destination - the address to copy to.
Source - the address to copy from.
Length - the number of bytes to copy.
Return Value:
Returns Destination.
--*/
{
for (ULONG Index = 0; Index < Length; Index++) {
((PCHAR)Destination)[Index] = ((PCHAR)Source)[Index];
}
return Destination;
}
PVOID
RtlZeroMemory (
PVOID Destination,
ULONG Length
)
/*++
Routine Description:
Sets a block of memory to zero.
Arguments:
Destination - the address to zero at.
Length - the number of bytes to set.
Return Value:
Returns Destination.
--*/
{
for (ULONG Index = 0; Index < Length; Index++) {
((PCHAR)Destination)[Index] = 0;
}
return Destination;
}