分配页面返回EFI_INVALID_PARAMETER作为内存类型为EfiConventionalMemory吗?

问题描述

嗨,我正在使用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,EFI_PAGES_TO_SIZE (NumberOfPages),(VOID *) (UINTN) *Memory,NULL
      );
    InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);
    ApplyMemoryProtectionPolicy (EfiConventionalMemory,*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 spec,该文件将EfiConventionalMemory定义为在调用ExitBootServices()之前是“可用(未分配的)内存”,之后是“可用的通用内存”。

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

非常感谢!

解决方法

内存类型参数指定分配之后内存应具有的类型。显然,分配后无法释放内存,因此这就是EfiConventionalMemory是无效参数的原因。

分配的内存源始终是EfiConventionalMemory。

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