Properly, recursively self map page tables; currently only for AMD64 and PML4
All checks were successful
Builds / ExectOS (amd64) (push) Successful in 45s
Builds / ExectOS (i686) (push) Successful in 42s

This commit is contained in:
Rafal Kupiec 2024-04-05 00:26:41 +02:00
parent d7b103f85d
commit 1305672875
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
6 changed files with 60 additions and 7 deletions

View File

@ -46,7 +46,7 @@ typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN LONG EfiMemoryType);
typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory);
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_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap); typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
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);

View File

@ -15,13 +15,17 @@
* @param PageMap * @param PageMap
* Supplies a pointer to the page mapping structure. * Supplies a pointer to the page mapping structure.
* *
* @param SelfMapAddress
* Supplies a virtual address of the page tables.
*
* @return This routine returns a status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap) BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{ {
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MEMORY_MAPPING Mapping; PXTBL_MEMORY_MAPPING Mapping;
@ -42,7 +46,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Add page mapping itself to memory mapping */ /* Add page mapping itself to memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, PageMap->PtePointer, 1, LoaderMemoryData); Status = BlpSelfMapPml(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* PML mapping failed */ /* PML mapping failed */
@ -227,3 +231,45 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Creates a recursive self mapping for all PML levels.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param SelfMapAddress
* Supplies a virtual address of the page tables.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{
ULONGLONG PmlIndex;
/* Check page map level */
if(PageMap->PageMapLevel == 5)
{
/* Self-mapping for PML5 is not supported */
BlDebugPrint(L"PML5 self-mapping not supported yet!\n");
return STATUS_EFI_UNSUPPORTED;
}
else
{
/* Calculate PML index based on provided self map address */
PmlIndex = (SelfMapAddress >> 39) & 0x1FF;
/* Add self-mapping for PML4 */
((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].Valid = 1;
((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].Writable = 1;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@ -21,7 +21,8 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap) BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{ {
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress; EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;

View File

@ -28,7 +28,8 @@ BlAllocateMemoryPool(IN UINT_PTR Size,
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap); BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress);
XTCDECL XTCDECL
VOID VOID
@ -524,6 +525,11 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory,
IN CONST PWCHAR ConfigFile, IN CONST PWCHAR ConfigFile,
OUT PCHAR *ConfigData); OUT PCHAR *ConfigData);
XTCDECL
EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress);
XTCDECL XTCDECL
ULONGLONG ULONGLONG
BlpStringReadPadding(IN PUSHORT *Format); BlpStringReadPadding(IN PUSHORT *Format);

View File

@ -35,7 +35,7 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
EFI_STATUS Status; EFI_STATUS Status;
/* Build page map */ /* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap); Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xFFFFF6FB7DBED000);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to build page map */ /* Failed to build page map */

View File

@ -55,7 +55,7 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
} }
/* Build page map */ /* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap); Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to build page map */ /* Failed to build page map */