Compare commits

...

2 Commits
extj ... appd

Author SHA1 Message Date
Simon Glass
aaa5af43b7 efi_loader: Support loading devicetree from a FIT
Where an EFI app is loaded separately from the devicetree, it is useful
to be able to read the devicetree from a FIT. This allows use of the
automatic mechanism described in the spec:

   https://fitspec.osfw.foundation/#select-a-configuration-to-boot

For now there is no test for this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Series-changes: 1
- Correct behaviour when there is actually no FIT

Series-to: heinrich
2025-06-01 12:50:34 +01:00
Simon Glass
9477143a16 doc: efi_loader: Tidy up the bootefi-command docs
There are backslashes in some of the tags which seems to be unnecessary.
Remove then.

Change the word 'either' to 'any' since there are three options.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-06-01 10:54:34 +01:00
2 changed files with 78 additions and 13 deletions

View File

@@ -119,6 +119,62 @@ static int do_efi_selftest(void)
return ret != EFI_SUCCESS;
}
/**
* locate_fdt() - Figure out the FDT to use, either from an arg or FIT
*
* @arg: Argument to process
* @fdtp: Returns devicetree located, on success
* Return: 0 on success, -ve on error
*
*
* The argument is in one of two formats:
*
* fit_addr
* fit_addr[#<conf>[#extra-conf]]
*
* In the first case, a pointer to the given address is simply returned. In the
* second case, the FIT is scanned to select the correct FDT, which is then
* returned
*/
static int locate_fdt(const char *arg, void **fdtp)
{
ulong addr;
void *buf;
char *ep;
addr = hextoul(arg, &ep);
buf = map_sysmem(addr, 0);
if (CONFIG_IS_ENABLED(FIT)) {
/* if it's not a valid FIT, bail out */
if (fit_check_format(buf, IMAGE_SIZE_INVAL)) {
/*
* complain if it looks like the user is trying to use
* a FIT
*/
if (*ep == '#')
return -EINVAL;
*fdtp = buf;
} else {
struct bootm_headers images = {};
ulong size;
char *fdt;
int ret;
/* read the devicetree from the FIT */
ret = boot_get_fdt(NULL, arg, IH_ARCH_DEFAULT, &images,
&fdt, &size);
if (ret)
return ret;
*fdtp = fdt;
}
} else {
*fdtp = buf;
}
return 0;
}
/**
* do_bootefi() - execute `bootefi` command
*
@@ -142,10 +198,13 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_USAGE;
if (argc > 2) {
uintptr_t fdt_addr;
int eret;
fdt_addr = hextoul(argv[2], NULL);
fdt = map_sysmem(fdt_addr, 0);
eret = locate_fdt(argv[2], &fdt);
if (eret) {
log_err("Cannot obtain devicetree (err %dE)\n", eret);
return CMD_RET_FAILURE;
}
} else {
fdt = EFI_FDT_USE_INTERNAL;
}

View File

@@ -13,6 +13,7 @@ Synopsis
::
bootefi <image_addr>[:<image_size>] [<fdt_addr>]
bootefi <image_addr>[:<image_size>] fit_addr[#<conf>[#extra-conf]]
bootefi bootmgr [<fdt_addr>]
bootefi hello [<fdt_addr>]
bootefi selftest [<fdt_addr>]
@@ -20,19 +21,19 @@ Synopsis
Description
-----------
The *bootefi* command is used to launch a UEFI binary which can be either of
The *bootefi* command is used to launch a UEFI binary which can be any of
* UEFI application
* UEFI boot services driver
* UEFI run-time services driver
An operating system requires a hardware description which can either be
presented as ACPI table (CONFIG\_GENERATE\_ACPI\_TABLE=y) or as device-tree.
The load address of the device-tree may be provided as parameter *fdt\_addr*. If
presented as ACPI table (CONFIG_GENERATE_ACPI_TABLE=y) or as device-tree.
The load address of the device-tree may be provided as parameter *fdt_addr*. If
this address is not specified, the bootefi command will try to fall back in
sequence to:
* the device-tree specified by environment variable *fdt\_addr*
* the device-tree specified by environment variable *fdt_addr*
* the device-tree specified by environment variable *fdtcontroladdr*
The load address of the binary is specified by parameter *image_address*. A
@@ -60,6 +61,11 @@ fdt_addr
U-Boot's internal device-tree $fdtcontroladdr as second fallback.
When using ACPI no device-tree shall be specified.
fit_addr
Address of a :doc:`../fit/index` and optional configuration specifiers for
the devicetree to use. The devicetree is loaded from the selected (or
default) configuration.
image_size
Size of the UEFI binary file. This argument is only needed if *image_addr*
does not match the address of the last loaded UEFI binary. In this case
@@ -110,7 +116,7 @@ U-Boot can be compiled with UEFI unit tests. These unit tests are invoked using
the *bootefi selftest* sub-command.
Which unit test is executed is controlled by the environment variable
*efi\_selftest*. If this variable is not set, all unit tests that are not marked
*efi_selftest*. If this variable is not set, all unit tests that are not marked
as 'on request' are executed.
To show a list of the available unit tests the value *list* can be used
@@ -126,7 +132,7 @@ To show a list of the available unit tests the value *list* can be used
'configuration tables'
...
A single test is selected for execution by setting the *efi\_selftest*
A single test is selected for execution by setting the *efi_selftest*
environment variable to match one of the listed identifiers
::
@@ -140,10 +146,10 @@ return to the command line but require a board reset.
Configuration
-------------
To use the *bootefi* command you must specify CONFIG\_CMD\_BOOTEFI=y.
The *bootefi bootmgr* sub-command requries CMD\_BOOTEFI\_BOOTMGR=y.
The *bootefi hello* sub-command requries CMD\_BOOTEFI\_HELLO=y.
The *bootefi selftest* sub-command depends on CMD\_BOOTEFI\_SELFTEST=y.
To use the *bootefi* command you must specify CONFIG_CMD_BOOTEFI=y.
The *bootefi bootmgr* sub-command requries CMD_BOOTEFI_BOOTMGR=y.
The *bootefi hello* sub-command requries CMD_BOOTEFI_HELLO=y.
The *bootefi selftest* sub-command depends on CMD_BOOTEFI_SELFTEST=y.
See also
--------