@@ -21,13 +21,14 @@
|
||||
#include "arch/defines.h"
|
||||
#include "boot_service.h"
|
||||
|
||||
#include "defer.h"
|
||||
#include "lib/bio.h"
|
||||
#include "libfdt.h"
|
||||
#include "protocols/block_io_protocol.h"
|
||||
#include "protocols/dt_fixup_protocol.h"
|
||||
#include "protocols/gbl_efi_os_configuration_protocol.h"
|
||||
#include "protocols/loaded_image_protocol.h"
|
||||
#include "uefi_platform.h"
|
||||
|
||||
#include <lk/compiler.h>
|
||||
|
||||
#include "switch_stack.h"
|
||||
#include "types.h"
|
||||
@@ -164,11 +165,6 @@ EfiStatus install_configuration_table(const EfiGuid *guid, void *table) {
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
|
||||
EfiStatus exit_boot_services(EfiHandle image_handle, size_t map_key) {
|
||||
printf("%s is called\n", __FUNCTION__);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void copy_mem(void *dest, const void *src, size_t len) {
|
||||
memcpy(dest, src, len);
|
||||
}
|
||||
@@ -179,74 +175,6 @@ EfiTpl raise_tpl(EfiTpl new_tpl) {
|
||||
return APPLICATION;
|
||||
}
|
||||
|
||||
EFI_STATUS efi_dt_fixup(struct EfiDtFixupProtocol *self, void *fdt,
|
||||
size_t *buffer_size, uint32_t flags) {
|
||||
auto offset = fdt_subnode_offset(fdt, 0, "chosen");
|
||||
if (offset < 0) {
|
||||
printf("Failed to find chosen node %d\n", offset);
|
||||
return SUCCESS;
|
||||
}
|
||||
int length = 0;
|
||||
auto prop = fdt_get_property(fdt, offset, "bootargs", &length);
|
||||
|
||||
if (prop == nullptr) {
|
||||
printf("Failed to find chosen/bootargs prop\n");
|
||||
return SUCCESS;
|
||||
}
|
||||
char *new_prop_data = reinterpret_cast<char *>(malloc(length));
|
||||
DEFER {
|
||||
free(new_prop_data);
|
||||
new_prop_data = nullptr;
|
||||
};
|
||||
auto prop_length = strnlen(prop->data, length);
|
||||
static constexpr auto &&to_add =
|
||||
"console=ttyAMA0 earlycon=pl011,mmio32,0x9000000 ";
|
||||
memset(new_prop_data, 0, length);
|
||||
memcpy(new_prop_data, to_add, sizeof(to_add) - 1);
|
||||
memcpy(new_prop_data + sizeof(to_add) - 1, prop->data, prop_length);
|
||||
auto ret = fdt_setprop(fdt, offset, "bootargs", new_prop_data, length);
|
||||
|
||||
printf("chosen/bootargs: %d %d \"%s\"\n", ret, length, new_prop_data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Generates fixups for the kernel command line built by GBL.
|
||||
EfiStatus fixup_kernel_commandline(struct GblEfiOsConfigurationProtocol *self,
|
||||
const char *command_line, char *fixup,
|
||||
size_t *fixup_buffer_size) {
|
||||
printf("%s(%p, \"%s\")\n", __FUNCTION__, self, command_line);
|
||||
*fixup_buffer_size = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Generates fixups for the bootconfig built by GBL.
|
||||
EfiStatus fixup_bootconfig(struct GblEfiOsConfigurationProtocol *self,
|
||||
const char *bootconfig, size_t size, char *fixup,
|
||||
size_t *fixup_buffer_size) {
|
||||
printf("%s(%p, %s, %lu, %lu)\n", __FUNCTION__, self, bootconfig, size,
|
||||
*fixup_buffer_size);
|
||||
constexpr auto &&to_add = "\nandroidboot.fstab_suffix=cf.f2fs."
|
||||
"hctr2\nandroidboot.boot_devices=4010000000.pcie";
|
||||
const auto final_len = sizeof(to_add);
|
||||
if (final_len > *fixup_buffer_size) {
|
||||
*fixup_buffer_size = final_len;
|
||||
return OUT_OF_RESOURCES;
|
||||
}
|
||||
*fixup_buffer_size = final_len;
|
||||
memcpy(fixup, to_add, final_len);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Selects which device trees and overlays to use from those loaded by GBL.
|
||||
EfiStatus select_device_trees(struct GblEfiOsConfigurationProtocol *self,
|
||||
GblEfiVerifiedDeviceTree *device_trees,
|
||||
size_t num_device_trees) {
|
||||
printf("%s(%p, %p %lu)\n", __FUNCTION__, self, device_trees,
|
||||
num_device_trees);
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
|
||||
EfiStatus open_protocol(EfiHandle handle, const EfiGuid *protocol, void **intf,
|
||||
EfiHandle agent_handle, EfiHandle controller_handle,
|
||||
@@ -291,7 +219,7 @@ EfiStatus open_protocol(EfiHandle handle, const EfiGuid *protocol, void **intf,
|
||||
}
|
||||
fixup->revision = EFI_DT_FIXUP_PROTOCOL_REVISION;
|
||||
fixup->fixup = efi_dt_fixup;
|
||||
*intf = reinterpret_cast<EfiHandle *>(fixup);
|
||||
*intf = reinterpret_cast<void *>(fixup);
|
||||
}
|
||||
return SUCCESS;
|
||||
} else if (guid_eq(protocol, EFI_GBL_OS_CONFIGURATION_PROTOCOL_GUID)) {
|
||||
@@ -309,7 +237,7 @@ EfiStatus open_protocol(EfiHandle handle, const EfiGuid *protocol, void **intf,
|
||||
config->fixup_bootconfig = fixup_bootconfig;
|
||||
config->fixup_kernel_commandline = fixup_kernel_commandline;
|
||||
config->select_device_trees = select_device_trees;
|
||||
*intf = reinterpret_cast<EfiHandle *>(config);
|
||||
*intf = reinterpret_cast<void *>(config);
|
||||
return SUCCESS;
|
||||
}
|
||||
printf("%s is unsupported 0x%x 0x%x 0x%x 0x%llx\n", __FUNCTION__,
|
||||
|
||||
@@ -121,4 +121,9 @@ struct EFI_LOADED_IMAGE_PROTOCOL {
|
||||
|
||||
static constexpr size_t EFI_LOADED_IMAGE_PROTOCOL_REVISION = 0x1000;
|
||||
|
||||
// This function would be called from GBL before jumping into android kernel
|
||||
// LK provides a default no-op implementation that is weakly linked,
|
||||
// different platforms can override with their own implementation.
|
||||
EfiStatus exit_boot_services(EfiHandle image_handle, size_t map_key);
|
||||
|
||||
#endif
|
||||
|
||||
15
lib/uefi/include/uefi.h
Normal file
15
lib/uefi/include/uefi.h
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
#ifndef __LIB_UEFI_HEADER_
|
||||
#define __LIB_UEFI_HEADER_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int load_pe_file(const char *blkdev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,14 @@
|
||||
|
||||
#include "relocation.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pe.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr size_t BIT26 = 1 << 26;
|
||||
constexpr size_t BIT11 = 1 << 11;
|
||||
constexpr size_t BIT10 = 1 << 10;
|
||||
@@ -97,6 +101,8 @@ void ThumbMovwMovtImmediatePatch(uint16_t *Instructions, uint32_t Address) {
|
||||
ThumbMovtImmediatePatch(Top, static_cast<uint16_t>(Address >> 16));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int relocate_image(char *image) {
|
||||
const auto dos_header = reinterpret_cast<IMAGE_DOS_HEADER *>(image);
|
||||
const auto pe_header = dos_header->GetPEHeader();
|
||||
|
||||
@@ -13,6 +13,7 @@ MODULE_SRCS += \
|
||||
$(LOCAL_DIR)/boot_service_provider.cpp \
|
||||
$(LOCAL_DIR)/memory_protocols.cpp \
|
||||
$(LOCAL_DIR)/blockio_protocols.cpp \
|
||||
$(LOCAL_DIR)/uefi_platform.cpp \
|
||||
$(LOCAL_DIR)/runtime_service_provider.cpp \
|
||||
$(LOCAL_DIR)/switch_stack.S \
|
||||
$(LOCAL_DIR)/configuration_table.cpp \
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
*/
|
||||
|
||||
#include "runtime_service_provider.h"
|
||||
#include "types.h"
|
||||
|
||||
#include <platform.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto &&kSecureBoot = L"SecureBoot";
|
||||
constexpr auto &&kSecureBoot = "SecureBoot";
|
||||
|
||||
EFI_STATUS GetVariable(char16_t *VariableName, EfiGuid *VendorGuid,
|
||||
uint32_t *Attributes, size_t *DataSize, void *Data) {
|
||||
@@ -37,7 +39,7 @@ EFI_STATUS GetVariable(char16_t *VariableName, EfiGuid *VendorGuid,
|
||||
i += j;
|
||||
}
|
||||
buffer[i] = 0;
|
||||
if (strcmp(buffer, "SecureBoot") == 0 || strcmp(buffer, "SetupMode") == 0) {
|
||||
if (strncmp(buffer, kSecureBoot, sizeof(kSecureBoot)) == 0 || strcmp(buffer, "SetupMode") == 0) {
|
||||
if (DataSize) {
|
||||
*DataSize = 1;
|
||||
}
|
||||
@@ -64,10 +66,17 @@ EFI_STATUS SetVariable(char16_t *VariableName, EfiGuid *VendorGuid,
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ResetSystem(EFI_RESET_TYPE ResetType, EFI_STATUS ResetStatus,
|
||||
size_t DataSize, void *ResetData) {
|
||||
platform_halt(HALT_ACTION_REBOOT, HALT_REASON_SW_RESET);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void setup_runtime_service_table(EfiRuntimeService *service) {
|
||||
service->GetVariable = GetVariable;
|
||||
service->SetVariable = SetVariable;
|
||||
service->SetVirtualAddressMap = SetVirtualAddressMap;
|
||||
service->ResetSystem = ResetSystem;
|
||||
}
|
||||
|
||||
100
lib/uefi/uefi_platform.cpp
Normal file
100
lib/uefi/uefi_platform.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <libfdt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <types.h>
|
||||
|
||||
#include "defer.h"
|
||||
#include "uefi_platform.h"
|
||||
#include "protocols/gbl_efi_os_configuration_protocol.h"
|
||||
|
||||
__WEAK EFI_STATUS efi_dt_fixup(struct EfiDtFixupProtocol *self, void *fdt,
|
||||
size_t *buffer_size, uint32_t flags) {
|
||||
auto offset = fdt_subnode_offset(fdt, 0, "chosen");
|
||||
if (offset < 0) {
|
||||
printf("Failed to find chosen node %d\n", offset);
|
||||
return SUCCESS;
|
||||
}
|
||||
int length = 0;
|
||||
auto prop = fdt_get_property(fdt, offset, "bootargs", &length);
|
||||
|
||||
if (prop == nullptr) {
|
||||
printf("Failed to find chosen/bootargs prop\n");
|
||||
return SUCCESS;
|
||||
}
|
||||
char *new_prop_data = reinterpret_cast<char *>(malloc(length));
|
||||
DEFER {
|
||||
free(new_prop_data);
|
||||
new_prop_data = nullptr;
|
||||
};
|
||||
auto prop_length = strnlen(prop->data, length);
|
||||
static constexpr auto &&to_add =
|
||||
"console=ttyAMA0 earlycon=pl011,mmio32,0x9000000 ";
|
||||
memset(new_prop_data, 0, length);
|
||||
memcpy(new_prop_data, to_add, sizeof(to_add) - 1);
|
||||
memcpy(new_prop_data + sizeof(to_add) - 1, prop->data, prop_length);
|
||||
auto ret = fdt_setprop(fdt, offset, "bootargs", new_prop_data, length);
|
||||
|
||||
printf("chosen/bootargs: %d %d \"%s\"\n", ret, length, new_prop_data);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Generates fixups for the kernel command line built by GBL.
|
||||
__WEAK EfiStatus fixup_kernel_commandline(
|
||||
struct GblEfiOsConfigurationProtocol *self, const char *command_line,
|
||||
char *fixup, size_t *fixup_buffer_size) {
|
||||
printf("%s(%p, \"%s\")\n", __FUNCTION__, self, command_line);
|
||||
*fixup_buffer_size = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Generates fixups for the bootconfig built by GBL.
|
||||
__WEAK EfiStatus fixup_bootconfig(struct GblEfiOsConfigurationProtocol *self,
|
||||
const char *bootconfig, size_t size,
|
||||
char *fixup, size_t *fixup_buffer_size) {
|
||||
printf("%s(%p, %s, %lu, %lu)\n", __FUNCTION__, self, bootconfig, size,
|
||||
*fixup_buffer_size);
|
||||
constexpr auto &&to_add =
|
||||
"\nandroidboot.fstab_suffix=cf.f2fs."
|
||||
"hctr2\nandroidboot.boot_devices=4010000000.pcie";
|
||||
const auto final_len = sizeof(to_add);
|
||||
if (final_len > *fixup_buffer_size) {
|
||||
*fixup_buffer_size = final_len;
|
||||
return OUT_OF_RESOURCES;
|
||||
}
|
||||
*fixup_buffer_size = final_len;
|
||||
memcpy(fixup, to_add, final_len);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// Selects which device trees and overlays to use from those loaded by GBL.
|
||||
__WEAK EfiStatus select_device_trees(struct GblEfiOsConfigurationProtocol *self,
|
||||
GblEfiVerifiedDeviceTree *device_trees,
|
||||
size_t num_device_trees) {
|
||||
printf("%s(%p, %p %lu)\n", __FUNCTION__, self, device_trees,
|
||||
num_device_trees);
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
|
||||
__WEAK EfiStatus exit_boot_services(EfiHandle image_handle, size_t map_key) {
|
||||
printf("%s is called\n", __FUNCTION__);
|
||||
return SUCCESS;
|
||||
}
|
||||
44
lib/uefi/uefi_platform.h
Normal file
44
lib/uefi/uefi_platform.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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_OS_CONFIGURATION_
|
||||
#define __GBL_OS_CONFIGURATION_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include "protocols/gbl_efi_os_configuration_protocol.h"
|
||||
|
||||
// Functions which should be implemented by individual platforms.
|
||||
// The UEFI library provides a default no-op implementation that
|
||||
// is weakly linked.
|
||||
|
||||
EFI_STATUS efi_dt_fixup(struct EfiDtFixupProtocol *self, void *fdt,
|
||||
size_t *buffer_size, uint32_t flags);
|
||||
|
||||
EfiStatus fixup_kernel_commandline(struct GblEfiOsConfigurationProtocol *self,
|
||||
const char *command_line, char *fixup,
|
||||
size_t *fixup_buffer_size);
|
||||
|
||||
EfiStatus fixup_bootconfig(struct GblEfiOsConfigurationProtocol *self,
|
||||
const char *bootconfig, size_t size, char *fixup,
|
||||
size_t *fixup_buffer_size);
|
||||
|
||||
EfiStatus select_device_trees(struct GblEfiOsConfigurationProtocol *self,
|
||||
GblEfiVerifiedDeviceTree *device_trees,
|
||||
size_t num_device_trees);
|
||||
EfiStatus exit_boot_services(EfiHandle image_handle, size_t map_key);
|
||||
#endif
|
||||
Reference in New Issue
Block a user