Pull request efi-2025-07-rc1

CI:

* https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/25648

Documentation:

* Update authenticated capsules documentation

UEFI:

* Add support for loading FIT images including initrd
  - efi_loader: efi_load_initrd: provide a memory mapped initrd
  - efi_loader: binary_run: register an initrd
  - bootm: add support for initrd in do_bootm_efi
* efi_selftest: remove un-needed NULL checks
* efi: Fix efiboot for payloads loaded from memory

* Print extra information from the bootmgr
* Move public cert for capsules to .rodata
* Set EFI capsule dfu_alt_info env explicitly
* Make FDT extra space configurable
* Install the ACPI table from the bloblist
* Handle GD_FLG_SKIP_RELOC
* Handle malloc() errors

Others:

* acpi: select CONFIG_BLOBLIST
* smbios: select CONFIG_BLOBLIST
* xilinx: dfu: Fill directly update_info.dfu_string
* cmd: fwu: Dump custom fields from mdata structure
* board: remove capsule update support in set_dfu_alt_info()
This commit is contained in:
Tom Rini
2025-04-11 09:09:08 -06:00
42 changed files with 306 additions and 274 deletions

View File

@@ -2231,7 +2231,7 @@ CLEAN_FILES += include/autoconf.mk* include/bmp_logo.h include/bmp_logo_data.h \
itb.fit.fit itb.fit.itb itb.map spl.map mkimage-out.rom.mkimage \
mkimage.rom.mkimage mkimage-in-simple-bin* rom.map simple-bin* \
idbloader-spi.img lib/efi_loader/helloworld_efi.S *.itb \
Test* capsule*.*.efi-capsule capsule*.map
Test* capsule*.*.efi-capsule capsule*.map capsule_esl_file
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include/generated spl tpl vpl \

View File

