The keys trusted for FIT signature verification are supposed to be embedded in the device tree built into u-boot. When running in Qemu it's convenient to use the device tree provided by the VM which doesn't know about signatures though. So merge both device trees at startup.
Signed-off-by: Ludwig Nussel <[email protected]> --- Changes in v3: - enable CONFIG_OF_OMIT_DTB=n in defconfig - add error returns - document decission about dt merging direction board/emulation/qemu-arm/qemu-arm.c | 50 +++++++++++++++++++++++++++-- configs/qemu_arm64_defconfig | 1 + 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 38f0ec5f2fb..f82bc81f4d5 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -144,12 +144,56 @@ int dram_init_banksize(void) return 0; } +/* QEMU loads a generated DTB for us at the start of RAM. + * When using signatures we may have a built-in FDT that contains our known + * public keys nevertheless. So merge those nodes into QEMU's FDT. + * We cannot merge the other way around (eg in fdtdec_board_setup() + * or board_fix_fdt() at this stage as U-Boot might be started from + * a ROM location. + * At the same time U-Boot needs QEMU's FDT to initialize serial + * devices even before relocation. + */ int board_fdt_blob_setup(void **fdtp) { - /* QEMU loads a generated DTB for us at the start of RAM. */ - *fdtp = (void *)CFG_SYS_SDRAM_BASE; + void *qemu_fdt = (void *)CFG_SYS_SDRAM_BASE; + int ret = -EINVAL; - return 0; + if (fdt_check_header(qemu_fdt) != 0) { + log_err("Invalid QEMU FDT at %p\n", qemu_fdt); + goto out; + } + + if (fdt_check_header(*fdtp) != 0) { + /* this was a perfectly normal condition before + * (CONFIG_OF_OMIT_DTB was set for qemu). So to avoid + * breaking existing configs don't error out. This + * might mean that we don't have keys in case + * FIT_SIGNATURE is on. We can't know though as + * existing setups might have injected them into + * QEMUS's FDT already. + */ + ret = 0; + goto out; + } + + log_debug("Found built-in FDT at %p. Merging into %p...\n", *fdtp, qemu_fdt); + + ret = fdt_increase_size(qemu_fdt, 1024 + fdt_totalsize(*fdtp)); + if (ret) { + log_err("Failed to resize FDT overlay: %s", fdt_strerror(ret)); + goto out; + } + + ret = fdt_overlay_apply_node(qemu_fdt, 0, (void *)*fdtp, 0); + if (ret) { + log_err("Failed to apply FDT overlay: %s\n", fdt_strerror(ret)); + goto out; + } + +out: + *fdtp = qemu_fdt; + + return ret; } void enable_caches(void) diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 68b80e28746..0edf80b7aaa 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -7,6 +7,7 @@ CONFIG_ENV_SIZE=0x40000 CONFIG_ENV_SECT_SIZE=0x40000 CONFIG_DEFAULT_DEVICE_TREE="qemu-arm64" CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_OF_OMIT_DTB=n CONFIG_SYS_LOAD_ADDR=0x40200000 CONFIG_DEBUG_UART_BASE=0x9000000 CONFIG_DEBUG_UART_CLOCK=0 -- 2.43.0

