Pull request for efi-2022-04-rc1

Documentation:

* Fix building HTML documentation of readthedocs.io
* Add ARM Juno board documentation
* Build requirements for Alpine Linux
* Include DM headers in API documentation

UEFI:

* Fix section alignment of EFI binaries
* Fix header length of RISC-V EFI binaries allowing to run them on EDK II
* Remove kaslr-seed from device tree if the EFI_RNG_PROTOCOL is provided

Other:

* Let 'part list' show all 128 GPT partitions
This commit is contained in:
Tom Rini
2022-01-15 07:39:09 -05:00
49 changed files with 1059 additions and 670 deletions

View File

@@ -135,3 +135,75 @@ void efi_free(struct efi_priv *priv, void *ptr)
boot->free_pool(ptr);
}
int efi_store_memory_map(struct efi_priv *priv)
{
struct efi_boot_services *boot = priv->sys_table->boottime;
efi_uintn_t size, desc_size;
efi_status_t ret;
/* Get the memory map so we can switch off EFI */
size = 0;
ret = boot->get_memory_map(&size, NULL, &priv->memmap_key,
&priv->memmap_desc_size,
&priv->memmap_version);
if (ret != EFI_BUFFER_TOO_SMALL) {
/*
* Note this function avoids using printf() since it is not
* available in the stub
*/
printhex2(EFI_BITS_PER_LONG);
putc(' ');
printhex2(ret);
puts(" No memory map\n");
return ret;
}
/*
* Since doing a malloc() may change the memory map and also we want to
* be able to read the memory map in efi_call_exit_boot_services()
* below, after more changes have happened
*/
priv->memmap_alloc = size + 1024;
priv->memmap_size = priv->memmap_alloc;
priv->memmap_desc = efi_malloc(priv, size, &ret);
if (!priv->memmap_desc) {
printhex2(ret);
puts(" No memory for memory descriptor\n");
return ret;
}
ret = boot->get_memory_map(&priv->memmap_size, priv->memmap_desc,
&priv->memmap_key, &desc_size,
&priv->memmap_version);
if (ret) {
printhex2(ret);
puts(" Can't get memory map\n");
return ret;
}
return 0;
}
int efi_call_exit_boot_services(void)
{
struct efi_priv *priv = efi_get_priv();
const struct efi_boot_services *boot = priv->boot;
efi_uintn_t size;
u32 version;
efi_status_t ret;
size = priv->memmap_alloc;
ret = boot->get_memory_map(&size, priv->memmap_desc,
&priv->memmap_key,
&priv->memmap_desc_size, &version);
if (ret) {
printhex2(ret);
puts(" Can't get memory map\n");
return ret;
}
ret = boot->exit_boot_services(priv->parent_image, priv->memmap_key);
if (ret)
return ret;
return 0;
}

View File

@@ -32,6 +32,39 @@ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep)
return -ENOSYS;
}
int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp,
int *desc_sizep, uint *versionp)
{
struct efi_priv *priv = efi_get_priv();
struct efi_boot_services *boot = priv->sys_table->boottime;
efi_uintn_t size, desc_size, key;
struct efi_mem_desc *desc;
efi_status_t ret;
u32 version;
/* Get the memory map so we can switch off EFI */
size = 0;
ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version);
if (ret != EFI_BUFFER_TOO_SMALL)
return log_msg_ret("get", -ENOMEM);
desc = malloc(size);
if (!desc)
return log_msg_ret("mem", -ENOMEM);
ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version);
if (ret)
return log_msg_ret("get", -EINVAL);
*descp = desc;
*sizep = size;
*desc_sizep = desc_size;
*versionp = version;
*keyp = key;
return 0;
}
/**
* efi_bind_block() - bind a new block device to an EFI device
*
@@ -321,6 +354,15 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
return ret;
}
/*
* We could store the EFI memory map here, but it changes all the time,
* so this is only useful for debugging.
*
* ret = efi_store_memory_map(priv);
* if (ret)
* return ret;
*/
printf("starting\n");
board_init_f(GD_FLG_SKIP_RELOC);

View File

@@ -304,15 +304,12 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
{
struct efi_priv local_priv, *priv = &local_priv;
struct efi_boot_services *boot = sys_table->boottime;
struct efi_mem_desc *desc;
struct efi_entry_memmap map;
struct efi_gop *gop;
struct efi_entry_gopmode mode;
struct efi_entry_systable table;
efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
efi_uintn_t key, desc_size, size;
efi_status_t ret;
u32 version;
int cs32;
ret = efi_init(priv, "Payload", image, sys_table);
@@ -327,24 +324,11 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
if (cs32 < 0)
return EFI_UNSUPPORTED;
/* Get the memory map so we can switch off EFI */
size = 0;
ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version);
if (ret != EFI_BUFFER_TOO_SMALL) {
printhex2(EFI_BITS_PER_LONG);
putc(' ');
printhex2(ret);
puts(" No memory map\n");
ret = efi_store_memory_map(priv);
if (ret)
return ret;
}
size += 1024; /* Since doing a malloc() may change the memory map! */
desc = efi_malloc(priv, size, &ret);
if (!desc) {
printhex2(ret);
puts(" No memory for memory descriptor\n");
return ret;
}
ret = setup_info_table(priv, size + 128);
ret = setup_info_table(priv, priv->memmap_size + 128);
if (ret)
return ret;
@@ -360,48 +344,20 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
sizeof(struct efi_gop_mode_info));
}
ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version);
if (ret) {
printhex2(ret);
puts(" Can't get memory map\n");
return ret;
}
table.sys_table = (ulong)sys_table;
add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0);
ret = boot->exit_boot_services(image, key);
if (ret) {
/*
* Unfortunately it happens that we cannot exit boot services
* the first time. But the second time it work. I don't know
* why but this seems to be a repeatable problem. To get
* around it, just try again.
*/
printhex2(ret);
puts(" Can't exit boot services\n");
size = sizeof(desc);
ret = boot->get_memory_map(&size, desc, &key, &desc_size,
&version);
if (ret) {
printhex2(ret);
puts(" Can't get memory map\n");
return ret;
}
ret = boot->exit_boot_services(image, key);
if (ret) {
printhex2(ret);
puts(" Can't exit boot services 2\n");
return ret;
}
}
ret = efi_call_exit_boot_services();
if (ret)
return ret;
/* The EFI UART won't work now, switch to a debug one */
use_uart = true;
map.version = version;
map.desc_size = desc_size;
add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), desc, size);
map.version = priv->memmap_version;
map.desc_size = priv->memmap_desc_size;
add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map),
priv->memmap_desc, priv->memmap_size);
add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0);
memcpy((void *)CONFIG_SYS_TEXT_BASE, _binary_u_boot_bin_start,

View File

@@ -8,6 +8,7 @@
#include <common.h>
#include <efi_dt_fixup.h>
#include <efi_loader.h>
#include <efi_rng.h>
#include <fdtdec.h>
#include <mapmem.h>
@@ -40,6 +41,38 @@ static void efi_reserve_memory(u64 addr, u64 size, bool nomap)
addr, size);
}
/**
* efi_try_purge_kaslr_seed() - Remove unused kaslr-seed
*
* Kernel's EFI STUB only relies on EFI_RNG_PROTOCOL for randomization
* and completely ignores the kaslr-seed for its own randomness needs
* (i.e the randomization of the physical placement of the kernel).
* Weed it out from the DTB we hand over, which would mess up our DTB
* TPM measurements as well.
*
* @fdt: Pointer to device tree
*/
void efi_try_purge_kaslr_seed(void *fdt)
{
const efi_guid_t efi_guid_rng_protocol = EFI_RNG_PROTOCOL_GUID;
struct efi_handler *handler;
efi_status_t ret;
int nodeoff = 0;
int err = 0;
ret = efi_search_protocol(efi_root, &efi_guid_rng_protocol, &handler);
if (ret != EFI_SUCCESS)
return;
nodeoff = fdt_path_offset(fdt, "/chosen");
if (nodeoff < 0)
return;
err = fdt_delprop(fdt, nodeoff, "kaslr-seed");
if (err < 0 && err != -FDT_ERR_NOTFOUND)
log_err("Error deleting kaslr-seed\n");
}
/**
* efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges
*

View File

@@ -128,8 +128,11 @@ static efi_status_t efi_get_dfu_info(
size_t names_len, total_size;
int dfu_num, i;
u16 *name, *next;
int ret;
dfu_init_env_entities(NULL, NULL);
ret = dfu_init_env_entities(NULL, NULL);
if (ret)
return EFI_SUCCESS;
names_len = 0;
dfu_num = 0;
@@ -138,7 +141,7 @@ static efi_status_t efi_get_dfu_info(
dfu_num++;
}
if (!dfu_num) {
log_warning("Probably dfu_alt_info not defined\n");
log_warning("No entities in dfu_alt_info\n");
*image_info_size = 0;
dfu_free_entities();