@@ -45,14 +45,6 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
int board_init(void)
{
return 0;

View File

@@ -41,14 +41,6 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
int board_init(void)
{
return 0;

View File

@@ -31,8 +31,6 @@ void set_dfu_alt_info(char *interface, char *devstr)
{
if (interface && strcmp(interface, "ram") == 0)
env_set("dfu_alt_info", "fitimage ram 0x08080000 0x4000000");
else if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif

View File

@@ -38,8 +38,6 @@ void set_dfu_alt_info(char *interface, char *devstr)
{
if (interface && strcmp(interface, "ram") == 0)
env_set("dfu_alt_info", "fitimage ram 0x08080000 0x4000000");
else if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif

View File

@@ -31,8 +31,6 @@ void set_dfu_alt_info(char *interface, char *devstr)
{
if (interface && strcmp(interface, "ram") == 0)
env_set("dfu_alt_info", "fitimage ram 0x08080000 0x4000000");
else if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif

View File

@@ -82,14 +82,6 @@ static void configure_capsule_updates(void)
}
#endif
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
#if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) || IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
int mmc_get_env_dev(void)
{

View File

@@ -41,14 +41,6 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
int board_init(void)
{
return 0;

View File

@@ -74,14 +74,6 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
int board_init(void)
{
return 0;

View File

@@ -54,14 +54,6 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
int board_init(void)
{
return 0;

View File

@@ -65,14 +65,6 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
int board_init(void)
{
return 0;

View File

@@ -40,14 +40,6 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
#if IS_ENABLED(CONFIG_SET_DFU_ALT_INFO)
void set_dfu_alt_info(char *interface, char *devstr)
{
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
env_set("dfu_alt_info", update_info.dfu_string);
}
#endif
int board_init(void)
{
return 0;

View File

@@ -18,4 +18,7 @@ bool board_detection(void);
char *soc_name_decode(void);
bool soc_detection(void);
void configure_capsule_updates(void);
#endif /* BOARD_XILINX_COMMON_BOARD_H */

View File

@@ -8,6 +8,7 @@
#include <cpu_func.h>
#include <dfu.h>
#include <env.h>
#include <efi_loader.h>
#include <fdtdec.h>
#include <init.h>
#include <env_internal.h>
@@ -280,6 +281,9 @@ int board_late_init(void)
{
int ret;
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
configure_capsule_updates();
if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
debug("Saved variables - Skipping\n");
return 0;
@@ -356,8 +360,6 @@ enum env_location env_get_location(enum env_operation op, int prio)
}
#endif
#if defined(CONFIG_SET_DFU_ALT_INFO)
#define DFU_ALT_BUF_LEN SZ_1K
static void mtd_found_part(u32 *base, u32 *size)
@@ -385,7 +387,7 @@ static void mtd_found_part(u32 *base, u32 *size)
}
}
void set_dfu_alt_info(char *interface, char *devstr)
void configure_capsule_updates(void)
{
int bootseq = 0, len = 0;
u32 multiboot = versal_multi_boot();
@@ -393,9 +395,6 @@ void set_dfu_alt_info(char *interface, char *devstr)
ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
if (env_get("dfu_alt_info"))
return;
memset(buf, 0, sizeof(buf));
multiboot = env_get_hex("multiboot", multiboot);
@@ -436,7 +435,6 @@ void set_dfu_alt_info(char *interface, char *devstr)
return;
}
env_set("dfu_alt_info", buf);
puts("DFU alt info setting: done\n");
update_info.dfu_string = strdup(buf);
debug("Capsule DFU: %s\n", update_info.dfu_string);
}
#endif

View File

@@ -7,6 +7,7 @@
#include <config.h>
#include <debug_uart.h>
#include <dfu.h>
#include <efi_loader.h>
#include <init.h>
#include <log.h>
#include <dm/uclass.h>
@@ -52,6 +53,9 @@ int board_late_init(void)
char *new_targets;
char *env_targets;
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
configure_capsule_updates();
if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
debug("Saved variables - Skipping\n");
return 0;
@@ -165,17 +169,12 @@ enum env_location env_get_location(enum env_operation op, int prio)
}
}
#if defined(CONFIG_SET_DFU_ALT_INFO)
#define DFU_ALT_BUF_LEN SZ_1K
void set_dfu_alt_info(char *interface, char *devstr)
void configure_capsule_updates(void)
{
ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
if (env_get("dfu_alt_info"))
return;
memset(buf, 0, sizeof(buf));
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
@@ -199,7 +198,6 @@ void set_dfu_alt_info(char *interface, char *devstr)
return;
}
env_set("dfu_alt_info", buf);
puts("DFU alt info setting: done\n");
update_info.dfu_string = strdup(buf);
debug("Capsule DFU: %s\n", update_info.dfu_string);
}
#endif

View File

@@ -11,6 +11,7 @@
#include <dfu.h>
#include <env.h>
#include <env_internal.h>
#include <efi_loader.h>
#include <init.h>
#include <log.h>
#include <net.h>
@@ -526,6 +527,9 @@ int board_late_init(void)
usb_ether_init();
#endif
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
configure_capsule_updates();
multiboot = multi_boot();
if (multiboot >= 0)
env_set_hex("multiboot", multiboot);
@@ -631,8 +635,6 @@ enum env_location env_get_location(enum env_operation op, int prio)
}
#endif
#if defined(CONFIG_SET_DFU_ALT_INFO)
#define DFU_ALT_BUF_LEN SZ_1K
static void mtd_found_part(u32 *base, u32 *size)
@@ -660,15 +662,12 @@ static void mtd_found_part(u32 *base, u32 *size)
}
}
void set_dfu_alt_info(char *interface, char *devstr)
void configure_capsule_updates(void)
{
int multiboot, bootseq = 0, len = 0;
ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
if (env_get("dfu_alt_info"))
return;
memset(buf, 0, sizeof(buf));
multiboot = multi_boot();
@@ -732,10 +731,9 @@ void set_dfu_alt_info(char *interface, char *devstr)
return;
}
env_set("dfu_alt_info", buf);
puts("DFU alt info setting: done\n");
update_info.dfu_string = strdup(buf);
debug("Capsule DFU: %s\n", update_info.dfu_string);
}
#endif
#if defined(CONFIG_SPL_SPI_LOAD)
unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash)

View File

@@ -507,7 +507,9 @@ static int do_bootm_efi(int flag, struct bootm_info *bmi)
ret = efi_binary_run(image_buf, images->os.image_len,
images->ft_len
? images->ft_addr : EFI_FDT_USE_INTERNAL);
? images->ft_addr : EFI_FDT_USE_INTERNAL,
(void *)images->initrd_start,
(size_t)(images->initrd_end - images->initrd_start));
return ret;
}

View File

