0

您好我正在使用 edk2 为内核编写引导服务,并且需要应用AllocatePages服务来应用类型为 EfiConventionalMemory 的内存。

但是,它返回 EFI_INVALID_PARAMETER 的错误代码。

我查看了git的源代码,实际功能如下:

EFI_STATUS
EFIAPI
CoreAllocatePages (
  IN  EFI_ALLOCATE_TYPE     Type,
  IN  EFI_MEMORY_TYPE       MemoryType,
  IN  UINTN                 NumberOfPages,
  OUT EFI_PHYSICAL_ADDRESS  *Memory
  )
{
  EFI_STATUS  Status;
  BOOLEAN     NeedGuard;

  NeedGuard = IsPageTypeToGuard (MemoryType, Type) && !mOnGuarding;
  Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,
                                      NeedGuard);
  if (!EFI_ERROR (Status)) {
    CoreUpdateProfile (
      (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),
      MemoryProfileActionAllocatePages,
      MemoryType,
      EFI_PAGES_TO_SIZE (NumberOfPages),
      (VOID *) (UINTN) *Memory,
      NULL
      );
    InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);
    ApplyMemoryProtectionPolicy (EfiConventionalMemory, MemoryType, *Memory,
      EFI_PAGES_TO_SIZE (NumberOfPages));
  }
  return Status;
}

它调用函数CoreInternalAllocatePages,如下:

EFI_STATUS
EFIAPI
CoreInternalAllocatePages (
  IN EFI_ALLOCATE_TYPE      Type,
  IN EFI_MEMORY_TYPE        MemoryType,
  IN UINTN                  NumberOfPages,
  IN OUT EFI_PHYSICAL_ADDRESS  *Memory,
  IN BOOLEAN                NeedGuard
  )
{
  EFI_STATUS       Status;
  UINT64           Start;
  UINT64           NumberOfBytes;
  UINT64           End;
  UINT64           MaxAddress;
  UINTN            Alignment;
  EFI_MEMORY_TYPE  CheckType;

  if ((UINT32)Type >= MaxAllocateType) {
    return EFI_INVALID_PARAMETER;
  }

  if ((MemoryType >= EfiMaxMemoryType && MemoryType < MEMORY_TYPE_OEM_RESERVED_MIN) ||
       (MemoryType == EfiConventionalMemory) || (MemoryType == EfiPersistentMemory)) {
    return EFI_INVALID_PARAMETER;
  }

因此,如果内存类型为 EfiConventionalMemory,它实际上会返回 EFI_INVALID_PARAMETER。

我还阅读了UEFI 规范,该规范在调用之前将 EfiConventionalMemory 定义为“空闲(未分配)内存”类型,之后将其定义为ExitBootServices()“可用于一般用途的内存”。

所以我有点困惑,如果我得到 EFI_INVALID_PARAMETER 是正常的,如果不是,我应该怎么做才能获得正确的内存分配?

非常感谢!

4

1 回答 1

2

内存类型参数指定分配后内存应具有的类型。显然内存在分配后不能空闲,这就是为什么 EfiConventionalMemory 是一个无效参数的原因。

分配的内存源始终是 EfiConventionalMemory。

通常您会使用 BootServicesData 作为请求的内存类型。

于 2020-09-03T21:45:00.290 回答