Rollback bootloader memory management changes
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 34s
Builds / ExectOS (i686, release) (push) Successful in 34s
Builds / ExectOS (i686, debug) (push) Successful in 43s
Builds / ExectOS (amd64, debug) (push) Successful in 44s

This commit is contained in:
2026-01-20 16:04:07 +01:00
parent d3edfef53b
commit 0b1b76e9df
10 changed files with 270 additions and 289 deletions

View File

@@ -4,7 +4,6 @@
* FILE: xtldr/memory.cc
* DESCRIPTION: XT Boot Loader memory management
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtldr.hh>
@@ -309,69 +308,17 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
PageMap->PageSize = PageSize;
}
/**
* Maps memory descriptor to the page mapping structure.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param Descriptor
* Supplies a pointer to EFI memory descriptor, which will be mapped.
*
* @param BaseAddress
* Supplies a base address, where EFI memory will be mapped.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::MapDescriptor(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PEFI_MEMORY_DESCRIPTOR Descriptor,
IN ULONG_PTR BaseAddress)
{
LOADER_MEMORY_TYPE MemoryType;
/* Skip EFI reserved memory */
if(Descriptor->Type == EfiReservedMemoryType)
{
/* Skip EFI reserved memory */
return STATUS_EFI_SUCCESS;
}
/* Convert EFI memory type into XTLDR memory type */
MemoryType = Memory::GetLoaderMemoryType((EFI_MEMORY_TYPE)Descriptor->Type);
/* Do memory mappings depending on memory type */
if(MemoryType == LoaderFirmwareTemporary)
{
/* Map EFI firmware code */
return Memory::MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add any non-free memory mappings based on provided base address */
return Memory::MapVirtualMemory(PageMap, (BaseAddress | Descriptor->PhysicalStart), Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
}
else
{
/* Map all other memory as loader free */
return Memory::MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree);
}
}
/**
* Adds EFI memory mapping to the page mapping structure.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param BaseAddress
* Supplies a base address, where EFI memory will be mapped.
* @param MemoryMapAddress
* Supplies a virtual address, where EFI memory will be mapped.
*
* @param GetMemoryTypeRoutine
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
*
* @return This routine returns a status code.
*
@@ -380,15 +327,27 @@ Memory::MapDescriptor(IN OUT PXTBL_PAGE_MAPPING PageMap,
XTCDECL
EFI_STATUS
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR BaseAddress)
IN OUT PVOID *MemoryMapAddress,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
{
ULONGLONG MaxAddress, VirtualAddress;
PEFI_MEMORY_DESCRIPTOR Descriptor;
LOADER_MEMORY_TYPE MemoryType;
PEFI_MEMORY_MAP MemoryMap;
SIZE_T DescriptorCount;
ULONGLONG MaxAddress;
EFI_STATUS Status;
SIZE_T Index;
/* Set virtual address as specified in argument */
VirtualAddress = (ULONGLONG)*MemoryMapAddress;
/* Check if custom memory type routine is specified */
if(GetMemoryTypeRoutine == NULLPTR)
{
/* Use default memory type routine */
GetMemoryTypeRoutine = GetLoaderMemoryType;
}
/* Allocate and zero-fill buffer for EFI memory map */
AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
@@ -434,17 +393,49 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Check if memory descriptor exceeds the lowest physical page */
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MaxAddress)
{
/* Truncate memory descriptor to maximum supported address */
/* Truncate memory descriptor to the lowest supported physical page */
Descriptor->NumberOfPages = (((ULONGLONG)MaxAddress) - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
}
}
/* Map this descriptor and make sure it succeeded */
Status = MapDescriptor(PageMap, Descriptor, BaseAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping failed */
return Status;
/* Skip EFI reserved memory */
if(Descriptor->Type == EfiReservedMemoryType)
{
/* Go to the next descriptor */
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
continue;
}
/* Convert EFI memory type into XTLDR memory type */
MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
/* Do memory mappings depending on memory type */
if(MemoryType == LoaderFirmwareTemporary)
{
/* Map EFI firmware code */
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add any non-free memory mapping */
Status = MapVirtualMemory(PageMap, VirtualAddress, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
}
else
{
/* Map all other memory as loader free */
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree);
}
/* Make sure memory mapping succeeded */
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping failed */
return Status;
}
}
/* Grab next descriptor */
@@ -468,6 +459,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
}
/* Store next valid virtual address and return success */
*MemoryMapAddress = (PVOID)VirtualAddress;
return STATUS_EFI_SUCCESS;
}
@@ -657,3 +649,105 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Converts physical address to virtual address based on physical base and virtual base.
*
* @param PhysicalAddress
* Specifies physical address that will be converted to virtual address.
*
* @param PhysicalBase
* Supplies a physical base address.
*
* @param VirtualBase
* Supplies a virtual base address.
*
* @return This routine returns a mapped virtual address.
*
* @since XT 1.0
*/
XTCDECL
PVOID
Memory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
IN PVOID PhysicalBase,
IN PVOID VirtualBase)
{
/* Convert physical address to virtual address */
return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase);
}
/**
* Converts whole linked list addressing from physical to virtual for future use after enabling paging.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
*
* @param PhysicalBase
* Supplies a physical base address.
*
* @param VirtualBase
* Supplies a virtual base address.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
IN OUT PLIST_ENTRY ListHead,
IN PVOID PhysicalBase,
IN PVOID VirtualBase)
{
PLIST_ENTRY ListEntry, NextEntry;
/* Make sure list is properly initialized */
if(ListHead->Flink == 0 || ListHead->Blink == 0)
{
/* List not initialized, return error code */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Iterate through all elements */
ListEntry = ListHead->Flink;
while(ListEntry != ListHead)
{
/* Save physical address of the next element */
NextEntry = ListEntry->Flink;
/* Convert the address of this element to VirtualAddress */
if(ListEntry->Blink == ListHead)
{
/* Find virtual address of list head */
ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink);
}
else
{
/* Convert list entry */
ListEntry->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase);
}
if(ListEntry->Flink == ListHead)
{
/* Convert list head */
ListEntry->Flink = ListHead->Flink->Blink;
}
else
{
/* Convert list entry */
ListEntry->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase);
}
/* Get to the next element*/
ListEntry = NextEntry;
}
/* Convert list head */
ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
/* Return success */
return STATUS_EFI_SUCCESS;
}