@@ -185,6 +185,7 @@ config CMD_UFETCH
config CMD_FWU_METADATA
bool "fwu metadata read"
depends on FWU_MULTI_BANK_UPDATE
imply HEXDUMP if FWU_MDATA_V2
help
Command to read the metadata and dump it's contents

View File

@@ -211,7 +211,7 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc,
}
}
ret = efi_binary_run(image_buf, size, fdt);
ret = efi_binary_run(image_buf, size, fdt, NULL, 0);
if (ret != EFI_SUCCESS)
return CMD_RET_FAILURE;

View File

@@ -7,6 +7,7 @@
#include <dm.h>
#include <fwu.h>
#include <fwu_mdata.h>
#include <hexdump.h>
#include <log.h>
#include <stdio.h>
#include <stdlib.h>
@@ -45,6 +46,30 @@ static void print_mdata(struct fwu_data *data)
img_info->accepted == 0x1 ? "yes" : "no");
}
}
if (data->version == 2) {
struct fwu_mdata *mdata = data->fwu_mdata;
struct fwu_fw_store_desc *desc;
void *end;
u32 diff;
/*
* fwu_mdata defines only header that's why taking it as array
* which exactly point to image description location
*/
desc = (struct fwu_fw_store_desc *)&mdata[1];
/* Number of entries is taken from for loop - variable i */
end = &desc->img_entry[i];
debug("mdata %p, desc %p, end %p\n", mdata, desc, end);
diff = data->metadata_size - ((void *)end - (void *)mdata);
if (diff) {
printf("Custom fields covered by CRC len: 0x%x\n", diff);
print_hex_dump_bytes("CUSTOM ", DUMP_PREFIX_OFFSET,
end, diff);
}
}
}
int do_fwu_mdata_read(struct cmd_tbl *cmdtp, int flag,

View File

@@ -169,6 +169,7 @@ static int initr_reloc_global_data(void)
*/
efi_save_gd();
if (!(gd->flags & GD_FLG_SKIP_RELOC))
efi_runtime_relocate(gd->relocaddr, NULL);
#endif

View File

@@ -597,21 +597,6 @@ and used by the steps highlighted below.
[--fit | --raw | --guid <guid-string] \
<image_blob> <capsule_file_name>
4. Insert the signature list into a device tree in the following format::
{
signature {
capsule-key = [ <binary of signature list> ];
}
...
}
You can perform step-4 through the Kconfig symbol
CONFIG_EFI_CAPSULE_CRT_FILE. This symbol points to the signing key
generated in step-2. As part of U-Boot build, the ESL certificate file will
be generated from the signing key and automatically get embedded into the
platform's dtb.
Anti-rollback Protection
************************

View File

@@ -576,6 +576,7 @@ config QFW_SMBIOS
bool
default y
depends on QFW && SMBIOS && !SANDBOX && !SYSINFO_SMBIOS
select BLOBLIST
help
Hidden option to read SMBIOS tables from QEMU.

View File

@@ -28,6 +28,8 @@ extern char __efi_helloworld_begin[];
extern char __efi_helloworld_end[];
extern char __efi_var_file_begin[];
extern char __efi_var_file_end[];
extern char __efi_capsule_sig_begin[];
extern char __efi_capsule_sig_end[];
/* Private data used by of-platdata devices/uclasses */
extern char __priv_data_start[], __priv_data_end[];

View File

@@ -600,7 +600,7 @@ efi_status_t efi_install_fdt(void *fdt);
/* Execute loaded UEFI image */
efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options);
/* Run loaded UEFI image with given fdt */
efi_status_t efi_binary_run(void *image, size_t size, void *fdt);
efi_status_t efi_binary_run(void *image, size_t size, void *fdt, void *initrd, size_t initrd_sz);
/**
* efi_bootflow_run() - Run a bootflow containing an EFI application
@@ -667,7 +667,7 @@ efi_status_t efi_http_register(const efi_handle_t handle,
struct efi_service_binding_protocol *http_service_binding);
/* Called by bootefi to make the watchdog available */
efi_status_t efi_watchdog_register(void);
efi_status_t efi_initrd_register(void);
efi_status_t efi_initrd_register(struct efi_device_path *dp_initrd);
efi_status_t efi_initrd_deregister(void);
/* Called by bootefi to make SMBIOS tables available */
/**

View File

@@ -317,6 +317,7 @@ config SPL_ACPI
config GENERATE_ACPI_TABLE
bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
depends on ACPI
select BLOBLIST
select QFW if QEMU
help
The Advanced Configuration and Power Interface (ACPI) specification

View File

@@ -305,7 +305,6 @@ config EFI_CAPSULE_FIRMWARE_FIT
depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
select UPDATE_FIT
select DFU
select SET_DFU_ALT_INFO
select EFI_CAPSULE_FIRMWARE
help
Select this option if you want to enable firmware management protocol
@@ -317,7 +316,6 @@ config EFI_CAPSULE_FIRMWARE_RAW
depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT)
select DFU_WRITE_ALT
select DFU
select SET_DFU_ALT_INFO
select EFI_CAPSULE_FIRMWARE
help
Select this option if you want to enable firmware management protocol

View File

@@ -29,6 +29,7 @@ obj-y += efi_boottime.o
obj-y += efi_helper.o
obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o
obj-$(CONFIG_EFI_CAPSULE_AUTHENTICATE) += efi_capsule_key.o
obj-y += efi_console.o
obj-y += efi_device_path.o
obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o
@@ -73,6 +74,23 @@ obj-$(CONFIG_EFI_ECPT) += efi_conformance.o
EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE))
$(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE)
ifeq ($(CONFIG_EFI_CAPSULE_AUTHENTICATE),y)
capsule_crt_path=($(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE)))
capsule_crt_full=$(srctree)/$(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE))
quiet_cmd_capsule_esl_gen = CAPSULE_ESL_GEN $@
cmd_capsule_esl_gen = cert-to-efi-sig-list $(capsule_crt_full) $@
$(srctree)/capsule_esl_file: FORCE
@if [ ! -e "$(capsule_crt_full)" ]; then \
echo "ERROR: path $(capsule_crt_full) is invalid." >&2; \
echo "EFI CONFIG_EFI_CAPSULE_CRT_FILE must be specified when CONFIG_EFI_CAPSULE_AUTHENTICATE is enabled." >&2; \
exit 1; \
fi
$(call cmd,capsule_esl_gen)
$(obj)/efi_capsule.o: $(srctree)/capsule_esl_file FORCE
asflags-y += -DCAPSULE_ESL_PATH=\"$(srctree)/capsule_esl_file\"
endif
# Set the C flags to add and remove for each app
$(foreach f,$(apps-y),\
$(eval CFLAGS_$(f).o := $(CFLAGS_EFI) -Os -ffreestanding)\

View File

@@ -1,11 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Devicetree file with the public key EFI Signature List(ESL)
* node. This file is used to generate the dtsi file to be
* included into the DTB.
*/
/ {
signature {
capsule-key = /incbin/("ESL_BIN_FILE");
};
};

