AllocatePages возвращает 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,
      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;
  }

Таким образом, он фактически возвращает EFI_INVALID_PARAMETER, если тип памяти EfiConventionalMemory.

Я также читал спецификацию UEFI, в которой EfiConventionalMemory определяется как тип "свободной (нераспределенной) памяти", прежде чемExitBootServices() вызывается, а затем "Память доступна для общего использования".

Так что я немного запутался, если это нормально, что я получил EFI_INVALID_PARAMETER, если нет, что мне делать, чтобы получить правильное распределение памяти?

Большое спасибо!

1 ответ

Решение

Параметр типа памяти указывает тип памяти, который должна иметь после выделения. Очевидно, что память не может быть освобождена после выделения, поэтому EfiConventionalMemory является недопустимым параметром.

Источником памяти для выделения всегда является EfiConventionalMemory.

Обычно вы используете BootServicesData в качестве запрошенного типа памяти.

Другие вопросы по тегам