Fix critical memory corruption bug caused by overwriting active page tables marked as free memory
Todas as verificações foram bem sucedidas
Todas as verificações foram bem sucedidas
Esse commit está contido em:
@@ -28,13 +28,12 @@ EFI_STATUS
|
|||||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR SelfMapAddress)
|
IN ULONG_PTR SelfMapAddress)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||||
PXTBL_MEMORY_MAPPING Mapping;
|
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
PVOID LoaderBase;
|
|
||||||
ULONGLONG LoaderSize;
|
ULONGLONG LoaderSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
PVOID LoaderBase;
|
||||||
|
|
||||||
/* Allocate pages for the Page Map */
|
/* Allocate pages for the Page Map */
|
||||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||||
@@ -65,7 +64,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map the trampoline code area */
|
/* Map the trampoline code area */
|
||||||
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS,MM_TRAMPOLINE_ADDRESS,
|
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS,
|
||||||
1, LoaderFirmwareTemporary);
|
1, LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -117,6 +116,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return STATUS_EFI_PROTOCOL_ERROR;
|
return STATUS_EFI_PROTOCOL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||||
|
*
|
||||||
|
* @param PageMap
|
||||||
|
* Supplies a pointer to the page mapping structure.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
|
{
|
||||||
|
PXTBL_MEMORY_MAPPING Mapping;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
/* Iterate through and map all the mappings*/
|
/* Iterate through and map all the mappings*/
|
||||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
|
|||||||
@@ -25,13 +25,12 @@ EFI_STATUS
|
|||||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR SelfMapAddress)
|
IN ULONG_PTR SelfMapAddress)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
|
||||||
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
|
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
|
||||||
|
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
PXTBL_MEMORY_MAPPING Mapping;
|
|
||||||
PVOID LoaderBase;
|
|
||||||
ULONGLONG LoaderSize;
|
ULONGLONG LoaderSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
PVOID LoaderBase;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
/* Check the page map level to determine which paging structure to create */
|
/* Check the page map level to determine which paging structure to create */
|
||||||
@@ -45,6 +44,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add new memory mapping for the page map itself */
|
||||||
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory mapping failure */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Assign the allocated page to the page map and zero it out */
|
/* Assign the allocated page to the page map and zero it out */
|
||||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||||
@@ -57,6 +64,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add new memory mapping for the Page Directories (PDs) */
|
||||||
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, DirectoryAddress, 4, LoaderMemoryData);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory mapping failure */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Zero-fill the allocated memory for the Page Directories */
|
/* Zero-fill the allocated memory for the Page Directories */
|
||||||
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
|
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
|
||||||
|
|
||||||
@@ -79,6 +94,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add new memory mapping for the page map itself */
|
||||||
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory mapping failure */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Assign the allocated page to the page map and zero it out */
|
/* Assign the allocated page to the page map and zero it out */
|
||||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||||
@@ -144,6 +167,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return STATUS_EFI_PROTOCOL_ERROR;
|
return STATUS_EFI_PROTOCOL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||||
|
*
|
||||||
|
* @param PageMap
|
||||||
|
* Supplies a pointer to the page mapping structure.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
|
{
|
||||||
|
PXTBL_MEMORY_MAPPING Mapping;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
/* Iterate through and map all the mappings*/
|
/* Iterate through and map all the mappings*/
|
||||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ class Memory
|
|||||||
OUT PVOID *Memory);
|
OUT PVOID *Memory);
|
||||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR SelfMapAddress);
|
IN ULONG_PTR SelfMapAddress);
|
||||||
|
STATIC XTCDECL EFI_STATUS CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
|
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
|
||||||
IN EFI_PHYSICAL_ADDRESS Memory);
|
IN EFI_PHYSICAL_ADDRESS Memory);
|
||||||
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
|
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
|
||||||
|
|||||||
@@ -10,6 +10,34 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Build page map */
|
||||||
|
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to build page map */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map memory for hardware layer */
|
||||||
|
Status = MapHardwareMemoryPool(PageMap);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to map memory for hardware layer */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the appropriate EFI memory mapping strategy for the AMD64 architecture.
|
* Determines the appropriate EFI memory mapping strategy for the AMD64 architecture.
|
||||||
*
|
*
|
||||||
@@ -91,24 +119,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
ULONG_PTR TrampolineSize;
|
ULONG_PTR TrampolineSize;
|
||||||
PVOID TrampolineCode;
|
PVOID TrampolineCode;
|
||||||
|
|
||||||
/* Build page map */
|
|
||||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to build page map */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map memory for hardware layer */
|
|
||||||
Status = MapHardwareMemoryPool(PageMap);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to map memory for hardware layer */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the configured page map level to set the LA57 state accordingly */
|
/* Check the configured page map level to set the LA57 state accordingly */
|
||||||
if(PageMap->PageMapLevel == 5)
|
if(PageMap->PageMapLevel == 5)
|
||||||
{
|
{
|
||||||
@@ -188,6 +198,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
if(PageMap->PageMapLevel == 5)
|
if(PageMap->PageMapLevel == 5)
|
||||||
{
|
{
|
||||||
@@ -205,6 +216,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by P5E */
|
/* Zero fill memory used by P5E */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
@@ -239,6 +253,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by PXE */
|
/* Zero fill memory used by PXE */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
@@ -267,6 +284,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by PPE */
|
/* Zero fill memory used by PPE */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
@@ -285,7 +305,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through 2 PDE entries */
|
/* Loop through 2 PDE entries */
|
||||||
for(UINT Index = 0 ; Index < 2 ; Index++)
|
for(Index = 0 ; Index < 2 ; Index++)
|
||||||
{
|
{
|
||||||
/* Check if PDE entry already exists */
|
/* Check if PDE entry already exists */
|
||||||
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
|
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
|
||||||
@@ -298,6 +318,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by PDE */
|
/* Zero fill memory used by PDE */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,47 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
|
{
|
||||||
|
ULONG_PTR SelfMapAddress;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Initialize self map address */
|
||||||
|
if(PageMap->PageMapLevel == 3)
|
||||||
|
{
|
||||||
|
/* For PML3 (PAE) use PTE base address */
|
||||||
|
SelfMapAddress = MM_PTE_BASE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For PML2 (PAE disabled) use legacy PDE base address */
|
||||||
|
SelfMapAddress = MM_PDE_LEGACY_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build page map */
|
||||||
|
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to build page map */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map memory for hardware layer */
|
||||||
|
Status = MapHardwareMemoryPool(PageMap);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to map memory for hardware layer */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the appropriate EFI memory mapping strategy for the i686 architecture.
|
* Determines the appropriate EFI memory mapping strategy for the i686 architecture.
|
||||||
*
|
*
|
||||||
@@ -74,37 +115,6 @@ EFI_STATUS
|
|||||||
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
ULONG_PTR SelfMapAddress;
|
|
||||||
|
|
||||||
/* Initialize self map address */
|
|
||||||
if(PageMap->PageMapLevel == 3)
|
|
||||||
{
|
|
||||||
/* For PML3 (PAE) use PTE base address */
|
|
||||||
SelfMapAddress = MM_PTE_BASE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* For PML2 (PAE disabled) use legacy PDE base address */
|
|
||||||
SelfMapAddress = MM_PDE_LEGACY_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build page map */
|
|
||||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to build page map */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map memory for hardware layer */
|
|
||||||
Status = MapHardwareMemoryPool(PageMap);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to map memory for hardware layer */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Exit EFI Boot Services */
|
/* Exit EFI Boot Services */
|
||||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||||
@@ -173,6 +183,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
/* Zero fill allocated memory */
|
/* Zero fill allocated memory */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Check if PAE is enabled (3-level paging) */
|
/* Check if PAE is enabled (3-level paging) */
|
||||||
if(PageMap->PageMapLevel == 3)
|
if(PageMap->PageMapLevel == 3)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class Xtos
|
|||||||
IN PVOID PhysicalAddress,
|
IN PVOID PhysicalAddress,
|
||||||
IN UINT NumberOfPages,
|
IN UINT NumberOfPages,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType);
|
IN LOADER_MEMORY_TYPE MemoryType);
|
||||||
|
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||||
STATIC XTCDECL BOOLEAN DetermineMappingStrategy();
|
STATIC XTCDECL BOOLEAN DetermineMappingStrategy();
|
||||||
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
||||||
@@ -47,10 +48,13 @@ class Xtos
|
|||||||
IN PULONG_PTR FrameBufferSize,
|
IN PULONG_PTR FrameBufferSize,
|
||||||
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
||||||
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||||
|
IN PVOID VirtualBase,
|
||||||
OUT PLIST_ENTRY MemoryDescriptorList);
|
OUT PLIST_ENTRY MemoryDescriptorList);
|
||||||
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||||
|
IN PVOID VirtualBase,
|
||||||
|
IN PVOID FrameBufferVirtualBase,
|
||||||
OUT PLIST_ENTRY SystemResourcesList);
|
OUT PLIST_ENTRY SystemResourcesList);
|
||||||
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID PhysicalAddress,
|
IN PVOID PhysicalAddress,
|
||||||
|
|||||||
@@ -191,38 +191,16 @@ Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||||
|
IN PVOID VirtualBase,
|
||||||
OUT PLIST_ENTRY MemoryDescriptorList)
|
OUT PLIST_ENTRY MemoryDescriptorList)
|
||||||
{
|
{
|
||||||
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
||||||
PXTBL_MEMORY_MAPPING MemoryMapping;
|
PXTBL_MEMORY_MAPPING MemoryMapping;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
EFI_STATUS Status;
|
|
||||||
ULONGLONG Pages;
|
|
||||||
|
|
||||||
/* Calculate the number of pages required to store the memory descriptor array */
|
|
||||||
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
|
|
||||||
|
|
||||||
/* Allocate physical pages to hold the memory descriptor list */
|
|
||||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Page allocation failed, return the status code */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a virtual memory mapping for the allocated descriptor buffer */
|
|
||||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, Address, Pages, LoaderMemoryData);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Release the allocated pages as the virtual mapping failed and return status code */
|
|
||||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the descriptor pointer to the start of the allocated physical buffer */
|
/* Initialize the descriptor pointer to the start of the allocated physical buffer */
|
||||||
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
|
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)PhysicalBase;
|
||||||
|
|
||||||
/* Get the first entry from the internal boot loader memory map */
|
/* Get the first entry from the internal boot loader memory map */
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
@@ -247,17 +225,18 @@ Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert all physical link pointers in the list to their corresponding virtual addresses */
|
/* Convert all physical link pointers in the list to their corresponding virtual addresses */
|
||||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)Address, *VirtualAddress);
|
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)PhysicalBase, VirtualBase);
|
||||||
|
|
||||||
/* Advance the virtual address pointer to the next available free region and return success */
|
/* Return success */
|
||||||
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
|
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||||
|
IN PVOID VirtualBase,
|
||||||
|
IN PVOID FrameBufferVirtualBase,
|
||||||
OUT PLIST_ENTRY SystemResourcesList)
|
OUT PLIST_ENTRY SystemResourcesList)
|
||||||
{
|
{
|
||||||
XTSTATUS Status;
|
XTSTATUS Status;
|
||||||
@@ -268,39 +247,18 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||||
EFI_PHYSICAL_ADDRESS FbAddress;
|
EFI_PHYSICAL_ADDRESS FbAddress;
|
||||||
|
EFI_PHYSICAL_ADDRESS OriginalPhysicalBase;
|
||||||
ULONG_PTR FbSize;
|
ULONG_PTR FbSize;
|
||||||
UINT FrameBufferPages;
|
|
||||||
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
|
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
|
||||||
PSYSTEM_RESOURCE_ACPI AcpiResource;
|
PSYSTEM_RESOURCE_ACPI AcpiResource;
|
||||||
ULONGLONG Pages;
|
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
|
||||||
PVOID PhysicalBase, VirtualBase;
|
|
||||||
|
|
||||||
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
/* Save original physical base */
|
||||||
|
OriginalPhysicalBase = PhysicalBase;
|
||||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, Address, Pages, LoaderFirmwarePermanent);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
PhysicalBase = (PVOID)Address;
|
|
||||||
VirtualBase = *VirtualAddress;
|
|
||||||
|
|
||||||
/* Calculate next valid virtual address */
|
|
||||||
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
|
|
||||||
|
|
||||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
|
|
||||||
|
|
||||||
|
AcpiResource = (PSYSTEM_RESOURCE_ACPI)PhysicalBase;
|
||||||
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
|
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
|
||||||
|
|
||||||
/* Load FrameBuffer protocol */
|
/* Load ACPI protocol */
|
||||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -319,13 +277,11 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
|
|
||||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
||||||
|
|
||||||
/* Close FrameBuffer protocol */
|
/* Close ACPI protocol */
|
||||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &AcpiGuid);
|
||||||
|
|
||||||
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
|
|
||||||
|
|
||||||
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address;
|
|
||||||
|
|
||||||
|
PhysicalBase = PhysicalBase + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||||
|
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)PhysicalBase;
|
||||||
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||||
|
|
||||||
/* Load FrameBuffer protocol */
|
/* Load FrameBuffer protocol */
|
||||||
@@ -346,26 +302,16 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate pages needed to map framebuffer */
|
/* Assign the pre-mapped virtual address to the resource block */
|
||||||
FrameBufferPages = EFI_SIZE_TO_PAGES(FbSize);
|
FrameBufferResource->Header.VirtualAddress = FrameBufferVirtualBase;
|
||||||
|
|
||||||
/* Rewrite framebuffer address by using virtual address */
|
|
||||||
FrameBufferResource->Header.VirtualAddress = *VirtualAddress;
|
|
||||||
|
|
||||||
/* Map frame buffer memory */
|
|
||||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FrameBufferResource->Header.VirtualAddress,
|
|
||||||
(ULONGLONG)FrameBufferResource->Header.PhysicalAddress,
|
|
||||||
FrameBufferPages, LoaderFirmwarePermanent);
|
|
||||||
|
|
||||||
/* Close FrameBuffer protocol */
|
|
||||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
|
||||||
*VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE);
|
|
||||||
|
|
||||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
||||||
|
|
||||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, PhysicalBase, VirtualBase);
|
/* Convert list pointers to virtual */
|
||||||
|
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, (PVOID)OriginalPhysicalBase, VirtualBase);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,34 +372,97 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN OUT PVOID *VirtualAddress,
|
||||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||||
{
|
{
|
||||||
|
EFI_PHYSICAL_ADDRESS FbPhysicalAddress, PhysicalBlock, PhysicalDescriptor, PhysicalResources;
|
||||||
|
PVOID FbVirtualAddress, VirtualBlock, VirtualResources, VirtualDescriptor;
|
||||||
|
UINT BlockPages, DescriptorPages, FbPages, ParametersSize, ResourcesPages;
|
||||||
|
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||||
|
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||||
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
|
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_HANDLE ProtocolHandle;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT BlockPages;
|
ULONG_PTR FbSize;
|
||||||
UINT ParametersSize;
|
|
||||||
|
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||||
|
|
||||||
|
/* Initialize Framebuffer information */
|
||||||
|
FbPhysicalAddress = 0;
|
||||||
|
FbSize = 0;
|
||||||
|
FbVirtualAddress = NULLPTR;
|
||||||
|
FbPages = 0;
|
||||||
|
|
||||||
/* Calculate size of parameters */
|
/* Calculate size of parameters */
|
||||||
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
|
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
/* Calculate number of pages needed for initialization block */
|
/* Calculate number of pages needed for initialization block */
|
||||||
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||||
|
ResourcesPages = EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||||
|
|
||||||
/* Allocate memory for kernel initialization block */
|
/* Query Framebuffer size for allocation */
|
||||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address);
|
if(XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid) == STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Get FrameBuffer information */
|
||||||
|
FrameBufProtocol->GetDisplayInformation(&FbPhysicalAddress, &FbSize, &FbModeInfo);
|
||||||
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
}
|
||||||
|
FbPages = EFI_SIZE_TO_PAGES(FbSize);
|
||||||
|
|
||||||
|
/* Calculate number of pages needed for memory descriptor list */
|
||||||
|
DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR));
|
||||||
|
|
||||||
|
/* Allocate memory for the kernel initialization block and boot parameters */
|
||||||
|
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Memory allocation failure */
|
/* Memory allocation failure, return status code */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize and zero-fill kernel initialization block */
|
/* Allocate memory for the system resources data structures */
|
||||||
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address;
|
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ResourcesPages, &PhysicalResources);
|
||||||
XtLdrProtocol->Memory.ZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory allocation failure, return status code */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the memory descriptor list */
|
||||||
|
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, DescriptorPages, &PhysicalDescriptor);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory allocation failure, return status code */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map the Kernel Initialization Block into virtual memory and advance the virtual address pointer */
|
||||||
|
VirtualBlock = *VirtualAddress;
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualBlock, PhysicalBlock, BlockPages, LoaderSystemBlock);
|
||||||
|
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Map the system resources physical memory into virtual address space and update the allocation pointer */
|
||||||
|
VirtualResources = *VirtualAddress;
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualResources, PhysicalResources, ResourcesPages, LoaderFirmwarePermanent);
|
||||||
|
*VirtualAddress = (PUINT8)*VirtualAddress + (ResourcesPages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Check if a framebuffer was detected and requires memory mapping */
|
||||||
|
if(FbPages > 0)
|
||||||
|
{
|
||||||
|
/* Map the framebuffer physical memory range into virtual address space */
|
||||||
|
FbVirtualAddress = *VirtualAddress;
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FbVirtualAddress, FbPhysicalAddress, FbPages, LoaderFirmwarePermanent);
|
||||||
|
*VirtualAddress = (PUINT8)*VirtualAddress + (FbPages * EFI_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map the allocated physical memory for memory descriptors into the virtual address space */
|
||||||
|
VirtualDescriptor = *VirtualAddress;
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualDescriptor, PhysicalDescriptor, DescriptorPages, LoaderMemoryData);
|
||||||
|
*VirtualAddress = (PUINT8)*VirtualAddress + (DescriptorPages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
/* Set basic loader block properties */
|
/* Set basic loader block properties */
|
||||||
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)PhysicalBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||||
|
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)PhysicalBlock;
|
||||||
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
|
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
|
||||||
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
|
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
|
||||||
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
||||||
@@ -467,24 +476,30 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
|
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
|
||||||
|
|
||||||
/* Copy parameters to kernel initialization block */
|
/* Copy parameters to kernel initialization block */
|
||||||
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK));
|
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)VirtualBlock + sizeof(KERNEL_INITIALIZATION_BLOCK));
|
||||||
XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
|
XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
|
||||||
Parameters->Parameters,
|
Parameters->Parameters, ParametersSize);
|
||||||
ParametersSize);
|
|
||||||
|
|
||||||
/* Map kernel initialization block */
|
/* Commit mappings */
|
||||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, (ULONGLONG)LoaderBlock,
|
XtLdrProtocol->Memory.CommitPageMap(PageMap);
|
||||||
BlockPages, LoaderSystemBlock);
|
|
||||||
|
|
||||||
/* Calculate next valid virtual address */
|
|
||||||
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
|
||||||
|
|
||||||
|
/* Initialize system resources list */
|
||||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
|
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
|
||||||
GetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
Status = GetSystemResourcesList(PageMap, PhysicalResources, VirtualResources, FbVirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to initialize system resources list, return status code */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize memory descriptor list */
|
/* Initialize memory descriptor list */
|
||||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
||||||
GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
|
Status = GetMemoryDescriptorList(PageMap, PhysicalDescriptor, VirtualDescriptor, &LoaderBlock->MemoryDescriptorListHead);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to initialize memory descriptor list, return status code */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set boot image size */
|
/* Set boot image size */
|
||||||
LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);
|
LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);
|
||||||
@@ -702,6 +717,14 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build page map */
|
||||||
|
Status = BuildPageMap(&PageMap);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Store virtual address of kernel initialization block for future kernel call */
|
/* Store virtual address of kernel initialization block for future kernel call */
|
||||||
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
||||||
|
|
||||||
|
|||||||
@@ -1054,6 +1054,7 @@ Protocol::InstallXtLoaderProtocol()
|
|||||||
LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;
|
LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;
|
||||||
LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;
|
LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;
|
||||||
LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
|
LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
|
||||||
|
LoaderProtocol.Memory.CommitPageMap = Memory::CommitPageMap;
|
||||||
LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
|
LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
|
||||||
LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
|
LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
|
||||||
LoaderProtocol.Memory.FreePages = Memory::FreePages;
|
LoaderProtocol.Memory.FreePages = Memory::FreePages;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ typedef EFI_STATUS (XTCDECL *PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLe
|
|||||||
typedef BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
|
typedef BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
|
||||||
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
|
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
|
typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
|
||||||
|
typedef EFI_STATUS (XTCDECL *PBL_COMMIT_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
||||||
typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
|
typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
|
||||||
typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);
|
typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);
|
||||||
@@ -449,6 +450,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_BUILD_PAGE_MAP BuildPageMap;
|
||||||
|
PBL_COMMIT_PAGE_MAP CommitPageMap;
|
||||||
PBL_COMPARE_MEMORY CompareMemory;
|
PBL_COMPARE_MEMORY CompareMemory;
|
||||||
PBL_COPY_MEMORY CopyMemory;
|
PBL_COPY_MEMORY CopyMemory;
|
||||||
PBL_FREE_PAGES FreePages;
|
PBL_FREE_PAGES FreePages;
|
||||||
|
|||||||
Referência em uma Nova Issue
Bloquear um usuário