Merge tag 'efi-2022-04-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user