Pull request efi-2024-10-rc1-2

Documentation:
 
 * use current versions of certifi and urllib3 for building documentation
 * add bootelf command documentation
 * correct the description of the Goldfish RTC driver
 * correct heading level of itest examples
 
 UEFI:
 
 * print device-tree in dtbdump.efi
 * consider CONFIG_EFI_IGNORE_OSINDICATIONS in TestEfiCapsuleFirmwareRaw
 * correct cmd_capsule_esl_gen invocation in scripts/Makefile.lib
 * use capsule CRT instead of ESL file when building capsules
 
 Others:
 
 * let ENV_IS_IN_EXT4 enable SYS_MMC_ENV_DEV
 * check if CONFIG_SYS_MMC_ENV_DEV is defined in mmc_get_env_dev
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEK7wKXt3/btL6/yA+hO4vgnE3U0sFAmaTrUYACgkQhO4vgnE3
 U0uMQA/8CfOBbJIROwz6EScjAFfY720+yBg1VtvE9fDy7XpHAUXNBcM62A/6g+tq
 7r+0Fs/fhVwyo/IDodBsM8DtDeUk/C3j/ZxYIyHlikHDEsg1sp7RdeMU+Dn4Vomi
 PXSb6dAAPryUPeWFjmdNRwdsDd17mAzBD/J0HemEOLdECkOdgbndiXI1jFFX+HZL
 sTkdUmugQRPob/ex3T7qqbI3Mz1gvmDGwu7udUnCV+y4giFm1BjLJEGM1Mk6WQpb
 AKajHT0g+2tsPGTaCiIa+8erXaWovNBM6CvG7jqiG6zJSVsoE7qOU6k3/CVWMLUY
 KW8BXZBfZ/J/AzcifE89GMLAykZHz3ZGfO60Fff++r7YldmWpNHQ+4iIsamZ4UN0
 lfMCdgPPc71FnWPb5P5I3afhp1EUmtR/IOPPRavgfqlvsbDiMZghgIrDLo813d8z
 yi1XGu4VQ9QwD5G10P1ldhhW6aS2GH0iixUFi8XydyymvtfFJS+9clqyURwLZbdT
 hf8q2AZtOiLZMc5Jl1cYupDOFUvx/+Q9Ug1imJNfj7vxhuTbTHxgjzjlxu1BkO7V
 QyBLPuPTqV9k4m9gCK9Zyz5KJ24xFIFew3KkKiJeLZGTOSwMioOVZjxYjb4clzfY
 QSdgfC8OeOfho1kVpuY69Aav0Oeow6BQ1V7eGUxi9hks6IRm2Fw=
 =A4Qj
 -----END PGP SIGNATURE-----

Merge tag 'efi-2024-10-rc1-2' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request efi-2024-10-rc1-2

Documentation:

* use current versions of certifi and urllib3 for building documentation
* add bootelf command documentation
* correct the description of the Goldfish RTC driver
* correct heading level of itest examples

UEFI:

* print device-tree in dtbdump.efi
* consider CONFIG_EFI_IGNORE_OSINDICATIONS in TestEfiCapsuleFirmwareRaw
* correct cmd_capsule_esl_gen invocation in scripts/Makefile.lib
* use capsule CRT instead of ESL file when building capsules

Others:

* let ENV_IS_IN_EXT4 enable SYS_MMC_ENV_DEV
* check if CONFIG_SYS_MMC_ENV_DEV is defined in mmc_get_env_dev
This commit is contained in:
Tom Rini 2024-07-15 08:21:46 -06:00
commit 5e9c055f90
15 changed files with 376 additions and 32 deletions

View File

