[BOOT] Huge refactor

This commit is contained in:
Quinn Stephens 2024-10-05 15:39:04 -04:00
parent 6a678794d3
commit 7c3dafc051
18 changed files with 982 additions and 399 deletions

View File

@ -43,7 +43,7 @@ Return Value:
--*/ --*/
{ {
PBOOT_INPUT_PARAMETERS InputParameters; PBOOT_APPLICATION_PARAMETERS InputParameters;
// //
// Create firmware-independent input structure from EFI parameters. // Create firmware-independent input structure from EFI parameters.

View File

@ -13,11 +13,11 @@ Abstract:
--*/ --*/
#include "bootlib.h" #include "bootmgr.h"
NTSTATUS NTSTATUS
BmOpenDataStore ( BmOpenDataStore (
IN OUT PHANDLE DataStore IN OUT PHANDLE Handle
) )
/*++ /*++
@ -28,7 +28,7 @@ Routine Description:
Arguments: Arguments:
DataStore - Pointer to a HANDLE that recieves the data store handle. Handle - Pointer to a HANDLE that recieves the data store handle.
Return Value: Return Value:
@ -37,7 +37,7 @@ Return Value:
--*/ --*/
{ {
*DataStore = INVALID_HANDLE_VALUE; *Handle = INVALID_HANDLE_VALUE;
/* /*
NTSTATUS Status; NTSTATUS Status;
@ -51,5 +51,6 @@ Return Value:
return BmGetDataStorePath(&Device, &FilePath, &FilePathSet); return BmGetDataStorePath(&Device, &FilePath, &FilePathSet);
*/ */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View File

@ -9,16 +9,15 @@ Module Name:
Abstract: Abstract:
Main functions of the boot manager. Boot manager main routine.
--*/ --*/
#include "bootmgr.h" #include "bootmgr.h"
#include "bootlib.h"
NTSTATUS NTSTATUS
BmMain ( BmMain (
IN PBOOT_INPUT_PARAMETERS InputParameters IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters
) )
/*++ /*++
@ -29,7 +28,7 @@ Routine Description:
Arguments: Arguments:
InputParameters - Input parameters for the boot manager. ApplicationParameters - Input parameters for the boot manager.
Return Value: Return Value:
@ -41,15 +40,16 @@ Return Value:
{ {
NTSTATUS Status; NTSTATUS Status;
BOOT_LIBRARY_PARAMETERS LibraryParameters; BOOT_LIBRARY_PARAMETERS LibraryParameters;
HANDLE DataStore; HANDLE DataStoreHandle;
LibraryParameters.Flags = 0; LibraryParameters.Flags = 0;
LibraryParameters.TranslationType = TRANSLATION_TYPE_NONE;
LibraryParameters.MinimumPageAllocation = 16; LibraryParameters.MinimumPageAllocation = 16;
// //
// Initialize the boot library. // Initialize the boot library.
// //
Status = BlInitializeLibrary(InputParameters, &LibraryParameters); Status = BlInitializeLibrary(ApplicationParameters, &LibraryParameters);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
ConsolePrintf(L"BlInitializeLibrary() failed: 0x%x\r\n", Status); ConsolePrintf(L"BlInitializeLibrary() failed: 0x%x\r\n", Status);
goto Exit; goto Exit;
@ -58,9 +58,7 @@ Return Value:
// //
// Open the boot data store. // Open the boot data store.
// //
(VOID)BmOpenDataStore(&DataStore); (VOID)BmOpenDataStore(&DataStoreHandle);
while (TRUE);
Exit: Exit:
BlDestroyLibrary(); BlDestroyLibrary();

View File

@ -17,7 +17,243 @@ Abstract:
#define _BOOTLIB_H #define _BOOTLIB_H
#include <nt.h> #include <nt.h>
#include "bootmgr.h"
#if defined(_EFI)
#include "efi.h"
#define PAGE_SIZE EFI_PAGE_SIZE
#define PAGE_SHIFT EFI_PAGE_SHIFT
#endif /* _EFI */
//
// 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
//
// Address translation types.
//
#define TRANSLATION_TYPE_NONE 0
#define TRANSLATION_TYPE_MAX 1
//
// Application entry option.
// Used to represent options passed to a boot
// application by whatever started it.
//
typedef struct {
ULONG Type;
ULONG DataOffset;
ULONG DataSize;
ULONG OtherOptionsOffset;
ULONG NextOptionOffset;
BOOLEAN IsInvalid;
UCHAR Reserved[3];
} BOOT_ENTRY_OPTION, *PBOOT_ENTRY_OPTION;
//
// Application entry.
// Used for any boot environment application,
// including the boot manager itself.
//
#define BOOT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER 0x01
typedef struct {
ULONG Attributes;
GUID BcdIdentifier;
PBOOT_ENTRY_OPTION Options;
} BOOT_APPLICATION_ENTRY, *PBOOT_APPLICATION_ENTRY;
//
// Initial application entry.
// Special form of BOOT_APPLICATION_ENTRY used
// when firmware first loads the boot manager.
//
#define BOOT_INIT_APPLICATION_ENTRY_SIGNATURE 0x544e4550415442 /* "BTAPENT" */
typedef struct {
ULONGLONG Signature;
ULONG Attributes;
GUID BcdIdentifier;
UCHAR Reserved[16];
BOOT_ENTRY_OPTION Options;
} BOOT_INIT_APPLICATION_ENTRY, *PBOOT_INIT_APPLICATION_ENTRY;
typedef ULONG MEMORY_TYPE;
//
// Memory type classes.
//
#define MEMORY_CLASS_APPLICATION 0xD
#define MEMORY_CLASS_LIBRARY 0xE
#define MEMORY_CLASS_SYSTEM 0xF
//
// Memory types.
//
#define MEMORY_TYPE_BOOT_APPLICATION 0xD0000002
#define MEMORY_TYPE_BOOT_APPLICATION_2 0xD0000013
#define MEMORY_TYPE_FREE 0xF0000001
#define MEMORY_TYPE_UNUSABLE 0xF0000002
#define MEMORY_TYPE_RESERVED 0xF0000003
#define MEMORY_TYPE_BOOT_SERVICES 0xF0000004
#define MEMORY_TYPE_FREE_ZEROED 0xF0000005
#define MEMORY_TYPE_RUNTIME_SERVICES_CODE 0xF0000006
#define MEMORY_TYPE_PERSISTENT 0xF0000007
#define MEMORY_TYPE_ACPI_RECLAIM 0xF0000008
#define MEMORY_TYPE_ACPI_NVS 0xF0000009
#define MEMORY_TYPE_MMIO 0xF000000A
#define MEMORY_TYPE_MMIO_PORT_SPACE 0xF000000B
#define MEMORY_TYPE_PAL_CODE 0xF000000C
#define MEMORY_TYPE_RUNTIME_SERVICES_DATA 0xF000000E
//
// Memory caching attributes.
//
#define MEMORY_ATTRIBUTE_UC 0x00000001
#define MEMORY_ATTRIBUTE_WC 0x00000002
#define MEMORY_ATTRIBUTE_WT 0x00000004
#define MEMORY_ATTRIBUTE_WB 0x00000008
#define MEMORY_ATTRIBUTE_UCE 0x00000010
//
// Memory protection attributes.
//
#define MEMORY_ATTRIBUTE_WP 0x00000100
#define MEMORY_ATTRIBUTE_RP 0x00000200
#define MEMORY_ATTRIBUTE_XP 0x00000400
//
// Memory location attributes.
//
#define MEMORY_ATTRIBUTE_BELOW_1MIB 0x00080000
//
// Memory runtime mapping attributes.
//
#define MEMORY_ATTRIBUTE_RUNTIME 0x01000000
typedef struct {
LIST_ENTRY ListEntry;
ULONGLONG FirstPage;
ULONGLONG MappedFirstPage;
ULONG PageCount;
ULONG Attributes;
MEMORY_TYPE Type;
} MEMORY_DESCRIPTOR, *PMEMORY_DESCRIPTOR;
typedef enum {
MDL_TYPE_PHYSICAL,
MDL_TYPE_VIRTUAL
} MEMORY_DESCRIPTOR_LIST_TYPE;
typedef struct {
LIST_ENTRY ListEntry;
PLIST_ENTRY Head;
PLIST_ENTRY Current;
MEMORY_DESCRIPTOR_LIST_TYPE Type;
} MEMORY_DESCRIPTOR_LIST, *PMEMORY_DESCRIPTOR_LIST;
#define BOOT_MEMORY_INFO_VERSION 1
typedef struct {
ULONG Version;
ULONG MdlOffset;
ULONG DescriptorCount;
ULONG DescriptorSize;
ULONG FirstPageOffset;
} BOOT_MEMORY_INFO, *PBOOT_MEMORY_INFO;
#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;
#if defined(__i386__) || defined(__x86_64__)
typedef struct __attribute__((packed)) {
USHORT Limit;
ULONG_PTR Base;
} DESCRIPTOR_TABLE_REGISTER, *PDESCRIPTOR_TABLE_REGISTER;
typedef struct {
DESCRIPTOR_TABLE_REGISTER Gdt;
DESCRIPTOR_TABLE_REGISTER Idt;
USHORT LdtSelector;
USHORT CS, DS, ES, FS, GS, SS;
} DESCRIPTOR_TABLE_CONTEXT, *PDESCRIPTOR_TABLE_CONTEXT;
#endif
typedef struct {
ULONG Reserved;
#if defined(__i386__) || defined(__x86_64__)
ULONG_PTR CR3;
#endif
DESCRIPTOR_TABLE_CONTEXT DescriptorTableContext;
} BOOT_PLATFORM_DATA, *PBOOT_PLATFORM_DATA;
//
// Firmware-independent application parameters.
// Passed to any boot application's entry point.
//
#define BOOT_APPLICATION_PARAMETERS_SIGNATURE 0x50504120544f4f42 /* "BOOT APP" */
#define BOOT_APPLICATION_PARAMETERS_VERSION 2
typedef struct {
ULONGLONG Signature;
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_APPLICATION_PARAMETERS, *PBOOT_APPLICATION_PARAMETERS;
//
// Library parameters.
// Specifies how the boot library should be
// set up.
//
typedef struct { typedef struct {
ULONG Flags; ULONG Flags;
@ -25,6 +261,121 @@ typedef struct {
ULONG MinimumPageAllocation; ULONG MinimumPageAllocation;
} BOOT_LIBRARY_PARAMETERS, *PBOOT_LIBRARY_PARAMETERS; } BOOT_LIBRARY_PARAMETERS, *PBOOT_LIBRARY_PARAMETERS;
typedef struct {
LARGE_INTEGER ImageBase;
ULONG ImageSize;
ULONG ImageOffset;
} BOOT_RAMDISK_IDENTIFIER, *PBOOT_RAMDISK_IDENTIFIER;
#define BOOT_HARDDRIVE_PARTITION_TYPE_GPT 0x00
#define BOOT_HARDDRIVE_PARTITION_TYPE_MBR 0x01
#define BOOT_HARDDRIVE_PARTITION_TYPE_RAW 0x02
typedef struct {
ULONG PartitionType;
union {
struct {
ULONG Signature;
} Mbr;
struct {
GUID Signature;
} Gpt;
struct {
ULONG DriveNumber;
} Raw;
};
} BOOT_HARDDRIVE_IDENTIFIER, *PBOOT_HARDDRIVE_IDENTIFIER;
typedef struct {
ULONG DriveNumber;
} BOOT_CDROM_IDENTIFIER, *PBOOT_CDROM_IDENTIFIER;
#define BOOT_BLOCK_DEVICE_TYPE_HARDDRIVE 0x00
#define BOOT_BLOCK_DEVICE_TYPE_CDROM 0x02
#define BOOT_BLOCK_DEVICE_TYPE_RAMDISK 0x03
typedef struct {
ULONG Type;
union {
BOOT_RAMDISK_IDENTIFIER Ramdisk;
BOOT_HARDDRIVE_IDENTIFIER Harddrive;
BOOT_CDROM_IDENTIFIER Cdrom;
};
} BOOT_BLOCK_IDENTIFIER, *PBOOT_BLOCK_IDENTIFIER;
typedef struct {
union {
struct {
ULONG PartitionNumber;
} Mbr;
struct {
GUID PartitionIdentifier;
} Gpt;
struct {
ULONG BootEntry;
} ElTorito;
};
BOOT_BLOCK_IDENTIFIER Parent;
} BOOT_PARTITION_IDENTIFIER, *PBOOT_PARTITION_IDENTIFIER;
typedef struct {
union {
struct {
PVOID PartitionOffset;
} Mbr;
struct {
GUID PartitionIdentifier;
} Gpt;
struct {
ULONG BootEntry;
} ElTorito;
};
BOOT_BLOCK_IDENTIFIER Parent;
} BOOT_PARTITION_IDENTIFIER_EX, *PBOOT_PARTITION_IDENTIFIER_EX;
#define BOOT_DEVICE_TYPE_BLOCK 0x00
#define BOOT_DEVICE_TYPE_PARTITION 0x02
#define BOOT_DEVICE_TYPE_PARTITION_EX 0x06
#define BOOT_DEVICE_ATTRIBUTE_NO_PARENT_SIGNATURE 0x04
typedef struct {
ULONG Type;
ULONG Attributes;
ULONG Size;
ULONG Pad;
union {
BOOT_BLOCK_IDENTIFIER Block;
BOOT_PARTITION_IDENTIFIER Partition;
BOOT_PARTITION_IDENTIFIER_EX PartitionEx;
};
} BOOT_DEVICE, *PBOOT_DEVICE;
typedef ULONG BCDE_DATA_TYPE;
#define BCDE_DATA_FORMAT_MASK 0x0F000000
#define BCDE_DATA_FORMAT_DEVICE 0x1
#define BCDE_DATA_TYPE_APPLICATION_DEVICE 0x11000001
#define BCDE_DATA_TYPE_APPLICATION_PATH 0x22000002
typedef struct {
GUID Options;
BOOT_DEVICE Device;
} BCDE_DEVICE, *PBCDE_DEVICE;
VOID VOID
ConsolePrint ( ConsolePrint (
IN PWSTR String IN PWSTR String
@ -39,7 +390,7 @@ ConsolePrintf (
// //
// Enable/disable debug printing. // Enable/disable debug printing.
// //
#ifdef _DEBUG #if defined(_DEBUG)
#define DebugPrint(String) ConsolePrint(String) #define DebugPrint(String) ConsolePrint(String)
#define DebugPrintf(Format, ...) ConsolePrintf(Format, __VA_ARGS__) #define DebugPrintf(Format, ...) ConsolePrintf(Format, __VA_ARGS__)
#else #else
@ -47,14 +398,9 @@ ConsolePrintf (
#define DebugPrintf(Format, ...) #define DebugPrintf(Format, ...)
#endif #endif
ULONG VOID
BlGetBootOptionSize ( BlpArchGetDescriptorTableContext (
IN PBOOT_APPLICATION_OPTION Option PDESCRIPTOR_TABLE_CONTEXT Context
);
ULONG
BlGetBootOptionListSize (
IN PBOOT_APPLICATION_OPTION Options
); );
NTSTATUS NTSTATUS
@ -75,9 +421,19 @@ BlpMmInitialize (
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
); );
ULONG
BlGetBootOptionSize (
IN PBOOT_ENTRY_OPTION Option
);
ULONG
BlGetBootOptionListSize (
IN PBOOT_ENTRY_OPTION Options
);
NTSTATUS NTSTATUS
BlInitializeLibrary ( BlInitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters, IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters,
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
); );

View File

@ -16,311 +16,16 @@ Abstract:
#ifndef _BOOTMGR_H #ifndef _BOOTMGR_H
#define _BOOTMGR_H #define _BOOTMGR_H
#include <nt.h> #include "bootlib.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
//
// Use EFI page size.
//
#define PAGE_SIZE EFI_PAGE_SIZE
#define PAGE_SHIFT EFI_PAGE_SHIFT
//
// Address translation types.
//
#define BOOT_TRANSLATION_TYPE_NONE 0
#define BOOT_TRANSLATION_TYPE_MAX 1
#define BOOT_INPUT_PARAMETERS_SIGNATURE 0x50504120544f4f42 /* "BOOT APP" */
#define BOOT_INPUT_PARAMETERS_VERSION 2
typedef struct {
ULONGLONG Signature;
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;
typedef struct {
ULONG Type;
ULONG DataOffset;
ULONG DataSize;
ULONG OtherOptionsOffset;
ULONG NextOptionOffset;
BOOLEAN IsInvalid;
UCHAR Unknown[3];
} BOOT_APPLICATION_OPTION, *PBOOT_APPLICATION_OPTION;
#define BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE 0x544e4550415442 /* "BTAPENT" */
#define BOOT_INPUT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER 0x01
typedef struct {
ULONGLONG Signature;
ULONG Attributes;
GUID BcdIdentifier;
UCHAR Unknown[16];
BOOT_APPLICATION_OPTION Options;
} BOOT_INPUT_APPLICATION_ENTRY, *PBOOT_INPUT_APPLICATION_ENTRY;
typedef struct {
ULONG Attributes;
GUID BcdIdentifier;
PBOOT_APPLICATION_OPTION Options;
} BOOT_APPLICATION_ENTRY, *PBOOT_APPLICATION_ENTRY;
#define BOOT_MEMORY_INFO_VERSION 1
typedef struct {
ULONG Version;
ULONG MdlOffset;
ULONG DescriptorCount;
ULONG DescriptorSize;
ULONG FirstPageOffset;
} BOOT_MEMORY_INFO, *PBOOT_MEMORY_INFO;
//
// Memory descriptor caching attributes.
//
#define MEMORY_ATTRIBUTE_UC 0x0000000000000001
#define MEMORY_ATTRIBUTE_WC 0x0000000000000002
#define MEMORY_ATTRIBUTE_WT 0x0000000000000004
#define MEMORY_ATTRIBUTE_WB 0x0000000000000008
#define MEMORY_ATTRIBUTE_UCE 0x0000000000000010
//
// Memory descriptor protection attributes.
//
#define MEMORY_ATTRIBUTE_WP 0x000000000000100
#define MEMORY_ATTRIBUTE_RP 0x000000000000200
#define MEMORY_ATTRIBUTE_XP 0x000000000000400
//
// Memory descriptor location attributes.
//
#define MEMORY_ATTRIBUTE_BELOW_1MIB 0x80000
//
// Memory descriptor runtime mapping attributes.
//
#define MEMORY_ATTRIBUTE_RUNTIME 0x1000000
#define MEMORY_CLASS_APPLICATION 0xD
#define MEMORY_CLASS_LIBRARY 0xE
#define MEMORY_CLASS_SYSTEM 0xF
#define MEMORY_TYPE_BOOT_APPLICATION 0xD0000002
#define MEMORY_TYPE_BOOT_APPLICATION_2 0xD0000013
#define MEMORY_TYPE_FREE 0xF0000001
#define MEMORY_TYPE_UNUSABLE 0xF0000002
#define MEMORY_TYPE_RESERVED 0xF0000003
#define MEMORY_TYPE_BOOT_SERVICES 0xF0000004
#define MEMORY_TYPE_FREE_ZEROED 0xF0000005
#define MEMORY_TYPE_RUNTIME_SERVICES_CODE 0xF0000006
#define MEMORY_TYPE_PERSISTENT 0xF0000007
#define MEMORY_TYPE_ACPI_RECLAIM 0xF0000008
#define MEMORY_TYPE_ACPI_NVS 0xF0000009
#define MEMORY_TYPE_MMIO 0xF000000A
#define MEMORY_TYPE_MMIO_PORT_SPACE 0xF000000B
#define MEMORY_TYPE_PAL_CODE 0xF000000C
#define MEMORY_TYPE_RUNTIME_SERVICES_DATA 0xF000000E
typedef ULONG MEMORY_TYPE;
typedef struct {
LIST_ENTRY ListEntry;
ULONGLONG FirstPage;
ULONGLONG MappedFirstPage;
ULONG PageCount;
ULONG Attributes;
MEMORY_TYPE Type;
} MEMORY_DESCRIPTOR, *PMEMORY_DESCRIPTOR;
typedef enum {
MDL_TYPE_PHYSICAL,
MDL_TYPE_VIRTUAL
} MEMORY_DESCRIPTOR_LIST_TYPE;
typedef struct {
LIST_ENTRY ListEntry;
PLIST_ENTRY Head;
PLIST_ENTRY Current;
MEMORY_DESCRIPTOR_LIST_TYPE Type;
} MEMORY_DESCRIPTOR_LIST, *PMEMORY_DESCRIPTOR_LIST;
#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 {
LARGE_INTEGER ImageBase;
ULONG ImageSize;
ULONG ImageOffset;
} BOOT_RAMDISK_IDENTIFIER, *PBOOT_RAMDISK_IDENTIFIER;
#define BOOT_HARDDRIVE_PARTITION_TYPE_GPT 0x00
#define BOOT_HARDDRIVE_PARTITION_TYPE_MBR 0x01
#define BOOT_HARDDRIVE_PARTITION_TYPE_RAW 0x02
typedef struct {
ULONG PartitionType;
union {
struct {
ULONG Signature;
} Mbr;
struct {
GUID Signature;
} Gpt;
struct {
ULONG DriveNumber;
} Raw;
};
} BOOT_HARDDRIVE_IDENTIFIER, *PBOOT_HARDDRIVE_IDENTIFIER;
typedef struct {
ULONG DriveNumber;
} BOOT_CDROM_IDENTIFIER, *PBOOT_CDROM_IDENTIFIER;
#define BOOT_BLOCK_DEVICE_TYPE_HARDDRIVE 0x00
#define BOOT_BLOCK_DEVICE_TYPE_CDROM 0x02
#define BOOT_BLOCK_DEVICE_TYPE_RAMDISK 0x03
typedef struct {
ULONG Type;
union {
BOOT_RAMDISK_IDENTIFIER Ramdisk;
BOOT_HARDDRIVE_IDENTIFIER Harddrive;
BOOT_CDROM_IDENTIFIER Cdrom;
};
} BOOT_BLOCK_IDENTIFIER, *PBOOT_BLOCK_IDENTIFIER;
typedef struct {
union {
struct {
ULONG PartitionNumber;
} Mbr;
struct {
GUID PartitionIdentifier;
} Gpt;
struct {
ULONG BootEntry;
} ElTorito;
};
BOOT_BLOCK_IDENTIFIER Parent;
} BOOT_PARTITION_IDENTIFIER, *PBOOT_PARTITION_IDENTIFIER;
typedef struct {
union {
struct {
PVOID PartitionOffset;
} Mbr;
struct {
GUID PartitionIdentifier;
} Gpt;
struct {
ULONG BootEntry;
} ElTorito;
};
BOOT_BLOCK_IDENTIFIER Parent;
} BOOT_PARTITION_IDENTIFIER_EX, *PBOOT_PARTITION_IDENTIFIER_EX;
#define BOOT_DEVICE_TYPE_BLOCK 0x00
#define BOOT_DEVICE_TYPE_PARTITION 0x02
#define BOOT_DEVICE_TYPE_PARTITION_EX 0x06
#define BOOT_DEVICE_ATTRIBUTE_NO_PARENT_SIGNATURE 0x04
typedef struct {
ULONG Type;
ULONG Attributes;
ULONG Size;
ULONG Pad;
union {
BOOT_BLOCK_IDENTIFIER Block;
BOOT_PARTITION_IDENTIFIER Partition;
BOOT_PARTITION_IDENTIFIER_EX PartitionEx;
};
} BOOT_DEVICE, *PBOOT_DEVICE;
#define BCDE_DATA_FORMAT_MASK 0x0F000000
#define BCDE_DATA_FORMAT_DEVICE 1
typedef enum {
BCDE_DATA_TYPE_APPLICATION_DEVICE = 0x11000001,
BCDE_DATA_TYPE_APPLICATION_PATH = 0x22000002
} BCDE_DATA_TYPE;
typedef struct {
GUID OtherOptions;
BOOT_DEVICE Device;
} BCDE_DEVICE, *PBCDE_DEVICE;
NTSTATUS NTSTATUS
BmOpenDataStore ( BmOpenDataStore (
IN OUT PHANDLE DataStore IN OUT PHANDLE Handle
); );
NTSTATUS NTSTATUS
BmMain ( BmMain (
IN PBOOT_INPUT_PARAMETERS InputParameters IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters
); );
#endif #endif

View File

@ -16,10 +16,17 @@ Abstract:
#ifndef _EFILIB_H #ifndef _EFILIB_H
#define _EFILIB_H #define _EFILIB_H
#include "bootmgr.h" #include "bootlib.h"
#include "efi.h" #include "efi.h"
PBOOT_INPUT_PARAMETERS PBOOT_APPLICATION_PARAMETERS
EfiInitCreateInputParametersEx (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable,
IN ULONG Flags
);
PBOOT_APPLICATION_PARAMETERS
EfiInitCreateInputParameters ( EfiInitCreateInputParameters (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable IN EFI_SYSTEM_TABLE *SystemTable

View File

@ -15,7 +15,7 @@ Abstract:
#include <stdarg.h> #include <stdarg.h>
#include <wchar.h> #include <wchar.h>
#include "bootmgr.h" #include "bootlib.h"
extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut; extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut;

View File

@ -14,7 +14,7 @@ Abstract:
--*/ --*/
#include "bootlib.h" #include "bootlib.h"
#include "bootmgr.h" #include "efi.h"
EFI_SYSTEM_TABLE *EfiST; EFI_SYSTEM_TABLE *EfiST;
EFI_BOOT_SERVICES *EfiBS; EFI_BOOT_SERVICES *EfiBS;

View File

@ -16,9 +16,7 @@ Abstract:
#include <ntrtl.h> #include <ntrtl.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
#include "bootlib.h" #include "efilib.h"
#include "bootmgr.h"
#include "efi.h"
UCHAR EfiInitScratch[2048]; UCHAR EfiInitScratch[2048];
const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL; const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
@ -277,7 +275,7 @@ NTSTATUS
EfiInitpConvertEfiDevicePath ( EfiInitpConvertEfiDevicePath (
IN EFI_DEVICE_PATH *EfiDevicePath, IN EFI_DEVICE_PATH *EfiDevicePath,
IN BCDE_DATA_TYPE OptionType, IN BCDE_DATA_TYPE OptionType,
IN OUT PBOOT_APPLICATION_OPTION Option, IN OUT PBOOT_ENTRY_OPTION Option,
IN ULONG BufferSize IN ULONG BufferSize
) )
@ -309,23 +307,23 @@ Return Value:
NTSTATUS Status; NTSTATUS Status;
PBCDE_DEVICE DeviceElement; PBCDE_DEVICE DeviceElement;
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) { if (BufferSize < sizeof(BOOT_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION)); RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION));
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_APPLICATION_OPTION)); DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_ENTRY_OPTION));
Status = EfiInitTranslateDevicePath( Status = EfiInitTranslateDevicePath(
EfiDevicePath, EfiDevicePath,
&DeviceElement->Device, &DeviceElement->Device,
BufferSize - (sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) BufferSize - (sizeof(BOOT_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device))
); );
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
return Status; return Status;
} }
Option->Type = OptionType; Option->Type = OptionType;
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION); Option->DataOffset = sizeof(BOOT_ENTRY_OPTION);
Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) + DeviceElement->Device.Size; Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) + DeviceElement->Device.Size;
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -335,7 +333,7 @@ NTSTATUS
EfiInitpConvertEfiFilePath ( EfiInitpConvertEfiFilePath (
IN EFI_DEVICE_PATH *EfiFilePath, IN EFI_DEVICE_PATH *EfiFilePath,
IN BCDE_DATA_TYPE OptionType, IN BCDE_DATA_TYPE OptionType,
IN OUT PBOOT_APPLICATION_OPTION Option, IN OUT PBOOT_ENTRY_OPTION Option,
IN ULONG BufferSize IN ULONG BufferSize
) )
@ -368,19 +366,19 @@ Return Value:
PWCHAR PathStart, Position; PWCHAR PathStart, Position;
ULONG BufferRemaining, Length, Appended; ULONG BufferRemaining, Length, Appended;
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION)) { if (BufferSize < sizeof(BOOT_ENTRY_OPTION)) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION)); RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION));
Option->Type = OptionType; Option->Type = OptionType;
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION); Option->DataOffset = sizeof(BOOT_ENTRY_OPTION);
// //
// Loop through nodes and add one at a time. // Loop through nodes and add one at a time.
// //
Option->DataSize = 0; Option->DataSize = 0;
BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_OPTION); BufferRemaining = BufferSize - sizeof(BOOT_ENTRY_OPTION);
Node = EfiFilePath; Node = EfiFilePath;
PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset); PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset);
Position = PathStart; Position = PathStart;
@ -440,7 +438,7 @@ Return Value:
VOID VOID
EfiInitpCreateApplicationEntry ( EfiInitpCreateApplicationEntry (
IN EFI_SYSTEM_TABLE *SystemTable, IN EFI_SYSTEM_TABLE *SystemTable,
IN OUT PBOOT_INPUT_APPLICATION_ENTRY Entry, IN OUT PBOOT_INIT_APPLICATION_ENTRY Entry,
IN ULONG BufferSize, IN ULONG BufferSize,
IN EFI_DEVICE_PATH *EfiDevicePath, IN EFI_DEVICE_PATH *EfiDevicePath,
IN EFI_DEVICE_PATH *EfiFilePath, IN EFI_DEVICE_PATH *EfiFilePath,
@ -491,7 +489,7 @@ Return Value:
PWCHAR BcdOptionString; PWCHAR BcdOptionString;
BOOLEAN BcdIdentifierSet; BOOLEAN BcdIdentifierSet;
UNICODE_STRING UnicodeString; UNICODE_STRING UnicodeString;
PBOOT_APPLICATION_OPTION Option, PrevOption; PBOOT_ENTRY_OPTION Option, PrevOption;
PBCDE_DEVICE BootDeviceElement; PBCDE_DEVICE BootDeviceElement;
(VOID)SystemTable; (VOID)SystemTable;
@ -503,13 +501,13 @@ Return Value:
BcdIdentifierSet = FALSE; BcdIdentifierSet = FALSE;
BufferRemaining = BufferSize; BufferRemaining = BufferSize;
if (BufferRemaining < sizeof(BOOT_INPUT_APPLICATION_ENTRY)) { if (BufferRemaining < sizeof(BOOT_INIT_APPLICATION_ENTRY)) {
return; return;
} }
RtlZeroMemory(Entry, sizeof(BOOT_INPUT_APPLICATION_ENTRY)); RtlZeroMemory(Entry, sizeof(BOOT_INIT_APPLICATION_ENTRY));
Entry->Signature = BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE; Entry->Signature = BOOT_INIT_APPLICATION_ENTRY_SIGNATURE;
BufferRemaining -= FIELD_OFFSET(BOOT_INPUT_APPLICATION_ENTRY, Options); BufferRemaining -= FIELD_OFFSET(BOOT_INIT_APPLICATION_ENTRY, Options);
// //
// Terminate load options. // Terminate load options.
@ -530,7 +528,7 @@ Return Value:
} }
if (!BcdIdentifierSet) { if (!BcdIdentifierSet) {
Entry->Attributes |= BOOT_INPUT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER; Entry->Attributes |= BOOT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER;
} }
// //
@ -553,7 +551,7 @@ Return Value:
// TODO: Support UDP/PXE boot. // TODO: Support UDP/PXE boot.
// //
PrevOption = Option; PrevOption = Option;
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize); Option = (PBOOT_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
Status = EfiInitpConvertEfiFilePath(EfiFilePath, BCDE_DATA_TYPE_APPLICATION_PATH, Option, BufferRemaining); Status = EfiInitpConvertEfiFilePath(EfiFilePath, BCDE_DATA_TYPE_APPLICATION_PATH, Option, BufferRemaining);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
goto exit; goto exit;
@ -567,7 +565,7 @@ Return Value:
// TODO: Parse additional options from LoadOptions. // TODO: Parse additional options from LoadOptions.
// //
PrevOption = Option; PrevOption = Option;
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize); Option = (PBOOT_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
// Status = Unknown(LoadOptions, &Entry->Options, RemainingSize, &OptionsSize, &PrevOption, &Size); // Status = Unknown(LoadOptions, &Entry->Options, RemainingSize, &OptionsSize, &PrevOption, &Size);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
goto exit; goto exit;
@ -577,10 +575,11 @@ exit:
*BufferUsed = BufferSize - BufferRemaining; *BufferUsed = BufferSize - BufferRemaining;
} }
PBOOT_INPUT_PARAMETERS PBOOT_APPLICATION_PARAMETERS
EfiInitCreateInputParameters ( EfiInitCreateInputParametersEx (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable IN EFI_SYSTEM_TABLE *SystemTable,
IN ULONG Flags
) )
/*++ /*++
@ -595,6 +594,8 @@ Arguments:
SystemTable - Pointer to the EFI system table. SystemTable - Pointer to the EFI system table.
Flags - Unused.
Return Value: Return Value:
Pointer to parameter structure if successful. Pointer to parameter structure if successful.
@ -603,19 +604,22 @@ Return Value:
--*/ --*/
{ {
ULONG ScratchUsed = 0;
ULONG ApplicationEntrySize = 0;
EFI_STATUS Status; EFI_STATUS Status;
ULONG ScratchUsed;
ULONG ApplicationEntrySize;
EFI_PHYSICAL_ADDRESS BadPageAddress; EFI_PHYSICAL_ADDRESS BadPageAddress;
EFI_LOADED_IMAGE *LoadedImage; EFI_LOADED_IMAGE *LoadedImage;
EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH *DevicePath;
PBOOT_INPUT_PARAMETERS InputParameters; PBOOT_APPLICATION_PARAMETERS InputParameters;
PBOOT_MEMORY_INFO MemoryInfo; PBOOT_MEMORY_INFO MemoryInfo;
PMEMORY_DESCRIPTOR MemoryDescriptor; PMEMORY_DESCRIPTOR MemoryDescriptor;
PBOOT_DEVICE BootDevice; PBOOT_DEVICE BootDevice;
PBOOT_FIRMWARE_DATA FirmwareData; PBOOT_FIRMWARE_DATA FirmwareData;
PBOOT_PLATFORM_DATA PlatformData;
PBOOT_RETURN_DATA ReturnData; PBOOT_RETURN_DATA ReturnData;
ScratchUsed = 0;
// //
// Page 0x102 may be broken on some machines. // Page 0x102 may be broken on some machines.
// It is mapped here so that it does not get used. // It is mapped here so that it does not get used.
@ -641,12 +645,12 @@ Return Value:
return NULL; return NULL;
} }
InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]); InputParameters = (PBOOT_APPLICATION_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS); ScratchUsed += sizeof(BOOT_APPLICATION_PARAMETERS);
InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE; InputParameters->Signature = BOOT_APPLICATION_PARAMETERS_SIGNATURE;
InputParameters->Version = BOOT_INPUT_PARAMETERS_VERSION; InputParameters->Version = BOOT_APPLICATION_PARAMETERS_VERSION;
InputParameters->MachineType = BOOT_MACHINE_TYPE; InputParameters->MachineType = BOOT_MACHINE_TYPE;
InputParameters->TranslationType = BOOT_TRANSLATION_TYPE_NONE; InputParameters->TranslationType = TRANSLATION_TYPE_NONE;
InputParameters->ImageBase = LoadedImage->ImageBase; InputParameters->ImageBase = LoadedImage->ImageBase;
InputParameters->ImageSize = LoadedImage->ImageSize; InputParameters->ImageSize = LoadedImage->ImageSize;
@ -669,13 +673,13 @@ Return Value:
InputParameters->ApplicationEntryOffset = ScratchUsed; InputParameters->ApplicationEntryOffset = ScratchUsed;
EfiInitpCreateApplicationEntry( EfiInitpCreateApplicationEntry(
SystemTable, SystemTable,
(PBOOT_INPUT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]), (PBOOT_INIT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]),
sizeof(EfiInitScratch) - ScratchUsed, sizeof(EfiInitScratch) - ScratchUsed,
DevicePath, DevicePath,
LoadedImage->FilePath, LoadedImage->FilePath,
LoadedImage->LoadOptions, LoadedImage->LoadOptions,
LoadedImage->LoadOptionsSize, LoadedImage->LoadOptionsSize,
0, Flags,
&ApplicationEntrySize, &ApplicationEntrySize,
&BootDevice &BootDevice
); );
@ -698,6 +702,15 @@ Return Value:
FirmwareData->ImageHandle = ImageHandle; FirmwareData->ImageHandle = ImageHandle;
FirmwareData->SystemTable = SystemTable; FirmwareData->SystemTable = SystemTable;
InputParameters->PlatformDataOffset = ScratchUsed;
PlatformData = (PBOOT_PLATFORM_DATA)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_PLATFORM_DATA);
PlatformData->Reserved = 0;
#if defined(__i386__) || defined(__x86_64__)
asm volatile("mov %%cr3, %0" :"=r"(PlatformData->CR3));
#endif
BlpArchGetDescriptorTableContext(&PlatformData->DescriptorTableContext);
InputParameters->ReturnDataOffset = ScratchUsed; InputParameters->ReturnDataOffset = ScratchUsed;
ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]); ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_RETURN_DATA); ScratchUsed += sizeof(BOOT_RETURN_DATA);
@ -710,3 +723,32 @@ Return Value:
return InputParameters; return InputParameters;
} }
PBOOT_APPLICATION_PARAMETERS
EfiInitCreateInputParameters (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Creates the input parameter structure for the boot application.
Arguments:
ImageHandle - EFI handle for the boot application image.
SystemTable - Pointer to the EFI system table.
Return Value:
Pointer to parameter structure if successful.
NULL on failure.
--*/
{
return EfiInitCreateInputParametersEx(ImageHandle, SystemTable, 0);
}

View File

@ -13,8 +13,7 @@ Abstract:
--*/ --*/
#include "bootmgr.h" #include "efilib.h"
#include "efi.h"
EFI_STATUS EFI_STATUS
EfiGetEfiStatusCode ( EfiGetEfiStatusCode (

View File

@ -13,7 +13,7 @@ Abstract:
--*/ --*/
#include "bootmgr.h" #include "bootlib.h"
#include "efi.h" #include "efi.h"
#include "efilib.h" #include "efilib.h"
#include "mm.h" #include "mm.h"

View File

@ -85,8 +85,8 @@ Return Value:
// Check TranslationType. // Check TranslationType.
// //
if ( if (
TranslationType > BOOT_TRANSLATION_TYPE_MAX || TranslationType > TRANSLATION_TYPE_MAX ||
LibraryParameters->TranslationType > BOOT_TRANSLATION_TYPE_MAX LibraryParameters->TranslationType > TRANSLATION_TYPE_MAX
) { ) {
DebugPrint(L"BlpMmInitialize(): TranslationType is invalid\r\n"); DebugPrint(L"BlpMmInitialize(): TranslationType is invalid\r\n");
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;

View File

@ -14,7 +14,7 @@ Abstract:
--*/ --*/
#include <ntrtl.h> #include <ntrtl.h>
#include "bootmgr.h" #include "bootlib.h"
#include "mm.h" #include "mm.h"
#define MAX_STATIC_DESCRIPTOR_COUNT 1024 #define MAX_STATIC_DESCRIPTOR_COUNT 1024

429
BOOT/ENVIRON/LIB/X86/arch.c Normal file
View File

@ -0,0 +1,429 @@
/*++
Copyright (c) 2024, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
arch.c
Abstract:
Provides x86 architecture-specific routines.
--*/
#include <ntrtl.h>
#include "bootlib.h"
// TODO: Move these to a header file?
#define CR0_PG (1 << 31)
#define CR4_OSFXSR (1 << 9)
#define CR4_LA57 (1 << 12)
#define IA32_EFER_MSR 0xC0000080
#define IA32_EFER_LME (1 << 10)
extern ULONG BlPlatformFlags;
extern PBOOT_FIRMWARE_DATA EfiFirmwareParameters;
EXECUTION_CONTEXT ApplicationExecutionContext;
EXECUTION_CONTEXT FirmwareExecutionContext;
PEXECUTION_CONTEXT CurrentExecutionContext;
VOID
Archpx64EnableInterruptsAsm (
);
/*++
Routine Description:
Enables interrupts.
Implemented in ctx.S.
Arguments:
None.
Return Value:
None.
--*/
VOID
Archpx64DisableInterruptsAsm (
);
/*++
Routine Description:
Disables interrupts.
Implemented in ctx.S.
Arguments:
None.
Return Value:
None.
--*/
VOID
BlpArchGetDescriptorTableContext (
PDESCRIPTOR_TABLE_CONTEXT Context
);
/*++
Routine Description:
Loads current descriptor values into a
descriptor table context structure.
Implemented in ctx.S.
Arguments:
Context - Pointer to the context structure.
Return Value:
None.
--*/
VOID
ArchSetDescriptorTableContext (
PDESCRIPTOR_TABLE_CONTEXT Context
);
/*++
Routine Description:
Loads current descriptor values from a
descriptor table context structure.
Implemented in ctx.S.
Arguments:
Context - Pointer to the context structure.
Return Value:
None.
--*/
BOOLEAN
BlArchIsFiveLevelPagingActive (
)
{
ULONG_PTR Cr0, Cr4;
ULONG Efer;
//
// Paging must be enabled.
//
asm volatile("mov %%cr0, %0" :"=r"(Cr0));
if (!(Cr0 & CR0_PG)) {
return FALSE;
}
//
// Long mode must be enabled.
//
asm volatile("rdmsr" :"=a"(Efer) :"c"(IA32_EFER_MSR));
if (!(Efer & IA32_EFER_LME)) {
return FALSE;
}
//
// 57-bit linear addresses must be enabled.
// If LA57 is enabled, 5-level paging is enabled.
//
asm volatile("mov %%cr4, %0" :"=r"(Cr4));
if (!(Cr4 & CR4_LA57)) {
return FALSE;
}
return TRUE;
}
NTSTATUS
ArchInitializeContext (
IN OUT PEXECUTION_CONTEXT Context
)
/*++
Routine Description:
Initializes an execution context.
Arguments:
Context - Pointer to the context structure.
Return Value:
STATUS_SUCCESS if successful.
--*/
{
ULONG_PTR Cr4;
if (Context->Type == ExecutionContextFirmware) {
Context->Flags &= ~(EXECUTION_CONTEXT_PAGING_ENABLED | 0x01);
Context->Flags |= EXECUTION_CONTEXT_INTERRUPTS_ENABLED;
//
// Use context data from firmware.
//
Context->Cr3 = EfiFirmwareParameters->Cr3;
RtlCopyMemory(&Context->DescriptorTableContext, &EfiFirmwareParameters->DescriptorTableContext, sizeof(DESCRIPTOR_TABLE_CONTEXT));
return STATUS_SUCCESS;
}
Context->Flags &= ~EXECUTION_CONTEXT_INTERRUPTS_ENABLED;
Context->Flags |= 0x01;
//
// Use current context.
//
asm volatile("mov %%cr3, %0" :"=r"(Context->Cr3));
BlpArchGetDescriptorTableContext(&Context->DescriptorTableContext);
//
// Check if 5-level paging is active.
//
if (!BlArchIsFiveLevelPagingActive()) {
Context->Flags &= ~EXECUTION_CONTEXT_PAGING_ENABLED;
//
// Enable SSE and FXSAVE/FXRSTOR.
//
asm volatile("mov %%cr4, %0" :"=r"(Cr4));
Cr4 |= CR4_OSFXSR;
asm volatile("mov %0, %%cr4" ::"r"(Cr4));
return STATUS_SUCCESS;
}
//
// TODO: Not sure what is supposed to happen here.
//
DebugPrint(L"ArchInitializeContext(): 5-level paging support not implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
VOID
ArchSetPagingContext(
IN PEXECUTION_CONTEXT NewContext,
IN PEXECUTION_CONTEXT CurrentContext
)
/*++
Routine Description:
Loads the current paging context.
Arguments:
NewContext - The context to switch to.
CurrentContext - The currently loaded context.
Return Value:
None.
--*/
{
BOOLEAN PagingEnabled;
//
// Check if paging is enabled.
//
if (CurrentContext != NULL) {
PagingEnabled = CurrentContext->Flags & EXECUTION_CONTEXT_PAGING_ENABLED ? TRUE:FALSE;
} else {
PagingEnabled = BlArchIsFiveLevelPagingActive() ? TRUE:FALSE;
}
//
// If paging is not being enabled/disabled,
// just switch CR3.
//
if (PagingEnabled == (NewContext->Flags & EXECUTION_CONTEXT_PAGING_ENABLED ? TRUE:FALSE)) {
asm volatile("mov %0, %%cr3" ::"r"(NewContext->Cr3));
return;
}
//
// TODO: Finish this routine.
//
DebugPrint(L"ArchSetPagingContext(): Paging mode enable/disable not implemented\r\n");
}
VOID
ArchSwitchContext (
IN PEXECUTION_CONTEXT NewContext,
IN PEXECUTION_CONTEXT CurrentContext
)
/*++
Routine Description:
Switches to a specified execution context.
Arguments:
NewContext - The context to switch to.
CurrentContext - The currently loaded context.
Return Value:
None.
--*/
{
if (CurrentContext != NULL && CurrentContext->Flags & EXECUTION_CONTEXT_INTERRUPTS_ENABLED) {
Archpx64DisableInterruptsAsm();
}
//
// Set descriptor table and paging contexts,
// in the correct order.
//
if (NewContext->Type == ExecutionContextFirmware) {
ArchSetPagingContext(NewContext, CurrentContext);
ArchSetDescriptorTableContext(&NewContext->DescriptorTableContext);
} else {
ArchSetDescriptorTableContext(&NewContext->DescriptorTableContext);
ArchSetPagingContext(NewContext, CurrentContext);
}
if (NewContext->Flags & EXECUTION_CONTEXT_INTERRUPTS_ENABLED) {
Archpx64EnableInterruptsAsm();
}
}
VOID
BlpArchSwitchContext (
IN EXECUTION_CONTEXT_TYPE Type
)
/*++
Routine Description:
Switches to an execution context of type Type.
Arguments:
Type - The requested context type.
Return Value:
None.
--*/
{
PEXECUTION_CONTEXT NewContext;
if (Type == ExecutionContextFirmware) {
NewContext = &FirmwareExecutionContext;
} else {
NewContext = &ApplicationExecutionContext;
}
if (CurrentExecutionContext->Type == NewContext->Type) {
return;
}
ArchSwitchContext(NewContext, CurrentExecutionContext);
CurrentExecutionContext = NewContext;
}
NTSTATUS
BlpArchInitialize (
IN ULONG Stage
)
/*++
Routine Description:
Internal routine to perform architecture-specific initialization.
Arguments:
Stage - 0.
Return Value:
STATUS_SUCCESS.
--*/
{
NTSTATUS Status;
if (Stage == 0) {
ApplicationExecutionContext.Type = ExecutionContextApplication;
FirmwareExecutionContext.Type = ExecutionContextFirmware;
CurrentExecutionContext = NULL;
//
// Initialize and use application context.
//
Status = ArchInitializeContext(&ApplicationExecutionContext);
if (NT_SUCCESS(Status)) {
CurrentExecutionContext = &ApplicationExecutionContext;
}
//
// Initialize firmware context if supported.
//
if (BlPlatformFlags & FIRMWARE_FLAG_EXECUTION_CONTEXT_SUPPORTED) {
Status = ArchInitializeContext(&FirmwareExecutionContext);
if (!NT_SUCCESS(Status)) {
// TODO: Implement ArchInitializeProcessorFeatures()?
// ArchInitializeProcessorFeatures();
return Status;
}
//
// Use firmware execution context if
// the application context is not
// supported.
//
if (CurrentExecutionContext == NULL) {
CurrentExecutionContext = &FirmwareExecutionContext;
}
}
//
// Switch to the correct context.
//
ArchSwitchContext(CurrentExecutionContext, NULL);
}
return STATUS_SUCCESS;
}

View File

@ -0,0 +1,41 @@
.text
SetSegmentRegisters:
mov 0x18(%rcx), %ds
mov 0x1a(%rcx), %es
mov 0x1c(%rcx), %fs
mov 0x1e(%rcx), %gs
mov 0x20(%rcx), %ss
ret
.globl Archpx64EnableInterruptsAsm
Archpx64EnableInterruptsAsm:
sti
ret
.globl Archpx64DisableInterruptsAsm
Archpx64DisableInterruptsAsm:
cli
ret
.globl BlpArchGetDescriptorTableContext
BlpArchGetDescriptorTableContext:
sgdt 0x00(%rcx)
sidt 0x0a(%rcx)
sldt 0x14(%rcx)
mov %cs, 0x16(%rcx)
mov %ds, 0x18(%rcx)
mov %es, 0x1a(%rcx)
mov %fs, 0x1c(%rcx)
mov %gs, 0x1e(%rcx)
mov %ss, 0x20(%rcx)
ret
.globl ArchSetDescriptorTableContext
ArchSetDescriptorTableContext:
sgdt 0x00(%rcx)
sidt 0x0a(%rcx)
sldt 0x14(%rcx)
push 0x16(%rcx)
push $SetSegmentRegisters
lretq

View File

@ -17,19 +17,21 @@ Abstract:
#include "bootlib.h" #include "bootlib.h"
#define MIN_INPUT_PARAMETERS_SIZE ( \ #define MIN_INPUT_PARAMETERS_SIZE ( \
sizeof(BOOT_INPUT_PARAMETERS) + \ sizeof(BOOT_APPLICATION_PARAMETERS) + \
sizeof(BOOT_MEMORY_INFO) + \ sizeof(BOOT_MEMORY_INFO) + \
sizeof(BOOT_INIT_APPLICATION_ENTRY) + \
sizeof(BOOT_FIRMWARE_DATA) + \ sizeof(BOOT_FIRMWARE_DATA) + \
sizeof(BOOT_RETURN_DATA) \ sizeof(BOOT_RETURN_DATA) \
) )
PBOOT_INPUT_PARAMETERS BlpApplicationParameters;
BOOT_APPLICATION_ENTRY BlpApplicationEntry;
PBOOT_DEVICE BlpBootDevice; PBOOT_DEVICE BlpBootDevice;
PBOOT_APPLICATION_PARAMETERS BlpApplicationParameters;
BOOT_LIBRARY_PARAMETERS BlpLibraryParameters;
BOOT_APPLICATION_ENTRY BlpApplicationEntry;
NTSTATUS NTSTATUS
InitializeLibrary ( InitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters, IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters,
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
) )
@ -41,7 +43,7 @@ Routine Description:
Arguments: Arguments:
InputParameters - Pointer to the application's input parameters. ApplicationParameters - Pointer to the application's input parameters.
LibraryParameters - Pointer to the library parameters. LibraryParameters - Pointer to the library parameters.
@ -54,23 +56,21 @@ Return Value:
{ {
NTSTATUS Status; NTSTATUS Status;
PBOOT_MEMORY_INFO MemoryInfo; PBOOT_MEMORY_INFO MemoryInfo;
PBOOT_INPUT_APPLICATION_ENTRY ApplicationEntry; PBOOT_INIT_APPLICATION_ENTRY ApplicationEntry;
PBOOT_FIRMWARE_DATA FirmwareData; PBOOT_FIRMWARE_DATA FirmwareData;
PBOOT_BLOCK_IDENTIFIER BlockDevice;
PBOOT_APPLICATION_OPTION Option;
(VOID)LibraryParameters; (VOID)LibraryParameters;
if (InputParameters == NULL || if (ApplicationParameters == NULL ||
InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE || ApplicationParameters->Signature != BOOT_APPLICATION_PARAMETERS_SIGNATURE ||
InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) { ApplicationParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)InputParameters + InputParameters->MemoryInfoOffset); MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)ApplicationParameters + ApplicationParameters->MemoryInfoOffset);
ApplicationEntry = (PBOOT_INPUT_APPLICATION_ENTRY)((PUCHAR)InputParameters + InputParameters->ApplicationEntryOffset); ApplicationEntry = (PBOOT_INIT_APPLICATION_ENTRY)((PUCHAR)ApplicationParameters + ApplicationParameters->ApplicationEntryOffset);
BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)InputParameters + InputParameters->BootDeviceOffset); BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)ApplicationParameters + ApplicationParameters->BootDeviceOffset);
FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)InputParameters + InputParameters->FirmwareDataOffset); FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)ApplicationParameters + ApplicationParameters->FirmwareDataOffset);
// //
// Initialize firmware library. // Initialize firmware library.
@ -83,24 +83,28 @@ Return Value:
} }
ConsolePrint(L"> Alcyone EFI Boot Manager\r\n"); ConsolePrint(L"> Alcyone EFI Boot Manager\r\n");
ConsolePrintf(L"Image base: %x %x\r\nImage size: %x\r\n", HIDWORD((ULONG_PTR)InputParameters->ImageBase), LODWORD((ULONG_PTR)InputParameters->ImageBase), InputParameters->ImageSize); ConsolePrintf(L"Image base: %x %x\r\nImage size: %x\r\n", HIDWORD((ULONG_PTR)ApplicationParameters->ImageBase), LODWORD((ULONG_PTR)ApplicationParameters->ImageBase), ApplicationParameters->ImageSize);
DebugPrint(L"Initializing boot library...\r\n"); DebugPrint(L"Initializing boot library...\r\n");
if (ApplicationEntry->Signature != BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE) { if (ApplicationEntry->Signature != BOOT_INIT_APPLICATION_ENTRY_SIGNATURE) {
DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n"); DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n");
return STATUS_INVALID_PARAMETER_9; return STATUS_INVALID_PARAMETER_9;
} }
// //
// Save input parameters and application entry. // Save library and application parameters.
//
BlpApplicationParameters = ApplicationParameters;
RtlCopyMemory(&BlpLibraryParameters, LibraryParameters, sizeof(BOOT_LIBRARY_PARAMETERS));
//
// Save application entry.
// //
BlpApplicationParameters = InputParameters;
BlpApplicationEntry.Attributes = ApplicationEntry->Attributes; BlpApplicationEntry.Attributes = ApplicationEntry->Attributes;
RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID)); RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID));
BlpApplicationEntry.Options = &ApplicationEntry->Options; BlpApplicationEntry.Options = &ApplicationEntry->Options;
Status = BlpMmInitialize(MemoryInfo, InputParameters->TranslationType, LibraryParameters); Status = BlpMmInitialize(MemoryInfo, ApplicationParameters->TranslationType, LibraryParameters);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
return Status; return Status;
} }
@ -110,7 +114,7 @@ Return Value:
NTSTATUS NTSTATUS
BlInitializeLibrary ( BlInitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters, IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters,
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
) )
@ -122,7 +126,7 @@ Routine Description:
Arguments: Arguments:
InputParameters - Pointer to the application's input parameters. ApplicationParameters - Pointer to the application's input parameters.
LibraryParameters - Pointer to the library parameters. LibraryParameters - Pointer to the library parameters.
@ -133,7 +137,7 @@ Return Value:
--*/ --*/
{ {
return InitializeLibrary(InputParameters, LibraryParameters); return InitializeLibrary(ApplicationParameters, LibraryParameters);
} }
NTSTATUS NTSTATUS

View File

@ -17,7 +17,7 @@ Abstract:
ULONG ULONG
BlGetBootOptionSize ( BlGetBootOptionSize (
IN PBOOT_APPLICATION_OPTION Option IN PBOOT_ENTRY_OPTION Option
) )
/*++ /*++
@ -42,11 +42,11 @@ Return Value:
if (Option->DataOffset != 0) { if (Option->DataOffset != 0) {
TotalSize = Option->DataOffset + Option->DataSize; TotalSize = Option->DataOffset + Option->DataSize;
} else { } else {
TotalSize = sizeof(BOOT_APPLICATION_OPTION); TotalSize = sizeof(BOOT_ENTRY_OPTION);
} }
if (Option->OtherOptionsOffset != 0) { if (Option->OtherOptionsOffset != 0) {
TotalSize += BlGetBootOptionListSize((PBOOT_APPLICATION_OPTION)((PUCHAR)Option + Option->OtherOptionsOffset)); TotalSize += BlGetBootOptionListSize((PBOOT_ENTRY_OPTION)((PUCHAR)Option + Option->OtherOptionsOffset));
} }
return TotalSize; return TotalSize;
@ -54,7 +54,7 @@ Return Value:
ULONG ULONG
BlGetBootOptionListSize ( BlGetBootOptionListSize (
IN PBOOT_APPLICATION_OPTION Options IN PBOOT_ENTRY_OPTION Options
) )
/*++ /*++
@ -75,12 +75,12 @@ Return Value:
{ {
ULONG TotalSize, NextOffset; ULONG TotalSize, NextOffset;
PBOOT_APPLICATION_OPTION Option; PBOOT_ENTRY_OPTION Option;
TotalSize = 0; TotalSize = 0;
NextOffset = 0; NextOffset = 0;
do { do {
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)Options + NextOffset); Option = (PBOOT_ENTRY_OPTION)((PUCHAR)Options + NextOffset);
NextOffset = Option->NextOptionOffset; NextOffset = Option->NextOptionOffset;
TotalSize += BlGetBootOptionSize(Option); TotalSize += BlGetBootOptionSize(Option);
} while (NextOffset != 0); } while (NextOffset != 0);

View File

@ -13,6 +13,7 @@
| LIB/EFI/eficon.c | ConsoleXX() | | LIB/EFI/eficon.c | ConsoleXX() |
| LIB/EFI/efilib.c | EfiGetEfiStatusCode() | | LIB/EFI/efilib.c | EfiGetEfiStatusCode() |
| LIB/MM/mm.c | BlpMmXX() | | LIB/MM/mm.c | BlpMmXX() |
| LIB/MM/mmmd.c | MmMdXX() |
| LIB/MM/mmpa.c | MmPaXX() | | LIB/MM/mmpa.c | MmPaXX() |
| LIB/bootlib.c | BlXXLibrary() | | LIB/bootlib.c | BlXXLibrary() |
| LIB/bootopt.c | BlXXBootOptionXX() | | LIB/bootopt.c | BlXXBootOptionXX() |