View File

@@ -7,6 +7,7 @@
#define LOG_CATEGORY LOGC_EFI
#include <bloblist.h>
#include <efi_loader.h>
#include <log.h>
#include <mapmem.h>
@@ -34,17 +35,29 @@ efi_status_t efi_acpi_register(void)
* add_u_boot_and_runtime(). At some point that function could create a
* more detailed map.
*/
if (IS_ENABLED(CONFIG_BLOBLIST_TABLES))
return EFI_SUCCESS;
if (IS_ENABLED(CONFIG_BLOBLIST_TABLES)) {
int size;
void *tab = bloblist_get_blob(BLOBLISTT_ACPI_TABLES, &size);
if (!tab)
return EFI_NOT_FOUND;
addr = map_to_sysmem(tab);
ret = efi_add_memory_map(addr, size,
EFI_ACPI_RECLAIM_MEMORY);
if (ret != EFI_SUCCESS)
return ret;
} else {
/* Mark space used for tables */
start = ALIGN_DOWN(gd->arch.table_start, EFI_PAGE_MASK);
end = ALIGN(gd->arch.table_end, EFI_PAGE_MASK);
ret = efi_add_memory_map(start, end - start, EFI_ACPI_RECLAIM_MEMORY);
ret = efi_add_memory_map(start, end - start,
EFI_ACPI_RECLAIM_MEMORY);
if (ret != EFI_SUCCESS)
return ret;
if (gd->arch.table_start_high) {
start = ALIGN_DOWN(gd->arch.table_start_high, EFI_PAGE_MASK);
start = ALIGN_DOWN(gd->arch.table_start_high,
EFI_PAGE_MASK);
end = ALIGN(gd->arch.table_end_high, EFI_PAGE_MASK);
ret = efi_add_memory_map(start, end - start,
EFI_ACPI_RECLAIM_MEMORY);
@@ -53,6 +66,7 @@ efi_status_t efi_acpi_register(void)
}
addr = gd_acpi_start();
}
log_debug("EFI using ACPI tables at %lx\n", addr);
/* And expose them to our EFI payload */

View File

@@ -204,6 +204,8 @@ out:
* @image: memory address of the UEFI image
* @size: size of the UEFI image
* @fdt: device-tree
* @initrd: initrd
* @initrd_sz: initrd size
* @dp_dev: EFI device-path
* @dp_img: EFI image-path
*
@@ -213,10 +215,12 @@ out:
* Return: status code
*/
static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt,
void *initrd, size_t initd_sz,
struct efi_device_path *dp_dev,
struct efi_device_path *dp_img)
{
efi_status_t ret;
struct efi_device_path *dp_initrd;
/* Initialize EFI drivers */
ret = efi_init_obj_list();
@@ -230,6 +234,14 @@ static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt,
if (ret != EFI_SUCCESS)
return ret;
dp_initrd = efi_dp_from_mem(EFI_LOADER_DATA, (uintptr_t)initrd, initd_sz);
if (!dp_initrd)
return EFI_OUT_OF_RESOURCES;
ret = efi_initrd_register(dp_initrd);
if (ret != EFI_SUCCESS)
return ret;
return efi_run_image(image, size, dp_dev, dp_img);
}
@@ -239,13 +251,15 @@ static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt,
* @image: memory address of the UEFI image
* @size: size of the UEFI image
* @fdt: device-tree
* @initrd: initrd
* @initrd_sz: initrd size
*
* Execute an EFI binary image loaded at @image.
* @size may be zero if the binary is loaded with U-Boot load command.
*
* Return: status code
*/
efi_status_t efi_binary_run(void *image, size_t size, void *fdt)
efi_status_t efi_binary_run(void *image, size_t size, void *fdt, void *initrd, size_t initrd_sz)
{
efi_handle_t mem_handle = NULL;
struct efi_device_path *file_path = NULL;
@@ -269,11 +283,14 @@ efi_status_t efi_binary_run(void *image, size_t size, void *fdt)
file_path, NULL);
if (ret != EFI_SUCCESS)
goto out;
bootefi_device_path = file_path;
bootefi_image_path = NULL;
} else {
log_debug("Loaded from disk\n");
}
ret = efi_binary_run_dp(image, size, fdt, bootefi_device_path,
ret = efi_binary_run_dp(image, size, fdt, initrd, initrd_sz, bootefi_device_path,
bootefi_image_path);
out:
if (mem_handle) {
@@ -355,7 +372,7 @@ efi_status_t efi_bootflow_run(struct bootflow *bflow)
log_debug("Booting with external fdt\n");
fdt = map_sysmem(bflow->fdt_addr, 0);
}
ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, device, image);
ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, NULL, 0, device, image);
return ret;
}

View File

@@ -685,12 +685,12 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
/* try to register load file2 for initrd's */
if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
ret = efi_initrd_register();
ret = efi_initrd_register(NULL);
if (ret != EFI_SUCCESS)
goto error;
}
log_info("Booting: %ls\n", lo.label);
log_info("Booting: Label: %ls Device path: %pD\n", lo.label, lo.file_path);
/* Ignore the optional data in auto-generated boot options */
if (size >= sizeof(efi_guid_t) &&

View File

@@ -22,6 +22,7 @@
#include <asm/global_data.h>
#include <u-boot/uuid.h>
#include <asm/sections.h>
#include <crypto/pkcs7.h>
#include <crypto/pkcs7_parser.h>
#include <linux/err.h>
@@ -284,33 +285,12 @@ out:
}
#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
static int efi_get_public_key_data(const void **pkey, efi_uintn_t *pkey_len)
{
const void *fdt_blob = gd->fdt_blob;
const void *blob;
const char *cnode_name = "capsule-key";
const char *snode_name = "signature";
int sig_node;
int len;
const void *blob = __efi_capsule_sig_begin;
const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin;
sig_node = fdt_subnode_offset(fdt_blob, 0, snode_name);
if (sig_node < 0) {
log_err("Unable to get signature node offset\n");
return -FDT_ERR_NOTFOUND;
}
blob = fdt_getprop(fdt_blob, sig_node, cnode_name, &len);
if (!blob || len < 0) {
log_err("Unable to get capsule-key value\n");
*pkey = NULL;
*pkey_len = 0;
return -FDT_ERR_NOTFOUND;
}
*pkey = (void *)blob;
*pkey = blob;
*pkey_len = len;
return 0;
@@ -321,7 +301,8 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s
{
u8 *buf;
int ret;
void *fdt_pkey, *pkey;
void *pkey;
const void *stored_pkey;
efi_uintn_t pkey_len;
uint64_t monotonic_count;
struct efi_signature_store *truststore;
@@ -373,7 +354,7 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s
goto out;
}
ret = efi_get_public_key_data(&fdt_pkey, &pkey_len);
ret = efi_get_public_key_data(&stored_pkey, &pkey_len);
if (ret < 0)
goto out;
@@ -381,7 +362,7 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s
if (!pkey)
goto out;
memcpy(pkey, fdt_pkey, pkey_len);
memcpy(pkey, stored_pkey, pkey_len);
truststore = efi_build_signature_store(pkey, pkey_len);
if (!truststore)
goto out;

View File

@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* .esl cert for capsule authentication
*
* Copyright (c) 2021, Ilias Apalodimas <ilias.apalodimas@linaro.org>
*/
#include <config.h>
.section .rodata.capsule_key.init,"a"
.balign 16
.global __efi_capsule_sig_begin
__efi_capsule_sig_begin:
.incbin CAPSULE_ESL_PATH
__efi_capsule_sig_end:
.global __efi_capsule_sig_end
.balign 16

View File

@@ -168,7 +168,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb,
/* Check size */
required_size = fdt_off_dt_strings(dtb) +
fdt_size_dt_strings(dtb) +
0x3000;
CONFIG_SYS_FDT_PAD;
total_size = fdt_totalsize(dtb);
if (required_size < total_size)
required_size = total_size;

View File

@@ -56,11 +56,6 @@ struct fmp_state {
u32 last_attempt_status; /* not used */
};
__weak void set_dfu_alt_info(char *interface, char *devstr)
{
env_set("dfu_alt_info", update_info.dfu_string);
}
/**
* efi_firmware_get_image_type_id - get image_type_id
* @image_index: image index
@@ -649,8 +644,10 @@ efi_status_t EFIAPI efi_firmware_fit_set_image(
efi_status_t (*progress)(efi_uintn_t completion),
u16 **abort_reason)
{
int ret;
efi_status_t status;
struct fmp_state state = { 0 };
char *orig_dfu_env;
EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
image_size, vendor_code, progress, abort_reason);
@@ -663,7 +660,28 @@ efi_status_t EFIAPI efi_firmware_fit_set_image(
if (status != EFI_SUCCESS)
return EFI_EXIT(status);
if (fit_update(image))
orig_dfu_env = env_get("dfu_alt_info");
if (orig_dfu_env) {
orig_dfu_env = strdup(orig_dfu_env);
if (!orig_dfu_env) {
log_err("strdup() failed!\n");
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
}
if (env_set("dfu_alt_info", update_info.dfu_string)) {
log_err("Unable to set env variable \"dfu_alt_info\"!\n");
free(orig_dfu_env);
return EFI_EXIT(EFI_DEVICE_ERROR);
}
ret = fit_update(image);
if (env_set("dfu_alt_info", orig_dfu_env))
log_warning("Unable to restore env variable \"dfu_alt_info\". Further DFU operations may fail!\n");
free(orig_dfu_env);
if (ret)
return EFI_EXIT(EFI_DEVICE_ERROR);
efi_firmware_set_fmp_state_var(&state, image_index);
@@ -717,6 +735,7 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
u8 dfu_alt_num;
efi_status_t status;
struct fmp_state state = { 0 };
char *orig_dfu_env;
EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
image_size, vendor_code, progress, abort_reason);
@@ -747,8 +766,29 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
}
}
if (dfu_write_by_alt(dfu_alt_num, (void *)image, image_size,
NULL, NULL))
orig_dfu_env = env_get("dfu_alt_info");
if (orig_dfu_env) {
orig_dfu_env = strdup(orig_dfu_env);
if (!orig_dfu_env) {
log_err("strdup() failed!\n");
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
}
if (env_set("dfu_alt_info", update_info.dfu_string)) {
log_err("Unable to set env variable \"dfu_alt_info\"!\n");
free(orig_dfu_env);
return EFI_EXIT(EFI_DEVICE_ERROR);
}
ret = dfu_write_by_alt(dfu_alt_num, (void *)image, image_size,
NULL, NULL);
if (env_set("dfu_alt_info", orig_dfu_env))
log_warning("Unable to restore env variable \"dfu_alt_info\". Further DFU operations may fail!\n");
free(orig_dfu_env);
if (ret)
return EFI_EXIT(EFI_DEVICE_ERROR);
efi_firmware_set_fmp_state_var(&state, image_index);

View File

@@ -485,7 +485,7 @@ static efi_status_t copy_fdt(void **fdtp)
* needs to be expanded later.
*/
fdt = *fdtp;
fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000);
fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + CONFIG_SYS_FDT_PAD);
fdt_size = fdt_pages << EFI_PAGE_SHIFT;
ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,

View File

@@ -343,6 +343,9 @@ static struct efi_hii_packagelist *new_packagelist(void)
struct efi_hii_packagelist *hii;
hii = malloc(sizeof(*hii));
if (!hii)
return NULL;
list_add_tail(&hii->link, &efi_package_lists);
hii->max_string_id = 0;
INIT_LIST_HEAD(&hii->string_tables);

View File

@@ -42,6 +42,7 @@ static const struct efi_lo_dp_prefix dp_lf2_handle = {
};
static efi_handle_t efi_initrd_handle;
static struct efi_device_path *efi_initrd_dp;
/**
* get_initrd_fp() - Get initrd device path from a FilePathList device path
@@ -72,6 +73,41 @@ static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp)
return EFI_SUCCESS;
}
/**
* efi_initrd_from_mem() - load initial RAM disk from memory
*
* This function copies the initrd from the memory mapped device
* path pointed to by efi_initrd_dp
*
* @buffer_size: size of allocated buffer
* @buffer: buffer to load the file
*
* Return: status code
*/
static efi_status_t efi_initrd_from_mem(efi_uintn_t *buffer_size, void *buffer)
{
efi_status_t ret = EFI_NOT_FOUND;
efi_uintn_t bs;
struct efi_device_path_memory *mdp;
mdp = (struct efi_device_path_memory *)efi_initrd_dp;
if (!mdp)
return ret;
bs = mdp->end_address - mdp->start_address;
if (!buffer || *buffer_size < bs) {
ret = EFI_BUFFER_TOO_SMALL;
*buffer_size = bs;
} else {
memcpy(buffer, (void *)(uintptr_t)mdp->start_address, bs);
*buffer_size = bs;
ret = EFI_SUCCESS;
}
return ret;
}
/**
* efi_load_file2_initrd() - load initial RAM disk
*
@@ -118,6 +154,9 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
goto out;
}
if (efi_initrd_dp)
return EFI_EXIT(efi_initrd_from_mem(buffer_size, buffer));
ret = get_initrd_fp(&initrd_fp);
if (ret != EFI_SUCCESS)
goto out;
@@ -209,6 +248,9 @@ efi_status_t efi_initrd_deregister(void)
NULL);
efi_initrd_handle = NULL;
efi_free_pool(efi_initrd_dp);
efi_initrd_dp = NULL;
return ret;
}
@@ -234,15 +276,21 @@ static void EFIAPI efi_initrd_return_notify(struct efi_event *event,
* This function creates a new handle and installs a Linux specific vendor
* device path and an EFI_LOAD_FILE2_PROTOCOL. Linux uses the device path
* to identify the handle and then calls the LoadFile service of the
* EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk.
* EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk. If dp_initrd is
* not provided, the initrd will be taken from the BootCurrent variable
*
* @dp_initrd: optional device path containing an initrd
*
* Return: status code
*/
efi_status_t efi_initrd_register(void)
efi_status_t efi_initrd_register(struct efi_device_path *dp_initrd)
{
efi_status_t ret;
struct efi_event *event;
if (dp_initrd) {
efi_initrd_dp = dp_initrd;
} else {
/*
* Allow the user to continue if Boot#### file path is not set for
* an initrd
@@ -252,6 +300,7 @@ efi_status_t efi_initrd_register(void)
return EFI_SUCCESS;
if (ret != EFI_SUCCESS)
return ret;
}
ret = efi_install_multiple_protocol_interfaces(&efi_initrd_handle,
/* initramfs */

View File

@@ -609,7 +609,6 @@ static int test_hii_database_get_package_list_handle(void)
result = EFI_ST_SUCCESS;
out:
if (handle) {
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
@@ -617,7 +616,6 @@ out:
(unsigned int)ret);
return EFI_ST_FAILURE;
}
}
return result;
}
@@ -711,7 +709,6 @@ static int test_hii_string_new_string(void)
result = EFI_ST_SUCCESS;
out:
if (handle) {
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
@@ -719,7 +716,6 @@ out:
(unsigned int)ret);
return EFI_ST_FAILURE;
}
}
return result;
}
@@ -792,7 +788,6 @@ static int test_hii_string_get_string(void)
result = EFI_ST_SUCCESS;
out:
if (handle) {
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
@@ -800,7 +795,6 @@ out:
(unsigned int)ret);
return EFI_ST_FAILURE;
}
}
return result;
}
@@ -851,7 +845,6 @@ static int test_hii_string_set_string(void)
result = EFI_ST_SUCCESS;
out:
if (handle) {
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
@@ -859,7 +852,6 @@ out:
(unsigned int)ret);
return EFI_ST_FAILURE;
}
}
return result;
}
@@ -918,7 +910,6 @@ static int test_hii_string_get_languages(void)
result = EFI_ST_SUCCESS;
out:
if (handle) {
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
@@ -926,7 +917,6 @@ out:
(unsigned int)ret);
return EFI_ST_FAILURE;
}
}
return result;
}
@@ -991,7 +981,6 @@ static int test_hii_string_get_secondary_languages(void)
result = EFI_ST_SUCCESS;
out:
if (handle) {
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
@@ -999,7 +988,6 @@ out:
(unsigned int)ret);
return EFI_ST_FAILURE;
}
}
return result;
}

View File

@@ -377,35 +377,8 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
; \
sed "s:$(pre-tmp):$(<):" $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
capsule_esl_input_file=$(srctree)/lib/efi_loader/capsule_esl.dtsi.in
capsule_crt_file=$(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE))
capsule_esl_dtsi=.capsule_esl.dtsi
quiet_cmd_capsule_esl_gen = CAPSULE_ESL_GEN $@
cmd_capsule_esl_gen = cert-to-efi-sig-list $< $@
$(obj)/capsule_esl_file: $(capsule_crt_file) FORCE
ifeq ($(CONFIG_EFI_CAPSULE_CRT_FILE),"")
$(error "CONFIG_EFI_CAPSULE_CRT_FILE is empty, EFI capsule authentication \
public key must be specified when CONFIG_EFI_CAPSULE_AUTHENTICATE is enabled")
else
$(call cmd,capsule_esl_gen)
endif
quiet_cmd_capsule_dtsi_gen = CAPSULE_DTSI_GEN $@
cmd_capsule_dtsi_gen = \
$(shell sed "s:ESL_BIN_FILE:$(abspath $<):" $(capsule_esl_input_file) > $@)
$(obj)/$(capsule_esl_dtsi): $(obj)/capsule_esl_file FORCE
$(call cmd,capsule_dtsi_gen)
dtsi_include_list_deps := $(addprefix $(u_boot_dtsi_loc),$(subst $(quote),,$(dtsi_include_list)))
ifdef CONFIG_EFI_CAPSULE_AUTHENTICATE
dtsi_include_list += $(capsule_esl_dtsi)
dtsi_include_list_deps += $(obj)/$(capsule_esl_dtsi)
endif
ifneq ($(CHECK_DTBS),)
DT_CHECKER ?= dt-validate
DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m)

View File

@@ -247,7 +247,7 @@ Setting up
section is ignored. If more than one line is provided, only the last one
is taken.
#. Make sure you have the require Python pre-requisites
#. Make sure you have the required Python pre-requisites
Buildman uses multiprocessing, Queue, shutil, StringIO, ConfigParser and
urllib2. These should normally be available, but if you get an error like