diff --git a/xtldr/amd64/memory.c b/xtldr/amd64/memory.c index 7525a56..0f4f850 100644 --- a/xtldr/amd64/memory.c +++ b/xtldr/amd64/memory.c @@ -61,16 +61,19 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, IN PVOID *PtePointer) { - UINT_PTR MapKey, DescriptorSize, DescriptorCount; - PEFI_MEMORY_DESCRIPTOR MemoryMap = NULL; PLOADER_MEMORY_MAPPING Mapping; EFI_PHYSICAL_ADDRESS Address; + PEFI_MEMORY_MAP MemoryMap; PLIST_ENTRY ListEntry; EFI_STATUS Status; PVOID Stack; + /* Allocate and zero-fill buffer for EFI memory map */ + BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + /* Get EFI memory map */ - Status = BlGetMemoryMap(&MemoryMap, &MapKey, &DescriptorSize, &DescriptorCount); + Status = BlGetMemoryMap(MemoryMap); if(Status != STATUS_EFI_SUCCESS) { /* Unable to get memory map */ @@ -144,7 +147,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, /* Exit EFI Boot Services */ BlDbgPrint(L"Exiting EFI boot services\n"); - EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MapKey); + EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); /* Write PML4 to CR3 */ HlWriteCR3((UINT_PTR)*PtePointer); diff --git a/xtldr/i686/memory.c b/xtldr/i686/memory.c index c01aef9..25c3b3f 100644 --- a/xtldr/i686/memory.c +++ b/xtldr/i686/memory.c @@ -61,11 +61,12 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, IN PVOID *PtePointer) { - UINT_PTR PhysicalAddress, MapKey, DescriptorSize, DescriptorCount; + UINT_PTR PhysicalAddress, DescriptorCount; EFI_PHYSICAL_ADDRESS Address, PDPTAddress = 0; - PEFI_MEMORY_DESCRIPTOR MemoryMap = NULL; + PEFI_MEMORY_DESCRIPTOR Descriptor; PLOADER_MEMORY_MAPPING Mapping; PCPUID_REGISTERS CpuRegisters; + PEFI_MEMORY_MAP MemoryMap; PLIST_ENTRY ListEntry; BOOLEAN PaeExtension; EFI_STATUS Status; @@ -86,14 +87,22 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, /* Store PAE status from the CPUID results */ PaeExtension = CpuRegisters->Edx & CPUID_FEATURES_EDX_PAE; + /* Allocate and zero-fill buffer for EFI memory map */ + BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + /* Get EFI memory map */ - Status = BlGetMemoryMap(&MemoryMap, &MapKey, &DescriptorSize, &DescriptorCount); + Status = BlGetMemoryMap(MemoryMap); if(Status != STATUS_EFI_SUCCESS) { /* Unable to get memory map */ return Status; } + /* Calculate descriptors count and get first one */ + Descriptor = MemoryMap->Map; + DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize; + /* Check if PAE supported by the underlying hardware */ if(PaeExtension) { @@ -107,11 +116,11 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, for(Index = 0; Index < DescriptorCount; Index++) { /* Check descriptor if it can be used to store PDPT */ - if((MemoryMap->PhysicalStart + ((MemoryMap->NumberOfPages - 1) * EFI_PAGE_SIZE) >= PhysicalAddress) && - (MemoryMap->Type == EfiConventionalMemory)) + if((Descriptor->PhysicalStart + ((Descriptor->NumberOfPages - 1) * EFI_PAGE_SIZE) >= PhysicalAddress) && + (Descriptor->Type == EfiConventionalMemory)) { /* Use highest address possible */ - if(PhysicalAddress >= MemoryMap->PhysicalStart) + if(PhysicalAddress >= Descriptor->PhysicalStart) { /* Use physical address */ PDPTAddress = PhysicalAddress; @@ -119,7 +128,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, else { /* Use descriptor physical start as PDPT address */ - PDPTAddress = MemoryMap->PhysicalStart; + PDPTAddress = Descriptor->PhysicalStart; } /* Allocate pages for the PDPT address */ @@ -131,7 +140,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, } /* Get next descriptor */ - MemoryMap = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)MemoryMap + DescriptorSize); + Descriptor = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)Descriptor + MemoryMap->DescriptorSize); } /* Make sure PDPT address found */ @@ -244,7 +253,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings, /* Exit EFI Boot Services */ BlDbgPrint(L"Exiting EFI boot services\n"); - EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MapKey); + EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); /* Enable PAE if supported by CPU */ if(PaeExtension) diff --git a/xtldr/includes/blproto.h b/xtldr/includes/blproto.h index a537292..a2b7e59 100644 --- a/xtldr/includes/blproto.h +++ b/xtldr/includes/blproto.h @@ -20,7 +20,7 @@ typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef EFI_STATUS (*PBL_ENABLE_PAGING)(IN PLIST_ENTRY MemoryMappings, IN PVOID VirtualAddress, IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, IN PVOID *PtePointer); typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); -typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_DESCRIPTOR *MemoryMap, OUT PUINT_PTR MapKey, OUT PUINT_PTR DescriptorSize, OUT PUINT_PTR DescriptorCount); +typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); typedef EFI_STATUS (*PBL_INIT_VIRTUAL_MEMORY)(IN OUT PLIST_ENTRY MemoryMappings, IN OUT PVOID *MemoryMapAddress); typedef EFI_STATUS (*PBL_MAP_VIRTUAL_MEMORY)(IN PLIST_ENTRY MemoryMappings, IN UINT_PTR VirtualAddress, IN UINT_PTR PhysicalAddress, IN UINT NumberOfPages, IN BOOLEAN PaeExtension, IN OUT PVOID *PtePointer); typedef VOID (*PBL_GET_STACK)(OUT PVOID *Stack); diff --git a/xtldr/includes/xtbl.h b/xtldr/includes/xtbl.h index bf87167..f03bab9 100644 --- a/xtldr/includes/xtbl.h +++ b/xtldr/includes/xtbl.h @@ -110,10 +110,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); EFI_STATUS -BlGetMemoryMap(OUT PEFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT PUINT_PTR MapKey, - OUT PUINT_PTR DescriptorSize, - OUT PUINT_PTR DescriptorCount); +BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); VOID BlGetStackPointer(OUT PVOID *Stack); diff --git a/xtldr/memory.c b/xtldr/memory.c index c33d257..b1360ff 100644 --- a/xtldr/memory.c +++ b/xtldr/memory.c @@ -145,20 +145,23 @@ BlAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings, if((Mapping2->PhysicalAddress >= Mapping1->PhysicalAddress && PhysicalAddress2End <= PhysicalAddressEnd) || (Mapping2->NumberOfPages == 0)) { - /* If it is of LoaderFree type, then we can skip it */ - if(Mapping2->MemoryType == LoaderFree) + /* Make sure it's memory type is LoaderFree */ + if(Mapping2->MemoryType != LoaderFree) { - /* Store address of the next mapping */ - MappingListEntry = ListEntry->Flink; - - /* Remove mapping from the list and free up it's memory */ - RtlRemoveEntryList(&Mapping2->ListEntry); - BlEfiMemoryFreePool(Mapping2); - ListEntry = MappingListEntry; - - /* Go to the next mapping */ - continue; + /* LoaderFree memory type is strictly expected */ + return STATUS_EFI_INVALID_PARAMETER; } + + /* Store address of the next mapping */ + MappingListEntry = ListEntry->Flink; + + /* Remove mapping from the list and free up it's memory */ + RtlRemoveEntryList(&Mapping2->ListEntry); + BlEfiMemoryFreePool(Mapping2); + ListEntry = MappingListEntry; + + /* Go to the next mapping */ + continue; } /* Determine phsical address order */ @@ -199,7 +202,6 @@ BlConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType) case EfiACPIMemoryNVS: case EfiACPIReclaimMemory: case EfiPalCode: - case EfiReservedMemoryType: MemoryType = LoaderSpecialMemory; break; case EfiRuntimeServicesCode: @@ -208,6 +210,7 @@ BlConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType) case EfiMemoryMappedIOPortSpace: MemoryType = LoaderFirmwarePermanent; break; + case EfiBootServicesData: case EfiLoaderCode: MemoryType = LoaderFirmwareTemporary; break; @@ -307,36 +310,29 @@ BlEfiMemoryFreePool(IN PVOID Memory) * @param MemoryMap * Supplies a pointer to the buffer where memory map will be written. * - * @param MapKey - * Supplies a pointer where the firmware stores the map key. - * - * @param DescriptorSize - * Supplies a pointer where the size of EFI_MEMORY_DESCRIPTOR will be stored. - * - * @param DescriptorCount - * Supplies a pointer where number of written descriptors will be stored. - * * @return This routine returns a status code. * * @since XT 1.0 */ EFI_STATUS -BlGetMemoryMap(OUT PEFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT PUINT_PTR MapKey, - OUT PUINT_PTR DescriptorSize, - OUT PUINT_PTR DescriptorCount) +BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) { - PEFI_MEMORY_DESCRIPTOR LocalMemoryMap = NULL; - UINT_PTR MemoryMapSize = 0, LocalMapKey, LocalDescriptorSize; - UINT32 DescriptorVersion; EFI_STATUS Status; + if(MemoryMap == NULL) + { + return STATUS_EFI_INVALID_PARAMETER; + } + + MemoryMap->Map = NULL; + MemoryMap->MapSize = 0; + /* Get memory map */ do { /* Attempt do get EFI memory map */ - Status = EfiSystemTable->BootServices->GetMemoryMap(&MemoryMapSize, LocalMemoryMap, &LocalMapKey, - &LocalDescriptorSize, &DescriptorVersion); + Status = EfiSystemTable->BootServices->GetMemoryMap(&MemoryMap->MapSize, MemoryMap->Map, &MemoryMap->MapKey, + &MemoryMap->DescriptorSize, &MemoryMap->DescriptorVersion); if(Status == STATUS_EFI_SUCCESS) { /* Go further if succeeded */ @@ -345,33 +341,27 @@ BlGetMemoryMap(OUT PEFI_MEMORY_DESCRIPTOR *MemoryMap, else if(Status != STATUS_EFI_BUFFER_TOO_SMALL) { /* Some error occurred */ - if(MemoryMap) + if(MemoryMap->Map) { /* Free allocated memory */ - BlEfiMemoryFreePool(MemoryMap); + BlEfiMemoryFreePool(MemoryMap->Map); } return Status; } /* Allocate the desired amount of memory */ - MemoryMapSize += 2 * LocalDescriptorSize; - BlEfiMemoryAllocatePool(MemoryMapSize, (PVOID *)&LocalMemoryMap); + MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; + BlEfiMemoryAllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); } while(Status == STATUS_EFI_BUFFER_TOO_SMALL); /* Make sure memory map is set */ - if(LocalMemoryMap == NULL) + if(MemoryMap->Map == NULL) { /* Something went wrong */ - return STATUS_EFI_INVALID_PARAMETER; + return STATUS_EFI_NO_MAPPING; } - /* Store memory map details */ - *MemoryMap = LocalMemoryMap; - *MapKey = LocalMapKey; - *DescriptorSize = LocalDescriptorSize; - *DescriptorCount = MemoryMapSize / LocalDescriptorSize; - /* Return success */ return STATUS_EFI_SUCCESS; } @@ -393,9 +383,10 @@ EFI_STATUS BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, IN OUT PVOID *MemoryMapAddress) { - UINT_PTR MapKey, DescriptorSize, DescriptorCount; - PEFI_MEMORY_DESCRIPTOR MemoryMap = NULL; + PEFI_MEMORY_DESCRIPTOR Descriptor; LOADER_MEMORY_TYPE MemoryType; + PEFI_MEMORY_MAP MemoryMap; + SIZE_T DescriptorCount; PUCHAR VirtualAddress; EFI_STATUS Status; SIZE_T Index; @@ -403,45 +394,51 @@ BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, /* Set initial virtual address */ VirtualAddress = *MemoryMapAddress; - /* Get memory map */ - Status = BlGetMemoryMap(&MemoryMap, &MapKey, &DescriptorSize, &DescriptorCount); + /* Allocate and zero-fill buffer for EFI memory map */ + BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + + /* Get EFI memory map */ + Status = BlGetMemoryMap(MemoryMap); if(Status != STATUS_EFI_SUCCESS) { return Status; } - /* Iterate through all descriptors from memory map */ + /* Calculate descriptors count and get first one */ + Descriptor = MemoryMap->Map; + DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize; + + /* Iterate through all descriptors from the memory map */ for(Index = 0; Index < DescriptorCount; Index++) { - /* Make sure descriptor does not go beyond lowest physical page */ - if((MemoryMap->PhysicalStart + (MemoryMap->NumberOfPages * EFI_PAGE_SIZE)) <= (UINT_PTR)-1) + if((Descriptor->PhysicalStart + (Descriptor->NumberOfPages * EFI_PAGE_SIZE)) <= (UINT_PTR)-1) { /* Convert EFI memory type into XTOS memory type */ - MemoryType = BlConvertEfiMemoryType(MemoryMap->Type); + MemoryType = BlConvertEfiMemoryType(Descriptor->Type); /* Do memory mappings depending on memory type */ if(MemoryType == LoaderFirmwareTemporary) { /* Map EFI firmware code */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, (PVOID)MemoryMap->PhysicalStart, - (PVOID)MemoryMap->PhysicalStart, MemoryMap->NumberOfPages, MemoryType); + Status = BlAddVirtualMemoryMapping(MemoryMappings, (PVOID)Descriptor->PhysicalStart, + (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); } else if(MemoryType != LoaderFree) { /* Add any non-free memory mapping */ Status = BlAddVirtualMemoryMapping(MemoryMappings, VirtualAddress, - (PVOID)MemoryMap->PhysicalStart, MemoryMap->NumberOfPages, MemoryType); + (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); /* Calculate next valid virtual address */ - VirtualAddress += MemoryMap->NumberOfPages * EFI_PAGE_SIZE; - + VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE; } else { /* Map all other memory as loader free */ - Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)MemoryMap->PhysicalStart, - MemoryMap->NumberOfPages, LoaderFree); + Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, LoaderFree); } /* Make sure memory mapping succeeded */ @@ -452,7 +449,7 @@ BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, } /* Grab next descriptor */ - MemoryMap = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)MemoryMap + DescriptorSize); + Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize); } }