diff --git a/BOOT/ENVIRON/APP/BOOTMGR/EFI/efientry.c b/BOOT/ENVIRON/APP/BOOTMGR/EFI/efientry.c index 5725400..769ab76 100644 --- a/BOOT/ENVIRON/APP/BOOTMGR/EFI/efientry.c +++ b/BOOT/ENVIRON/APP/BOOTMGR/EFI/efientry.c @@ -43,7 +43,7 @@ Return Value: --*/ { - PBOOT_INPUT_PARAMETERS InputParameters; + PBOOT_APPLICATION_PARAMETERS InputParameters; // // Create firmware-independent input structure from EFI parameters. diff --git a/BOOT/ENVIRON/APP/BOOTMGR/bcd.c b/BOOT/ENVIRON/APP/BOOTMGR/bcd.c index a93dcd0..d8abf49 100644 --- a/BOOT/ENVIRON/APP/BOOTMGR/bcd.c +++ b/BOOT/ENVIRON/APP/BOOTMGR/bcd.c @@ -13,11 +13,11 @@ Abstract: --*/ -#include "bootlib.h" +#include "bootmgr.h" NTSTATUS BmOpenDataStore ( - IN OUT PHANDLE DataStore + IN OUT PHANDLE Handle ) /*++ @@ -28,7 +28,7 @@ Routine Description: 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: @@ -37,7 +37,7 @@ Return Value: --*/ { - *DataStore = INVALID_HANDLE_VALUE; + *Handle = INVALID_HANDLE_VALUE; /* NTSTATUS Status; @@ -51,5 +51,6 @@ Return Value: return BmGetDataStorePath(&Device, &FilePath, &FilePathSet); */ + return STATUS_SUCCESS; } diff --git a/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c b/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c index d69155a..7510145 100644 --- a/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c +++ b/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c @@ -9,16 +9,15 @@ Module Name: Abstract: - Main functions of the boot manager. + Boot manager main routine. --*/ #include "bootmgr.h" -#include "bootlib.h" NTSTATUS BmMain ( - IN PBOOT_INPUT_PARAMETERS InputParameters + IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters ) /*++ @@ -29,7 +28,7 @@ Routine Description: Arguments: - InputParameters - Input parameters for the boot manager. + ApplicationParameters - Input parameters for the boot manager. Return Value: @@ -41,15 +40,16 @@ Return Value: { NTSTATUS Status; BOOT_LIBRARY_PARAMETERS LibraryParameters; - HANDLE DataStore; + HANDLE DataStoreHandle; LibraryParameters.Flags = 0; + LibraryParameters.TranslationType = TRANSLATION_TYPE_NONE; LibraryParameters.MinimumPageAllocation = 16; // // Initialize the boot library. // - Status = BlInitializeLibrary(InputParameters, &LibraryParameters); + Status = BlInitializeLibrary(ApplicationParameters, &LibraryParameters); if (!NT_SUCCESS(Status)) { ConsolePrintf(L"BlInitializeLibrary() failed: 0x%x\r\n", Status); goto Exit; @@ -58,9 +58,7 @@ Return Value: // // Open the boot data store. // - (VOID)BmOpenDataStore(&DataStore); - - while (TRUE); + (VOID)BmOpenDataStore(&DataStoreHandle); Exit: BlDestroyLibrary(); diff --git a/BOOT/ENVIRON/INC/bootlib.h b/BOOT/ENVIRON/INC/bootlib.h index 59969b9..2ff7501 100644 --- a/BOOT/ENVIRON/INC/bootlib.h +++ b/BOOT/ENVIRON/INC/bootlib.h @@ -17,7 +17,243 @@ Abstract: #define _BOOTLIB_H #include -#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 { ULONG Flags; @@ -25,6 +261,121 @@ typedef struct { ULONG MinimumPageAllocation; } 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 ConsolePrint ( IN PWSTR String @@ -39,7 +390,7 @@ ConsolePrintf ( // // Enable/disable debug printing. // -#ifdef _DEBUG +#if defined(_DEBUG) #define DebugPrint(String) ConsolePrint(String) #define DebugPrintf(Format, ...) ConsolePrintf(Format, __VA_ARGS__) #else @@ -47,14 +398,9 @@ ConsolePrintf ( #define DebugPrintf(Format, ...) #endif -ULONG -BlGetBootOptionSize ( - IN PBOOT_APPLICATION_OPTION Option - ); - -ULONG -BlGetBootOptionListSize ( - IN PBOOT_APPLICATION_OPTION Options +VOID +BlpArchGetDescriptorTableContext ( + PDESCRIPTOR_TABLE_CONTEXT Context ); NTSTATUS @@ -75,9 +421,19 @@ BlpMmInitialize ( IN PBOOT_LIBRARY_PARAMETERS LibraryParameters ); +ULONG +BlGetBootOptionSize ( + IN PBOOT_ENTRY_OPTION Option + ); + +ULONG +BlGetBootOptionListSize ( + IN PBOOT_ENTRY_OPTION Options + ); + NTSTATUS BlInitializeLibrary ( - IN PBOOT_INPUT_PARAMETERS InputParameters, + IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters, IN PBOOT_LIBRARY_PARAMETERS LibraryParameters ); diff --git a/BOOT/ENVIRON/INC/bootmgr.h b/BOOT/ENVIRON/INC/bootmgr.h index 6acdf09..7a327b9 100644 --- a/BOOT/ENVIRON/INC/bootmgr.h +++ b/BOOT/ENVIRON/INC/bootmgr.h @@ -16,311 +16,16 @@ Abstract: #ifndef _BOOTMGR_H #define _BOOTMGR_H -#include -#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; +#include "bootlib.h" NTSTATUS BmOpenDataStore ( - IN OUT PHANDLE DataStore + IN OUT PHANDLE Handle ); NTSTATUS BmMain ( - IN PBOOT_INPUT_PARAMETERS InputParameters + IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters ); #endif diff --git a/BOOT/ENVIRON/INC/efilib.h b/BOOT/ENVIRON/INC/efilib.h index 294d95d..1a3851c 100644 --- a/BOOT/ENVIRON/INC/efilib.h +++ b/BOOT/ENVIRON/INC/efilib.h @@ -16,10 +16,17 @@ Abstract: #ifndef _EFILIB_H #define _EFILIB_H -#include "bootmgr.h" +#include "bootlib.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 ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable diff --git a/BOOT/ENVIRON/LIB/EFI/eficon.c b/BOOT/ENVIRON/LIB/EFI/eficon.c index 1251b70..440d8d2 100644 --- a/BOOT/ENVIRON/LIB/EFI/eficon.c +++ b/BOOT/ENVIRON/LIB/EFI/eficon.c @@ -15,7 +15,7 @@ Abstract: #include #include -#include "bootmgr.h" +#include "bootlib.h" extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut; diff --git a/BOOT/ENVIRON/LIB/EFI/efifw.c b/BOOT/ENVIRON/LIB/EFI/efifw.c index 9aa3ad5..7b497b8 100644 --- a/BOOT/ENVIRON/LIB/EFI/efifw.c +++ b/BOOT/ENVIRON/LIB/EFI/efifw.c @@ -14,7 +14,7 @@ Abstract: --*/ #include "bootlib.h" -#include "bootmgr.h" +#include "efi.h" EFI_SYSTEM_TABLE *EfiST; EFI_BOOT_SERVICES *EfiBS; diff --git a/BOOT/ENVIRON/LIB/EFI/efiinit.c b/BOOT/ENVIRON/LIB/EFI/efiinit.c index 4020040..7cae2e6 100644 --- a/BOOT/ENVIRON/LIB/EFI/efiinit.c +++ b/BOOT/ENVIRON/LIB/EFI/efiinit.c @@ -16,9 +16,7 @@ Abstract: #include #include #include -#include "bootlib.h" -#include "bootmgr.h" -#include "efi.h" +#include "efilib.h" UCHAR EfiInitScratch[2048]; const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL; @@ -277,7 +275,7 @@ NTSTATUS EfiInitpConvertEfiDevicePath ( IN EFI_DEVICE_PATH *EfiDevicePath, IN BCDE_DATA_TYPE OptionType, - IN OUT PBOOT_APPLICATION_OPTION Option, + IN OUT PBOOT_ENTRY_OPTION Option, IN ULONG BufferSize ) @@ -309,23 +307,23 @@ Return Value: NTSTATUS Status; 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; } - RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION)); - DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_APPLICATION_OPTION)); + RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION)); + DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_ENTRY_OPTION)); Status = EfiInitTranslateDevicePath( EfiDevicePath, &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)) { return Status; } 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; return STATUS_SUCCESS; @@ -335,7 +333,7 @@ NTSTATUS EfiInitpConvertEfiFilePath ( IN EFI_DEVICE_PATH *EfiFilePath, IN BCDE_DATA_TYPE OptionType, - IN OUT PBOOT_APPLICATION_OPTION Option, + IN OUT PBOOT_ENTRY_OPTION Option, IN ULONG BufferSize ) @@ -368,19 +366,19 @@ Return Value: PWCHAR PathStart, Position; ULONG BufferRemaining, Length, Appended; - if (BufferSize < sizeof(BOOT_APPLICATION_OPTION)) { + if (BufferSize < sizeof(BOOT_ENTRY_OPTION)) { return STATUS_INVALID_PARAMETER; } - RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION)); + RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION)); Option->Type = OptionType; - Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION); + Option->DataOffset = sizeof(BOOT_ENTRY_OPTION); // // Loop through nodes and add one at a time. // Option->DataSize = 0; - BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_OPTION); + BufferRemaining = BufferSize - sizeof(BOOT_ENTRY_OPTION); Node = EfiFilePath; PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset); Position = PathStart; @@ -440,7 +438,7 @@ Return Value: VOID EfiInitpCreateApplicationEntry ( IN EFI_SYSTEM_TABLE *SystemTable, - IN OUT PBOOT_INPUT_APPLICATION_ENTRY Entry, + IN OUT PBOOT_INIT_APPLICATION_ENTRY Entry, IN ULONG BufferSize, IN EFI_DEVICE_PATH *EfiDevicePath, IN EFI_DEVICE_PATH *EfiFilePath, @@ -491,7 +489,7 @@ Return Value: PWCHAR BcdOptionString; BOOLEAN BcdIdentifierSet; UNICODE_STRING UnicodeString; - PBOOT_APPLICATION_OPTION Option, PrevOption; + PBOOT_ENTRY_OPTION Option, PrevOption; PBCDE_DEVICE BootDeviceElement; (VOID)SystemTable; @@ -503,13 +501,13 @@ Return Value: BcdIdentifierSet = FALSE; BufferRemaining = BufferSize; - if (BufferRemaining < sizeof(BOOT_INPUT_APPLICATION_ENTRY)) { + if (BufferRemaining < sizeof(BOOT_INIT_APPLICATION_ENTRY)) { return; } - RtlZeroMemory(Entry, sizeof(BOOT_INPUT_APPLICATION_ENTRY)); - Entry->Signature = BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE; - BufferRemaining -= FIELD_OFFSET(BOOT_INPUT_APPLICATION_ENTRY, Options); + RtlZeroMemory(Entry, sizeof(BOOT_INIT_APPLICATION_ENTRY)); + Entry->Signature = BOOT_INIT_APPLICATION_ENTRY_SIGNATURE; + BufferRemaining -= FIELD_OFFSET(BOOT_INIT_APPLICATION_ENTRY, Options); // // Terminate load options. @@ -530,7 +528,7 @@ Return Value: } 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. // 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); if (!NT_SUCCESS(Status)) { goto exit; @@ -567,7 +565,7 @@ Return Value: // TODO: Parse additional options from LoadOptions. // 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); if (!NT_SUCCESS(Status)) { goto exit; @@ -577,10 +575,11 @@ exit: *BufferUsed = BufferSize - BufferRemaining; } -PBOOT_INPUT_PARAMETERS -EfiInitCreateInputParameters ( +PBOOT_APPLICATION_PARAMETERS +EfiInitCreateInputParametersEx ( 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. + Flags - Unused. + Return Value: Pointer to parameter structure if successful. @@ -603,19 +604,22 @@ Return Value: --*/ { - ULONG ScratchUsed = 0; - ULONG ApplicationEntrySize = 0; EFI_STATUS Status; + ULONG ScratchUsed; + ULONG ApplicationEntrySize; EFI_PHYSICAL_ADDRESS BadPageAddress; EFI_LOADED_IMAGE *LoadedImage; EFI_DEVICE_PATH *DevicePath; - PBOOT_INPUT_PARAMETERS InputParameters; + PBOOT_APPLICATION_PARAMETERS InputParameters; PBOOT_MEMORY_INFO MemoryInfo; PMEMORY_DESCRIPTOR MemoryDescriptor; PBOOT_DEVICE BootDevice; PBOOT_FIRMWARE_DATA FirmwareData; + PBOOT_PLATFORM_DATA PlatformData; PBOOT_RETURN_DATA ReturnData; + ScratchUsed = 0; + // // Page 0x102 may be broken on some machines. // It is mapped here so that it does not get used. @@ -641,12 +645,12 @@ Return Value: return NULL; } - InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]); - ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS); - InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE; - InputParameters->Version = BOOT_INPUT_PARAMETERS_VERSION; + InputParameters = (PBOOT_APPLICATION_PARAMETERS)(&EfiInitScratch[ScratchUsed]); + ScratchUsed += sizeof(BOOT_APPLICATION_PARAMETERS); + InputParameters->Signature = BOOT_APPLICATION_PARAMETERS_SIGNATURE; + InputParameters->Version = BOOT_APPLICATION_PARAMETERS_VERSION; InputParameters->MachineType = BOOT_MACHINE_TYPE; - InputParameters->TranslationType = BOOT_TRANSLATION_TYPE_NONE; + InputParameters->TranslationType = TRANSLATION_TYPE_NONE; InputParameters->ImageBase = LoadedImage->ImageBase; InputParameters->ImageSize = LoadedImage->ImageSize; @@ -669,13 +673,13 @@ Return Value: InputParameters->ApplicationEntryOffset = ScratchUsed; EfiInitpCreateApplicationEntry( SystemTable, - (PBOOT_INPUT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]), + (PBOOT_INIT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]), sizeof(EfiInitScratch) - ScratchUsed, DevicePath, LoadedImage->FilePath, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize, - 0, + Flags, &ApplicationEntrySize, &BootDevice ); @@ -698,6 +702,15 @@ Return Value: FirmwareData->ImageHandle = ImageHandle; 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; ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]); ScratchUsed += sizeof(BOOT_RETURN_DATA); @@ -710,3 +723,32 @@ Return Value: 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); +} diff --git a/BOOT/ENVIRON/LIB/EFI/efilib.c b/BOOT/ENVIRON/LIB/EFI/efilib.c index 229f5ae..94793cc 100644 --- a/BOOT/ENVIRON/LIB/EFI/efilib.c +++ b/BOOT/ENVIRON/LIB/EFI/efilib.c @@ -13,8 +13,7 @@ Abstract: --*/ -#include "bootmgr.h" -#include "efi.h" +#include "efilib.h" EFI_STATUS EfiGetEfiStatusCode ( diff --git a/BOOT/ENVIRON/LIB/EFI/efimm.c b/BOOT/ENVIRON/LIB/EFI/efimm.c index 898b4a3..3119480 100644 --- a/BOOT/ENVIRON/LIB/EFI/efimm.c +++ b/BOOT/ENVIRON/LIB/EFI/efimm.c @@ -13,7 +13,7 @@ Abstract: --*/ -#include "bootmgr.h" +#include "bootlib.h" #include "efi.h" #include "efilib.h" #include "mm.h" diff --git a/BOOT/ENVIRON/LIB/MM/mm.c b/BOOT/ENVIRON/LIB/MM/mm.c index c0a4c91..0562ff6 100644 --- a/BOOT/ENVIRON/LIB/MM/mm.c +++ b/BOOT/ENVIRON/LIB/MM/mm.c @@ -85,8 +85,8 @@ Return Value: // Check TranslationType. // if ( - TranslationType > BOOT_TRANSLATION_TYPE_MAX || - LibraryParameters->TranslationType > BOOT_TRANSLATION_TYPE_MAX + TranslationType > TRANSLATION_TYPE_MAX || + LibraryParameters->TranslationType > TRANSLATION_TYPE_MAX ) { DebugPrint(L"BlpMmInitialize(): TranslationType is invalid\r\n"); return STATUS_INVALID_PARAMETER; diff --git a/BOOT/ENVIRON/LIB/MM/mmmd.c b/BOOT/ENVIRON/LIB/MM/mmmd.c index 6d154ab..438fcc9 100644 --- a/BOOT/ENVIRON/LIB/MM/mmmd.c +++ b/BOOT/ENVIRON/LIB/MM/mmmd.c @@ -14,7 +14,7 @@ Abstract: --*/ #include -#include "bootmgr.h" +#include "bootlib.h" #include "mm.h" #define MAX_STATIC_DESCRIPTOR_COUNT 1024 diff --git a/BOOT/ENVIRON/LIB/X86/arch.c b/BOOT/ENVIRON/LIB/X86/arch.c new file mode 100644 index 0000000..cbb6267 --- /dev/null +++ b/BOOT/ENVIRON/LIB/X86/arch.c @@ -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 +#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; +} \ No newline at end of file diff --git a/BOOT/ENVIRON/LIB/X86/ctx.S b/BOOT/ENVIRON/LIB/X86/ctx.S new file mode 100644 index 0000000..2cbe98a --- /dev/null +++ b/BOOT/ENVIRON/LIB/X86/ctx.S @@ -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 diff --git a/BOOT/ENVIRON/LIB/bootlib.c b/BOOT/ENVIRON/LIB/bootlib.c index 7713878..ce7e6e8 100644 --- a/BOOT/ENVIRON/LIB/bootlib.c +++ b/BOOT/ENVIRON/LIB/bootlib.c @@ -17,19 +17,21 @@ Abstract: #include "bootlib.h" #define MIN_INPUT_PARAMETERS_SIZE ( \ - sizeof(BOOT_INPUT_PARAMETERS) + \ + sizeof(BOOT_APPLICATION_PARAMETERS) + \ sizeof(BOOT_MEMORY_INFO) + \ + sizeof(BOOT_INIT_APPLICATION_ENTRY) + \ sizeof(BOOT_FIRMWARE_DATA) + \ sizeof(BOOT_RETURN_DATA) \ ) -PBOOT_INPUT_PARAMETERS BlpApplicationParameters; -BOOT_APPLICATION_ENTRY BlpApplicationEntry; PBOOT_DEVICE BlpBootDevice; +PBOOT_APPLICATION_PARAMETERS BlpApplicationParameters; +BOOT_LIBRARY_PARAMETERS BlpLibraryParameters; +BOOT_APPLICATION_ENTRY BlpApplicationEntry; NTSTATUS InitializeLibrary ( - IN PBOOT_INPUT_PARAMETERS InputParameters, + IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters, IN PBOOT_LIBRARY_PARAMETERS LibraryParameters ) @@ -41,7 +43,7 @@ Routine Description: Arguments: - InputParameters - Pointer to the application's input parameters. + ApplicationParameters - Pointer to the application's input parameters. LibraryParameters - Pointer to the library parameters. @@ -54,23 +56,21 @@ Return Value: { NTSTATUS Status; PBOOT_MEMORY_INFO MemoryInfo; - PBOOT_INPUT_APPLICATION_ENTRY ApplicationEntry; + PBOOT_INIT_APPLICATION_ENTRY ApplicationEntry; PBOOT_FIRMWARE_DATA FirmwareData; - PBOOT_BLOCK_IDENTIFIER BlockDevice; - PBOOT_APPLICATION_OPTION Option; (VOID)LibraryParameters; - if (InputParameters == NULL || - InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE || - InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) { + if (ApplicationParameters == NULL || + ApplicationParameters->Signature != BOOT_APPLICATION_PARAMETERS_SIGNATURE || + ApplicationParameters->Size < MIN_INPUT_PARAMETERS_SIZE) { return STATUS_INVALID_PARAMETER; } - MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)InputParameters + InputParameters->MemoryInfoOffset); - ApplicationEntry = (PBOOT_INPUT_APPLICATION_ENTRY)((PUCHAR)InputParameters + InputParameters->ApplicationEntryOffset); - BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)InputParameters + InputParameters->BootDeviceOffset); - FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)InputParameters + InputParameters->FirmwareDataOffset); + MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)ApplicationParameters + ApplicationParameters->MemoryInfoOffset); + ApplicationEntry = (PBOOT_INIT_APPLICATION_ENTRY)((PUCHAR)ApplicationParameters + ApplicationParameters->ApplicationEntryOffset); + BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)ApplicationParameters + ApplicationParameters->BootDeviceOffset); + FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)ApplicationParameters + ApplicationParameters->FirmwareDataOffset); // // Initialize firmware library. @@ -83,24 +83,28 @@ Return Value: } 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"); - 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"); 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; RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID)); BlpApplicationEntry.Options = &ApplicationEntry->Options; - Status = BlpMmInitialize(MemoryInfo, InputParameters->TranslationType, LibraryParameters); + Status = BlpMmInitialize(MemoryInfo, ApplicationParameters->TranslationType, LibraryParameters); if (!NT_SUCCESS(Status)) { return Status; } @@ -110,7 +114,7 @@ Return Value: NTSTATUS BlInitializeLibrary ( - IN PBOOT_INPUT_PARAMETERS InputParameters, + IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters, IN PBOOT_LIBRARY_PARAMETERS LibraryParameters ) @@ -122,7 +126,7 @@ Routine Description: Arguments: - InputParameters - Pointer to the application's input parameters. + ApplicationParameters - Pointer to the application's input parameters. LibraryParameters - Pointer to the library parameters. @@ -133,7 +137,7 @@ Return Value: --*/ { - return InitializeLibrary(InputParameters, LibraryParameters); + return InitializeLibrary(ApplicationParameters, LibraryParameters); } NTSTATUS diff --git a/BOOT/ENVIRON/LIB/bootopt.c b/BOOT/ENVIRON/LIB/bootopt.c index b2be785..4b3ec84 100644 --- a/BOOT/ENVIRON/LIB/bootopt.c +++ b/BOOT/ENVIRON/LIB/bootopt.c @@ -17,7 +17,7 @@ Abstract: ULONG BlGetBootOptionSize ( - IN PBOOT_APPLICATION_OPTION Option + IN PBOOT_ENTRY_OPTION Option ) /*++ @@ -42,11 +42,11 @@ Return Value: if (Option->DataOffset != 0) { TotalSize = Option->DataOffset + Option->DataSize; } else { - TotalSize = sizeof(BOOT_APPLICATION_OPTION); + TotalSize = sizeof(BOOT_ENTRY_OPTION); } if (Option->OtherOptionsOffset != 0) { - TotalSize += BlGetBootOptionListSize((PBOOT_APPLICATION_OPTION)((PUCHAR)Option + Option->OtherOptionsOffset)); + TotalSize += BlGetBootOptionListSize((PBOOT_ENTRY_OPTION)((PUCHAR)Option + Option->OtherOptionsOffset)); } return TotalSize; @@ -54,7 +54,7 @@ Return Value: ULONG BlGetBootOptionListSize ( - IN PBOOT_APPLICATION_OPTION Options + IN PBOOT_ENTRY_OPTION Options ) /*++ @@ -75,12 +75,12 @@ Return Value: { ULONG TotalSize, NextOffset; - PBOOT_APPLICATION_OPTION Option; + PBOOT_ENTRY_OPTION Option; TotalSize = 0; NextOffset = 0; do { - Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)Options + NextOffset); + Option = (PBOOT_ENTRY_OPTION)((PUCHAR)Options + NextOffset); NextOffset = Option->NextOptionOffset; TotalSize += BlGetBootOptionSize(Option); } while (NextOffset != 0); diff --git a/BOOT/ENVIRON/README.md b/BOOT/ENVIRON/README.md index 70d61cc..2a87229 100644 --- a/BOOT/ENVIRON/README.md +++ b/BOOT/ENVIRON/README.md @@ -13,6 +13,7 @@ | LIB/EFI/eficon.c | ConsoleXX() | | LIB/EFI/efilib.c | EfiGetEfiStatusCode() | | LIB/MM/mm.c | BlpMmXX() | +| LIB/MM/mmmd.c | MmMdXX() | | LIB/MM/mmpa.c | MmPaXX() | | LIB/bootlib.c | BlXXLibrary() | | LIB/bootopt.c | BlXXBootOptionXX() |