diff --git a/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c b/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c index 5d4f893..4f8271c 100644 --- a/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c +++ b/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c @@ -44,6 +44,7 @@ Return Value: HANDLE DataStore; LibraryParameters.Flags = 0; + LibraryParameters.MinimumPageAllocation = 16; // // Initialize the boot library. diff --git a/BOOT/ENVIRON/INC/bootlib.h b/BOOT/ENVIRON/INC/bootlib.h index d45d80c..b0973f1 100644 --- a/BOOT/ENVIRON/INC/bootlib.h +++ b/BOOT/ENVIRON/INC/bootlib.h @@ -21,6 +21,8 @@ Abstract: typedef struct { ULONG Flags; + ULONG TranslationType; + ULONG MinimumPageAllocation; } BOOT_LIBRARY_PARAMETERS, *PBOOT_LIBRARY_PARAMETERS; VOID @@ -61,6 +63,13 @@ BlpFwInitialize ( IN PBOOT_FIRMWARE_DATA FirmwareData ); +NTSTATUS +BlpMmInitialize ( + IN PBOOT_MEMORY_INFO MemoryInfo, + IN ULONG TranslationType, + IN PBOOT_LIBRARY_PARAMETERS LibraryParameters + ); + NTSTATUS BlInitializeLibrary ( IN PBOOT_INPUT_PARAMETERS InputParameters, diff --git a/BOOT/ENVIRON/INC/bootmgr.h b/BOOT/ENVIRON/INC/bootmgr.h index 17e3321..0defc42 100644 --- a/BOOT/ENVIRON/INC/bootmgr.h +++ b/BOOT/ENVIRON/INC/bootmgr.h @@ -28,17 +28,18 @@ Abstract: #define BOOT_MACHINE_TYPE IMAGE_FILE_MACHINE_I386 #endif -// -// No address translation. -// -#define BOOT_TRANSLATION_TYPE 0 - // // Use EFI page size. // #define PAGE_SIZE EFI_PAGE_SIZE #define PAGE_SHIFT EFI_PAGE_SHIFT +// +// 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 @@ -122,6 +123,19 @@ typedef struct { ULONG Type; } BOOT_MEMORY_DESCRIPTOR, *PBOOT_MEMORY_DESCRIPTOR; +typedef enum { + MDL_TYPE_PHYSICAL, + MDL_TYPE_VIRTUAL +} BOOT_MEMORY_DESCRIPTOR_LIST_TYPE; + +typedef struct { + LIST_ENTRY ListEntry; + + PVOID Head; + PVOID Current; + BOOT_MEMORY_DESCRIPTOR_LIST_TYPE Type; +} BOOT_MEMORY_DESCRIPTOR_LIST, *PBOOT_MEMORY_DESCRIPTOR_LIST; + #define BOOT_FIRMWARE_DATA_VERSION 2 typedef struct { @@ -240,6 +254,10 @@ typedef struct { }; } 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 diff --git a/BOOT/ENVIRON/INC/mm.h b/BOOT/ENVIRON/INC/mm.h new file mode 100644 index 0000000..9dec7de --- /dev/null +++ b/BOOT/ENVIRON/INC/mm.h @@ -0,0 +1,27 @@ +/*++ + +Copyright (c) 2024, Quinn Stephens. +Provided under the BSD 3-Clause license. + +Module Name: + + mm.h + +Abstract: + + Boot memory manager definitions. + +--*/ + +#ifndef _MM_H +#define _MM_H + +#include "bootlib.h" + +NTSTATUS +MmPaInitialize ( + IN PBOOT_MEMORY_INFO MemoryInfo, + IN ULONG MinimumAllocation + ); + +#endif diff --git a/BOOT/ENVIRON/LIB/EFI/efiinit.c b/BOOT/ENVIRON/LIB/EFI/efiinit.c index 8311456..58ee453 100644 --- a/BOOT/ENVIRON/LIB/EFI/efiinit.c +++ b/BOOT/ENVIRON/LIB/EFI/efiinit.c @@ -680,7 +680,7 @@ Return Value: InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE; InputParameters->Version = BOOT_INPUT_PARAMETERS_VERSION; InputParameters->MachineType = BOOT_MACHINE_TYPE; - InputParameters->TranslationType = BOOT_TRANSLATION_TYPE; + InputParameters->TranslationType = BOOT_TRANSLATION_TYPE_NONE; InputParameters->ImageBase = LoadedImage->ImageBase; InputParameters->ImageSize = LoadedImage->ImageSize; diff --git a/BOOT/ENVIRON/LIB/MM/mm.c b/BOOT/ENVIRON/LIB/MM/mm.c new file mode 100644 index 0000000..ec36542 --- /dev/null +++ b/BOOT/ENVIRON/LIB/MM/mm.c @@ -0,0 +1,87 @@ +/*++ + +Copyright (c) 2024, Quinn Stephens. +Provided under the BSD 3-Clause license. + +Module Name: + + mm.c + +Abstract: + + Provides boot library memory manager routines. + +--*/ + +#include +#include "bootlib.h" +#include "mm.h" + +#define MAX_STATIC_DESCRIPTOR_COUNT 1024 + +BOOT_MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT]; +PBOOT_MEMORY_DESCRIPTOR MmGlobalMemoryDescriptors; +ULONG MmGlobalMemoryDescriptorCount; + +NTSTATUS +BlpMmInitialize ( + IN PBOOT_MEMORY_INFO MemoryInfo, + IN ULONG TranslationType, + IN PBOOT_LIBRARY_PARAMETERS LibraryParameters + ) + +/*++ + +Routine Description: + + Initializes the boot memory manager. + +Arguments: + + MemoryInfo - pointer to the memory info structure. + + TranslationType - the current translation type being used. + + LibraryParameters - pointer to the library parameters structure. + +Return Value: + + STATUS_SUCCESS if successful, + STATUS_INVALID_PARAMETER if TranslationType is invalid, + Other NTSTATUS value if an error occurs. + +--*/ + +{ + NTSTATUS Status; + + DebugPrint(L"Initializing memory manager...\r\n"); + + // + // Check TranslationType. + // + if ( + TranslationType > BOOT_TRANSLATION_TYPE_MAX || + LibraryParameters->TranslationType > BOOT_TRANSLATION_TYPE_MAX + ) { + DebugPrint(L"BlpMmInitialize(): TranslationType is invalid\r\n"); + return STATUS_INVALID_PARAMETER; + } + + // + // Initialize memory descriptors. + // + MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0]; + MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT; + RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(BOOT_MEMORY_DESCRIPTOR)); + + // + // Initialize the page allocator. + // + Status = MmPaInitialize(MemoryInfo, LibraryParameters->MinimumPageAllocation); + if (!NT_SUCCESS(Status)) { + return Status; + } + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/BOOT/ENVIRON/LIB/MM/mmpa.c b/BOOT/ENVIRON/LIB/MM/mmpa.c new file mode 100644 index 0000000..a759219 --- /dev/null +++ b/BOOT/ENVIRON/LIB/MM/mmpa.c @@ -0,0 +1,120 @@ +/*++ + +Copyright (c) 2024, Quinn Stephens. +Provided under the BSD 3-Clause license. + +Module Name: + + mmpa.c + +Abstract: + + Provides memory manager page routines. + +--*/ + +#include "bootlib.h" +#include "mm.h" + +ULONG PapMinimumAllocationCount; +ULONGLONG PapMinimumPhysicalPage; +ULONGLONG PapMaximumPhysicalPage; + +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlBadMemory; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated; +BOOT_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated; + +FORCEINLINE +VOID +InitializeList ( + IN PBOOT_MEMORY_DESCRIPTOR_LIST List + ) + +/*++ + +Routine Description: + + Initializes a MDL. + +Arguments: + + List - the MDL to initialize. + +Return Value: + + None. + +--*/ + +{ + List->Head = NULL; + List->Current = NULL; + List->Type = MDL_TYPE_PHYSICAL; +} + +NTSTATUS +MmPaInitialize ( + IN PBOOT_MEMORY_INFO MemoryInfo, + IN ULONG MinimumAllocation + ) + +/*++ + +Routine Description: + + Initializes the page allocator. + +Arguments: + + MemoryInfo - pointer to the memory info structure. + + MinimumAllocation - minimum amount of pages to grow the pool by at a time. + +Return Value: + + STATUS_SUCCESS if successful, + +--*/ + +{ + (VOID)MemoryInfo; + + DebugPrint(L"Initializing page allocator...\r\n"); + + // + // Initialize page allocator settings. + // + PapMinimumAllocationCount = MinimumAllocation; + PapMinimumPhysicalPage = 1; + PapMaximumPhysicalPage = MAXULONGLONG >> PAGE_SHIFT; + DebugPrintf(L"Maximum physical page: %x %x\r\n", (ULONG)(PapMaximumPhysicalPage >> 32), (ULONG)(PapMaximumPhysicalPage)); + + // + // Initialize MDLs. + // + InitializeList(&MmMdlFwAllocationTracker); + InitializeList(&MmMdlBadMemory); + InitializeList(&MmMdlTruncatedMemory); + InitializeList(&MmMdlPersistentMemory); + InitializeList(&MmMdlReservedAllocated);; + InitializeList(&MmMdlMappedAllocated); + InitializeList(&MmMdlMappedUnallocated); + InitializeList(&MmMdlUnmappedAllocated); + InitializeList(&MmMdlUnmappedUnallocated); + + // + // Get the firmware memory map. + // + // Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, 0x03); + // if (!NT_SUCCESS(Status)) { + // return Status; + // } + + return STATUS_SUCCESS; +} diff --git a/BOOT/ENVIRON/LIB/bootlib.c b/BOOT/ENVIRON/LIB/bootlib.c index aa6fbc8..9f2e089 100644 --- a/BOOT/ENVIRON/LIB/bootlib.c +++ b/BOOT/ENVIRON/LIB/bootlib.c @@ -56,6 +56,7 @@ Return Value: { NTSTATUS Status; + PBOOT_MEMORY_INFO MemoryInfo; PBOOT_INPUT_APPLICATION_ENTRY ApplicationEntry; PBOOT_FIRMWARE_DATA FirmwareData; PBOOT_BLOCK_IDENTIFIER BlockDevice; @@ -75,6 +76,7 @@ Return Value: // // Calculate structure addresses from offsets. // + 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); @@ -99,7 +101,7 @@ Return Value: // Check application entry signature. // if (ApplicationEntry->Signature != BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE) { - DebugPrint(L"Application entry signature is invalid\r\n"); + DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n"); return STATUS_INVALID_PARAMETER_9; } @@ -111,6 +113,14 @@ Return Value: RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID)); BlpApplicationEntry.Options = &ApplicationEntry->Options; + // + // Initialize memory manager. + // + Status = BlpMmInitialize(MemoryInfo, InputParameters->TranslationType, LibraryParameters); + if (!NT_SUCCESS(Status)) { + return Status; + } + // // Print debug information. // TODO: Remove this once the project is more stable?