[BOOT:MM] More work on memory manager

This commit is contained in:
Quinn Stephens 2024-08-26 12:30:31 -04:00
parent bbd8f475bb
commit ef1ac515dd
9 changed files with 322 additions and 37 deletions

View File

@ -60,6 +60,8 @@ Return Value:
// //
(VOID)BmOpenDataStore(&DataStore); (VOID)BmOpenDataStore(&DataStore);
while (TRUE);
Exit: Exit:
BlDestroyLibrary(); BlDestroyLibrary();
return Status; return Status;

View File

@ -121,20 +121,20 @@ typedef struct {
ULONG Attributes; ULONG Attributes;
ULONG Type; ULONG Type;
} BOOT_MEMORY_DESCRIPTOR, *PBOOT_MEMORY_DESCRIPTOR; } MEMORY_DESCRIPTOR, *PMEMORY_DESCRIPTOR;
typedef enum { typedef enum {
MDL_TYPE_PHYSICAL, MDL_TYPE_PHYSICAL,
MDL_TYPE_VIRTUAL MDL_TYPE_VIRTUAL
} BOOT_MEMORY_DESCRIPTOR_LIST_TYPE; } MEMORY_DESCRIPTOR_LIST_TYPE;
typedef struct { typedef struct {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
PVOID Head; PLIST_ENTRY Head;
PVOID Current; PLIST_ENTRY Current;
BOOT_MEMORY_DESCRIPTOR_LIST_TYPE Type; MEMORY_DESCRIPTOR_LIST_TYPE Type;
} BOOT_MEMORY_DESCRIPTOR_LIST, *PBOOT_MEMORY_DESCRIPTOR_LIST; } MEMORY_DESCRIPTOR_LIST, *PMEMORY_DESCRIPTOR_LIST;
#define BOOT_FIRMWARE_DATA_VERSION 2 #define BOOT_FIRMWARE_DATA_VERSION 2

View File

@ -16,7 +16,6 @@ Abstract:
#ifndef _EFILIB_H #ifndef _EFILIB_H
#define _EFILIB_H #define _EFILIB_H
#include <nt.h>
#include "bootmgr.h" #include "bootmgr.h"
#include "efi.h" #include "efi.h"

View File

