[lib][uefi] Implement os loading buffer protocol

This commit is contained in:
Kelvin Zhang
2025-06-11 15:38:19 -07:00
parent 953b519d69
commit 2ff6ab3920
3 changed files with 130 additions and 0 deletions

View File

@@ -24,6 +24,7 @@
#include <uefi/boot_service.h>
#include <uefi/protocols/block_io_protocol.h>
#include <uefi/protocols/dt_fixup_protocol.h>
#include <uefi/protocols/gbl_efi_image_loading_protocol.h>
#include <uefi/protocols/gbl_efi_os_configuration_protocol.h>
#include <uefi/protocols/loaded_image_protocol.h>
#include <uefi/types.h>
@@ -173,6 +174,53 @@ EfiTpl raise_tpl(EfiTpl new_tpl) {
return APPLICATION;
}
const char *GetImageType(const char16_t *ImageType) {
if (memcmp(ImageType, GBL_IMAGE_TYPE_OS_LOAD,
sizeof(GBL_IMAGE_TYPE_OS_LOAD)) == 0) {
return "os_load";
} else if (memcmp(ImageType, GBL_IMAGE_TYPE_FASTBOOT,
sizeof(GBL_IMAGE_TYPE_FASTBOOT)) == 0) {
return "fastboot";
} else if (memcmp(ImageType, GBL_IMAGE_TYPE_PVMFW_DATA,
sizeof(GBL_IMAGE_TYPE_PVMFW_DATA)) == 0) {
return "pvmfw_data";
}
return "unknown";
}
template <typename T>
T clamp(T n, T lower, T upper) {
if (n < lower) {
return lower;
}
if (n > upper) {
return upper;
}
return n;
}
EfiStatus get_buffer(struct GblEfiImageLoadingProtocol *self,
const GblEfiImageInfo *ImageInfo,
GblEfiImageBuffer *Buffer) {
printf("%s(%s, %lu)\n", __FUNCTION__, GetImageType(ImageInfo->ImageType),
ImageInfo->SizeBytes);
// Allow maximum of 128MB buffer
const size_t buffer_size =
clamp(Buffer->SizeBytes, PAGE_SIZE, 128ul * 1024 * 1024);
Buffer->Memory = alloc_page(buffer_size);
if (Buffer->Memory == nullptr) {
return OUT_OF_RESOURCES;
}
Buffer->SizeBytes = buffer_size;
return SUCCESS;
}
EfiStatus get_verify_partitions(struct GblEfiImageLoadingProtocol *self,
size_t *NumberOfPartitions,
GblEfiPartitionName *Partitions) {
printf("%s is called\n");
return UNSUPPORTED;
}
EfiStatus open_protocol(EfiHandle handle, const EfiGuid *protocol, void **intf,
EfiHandle agent_handle, EfiHandle controller_handle,
@@ -236,6 +284,20 @@ EfiStatus open_protocol(EfiHandle handle, const EfiGuid *protocol, void **intf,
config->select_device_trees = select_device_trees;
*intf = reinterpret_cast<void *>(config);
return SUCCESS;
} else if (guid_eq(protocol, EFI_GBL_EFI_IMAGE_LOADING_PROTOCOL_GUID)) {
printf(
"%s(EFI_GBL_EFI_IMAGE_LOADING_PROTOCOL_GUID, handle=%p, "
"agent_handle%p, controller_handle=%p, attr=0x%x)\n",
__FUNCTION__, handle, agent_handle, controller_handle, attr);
GblEfiImageLoadingProtocol *image_loading = nullptr;
allocate_pool(BOOT_SERVICES_DATA, sizeof(*image_loading),
reinterpret_cast<void **>(&image_loading));
if (image_loading == nullptr) {
return OUT_OF_RESOURCES;
}
image_loading->revision = GBL_EFI_IMAGE_LOADING_PROTOCOL_REVISION;
*intf = reinterpret_cast<void *>(image_loading);
return SUCCESS;
}
printf("%s is unsupported 0x%x 0x%x 0x%x 0x%llx\n", __FUNCTION__,
protocol->data1, protocol->data2, protocol->data3,

View File

@@ -80,6 +80,12 @@ static constexpr auto EFI_GBL_OS_CONFIGURATION_PROTOCOL_GUID =
0x42ff,
{0x85, 0xac, 0xe3, 0xad, 0x6e, 0xfb, 0x46, 0x19}};
static constexpr auto EFI_GBL_EFI_IMAGE_LOADING_PROTOCOL_GUID =
EfiGuid{0xdb84b4fa,
0x53bd,
0x4436,
{0x98, 0xa7, 0x4e, 0x02, 0x71, 0x42, 0x8b, 0xa8}};
static constexpr auto EFI_DT_FIXUP_PROTOCOL_GUID =
EfiGuid{0xe617d64c,
0xfe08,

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef __GBL_EFI_IMAGE_LOADING_PROTOCOL_H__
#define __GBL_EFI_IMAGE_LOADING_PROTOCOL_H__
#include <stddef.h>
#include <uefi/types.h>
static constexpr uint64_t GBL_EFI_IMAGE_LOADING_PROTOCOL_REVISION = 0x00010000;
#define PARTITION_NAME_LEN_U16 36
//******************************************************
// GBL reserved image types
//******************************************************
// Buffer for loading, verifying and fixing up OS images.
#define GBL_IMAGE_TYPE_OS_LOAD L"os_load"
// Buffer for use as fastboot download buffer.
#define GBL_IMAGE_TYPE_FASTBOOT L"fastboot"
// Buffer reserved for pvmfw binary and configuration (must be 4KiB-aligned).
#define GBL_IMAGE_TYPE_PVMFW_DATA L"pvmfw_data"
typedef struct GblEfiImageInfo {
char16_t ImageType[PARTITION_NAME_LEN_U16];
size_t SizeBytes;
} GblEfiImageInfo;
typedef struct GblEfiImageBuffer {
void* Memory;
size_t SizeBytes;
} GblEfiImageBuffer;
typedef struct GblEfiPartitionName {
char16_t StrUtf16[PARTITION_NAME_LEN_U16];
} GblEfiPartitionName;
typedef struct GblEfiImageLoadingProtocol {
uint64_t revision;
EfiStatus (*get_buffer)(struct GblEfiImageLoadingProtocol* self,
const GblEfiImageInfo* ImageInfo,
GblEfiImageBuffer* Buffer);
EfiStatus (*get_verify_partitions)(struct GblEfiImageLoadingProtocol* self,
size_t* NumberOfPartitions,
GblEfiPartitionName* Partitions);
} GblEfiImageLoadingProtocol;
#endif //__GBL_EFI_IMAGE_LOADING_PROTOCOL_H__