diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 89b56a9..5825d51 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -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 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_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); 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_POOL AllocatePool; + PBL_BUILD_PAGE_MAP BuildPageMap; PBL_COPY_MEMORY CopyMemory; PBL_FREE_PAGES FreePages; PBL_FREE_POOL FreePool; diff --git a/xtldr/arch/amd64/memory.c b/xtldr/arch/amd64/memory.c index a566c52..0a56ba8 100644 --- a/xtldr/arch/amd64/memory.c +++ b/xtldr/arch/amd64/memory.c @@ -9,6 +9,123 @@ #include +/** + * 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. * diff --git a/xtldr/arch/i686/memory.c b/xtldr/arch/i686/memory.c index fe89608..a2192d4 100644 --- a/xtldr/arch/i686/memory.c +++ b/xtldr/arch/i686/memory.c @@ -9,6 +9,146 @@ #include +/** + * 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. * diff --git a/xtldr/protocol.c b/xtldr/protocol.c index db62936..2be52c0 100644 --- a/xtldr/protocol.c +++ b/xtldr/protocol.c @@ -627,6 +627,7 @@ BlpInstallXtLoaderProtocol() BlpLdrProtocol.Disk.ReadFile = BlReadFile; BlpLdrProtocol.Memory.AllocatePages = BlAllocateMemoryPages; BlpLdrProtocol.Memory.AllocatePool = BlAllocateMemoryPool; + BlpLdrProtocol.Memory.BuildPageMap = BlBuildPageMap; BlpLdrProtocol.Memory.CopyMemory = RtlCopyMemory; BlpLdrProtocol.Memory.FreePages = BlFreeMemoryPages; BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool;