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
+1 -1
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 \
@@ -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;
-8
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;
@@ -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
@@ -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
@@ -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
-8
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)
{
-8
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;
-8
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;
-8
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;
-8
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;
-8
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;
+3
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 */
+7 -9
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
+7 -9
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
+7 -9
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)
+3 -1
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;
}
+1
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
+1 -1
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;
+25
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,
+2 -1
View File
@@ -169,7 +169,8 @@ static int initr_reloc_global_data(void)
*/
efi_save_gd();
efi_runtime_relocate(gd->relocaddr, NULL);
if (!(gd->flags & GD_FLG_SKIP_RELOC))
efi_runtime_relocate(gd->relocaddr, NULL);
#endif
/*
-15
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
************************
+1
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.
+2
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[];
+2 -2
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 */
/**
+1
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
-2
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
+18
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)\
-11
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");
};
};
+27 -13
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,25 +35,38 @@ 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);
/* 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);
if (ret != EFI_SUCCESS)
return ret;
if (gd->arch.table_start_high) {
start = ALIGN_DOWN(gd->arch.table_start_high, EFI_PAGE_MASK);
end = ALIGN(gd->arch.table_end_high, EFI_PAGE_MASK);
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);
if (ret != EFI_SUCCESS)
return ret;
}
if (gd->arch.table_start_high) {
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);
if (ret != EFI_SUCCESS)
return ret;
}
addr = gd_acpi_start();
addr = gd_acpi_start();
}
log_debug("EFI using ACPI tables at %lx\n", addr);
/* And expose them to our EFI payload */
+20 -3
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;
}
+2 -2
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) &&
+9 -28
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;
+17
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
+1 -1
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;
+48 -8
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);
+1 -1
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,
+3
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);
+60 -11
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,24 +276,31 @@ 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;
/*
* Allow the user to continue if Boot#### file path is not set for
* an initrd
*/
ret = check_initrd();
if (ret == EFI_INVALID_PARAMETER)
return EFI_SUCCESS;
if (ret != EFI_SUCCESS)
return ret;
if (dp_initrd) {
efi_initrd_dp = dp_initrd;
} else {
/*
* Allow the user to continue if Boot#### file path is not set for
* an initrd
*/
ret = check_initrd();
if (ret == EFI_INVALID_PARAMETER)
return EFI_SUCCESS;
if (ret != EFI_SUCCESS)
return ret;
}
ret = efi_install_multiple_protocol_interfaces(&efi_initrd_handle,
/* initramfs */
+36 -48
View File
@@ -609,14 +609,12 @@ 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) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
return result;
@@ -711,14 +709,12 @@ 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) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
return result;
@@ -792,14 +788,12 @@ 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) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
return result;
@@ -851,14 +845,12 @@ 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) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
return result;
@@ -918,14 +910,12 @@ 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) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
return result;
@@ -991,14 +981,12 @@ 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) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
ret = hii_database_protocol->remove_package_list(
hii_database_protocol, handle);
if (ret != EFI_SUCCESS) {
efi_st_error("remove_package_list returned %u\n",
(unsigned int)ret);
return EFI_ST_FAILURE;
}
return result;
-27
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)
+1 -1
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