@ -515,7 +515,7 @@ int board_mmc_init(struct bd_info *bis)
return 0;
}
#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
#ifdef CONFIG_SYS_MMC_ENV_DEV
int mmc_get_env_dev(void)
{
switch (sunxi_get_boot_device()) {

View File

@ -353,7 +353,7 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
CONFIG_EFI_CAPSULE_ON_DISK=y
CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_EFI_CAPSULE_AUTHENTICATE=y
CONFIG_EFI_CAPSULE_ESL_FILE="board/sandbox/capsule_pub_esl_good.esl"
CONFIG_EFI_CAPSULE_CRT_FILE="board/sandbox/capsule_pub_key_good.crt"
CONFIG_EFI_SECURE_BOOT=y
CONFIG_TEST_FDTDEC=y
CONFIG_UNIT_TEST=y

View File

@ -227,7 +227,7 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
CONFIG_EFI_CAPSULE_ON_DISK=y
CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y
CONFIG_EFI_CAPSULE_AUTHENTICATE=y
CONFIG_EFI_CAPSULE_ESL_FILE="board/sandbox/capsule_pub_esl_good.esl"
CONFIG_EFI_CAPSULE_CRT_FILE="board/sandbox/capsule_pub_key_good.crt"
CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y

View File

@ -580,10 +580,10 @@ and used by the steps highlighted below.
}
You can perform step-4 through the Kconfig symbol
CONFIG_EFI_CAPSULE_ESL_FILE. This symbol points to the esl file
generated in step-2. Once the symbol has been populated with the path
to the esl file, it will automatically get embedded into the
platform's dtb as part of U-Boot build.
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

@ -1,6 +1,6 @@
alabaster==0.7.16
Babel==2.15.0
certifi==2024.6.2
certifi==2024.7.4
charset-normalizer==3.3.2
docutils==0.20.1
idna==3.7
@ -22,4 +22,4 @@ sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.7
sphinxcontrib-serializinghtml==1.1.10
urllib3==2.2.1
urllib3==2.2.2

61
doc/usage/cmd/bootelf.rst Normal file
View File

@ -0,0 +1,61 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
.. Copyright 2024, Maxim Moskalets <maximmosk4@gmail.com>
.. index::
single: bootelf (command)
bootelf command
===============
Synopsis
--------
::
bootelf [-p|-s] [-d <fdt_addr>] [<image_addr> [<arg>]...]
Description
-----------
The *bootelf* command is used to launch a ELF binary at *image_addr*. If
*image_addr* is not specified, the bootelf command will try to find image in
*image_load_addr* variable (*CONFIG\_SYS\_LOAD\_ADDR* by default).
Args after *image_addr* will be passed to application in common *argc*, *argv*
format.
A command sequence to run a ELF image using FDT might look like
::
load mmc 0:1 ${loadaddr} /kernel.elf
load mmc 0:1 ${fdt_addr_r} /soc-board.dtb
bootelf -d ${fdt_addr_r} ${loadaddr} ${loadaddr}
image_addr
Address of the ELF binary.
fdt_addr
Address of the device-tree. This argument in only needed if bootable
application uses FDT that requires additional setup (like /memory node).
arg
Any text arguments for bootable application. This is usually the address
of the device-tree.
Flags:
-p
Load ELF image via program headers.
-s
Load ELF image via section headers.
-d
Setup FDT by address.
Configuration
-------------
The bootelf command is only available if CONFIG_CMD_ELF=y. FDT setup by flag -d
need CONFIG_CMD_ELF_FDT_SETUP=y.

View File

@ -58,7 +58,7 @@ op
======== ======================
Examples
========
--------
The itest command sets the result variable $? to true (0) or false (1):

View File

@ -33,6 +33,7 @@ Shell commands
cmd/bootd
cmd/bootdev
cmd/bootefi
cmd/bootelf
cmd/bootflow
cmd/booti
cmd/bootm

View File

@ -2,7 +2,9 @@
/*
* Copyright 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
*
* This driver emulates a real time clock based on timer ticks.
* This driver supports the Google Goldfish virtual platform RTC device.
* The device is provided by the RISC-V virt machine in QEMU. It exposes
* a 64-bit nanosecond timer via two memory-mapped 32-bit registers.
*/
#include <div64.h>

2
env/Kconfig vendored
View File

@ -655,7 +655,7 @@ config SYS_RELOC_GD_ENV_ADDR
config SYS_MMC_ENV_DEV
int "mmc device number"
depends on ENV_IS_IN_MMC || ENV_IS_IN_FAT || \
depends on ENV_IS_IN_MMC || ENV_IS_IN_FAT || ENV_IS_IN_EXT4 || \
CMD_MVEBU_BUBT || FMAN_ENET || QE || PHY_CORTINA
default 0
help

View File

@ -298,13 +298,15 @@ config EFI_CAPSULE_MAX
Select the max capsule index value used for capsule report
variables. This value is used to create CapsuleMax variable.
config EFI_CAPSULE_ESL_FILE
string "Path to the EFI Signature List File"
config EFI_CAPSULE_CRT_FILE
string "Path to the EFI capsule public key certificate"
depends on EFI_CAPSULE_AUTHENTICATE
help
Provides the path to the EFI Signature List file which will
be embedded in the platform's device tree and used for
capsule authentication at the time of capsule update.
Provides the path to the EFI capsule public key certificate that
corresponds to the capsule signing key. This certificate will be used
to generate the EFI capsule ESL (signature list file) that gets
embedded in the platform's device tree and used for capsule
authentication at the time of capsule update.
config EFI_DEVICE_PATH_TO_TEXT
bool "Device path to text protocol"

View File

@ -40,6 +40,53 @@ static void print(u16 *string)
cout->output_string(cout, string);
}
/**
* print_char() - print character
*
* 0x00 is replaced by '", "'.
*
* @c: - character
*/
static void print_char(unsigned char c)
{
u16 out[2] = u"?";
if (!c) {
print(u"\", \"");
return;
}
if (c > 0x1f && c < 0x80)
out[0] = c;
print(out);
}
/**
* print_hex_digit() - print hexadecimal digit
*
* @digit: digit to print
*/
static void print_hex_digit(unsigned char digit)
{
if (digit < 10)
digit += '0';
else
digit += 'a' - 10;
print_char(digit);
}
/**
* printx() - print hexadecimal byte
*
* @val: value to print
*/
static void printx(unsigned char val)
{
print_hex_digit(val >> 4);
print_hex_digit(val & 0xf);
}
/**
* error() - print error string
*
@ -227,6 +274,7 @@ bool starts_with(u16 *string, u16 *keyword)
*/
void do_help(void)
{
error(u"dump - print device-tree\r\n");
error(u"load <dtb> - load device-tree from file\r\n");
error(u"save <dtb> - save device-tree to file\r\n");
error(u"exit - exit the shell\r\n");
@ -489,6 +537,217 @@ efi_status_t do_save(u16 *filename)
return ret;
}
/**
* indent() - print a number of tabstops
*
* @level: indentation level
*/
static void indent(u32 level)
{
for (; level; --level)
print(u"\t");
}
/**
* is_string_value() - determine if property is a string
*
* If a property is a string, an x-string, or a u32 cannot be deducted
* from the device-tree. Therefore a heuristic is used.
*
* @str: pointer to device-tree property
* @len: length of the device-tree property
* Return: 1 for string, 0 otherwise
*/
static int is_string_value(const unsigned char *str, u32 len)
{
int nonzero_flag = 0;
/* Zero length or not ending with 0x00 */
if (!len || str[len - 1])
return 0;
for (u32 i = 0; i < len; ++i) {
if (!str[i]) {
/* Zero length string or two consecutive 0x00 */
if (!nonzero_flag)
return 0;
nonzero_flag = 0;
continue;
}
/* Non-printable */
if (str[i] < 0x20 || str[i] >= 0x80)
return 0;
nonzero_flag = 1;
}
return 1;
}
/**
* print_property() - print device-tree property
*
* If a property is a string, an x-string, or a u32 cannot be deducted
* from the device-tree. Therefore a heuristic is used.
*
* @str: property value
* @len: length of property value
*/
static void print_property(const unsigned char *val, u32 len)
{
if (is_string_value(val, len)) {
/* string */
print(u"\"");
for (int i = 0; i < len - 1; ++i)
print_char(val[i]);
print(u"\"");
} else if (len & 0x3) {
/* byte string */
print(u"[");
for (int i = 0; i < len; ++i) {
if (i)
print(u" ");
printx(val[i]);
}
print(u"]\"");
} else {
/* cell list */
print(u"<");
for (u32 i = 0; i < len; ++i) {
if ((i & 0x3) == 0) {
if (i > 0)
print(u" ");
print(u"0x");
}
printx(val[i]);
}
print(u">");
}
}
/**
* print_mem_res_block() - print memory reservation block
*
* @rsvblk: memory reservation block
*/
static void print_mem_res_block(const struct fdt_reserve_entry *rsvblk)
{
for (; rsvblk->address || rsvblk->size; ++rsvblk) {
const unsigned char *val;
print(u"/memreserve/ 0x");
val = (const unsigned char *)&rsvblk->address;
for (u32 i = 0; i < sizeof(u64); ++i)
printx(val[i]);
print(u" 0x");
val = (const unsigned char *)&rsvblk->size;
for (u32 i = 0; i < sizeof(u64); ++i)
printx(val[i]);
print(u";\r\n");
}
}
/**
* do_dump() - print device-tree
*/
static efi_status_t do_dump(void)
{
const unsigned char *fdt;
struct fdt_header *header;
const u32 *end;
const u32 *pos;
const char *strings;
u32 level = 0;
fdt = get_dtb(systable);
if (!fdt) {
error(u"DTB not found\r\n");
return EFI_NOT_FOUND;
}
header = (struct fdt_header *)fdt;
if (f2h(header->magic) != FDT_MAGIC) {
error(u"Wrong device tree magic\r\n");
error(u"Not a device-tree\r\n");
return EFI_LOAD_ERROR;
}
pos = (u32 *)(fdt + f2h(header->off_dt_struct));
end = &pos[f2h(header->totalsize) >> 2];
strings = fdt + f2h(header->off_dt_strings);
print(u"/dts-v1/;\r\n");
print_mem_res_block((const struct fdt_reserve_entry *)
(fdt + f2h(header->off_mem_rsvmap)));
print(u"/");
for (; pos < end;) {
switch (f2h(pos[0])) {
case FDT_BEGIN_NODE: {
const char *c = (char *)&pos[1];
size_t i;
indent(level);
for (i = 0; c[i]; ++i)
print_char(c[i]);
print(u" {\n\r");
++level;
pos = &pos[2 + (i >> 2)];
break;
}
case FDT_PROP: {
struct fdt_property *prop = (struct fdt_property *)pos;
const unsigned char *label = &strings[f2h(prop->nameoff)];
u32 len = f2h(prop->len);
const unsigned char *str = (unsigned char *)&pos[3];
indent(level);
for (int i = 0; label[i]; ++i)
print_char(label[i]);
if (len) {
print(u" = ");
print_property(str, len);
}
print(u";\r\n");
pos = &pos[3 + ((f2h(prop->len) + 3) >> 2)];
break;
}
case FDT_NOP:
++pos;
break;
case FDT_END_NODE:
if (!level) {
error(u"Extraneous end node\r\n");
return EFI_LOAD_ERROR;
}
--level;
indent(level);
print(u"};\n\r");
++pos;
break;
case FDT_END:
if (level) {
error(u"Missing end node\r\n");
return EFI_LOAD_ERROR;
}
return EFI_SUCCESS;
default:
error(u"Invalid device tree token\r\n");
return EFI_LOAD_ERROR;
}
}
error(u"Overrun\r\n");
return EFI_LOAD_ERROR;
}
/**
* efi_main() - entry point of the EFI application.
*
@ -524,6 +783,8 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
pos = skip_whitespace(command);
if (starts_with(pos, u"exit"))
break;
else if (starts_with(pos, u"dump"))
do_dump();
else if (starts_with(pos, u"load "))
do_load(pos + 5);
else if (starts_with(pos, u"save "))

View File

@ -342,21 +342,27 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
; \
sed "s:$(pre-tmp):$(<):" $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
quiet_cmd_capsule_esl_gen = CAPSULE_ESL_GEN $@
cmd_capsule_esl_gen = \
$(shell sed "s:ESL_BIN_FILE:$(capsule_esl_path):" $(capsule_esl_input_file) > $@)
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
$(obj)/.capsule_esl.dtsi: FORCE
ifeq ($(CONFIG_EFI_CAPSULE_ESL_FILE),"")
$(error "CONFIG_EFI_CAPSULE_ESL_FILE is empty, EFI capsule authentication \
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)
$(call cmd,capsule_esl_gen)
endif
capsule_esl_input_file=$(srctree)/lib/efi_loader/capsule_esl.dtsi.in
capsule_esl_dtsi = .capsule_esl.dtsi
capsule_esl_path=$(abspath $(srctree)/$(subst $(quote),,$(CONFIG_EFI_CAPSULE_ESL_FILE)))
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)))

View File

@ -76,7 +76,7 @@ class TestEfiCapsuleFirmwareRaw:
self, u_boot_config, u_boot_console, efi_capsule_data):
""" Test Case 2
Update U-Boot and U-Boot environment on SPI Flash but with OsIndications unset
No update should happen
No update should happen unless CONFIG_EFI_IGNORE_OSINDICATIONS is set
0x100000-0x150000: U-Boot binary (but dummy)
0x150000-0x200000: U-Boot environment (but dummy)
"""
@ -91,16 +91,27 @@ class TestEfiCapsuleFirmwareRaw:
# reboot
u_boot_console.restart_uboot()
ignore_os_indications = u_boot_config.buildconfig.get(
'config_efi_ignore_osindications')
need_reboot = True if ignore_os_indications else False
capsule_auth = u_boot_config.buildconfig.get(
'config_efi_capsule_authenticate')
capsule_early = u_boot_config.buildconfig.get(
'config_efi_capsule_on_disk_early')
with u_boot_console.log.section('Test Case 2-b, after reboot'):
if not capsule_early:
exec_manual_update(u_boot_console, disk_img, capsule_files, False)
exec_manual_update(u_boot_console, disk_img, capsule_files, need_reboot)
check_file_exist(u_boot_console, disk_img, capsule_files)
if not ignore_os_indications:
check_file_exist(u_boot_console, disk_img, capsule_files)
verify_content(u_boot_console, '100000', 'u-boot:Old')
verify_content(u_boot_console, '150000', 'u-boot-env:Old')
expected = 'u-boot:New' if (ignore_os_indications and not capsule_auth) else 'u-boot:Old'
verify_content(u_boot_console, '100000', expected)
expected = 'u-boot-env:New' if (ignore_os_indications and not capsule_auth) else 'u-boot-env:Old'
verify_content(u_boot_console, '150000', expected)
def test_efi_capsule_fw3(
self, u_boot_config, u_boot_console, efi_capsule_data):