Implement BlBuildPageMap() routine
Some checks failed
Builds / ExectOS (amd64) (push) Failing after 15s
Builds / ExectOS (i686) (push) Failing after 14s

This commit is contained in:
Rafal Kupiec 2024-01-22 15:15:21 +01:00
parent 85d43e54b8
commit 7128159c42
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
4 changed files with 260 additions and 0 deletions

View File

@ -49,6 +49,7 @@ typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRE
typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory);
typedef VOID (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); typedef VOID (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId);
typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters); typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters);
typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap);
typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid);
@ -264,6 +265,7 @@ typedef struct _XTBL_LOADER_PROTOCOL
{ {
PBL_ALLOCATE_PAGES AllocatePages; PBL_ALLOCATE_PAGES AllocatePages;
PBL_ALLOCATE_POOL AllocatePool; PBL_ALLOCATE_POOL AllocatePool;
PBL_BUILD_PAGE_MAP BuildPageMap;
PBL_COPY_MEMORY CopyMemory; PBL_COPY_MEMORY CopyMemory;
PBL_FREE_PAGES FreePages; PBL_FREE_PAGES FreePages;
PBL_FREE_POOL FreePool; PBL_FREE_POOL FreePool;

View File

@ -9,6 +9,123 @@
#include <xtldr.h> #include <xtldr.h>
/**
* Maps boot loader related code and builds page map.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
{
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PLOADER_MEMORY_MAPPING Mapping;
PXTBL_MODULE_INFO ModuleInfo;
EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status;
/* Allocate pages for the Page Map */
Status = BlAllocateMemoryPages(1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Assign and zero-fill memory used by page mappings */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Add page mapping itself to memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, PageMap->PtePointer, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* PML mapping failed */
return Status;
}
/* Get list of XTLDR modules */
ModulesList = BlGetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
/* Get module info */
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping module code failed */
return Status;
}
/* Get next module */
ModulesListEntry = ModulesListEntry->Flink;
}
/* Make sure boot loader image base and size are set */
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize)
{
/* Map boot loader code as well */
Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase,
EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping boot loader code failed */
return Status;
}
}
else
{
/* Boot loader image information re not available */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Iterate through and map all the mappings*/
BlDebugPrint(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap)
{
/* Take mapping from the list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
/* Check if virtual address is set */
if(Mapping->VirtualAddress)
{
/* Dump memory mapping */
BlDebugPrint(L" Type=%02lu, PhysicalBase=0x%016lx, VirtualBase=0x%016lx, Pages=%lu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failed */
return Status;
}
}
/* Take next element */
ListEntry = ListEntry->Flink;
}
/* Finally, map zero page */
BlMapPage(PageMap, 0, 0, 1);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Does the actual virtual memory mapping. * Does the actual virtual memory mapping.
* *

View File

@ -9,6 +9,146 @@
#include <xtldr.h> #include <xtldr.h>
/**
* Maps boot loader related code and builds page map.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
EFI_STATUS Status;
ULONG Index;
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MODULE_INFO ModuleInfo;
PLOADER_MEMORY_MAPPING Mapping;
/* Allocate pages for the Page Map */
Status = BlAllocateMemoryPages(1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Assign and zero-fill memory used by page mappings */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Allocate pages for the Page Directory */
Status = BlAllocateMemoryPages(4, &DirectoryAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Zero fill memory used by Page Directory */
RtlZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
/* Set the page directory into the PDPT and mark it present */
for(Index = 0; Index < 4; Index++)
{
/* Set paging entry settings */
((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE;
((PHARDWARE_PTE)PageMap->PtePointer)[Index].Valid = 1;
/* Next valid PFN address */
DirectoryAddress += EFI_PAGE_SIZE;
}
/* Add page mapping itself to memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, PageMap->PtePointer, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* PML mapping failed */
return Status;
}
/* Get list of XTLDR modules */
ModulesList = BlGetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
/* Get module info */
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping module code failed */
return Status;
}
/* Get next module */
ModulesListEntry = ModulesListEntry->Flink;
}
/* Make sure boot loader image base and size are set */
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize)
{
/* Map boot loader code as well */
Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase,
EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping boot loader code failed */
return Status;
}
}
else
{
/* Boot loader image information re not available */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Iterate through and map all the mappings*/
BlDebugPrint(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap)
{
/* Take mapping from the list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
/* Check if virtual address is set */
if(Mapping->VirtualAddress)
{
/* Dump memory mapping */
BlDebugPrint(L" Type=%02lu, PhysicalBase=0x%016lx, VirtualBase=0x%016lx, Pages=%lu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failed */
return Status;
}
}
/* Take next element */
ListEntry = ListEntry->Flink;
}
/* Finally, map zero page */
BlMapPage(PageMap, 0, 0, 1);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Does the actual virtual memory mapping. * Does the actual virtual memory mapping.
* *

View File

@ -627,6 +627,7 @@ BlpInstallXtLoaderProtocol()
BlpLdrProtocol.Disk.ReadFile = BlReadFile; BlpLdrProtocol.Disk.ReadFile = BlReadFile;
BlpLdrProtocol.Memory.AllocatePages = BlAllocateMemoryPages; BlpLdrProtocol.Memory.AllocatePages = BlAllocateMemoryPages;
BlpLdrProtocol.Memory.AllocatePool = BlAllocateMemoryPool; BlpLdrProtocol.Memory.AllocatePool = BlAllocateMemoryPool;
BlpLdrProtocol.Memory.BuildPageMap = BlBuildPageMap;
BlpLdrProtocol.Memory.CopyMemory = RtlCopyMemory; BlpLdrProtocol.Memory.CopyMemory = RtlCopyMemory;
BlpLdrProtocol.Memory.FreePages = BlFreeMemoryPages; BlpLdrProtocol.Memory.FreePages = BlFreeMemoryPages;
BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool; BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool;