diff --git a/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c b/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c index 4f8271c..d69155a 100644 --- a/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c +++ b/BOOT/ENVIRON/APP/BOOTMGR/bootmgr.c @@ -60,6 +60,8 @@ Return Value: // (VOID)BmOpenDataStore(&DataStore); + while (TRUE); + Exit: BlDestroyLibrary(); return Status; diff --git a/BOOT/ENVIRON/INC/bootmgr.h b/BOOT/ENVIRON/INC/bootmgr.h index 0defc42..43acb26 100644 --- a/BOOT/ENVIRON/INC/bootmgr.h +++ b/BOOT/ENVIRON/INC/bootmgr.h @@ -121,20 +121,20 @@ typedef struct { ULONG Attributes; ULONG Type; -} BOOT_MEMORY_DESCRIPTOR, *PBOOT_MEMORY_DESCRIPTOR; +} MEMORY_DESCRIPTOR, *PMEMORY_DESCRIPTOR; typedef enum { MDL_TYPE_PHYSICAL, MDL_TYPE_VIRTUAL -} BOOT_MEMORY_DESCRIPTOR_LIST_TYPE; +} 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; + PLIST_ENTRY Head; + PLIST_ENTRY Current; + MEMORY_DESCRIPTOR_LIST_TYPE Type; +} MEMORY_DESCRIPTOR_LIST, *PMEMORY_DESCRIPTOR_LIST; #define BOOT_FIRMWARE_DATA_VERSION 2 diff --git a/BOOT/ENVIRON/INC/efilib.h b/BOOT/ENVIRON/INC/efilib.h index ebdebc2..90feb6c 100644 --- a/BOOT/ENVIRON/INC/efilib.h +++ b/BOOT/ENVIRON/INC/efilib.h @@ -16,7 +16,6 @@ Abstract: #ifndef _EFILIB_H #define _EFILIB_H -#include #include "bootmgr.h" #include "efi.h" diff --git a/BOOT/ENVIRON/INC/mm.h b/BOOT/ENVIRON/INC/mm.h index 9dec7de..654fa68 100644 --- a/BOOT/ENVIRON/INC/mm.h +++ b/BOOT/ENVIRON/INC/mm.h @@ -18,6 +18,34 @@ Abstract: #include "bootlib.h" +NTSTATUS +MmFwGetMemoryMap ( + IN OUT PMEMORY_DESCRIPTOR_LIST Mdl, + IN ULONG Flags + ); + +VOID +MmMdRemoveDescriptorFromList ( + IN PMEMORY_DESCRIPTOR_LIST Mdl, + IN PMEMORY_DESCRIPTOR Descriptor + ); + +NTSTATUS +MmMdFreeDescriptor ( + IN PMEMORY_DESCRIPTOR Descriptor + ); + +VOID +MmMdFreeList ( + IN PMEMORY_DESCRIPTOR_LIST Mdl + ); + +VOID +MmMdInitialize ( + IN ULONG Unused, + IN PBOOT_LIBRARY_PARAMETERS LibraryParameters + ); + NTSTATUS MmPaInitialize ( IN PBOOT_MEMORY_INFO MemoryInfo, diff --git a/BOOT/ENVIRON/LIB/EFI/efiinit.c b/BOOT/ENVIRON/LIB/EFI/efiinit.c index 58ee453..f8f520b 100644 --- a/BOOT/ENVIRON/LIB/EFI/efiinit.c +++ b/BOOT/ENVIRON/LIB/EFI/efiinit.c @@ -636,7 +636,7 @@ Return Value: EFI_DEVICE_PATH *DevicePath; PBOOT_INPUT_PARAMETERS InputParameters; PBOOT_MEMORY_INFO MemoryInfo; - PBOOT_MEMORY_DESCRIPTOR MemoryDescriptor; + PMEMORY_DESCRIPTOR MemoryDescriptor; PBOOT_DEVICE BootDevice; PBOOT_FIRMWARE_DATA FirmwareData; PBOOT_RETURN_DATA ReturnData; @@ -693,14 +693,14 @@ Return Value: MemoryInfo->Version = BOOT_MEMORY_INFO_VERSION; MemoryInfo->MdlOffset = sizeof(BOOT_MEMORY_INFO); MemoryInfo->DescriptorCount = 1; - MemoryInfo->DescriptorSize = sizeof(BOOT_MEMORY_DESCRIPTOR); - MemoryInfo->BasePageOffset = FIELD_OFFSET(BOOT_MEMORY_DESCRIPTOR, BasePage); + MemoryInfo->DescriptorSize = sizeof(MEMORY_DESCRIPTOR); + MemoryInfo->BasePageOffset = FIELD_OFFSET(MEMORY_DESCRIPTOR, BasePage); // // Create a memory descriptor for the boot manager image. // - MemoryDescriptor = (PBOOT_MEMORY_DESCRIPTOR)(&EfiInitScratch[ScratchUsed]); - ScratchUsed += sizeof(BOOT_MEMORY_DESCRIPTOR); + MemoryDescriptor = (PMEMORY_DESCRIPTOR)(&EfiInitScratch[ScratchUsed]); + ScratchUsed += sizeof(MEMORY_DESCRIPTOR); MemoryDescriptor->BasePage = (UINTN)InputParameters->ImageBase >> PAGE_SHIFT; MemoryDescriptor->Pages = ALIGN_UP(InputParameters->ImageSize, PAGE_SIZE) >> PAGE_SHIFT; MemoryDescriptor->Attributes = MEMORY_ATTRIBUTE_CACHE_WB; diff --git a/BOOT/ENVIRON/LIB/EFI/efimm.c b/BOOT/ENVIRON/LIB/EFI/efimm.c new file mode 100644 index 0000000..3ec6031 --- /dev/null +++ b/BOOT/ENVIRON/LIB/EFI/efimm.c @@ -0,0 +1,56 @@ +/*++ + +Copyright (c) 2024, Quinn Stephens. +Provided under the BSD 3-Clause license. + +Module Name: + + efimm.c + +Abstract: + + Provides EFI memory manager routines. + +--*/ + +#include "bootmgr.h" +#include "efi.h" +#include "mm.h" + +NTSTATUS +MmFwGetMemoryMap ( + IN OUT PMEMORY_DESCRIPTOR_LIST Mdl, + IN ULONG Flags + ) + +/*++ + +Routine Description: + + Converts an NT status code into an EFI status code. + +Arguments: + + Status - The NT status code to be converted. + +Return Value: + + STATUS_SUCCESS if successful, + STATUS_INVALID_PARAMETER if Mdl is invalid. + +--*/ + +{ + (VOID)Flags; + + // + // Make sure Mdl is valid. + // + if (Mdl == NULL) { + return STATUS_INVALID_PARAMETER; + } + + MmMdFreeList(Mdl); + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/BOOT/ENVIRON/LIB/MM/mm.c b/BOOT/ENVIRON/LIB/MM/mm.c index ec36542..703f0c0 100644 --- a/BOOT/ENVIRON/LIB/MM/mm.c +++ b/BOOT/ENVIRON/LIB/MM/mm.c @@ -17,12 +17,6 @@ Abstract: #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, @@ -69,14 +63,12 @@ Return Value: } // - // Initialize memory descriptors. + // Initialize memory descriptor manager. // - MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0]; - MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT; - RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(BOOT_MEMORY_DESCRIPTOR)); + MmMdInitialize(0, LibraryParameters); // - // Initialize the page allocator. + // Initialize page allocator. // Status = MmPaInitialize(MemoryInfo, LibraryParameters->MinimumPageAllocation); if (!NT_SUCCESS(Status)) { diff --git a/BOOT/ENVIRON/LIB/MM/mmmd.c b/BOOT/ENVIRON/LIB/MM/mmmd.c new file mode 100644 index 0000000..9205983 --- /dev/null +++ b/BOOT/ENVIRON/LIB/MM/mmmd.c @@ -0,0 +1,206 @@ +/*++ + +Copyright (c) 2024, Quinn Stephens. +Provided under the BSD 3-Clause license. + +Module Name: + + mmmd.c + +Abstract: + + Provides memory descriptor routines. + +--*/ + +#include +#include "bootmgr.h" +#include "mm.h" + +#define MAX_STATIC_DESCRIPTOR_COUNT 1024 + +MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT]; + +PMEMORY_DESCRIPTOR MmGlobalMemoryDescriptors; +ULONG MmGlobalMemoryDescriptorCount; + +PMEMORY_DESCRIPTOR MmDynamicMemoryDescriptors; +ULONG MmDynamicMemoryDescriptorCount; + +VOID +MmMdRemoveDescriptorFromList ( + IN PMEMORY_DESCRIPTOR_LIST Mdl, + IN PMEMORY_DESCRIPTOR Descriptor + ) + +/*++ + +Routine Description: + + Removes a descriptor from a MDL. + +Arguments: + + Mdl - the MDL to remove Descriptor from. + + Descriptor - the descriptor to remove from Mdl. + +Return Value: + + None. + +--*/ + +{ + PLIST_ENTRY Blink; + + Blink = Descriptor->ListEntry.Blink; + + // + // Remove the descriptor from the MDL. + // + RemoveEntryList(&Descriptor->ListEntry); + + // + // Check if the removed descriptor was cached. + // + if (Mdl->Current != &Descriptor->ListEntry) { + return; + } + + // + // Cache the previous descriptor if possible. + // + if ( + ( + (ULONG_PTR)Blink < (ULONG_PTR)MmGlobalMemoryDescriptors + || (ULONG_PTR)Blink >= (ULONG_PTR)&MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorCount] + ) + && Blink != Mdl->Head + ) { + Mdl->Current = Blink; + } else { + Mdl->Current = NULL; + } +} + +NTSTATUS +MmMdFreeDescriptor ( + IN PMEMORY_DESCRIPTOR Descriptor + ) + +/*++ + +Routine Description: + + Frees a memory descriptor. + +Arguments: + + Descriptor - the descriptor to free. + +Return Value: + + STATUS_SUCCESS if successful, + other NTSTATUS value if an error occurs. + +--*/ + +{ + if ( + ( + MmDynamicMemoryDescriptors != NULL + && (ULONG_PTR)Descriptor >= (ULONG_PTR)MmDynamicMemoryDescriptors + && (ULONG_PTR)Descriptor <= (ULONG_PTR)&MmDynamicMemoryDescriptors[MmDynamicMemoryDescriptorCount] + ) + || ( + (ULONG_PTR)Descriptor >= (ULONG_PTR)MmStaticMemoryDescriptors + && (ULONG_PTR)Descriptor <= (ULONG_PTR)&MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT] + ) + ) { + // + // Clear the descriptor from static/dynamic MDL. + // + RtlZeroMemory(Descriptor, sizeof(MEMORY_DESCRIPTOR)); + return STATUS_SUCCESS; + } + + // + // Free the descriptor from the heap. + // TODO: Use BlMmFreeHeap() + // + ConsolePrint(L"Cannot free memory descriptor: BlMmFreeHeap() is not implemented\r\n"); + return STATUS_NOT_IMPLEMENTED; + // return BlMmFreeHeap(Descriptor); +} + +VOID +MmMdFreeList ( + IN PMEMORY_DESCRIPTOR_LIST Mdl + ) + +/*++ + +Routine Description: + + Frees a memory descriptor list (MDL). + +Arguments: + + Mdl - the MDL to free. + +Return Value: + + None. + +--*/ + +{ + PLIST_ENTRY Entry; + + Entry = Mdl->Head->Flink; + while (Entry != Mdl->Head) { + MmMdRemoveDescriptorFromList(Mdl, (PMEMORY_DESCRIPTOR)Entry); + MmMdFreeDescriptor((PMEMORY_DESCRIPTOR)Entry); + Entry = Entry->Flink; + } +} + +VOID +MmMdInitialize ( + IN ULONG Unused, + IN PBOOT_LIBRARY_PARAMETERS LibraryParameters + ) + +/*++ + +Routine Description: + + Initializes the memory descriptor manager. + +Arguments: + + Unused - Ignored. + + LibraryParameters - pointer to the library parameters structure. + +Return Value: + + None. + +--*/ + +{ + (VOID)Unused; + (VOID)LibraryParameters; + + DebugPrint(L"Initializing memory descriptor manager...\r\n"); + + // + // Initialize global memory descriptor list. + // + MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0]; + MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT; + RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(MEMORY_DESCRIPTOR)); + DebugPrintf(L"Global memory descriptor count: %x\r\n", MmGlobalMemoryDescriptorCount); +} diff --git a/BOOT/ENVIRON/LIB/MM/mmpa.c b/BOOT/ENVIRON/LIB/MM/mmpa.c index a759219..ac25292 100644 --- a/BOOT/ENVIRON/LIB/MM/mmpa.c +++ b/BOOT/ENVIRON/LIB/MM/mmpa.c @@ -20,20 +20,20 @@ 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; +MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker; +MEMORY_DESCRIPTOR_LIST MmMdlBadMemory; +MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory; +MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory; +MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated; +MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated; +MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated; +MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated; +MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated; FORCEINLINE VOID InitializeList ( - IN PBOOT_MEMORY_DESCRIPTOR_LIST List + IN PMEMORY_DESCRIPTOR_LIST List ) /*++ @@ -83,6 +83,8 @@ Return Value: --*/ { + NTSTATUS Status; + (VOID)MemoryInfo; DebugPrint(L"Initializing page allocator...\r\n"); @@ -111,10 +113,10 @@ Return Value: // // Get the firmware memory map. // - // Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, 0x03); - // if (!NT_SUCCESS(Status)) { - // return Status; - // } + Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, 0x03); + if (!NT_SUCCESS(Status)) { + return Status; + } return STATUS_SUCCESS; }