@ -18,6 +18,34 @@ Abstract:
#include "bootlib.h" #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 NTSTATUS
MmPaInitialize ( MmPaInitialize (
IN PBOOT_MEMORY_INFO MemoryInfo, IN PBOOT_MEMORY_INFO MemoryInfo,

View File

@ -636,7 +636,7 @@ Return Value:
EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH *DevicePath;
PBOOT_INPUT_PARAMETERS InputParameters; PBOOT_INPUT_PARAMETERS InputParameters;
PBOOT_MEMORY_INFO MemoryInfo; PBOOT_MEMORY_INFO MemoryInfo;
PBOOT_MEMORY_DESCRIPTOR MemoryDescriptor; PMEMORY_DESCRIPTOR MemoryDescriptor;
PBOOT_DEVICE BootDevice; PBOOT_DEVICE BootDevice;
PBOOT_FIRMWARE_DATA FirmwareData; PBOOT_FIRMWARE_DATA FirmwareData;
PBOOT_RETURN_DATA ReturnData; PBOOT_RETURN_DATA ReturnData;
@ -693,14 +693,14 @@ Return Value:
MemoryInfo->Version = BOOT_MEMORY_INFO_VERSION; MemoryInfo->Version = BOOT_MEMORY_INFO_VERSION;
MemoryInfo->MdlOffset = sizeof(BOOT_MEMORY_INFO); MemoryInfo->MdlOffset = sizeof(BOOT_MEMORY_INFO);
MemoryInfo->DescriptorCount = 1; MemoryInfo->DescriptorCount = 1;
MemoryInfo->DescriptorSize = sizeof(BOOT_MEMORY_DESCRIPTOR); MemoryInfo->DescriptorSize = sizeof(MEMORY_DESCRIPTOR);
MemoryInfo->BasePageOffset = FIELD_OFFSET(BOOT_MEMORY_DESCRIPTOR, BasePage); MemoryInfo->BasePageOffset = FIELD_OFFSET(MEMORY_DESCRIPTOR, BasePage);
// //
// Create a memory descriptor for the boot manager image. // Create a memory descriptor for the boot manager image.
// //
MemoryDescriptor = (PBOOT_MEMORY_DESCRIPTOR)(&EfiInitScratch[ScratchUsed]); MemoryDescriptor = (PMEMORY_DESCRIPTOR)(&EfiInitScratch[ScratchUsed]);
ScratchUsed += sizeof(BOOT_MEMORY_DESCRIPTOR); ScratchUsed += sizeof(MEMORY_DESCRIPTOR);
MemoryDescriptor->BasePage = (UINTN)InputParameters->ImageBase >> PAGE_SHIFT; MemoryDescriptor->BasePage = (UINTN)InputParameters->ImageBase >> PAGE_SHIFT;
MemoryDescriptor->Pages = ALIGN_UP(InputParameters->ImageSize, PAGE_SIZE) >> PAGE_SHIFT; MemoryDescriptor->Pages = ALIGN_UP(InputParameters->ImageSize, PAGE_SIZE) >> PAGE_SHIFT;
MemoryDescriptor->Attributes = MEMORY_ATTRIBUTE_CACHE_WB; MemoryDescriptor->Attributes = MEMORY_ATTRIBUTE_CACHE_WB;

View File

@ -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;
}

View File

@ -17,12 +17,6 @@ Abstract:
#include "bootlib.h" #include "bootlib.h"
#include "mm.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 NTSTATUS
BlpMmInitialize ( BlpMmInitialize (
IN PBOOT_MEMORY_INFO MemoryInfo, IN PBOOT_MEMORY_INFO MemoryInfo,
@ -69,14 +63,12 @@ Return Value:
} }
// //
// Initialize memory descriptors. // Initialize memory descriptor manager.
// //
MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0]; MmMdInitialize(0, LibraryParameters);
MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT;
RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(BOOT_MEMORY_DESCRIPTOR));
// //
// Initialize the page allocator. // Initialize page allocator.
// //
Status = MmPaInitialize(MemoryInfo, LibraryParameters->MinimumPageAllocation); Status = MmPaInitialize(MemoryInfo, LibraryParameters->MinimumPageAllocation);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {

206
BOOT/ENVIRON/LIB/MM/mmmd.c Normal file
View File

@ -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 <ntrtl.h>
#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);
}

View File

@ -20,20 +20,20 @@ ULONG PapMinimumAllocationCount;
ULONGLONG PapMinimumPhysicalPage; ULONGLONG PapMinimumPhysicalPage;
ULONGLONG PapMaximumPhysicalPage; ULONGLONG PapMaximumPhysicalPage;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker; MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlBadMemory; MEMORY_DESCRIPTOR_LIST MmMdlBadMemory;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory; MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory; MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated; MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated; MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated; MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated; MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated;
BOOT_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated; MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated;
FORCEINLINE FORCEINLINE
VOID VOID
InitializeList ( InitializeList (
IN PBOOT_MEMORY_DESCRIPTOR_LIST List IN PMEMORY_DESCRIPTOR_LIST List
) )
/*++ /*++
@ -83,6 +83,8 @@ Return Value:
--*/ --*/
{ {
NTSTATUS Status;
(VOID)MemoryInfo; (VOID)MemoryInfo;
DebugPrint(L"Initializing page allocator...\r\n"); DebugPrint(L"Initializing page allocator...\r\n");
@ -111,10 +113,10 @@ Return Value:
// //
// Get the firmware memory map. // Get the firmware memory map.
// //
// Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, 0x03); Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, 0x03);
// if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
// return Status; return Status;
// } }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }