Anonymous user
Detecting Memory (x86): Difference between revisions
m
Added UEFI Memory Map code example
[unchecked revision] | [unchecked revision] |
No edit summary |
m (Added UEFI Memory Map code example) |
||
Line 343:
== What about on UEFI? ==
On UEFI, you have 'BootServices->GetMemoryMap'. This function is
<source lang="c">▼
</source>▼
<source lang="c">
typedef struct {
UINT32 Type; // EFI_MEMORY_TYPE, Field size is 32 bits followed by 32 bit pad
UINT32 Pad;
EFI_PHYSICAL_ADDRESS PhysicalStart; // Field size is 64 bits
Line 362 ⟶ 354:
} EFI_MEMORY_DESCRIPTOR;
</source>
To traverse them, you can use the NEXT_MEMORY_DESCRITOR macro.
Memory types are different to the E820 codes. For converting, see [https://github.com/tianocore/edk2/blob/70d5086c3274b1a5b099d642d546581070374e6e/OvmfPkg/Csm/LegacyBiosDxe/LegacyBootSupport.c#L1601 CSM E820 compatibility].
▲<source lang="c">
typedef enum {
EfiReservedMemoryType,
EfiLoaderCode,
EfiLoaderData,
EfiBootServicesCode,
EfiBootServicesData,
EfiRuntimeServicesCode,
EfiRuntimeServicesData,
EfiConventionalMemory,
EfiUnusableMemory,
EfiACPIReclaimMemory,
EfiACPIMemoryNVS,
EfiMemoryMappedIO,
EfiMemoryMappedIOPortSpace,
EfiPalCode,
EfiPersistentMemory,
EfiMaxMemoryType
} EFI_MEMORY_TYPE;
▲</source>
==Code Examples==
Line 509 ⟶ 523:
}
}
</source>
===Getting an UEFI Memory Map===
<source lang="c">
EFI_STATUS Status;
EFI_MEMORY_DESCRIPTOR *EfiMemoryMap;
UINTN EfiMemoryMapSize;
UINTN EfiMapKey;
UINTN EfiDescriptorSize;
UINT32 EfiDescriptorVersion;
//
// Get the EFI memory map.
//
EfiMemoryMapSize = 0;
EfiMemoryMap = NULL;
Status = gBS->GetMemoryMap (
&EfiMemoryMapSize,
EfiMemoryMap,
&EfiMapKey,
&EfiDescriptorSize,
&EfiDescriptorVersion
);
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
//
// Use size returned for the AllocatePool.
//
EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (EfiMemoryMapSize + 2 * EfiDescriptorSize);
ASSERT (EfiMemoryMap != NULL);
Status = gBS->GetMemoryMap (
&EfiMemoryMapSize,
EfiMemoryMap,
&EfiMapKey,
&EfiDescriptorSize,
&EfiDescriptorVersion
);
if (EFI_ERROR (Status)) {
FreePool (EfiMemoryMap);
}
//
// Get descriptors
//
EFI_MEMORY_DESCRIPTOR *EfiEntry = EfiMemoryMap;
do {
// ... do something with EfiEntry ...
EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
} while((UINT8*)EfiEntry < (UINT8*)EfiMemoryMap + EfiMemoryMapSize);
</source>
|