fit: gzip-compressed kernel + ramdisk (initramfs) support

Wires the new wolfBoot_gunzip inflater into the FIT image-loading path
and adds initramfs (ramdisk) extraction with DTB /chosen fixup so a
single signed FIT can carry kernel, DTB, and rootfs.

GZIP path
---------
* fit_load_image_ex(out_max) added; fit_load_image kept as a wrapper.
* When a subimage carries compression="gzip", inflate straight to the
  FIT-declared load address, then verify the FIT hash-1 subnode
  (sha256 / sha384 if available) for defense in depth on top of the
  outer wolfBoot signature. The compression property is now read
  unconditionally so a build without WOLFBOOT_GZIP can warn and fail
  closed instead of silently memcpy-ing compressed bytes as if they
  were raw.
* fit_verify_hash propagates wc_InitSha256 / wc_Sha256Update /
  wc_Sha256Final return codes (and the SHA-384 equivalents) - any
  non-zero return is treated as a verification failure so a misbehaving
  backend cannot silently degrade to a no-op.
* GZIP=1 is the new default in the FIT-using example configs (zynqmp,
  zynqmp_sdcard, polarfire_mpfs250, polarfire_mpfs250_qspi,
  versal_vmk180, versal_vmk180_sdcard); set GZIP=0 to opt out.

Ramdisk path
------------
* fit_find_images() gains a ramdisk out-arg and fdt_fixup_initrd()
  writes /chosen/linux,initrd-{start,end} as 64-bit big-endian cells.
* update_disk.c and update_ram.c load the FIT ramdisk node (under
  WOLFBOOT_FIT_RAMDISK) and patch the loaded DTB. Compressed (gzip)
  ramdisks reuse the same fit_load_image_ex() decompress path.
* RAMDISK=1 build switch defines WOLFBOOT_FIT_RAMDISK;
  WOLFBOOT_LOAD_RAMDISK_ADDRESS is plumbed through tools/config.mk ->
  Makefile sed -> include/target.h.in. Defaults to 0; when 0 the
  ramdisk stays at whatever fit_load_image returned.
* hal/zynq.c and hal/versal.c bump fdt_totalsize headroom from 512 to
  768 bytes to fit the new linux,initrd-{start,end} entries.
* config/examples/zynqmp_sdcard.config gains a commented-out opt-in
  block (RAMDISK=1, WOLFBOOT_LOAD_RAMDISK_ADDRESS=0x40000000, alt
  LINUX_BOOTARGS) so a single config file covers both rootfs-on-disk
  and FIT-bundled-initramfs flows.

Builds against the existing master configs are byte-identical when
GZIP=0 and RAMDISK is unset.
pull/772/head
David Garske 2026-04-29 10:58:25 -07:00 committed by Daniele Lacamera
parent 090f0ef411
commit c643215c5e
17 changed files with 397 additions and 21 deletions

View File

@ -638,6 +638,7 @@ include/target.h: $(TARGET_H_TEMPLATE) FORCE
sed -e "s/@WOLFBOOT_DTS_UPDATE_ADDRESS@/$(WOLFBOOT_DTS_UPDATE_ADDRESS)/g" | \
sed -e "s/@WOLFBOOT_LOAD_ADDRESS@/$(WOLFBOOT_LOAD_ADDRESS)/g" | \
sed -e "s/@WOLFBOOT_LOAD_DTS_ADDRESS@/$(WOLFBOOT_LOAD_DTS_ADDRESS)/g" | \
sed -e "s/@WOLFBOOT_LOAD_RAMDISK_ADDRESS@/$(WOLFBOOT_LOAD_RAMDISK_ADDRESS)/g" | \
sed -e "s|@WOLFBOOT_RAMBOOT_MAX_SIZE_DEFINE@|$(if $(strip $(WOLFBOOT_RAMBOOT_MAX_SIZE)),#define WOLFBOOT_RAMBOOT_MAX_SIZE $(WOLFBOOT_RAMBOOT_MAX_SIZE),/* WOLFBOOT_RAMBOOT_MAX_SIZE undefined */)|g" | \
sed -e "s/@WOLFBOOT_PARTITION_SELF_HEADER_ADDRESS@/$(WOLFBOOT_PARTITION_SELF_HEADER_ADDRESS)/g" \
> $@

View File

@ -46,6 +46,9 @@ WOLFTPM?=0
ELF?=1
#DEBUG_ELF?=1
# Native gzip decompression for FIT subimages (set GZIP=0 to disable)
GZIP?=1
# Use RISC-V assembly version of ECDSA and SHA
NO_ASM?=0

View File

@ -35,6 +35,9 @@ WOLFTPM?=0
ELF?=1
#DEBUG_ELF?=1
# Native gzip decompression for FIT subimages (set GZIP=0 to disable)
GZIP?=1
# Use RISC-V assembly version of ECDSA and SHA
NO_ASM?=0

View File

@ -59,6 +59,9 @@ NO_XIP=1
# ELF loading support
ELF?=1
# Native gzip decompression for FIT subimages (set GZIP=0 to disable)
GZIP?=1
# Toolchain
USE_GCC=1
CROSS_COMPILE=aarch64-none-elf-

View File

@ -33,6 +33,9 @@ NO_XIP=1
# ELF loading support
ELF?=1
# Native gzip decompression for FIT subimages (set GZIP=0 to disable)
GZIP?=1
# Boot Benchmarking (optional)
BOOT_BENCHMARK?=1

View File

@ -58,6 +58,9 @@ USE_GCC=1
ELF?=1
#DEBUG_ELF?=1
# Native gzip decompression for FIT subimages (set GZIP=0 to disable)
GZIP?=1
# Flash Sector Size
WOLFBOOT_SECTOR_SIZE=0x20000
# Application Partition Size

View File

@ -43,6 +43,9 @@ NO_XIP=1
ELF?=1
#DEBUG_ELF?=1
# Native gzip decompression for FIT subimages (set GZIP=0 to disable)
GZIP?=1
# Boot Exception Level: leave wolfBoot at EL2 for handoff to Linux (matches
# the standard PetaLinux U-Boot flow and preserves KVM/hypervisor use of
# EL2). The EL2 Linux-cleanup path in do_boot() will clean dcache/disable
@ -100,6 +103,21 @@ CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000
# Check `ls /sys/class/mmc_host/` on your running target to confirm.
CFLAGS_EXTRA+=-DLINUX_BOOTARGS_ROOT=\"/dev/mmcblk0p4\"
# ============================================================================
# Optional: FIT-bundled initramfs (ramdisk) instead of an on-disk rootfs
# ============================================================================
# Expects the PetaLinux INITRAMFS_IMAGE_BUNDLE=0 layout (FIT contains kernel
# + DTB + ramdisk). wolfBoot extracts the ramdisk to
# WOLFBOOT_LOAD_RAMDISK_ADDRESS and patches the loaded DTB with
# /chosen/linux,initrd-{start,end} so the kernel can find it. Compressed
# (gzip) ramdisks decompress automatically when GZIP=1.
#
# To enable: uncomment the three lines below and comment out the
# LINUX_BOOTARGS_ROOT line above (root= is supplied by the cpio's /init).
#RAMDISK?=1
#WOLFBOOT_LOAD_RAMDISK_ADDRESS?=0x40000000
#CFLAGS_EXTRA+=-DLINUX_BOOTARGS='"earlycon console=ttyPS0,115200 init_fatal_sh=1"'
# ============================================================================
# Boot Memory Layout
# ============================================================================

View File

@ -1276,8 +1276,9 @@ int hal_dts_fixup(void* dts_addr)
wolfBoot_printf("FDT: Version %d, Size %d\n",
fdt_version(fdt), fdt_totalsize(fdt));
/* Expand total size to allow adding/modifying properties */
fdt_set_totalsize(fdt, fdt_totalsize(fdt) + 512);
/* Expand total size to allow adding/modifying properties (bootargs and,
* when WOLFBOOT_FIT_RAMDISK is in play, linux,initrd-{start,end}). */
fdt_set_totalsize(fdt, fdt_totalsize(fdt) + 768);
/* Find /chosen node; create it only if genuinely missing. Any other
* negative return (malformed FDT, etc.) is surfaced directly rather

View File

@ -1927,11 +1927,12 @@ int hal_dts_fixup(void* dts_addr)
fdt_version(fdt), fdt_totalsize(fdt));
/* Expand totalsize so fdt_setprop() has in-blob free space to place
* a new/larger bootargs property. Physical headroom is already
* guaranteed by the load-address layout (DTB at WOLFBOOT_LOAD_DTS_ADDRESS,
* kernel loaded much higher), so growing the header is safe. Matches
* the pattern used in hal/versal.c:hal_dts_fixup. */
fdt_set_totalsize(fdt, fdt_totalsize(fdt) + 512);
* a new/larger bootargs property and (when WOLFBOOT_FIT_RAMDISK is in
* play) the linux,initrd-{start,end} properties. Physical headroom is
* already guaranteed by the load-address layout (DTB at
* WOLFBOOT_LOAD_DTS_ADDRESS, kernel loaded much higher), so growing
* the header is safe. Matches the pattern in hal/versal.c. */
fdt_set_totalsize(fdt, fdt_totalsize(fdt) + 768);
/* Find /chosen node; create it only if genuinely missing. Any other
* negative return (malformed FDT, etc.) is surfaced directly rather

View File

@ -158,8 +158,15 @@ int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name, uint
int fdt_shrink(void* fdt);
/* FIT */
const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_dt);
const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_dt,
const char** pramdisk);
void* fit_load_image(void* fdt, const char* image, int* lenp);
void* fit_load_image_ex(void* fdt, const char* image, int* lenp, uint32_t out_max);
/* FDT initrd fixup: writes /chosen/linux,initrd-{start,end} as 64-bit
* big-endian properties. Creates /chosen if missing. Returns 0 on success
* or a negative FDT_ERR_*. */
int fdt_fixup_initrd(void* fdt, uint64_t start, uint64_t size);
#ifdef __cplusplus
}

View File

@ -157,5 +157,10 @@
@WOLFBOOT_RAMBOOT_MAX_SIZE_DEFINE@
#define WOLFBOOT_LOAD_DTS_ADDRESS @WOLFBOOT_LOAD_DTS_ADDRESS@
/* Load address for FIT ramdisk extraction (used when WOLFBOOT_FIT_RAMDISK
* is set; otherwise unused). 0 means "use the FIT image's `load` property
* verbatim — do not relocate". */
#define WOLFBOOT_LOAD_RAMDISK_ADDRESS @WOLFBOOT_LOAD_RAMDISK_ADDRESS@
#endif /* !H_TARGETS_TARGET_ */

View File

@ -900,6 +900,22 @@ ifeq ($(DELTA_UPDATES),1)
endif
endif
# GZIP=1 enables native gzip decompression of FIT subimages
# (RFC 1951 + RFC 1952). Enabled by default in FIT-using example configs.
GZIP ?= 0
ifeq ($(GZIP),1)
OBJS += src/gzip.o
CFLAGS+=-DWOLFBOOT_GZIP
endif
# RAMDISK=1 enables FIT ramdisk (initramfs) extraction and DTB
# /chosen/linux,initrd-{start,end} fixup. Compressed (gzip) ramdisks
# decompress through the same path when GZIP=1.
RAMDISK ?= 0
ifeq ($(RAMDISK),1)
CFLAGS+=-DWOLFBOOT_FIT_RAMDISK
endif
ifeq ($(ARMORED),1)
CFLAGS+=-DWOLFBOOT_ARMORED
endif

240
src/fdt.c
View File

@ -30,6 +30,16 @@
#include "string.h"
#include <stdint.h>
#ifdef WOLFBOOT_GZIP
#include "gzip.h"
#ifdef WOLFBOOT_HASH_SHA256
#include <wolfssl/wolfcrypt/sha256.h>
#endif
#ifdef WOLFBOOT_HASH_SHA384
#include <wolfssl/wolfcrypt/sha512.h>
#endif
#endif /* WOLFBOOT_GZIP */
uint32_t cpu_to_fdt32(uint32_t x)
{
#ifdef BIG_ENDIAN_ORDER
@ -787,10 +797,11 @@ int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name,
/* FIT Specific */
const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_dt)
const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_dt,
const char** pramdisk)
{
const void* val;
const char *conf = NULL, *kernel = NULL, *flat_dt = NULL;
const char *conf = NULL, *kernel = NULL, *flat_dt = NULL, *ramdisk = NULL;
int off, len = 0;
/* Find the default configuration (optional) */
@ -806,6 +817,7 @@ const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_
if (off > 0) {
kernel = fdt_getprop(fdt, off, "kernel", &len);
flat_dt = fdt_getprop(fdt, off, "fdt", &len);
ramdisk = fdt_getprop(fdt, off, "ramdisk", &len);
}
}
if (kernel == NULL) {
@ -828,19 +840,190 @@ const char* fit_find_images(void* fdt, const char** pkernel, const char** pflat_
}
}
}
if (ramdisk == NULL) {
/* find node with "type" == ramdisk */
off = fdt_find_prop_offset(fdt, -1, "type", "ramdisk");
if (off > 0) {
val = fdt_get_name(fdt, off, &len);
if (val != NULL && len > 0) {
ramdisk = (const char*)val;
}
}
}
if (pkernel)
*pkernel = kernel;
if (pflat_dt)
*pflat_dt = flat_dt;
if (pramdisk)
*pramdisk = ramdisk;
return conf;
}
void* fit_load_image(void* fdt, const char* image, int* lenp)
int fdt_fixup_initrd(void* fdt, uint64_t start, uint64_t size)
{
int off, ret;
uint64_t end;
if (fdt == NULL) {
return -1;
}
end = start + size;
off = fdt_find_node_offset(fdt, -1, "chosen");
if (off == -FDT_ERR_NOTFOUND) {
off = fdt_add_subnode(fdt, 0, "chosen");
}
if (off < 0) {
return off;
}
ret = fdt_fixup_val64(fdt, off, "chosen", "linux,initrd-start", start);
if (ret < 0) {
return ret;
}
ret = fdt_fixup_val64(fdt, off, "chosen", "linux,initrd-end", end);
if (ret < 0) {
return ret;
}
return 0;
}
#ifdef WOLFBOOT_GZIP
/* Verify FIT per-subimage hash-1 subnode against the loaded/decompressed
* image bytes. This is defense-in-depth: the outer wolfBoot signature
* already authenticates the entire FIT blob, but recomputing the per-image
* hash catches inflater bugs and corrupt streams that still parse.
*
* Returns 0 on success or when no usable hash node is present.
* Returns negative on hash mismatch.
*
* If hash-1.algo names an algorithm that is not compiled into this build,
* a warning is printed and 0 is returned (best-effort verification). */
static int fit_verify_hash(const void *fdt, int img_off,
const uint8_t *data, uint32_t data_len)
{
int ret = 0;
int done = 0;
int hash_off, len = 0;
const char *algo = NULL;
const uint8_t *value = NULL;
#ifdef WOLFBOOT_HASH_SHA256
wc_Sha256 sha256_ctx;
uint8_t sha256_digest[WC_SHA256_DIGEST_SIZE];
#endif
#ifdef WOLFBOOT_HASH_SHA384
wc_Sha384 sha384_ctx;
uint8_t sha384_digest[WC_SHA384_DIGEST_SIZE];
#endif
hash_off = fdt_subnode_offset_namelen(fdt, img_off, "hash-1", 6);
if (hash_off < 0) {
done = 1; /* no hash-1 subnode; nothing to verify */
}
if (!done) {
algo = (const char*)fdt_getprop(fdt, hash_off, "algo", &len);
if (algo == NULL || len <= 0) {
wolfBoot_printf("FIT hash-1: missing algo\n");
done = 1;
}
}
if (!done) {
value = (const uint8_t*)fdt_getprop(fdt, hash_off, "value", &len);
if (value == NULL) {
/* mkimage emits the hash node but populates 'value' only after
* signing; an empty 'value' on an unsigned tree is benign. */
done = 1;
}
}
#ifdef WOLFBOOT_HASH_SHA256
if (!done && strcmp(algo, "sha256") == 0) {
if (len != WC_SHA256_DIGEST_SIZE) {
wolfBoot_printf("FIT hash-1: bad sha256 value len %d\n", len);
ret = -1;
}
if (ret == 0) {
ret = wc_InitSha256(&sha256_ctx);
}
if (ret == 0) {
ret = wc_Sha256Update(&sha256_ctx, data, (word32)data_len);
}
if (ret == 0) {
ret = wc_Sha256Final(&sha256_ctx, sha256_digest);
}
wc_Sha256Free(&sha256_ctx);
if (ret != 0) {
wolfBoot_printf("FIT hash-1 (sha256): wc_Sha256 failed rc=%d\n",
ret);
ret = -1;
}
else if (memcmp(sha256_digest, value, WC_SHA256_DIGEST_SIZE) != 0) {
wolfBoot_printf("FIT hash-1 (sha256): MISMATCH\n");
ret = -1;
}
else {
wolfBoot_printf("FIT hash-1 (sha256): OK\n");
}
done = 1;
}
#endif
#ifdef WOLFBOOT_HASH_SHA384
if (!done && strcmp(algo, "sha384") == 0) {
if (len != WC_SHA384_DIGEST_SIZE) {
wolfBoot_printf("FIT hash-1: bad sha384 value len %d\n", len);
ret = -1;
}
if (ret == 0) {
ret = wc_InitSha384(&sha384_ctx);
}
if (ret == 0) {
ret = wc_Sha384Update(&sha384_ctx, data, (word32)data_len);
}
if (ret == 0) {
ret = wc_Sha384Final(&sha384_ctx, sha384_digest);
}
wc_Sha384Free(&sha384_ctx);
if (ret != 0) {
wolfBoot_printf("FIT hash-1 (sha384): wc_Sha384 failed rc=%d\n",
ret);
ret = -1;
}
else if (memcmp(sha384_digest, value, WC_SHA384_DIGEST_SIZE) != 0) {
wolfBoot_printf("FIT hash-1 (sha384): MISMATCH\n");
ret = -1;
}
else {
wolfBoot_printf("FIT hash-1 (sha384): OK\n");
}
done = 1;
}
#endif
if ((ret == 0) && !done) {
wolfBoot_printf("FIT hash-1: algo '%s' not built in, skipping\n",
algo);
}
return ret;
}
#endif /* WOLFBOOT_GZIP */
void* fit_load_image_ex(void* fdt, const char* image, int* lenp,
uint32_t out_max)
{
void *load, *entry, *data = NULL;
int off, len = 0;
const char *comp;
int complen = 0;
#ifndef WOLFBOOT_GZIP
(void)out_max;
#endif
off = fdt_find_node_offset(fdt, -1, image);
if (off > 0) {
@ -849,9 +1032,49 @@ void* fit_load_image(void* fdt, const char* image, int* lenp)
load = fdt_getprop_address(fdt, off, "load");
entry = fdt_getprop_address(fdt, off, "entry");
if (data != NULL && load != NULL && data != load) {
wolfBoot_printf("Loading Image %s: %p -> %p (%d bytes)\n",
image, data, load, len);
memcpy(load, data, len);
/* Detect compression unconditionally so we can warn (and fail
* closed) when the build lacks support for it instead of
* silently copying compressed bytes as if they were raw. */
comp = (const char*)fdt_getprop(fdt, off, "compression",
&complen);
if (comp != NULL && complen > 0 && strcmp(comp, "gzip") == 0) {
#ifdef WOLFBOOT_GZIP
uint32_t out_len = 0;
int rc;
wolfBoot_printf("Decompressing Image %s (gzip): "
"%p -> %p (%d bytes)\n", image, data, load, len);
rc = wolfBoot_gunzip((const uint8_t*)data, (uint32_t)len,
(uint8_t*)load, out_max, &out_len);
if (rc != 0) {
wolfBoot_printf("FIT gunzip failed for %s: rc=%d "
"(wrote %u bytes)\n", image, rc, out_len);
return NULL;
}
len = (int)out_len;
wolfBoot_printf("Decompressed %s: %u bytes\n", image,
out_len);
#else
wolfBoot_printf("FIT: subimage '%s' has compression="
"\"gzip\" but WOLFBOOT_GZIP is not enabled in this "
"build (rebuild with GZIP=1)\n", image);
return NULL;
#endif
}
else {
wolfBoot_printf("Loading Image %s: %p -> %p (%d bytes)\n",
image, data, load, len);
memcpy(load, data, len);
}
#ifdef WOLFBOOT_GZIP
/* Defense-in-depth: verify FIT hash-1 against loaded bytes */
if (fit_verify_hash(fdt, off, (const uint8_t*)load,
(uint32_t)len) != 0) {
wolfBoot_printf("FIT hash verification failed for %s\n",
image);
return NULL;
}
#endif
/* load should always have entry, but if not use load address */
data = (entry != NULL) ? entry : load;
@ -868,4 +1091,9 @@ void* fit_load_image(void* fdt, const char* image, int* lenp)
}
void* fit_load_image(void* fdt, const char* image, int* lenp)
{
return fit_load_image_ex(fdt, image, lenp, 0xFFFFFFFFU);
}
#endif /* (MMU || WOLFBOOT_FDT) && !BUILD_LOADER_STAGE1 */

View File

@ -541,12 +541,12 @@ void RAMFUNCTION wolfBoot_start(void)
/* Is this a Flattened uImage Tree (FIT) image (FDT format) */
if (wolfBoot_get_dts_size(load_address) > 0) {
void* fit = (void*)load_address;
const char *kernel = NULL, *flat_dt = NULL;
const char *kernel = NULL, *flat_dt = NULL, *ramdisk = NULL;
wolfBoot_printf("Flattened uImage Tree: Version %d, Size %d\n",
fdt_version(fit), fdt_totalsize(fit));
(void)fit_find_images(fit, &kernel, &flat_dt);
(void)fit_find_images(fit, &kernel, &flat_dt, &ramdisk);
if (kernel != NULL) {
load_address = fit_load_image(fit, kernel, NULL);
}
@ -560,6 +560,45 @@ void RAMFUNCTION wolfBoot_start(void)
memcpy(dts_addr, dts_ptr, dts_size);
}
}
#ifdef WOLFBOOT_FIT_RAMDISK
if (ramdisk != NULL) {
int rd_size = 0;
uint8_t *rd_ptr = (uint8_t*)fit_load_image(fit, ramdisk, &rd_size);
if (rd_ptr != NULL && rd_size > 0) {
uint8_t *rd_dst;
/* If WOLFBOOT_LOAD_RAMDISK_ADDRESS is set (nonzero), use it
* as the canonical destination (overrides the FIT's `load`
* property). Otherwise honor whatever fit_load_image
* returned (FIT-specified load addr or in-FIT pointer). */
if (WOLFBOOT_LOAD_RAMDISK_ADDRESS != 0) {
rd_dst = (uint8_t*)WOLFBOOT_LOAD_RAMDISK_ADDRESS;
if (rd_ptr != rd_dst) {
wolfBoot_printf("Loading ramdisk: %p -> %p (%d bytes)\n",
rd_ptr, rd_dst, rd_size);
memcpy(rd_dst, rd_ptr, rd_size);
}
else {
wolfBoot_printf("Loaded ramdisk: %p (%d bytes)\n",
rd_dst, rd_size);
}
}
else {
rd_dst = rd_ptr;
wolfBoot_printf("Loaded ramdisk: %p (%d bytes)\n",
rd_dst, rd_size);
}
if (dts_addr != NULL) {
(void)fdt_fixup_initrd((void*)dts_addr,
(uint64_t)(uintptr_t)rd_dst, (uint64_t)rd_size);
}
}
else {
wolfBoot_printf("FIT: ramdisk node present but load failed\n");
}
}
#else
(void)ramdisk;
#endif
}
#endif

View File

@ -368,12 +368,12 @@ backup_on_failure:
/* Is this a Flattened uImage Tree (FIT) image (FDT format) */
if (wolfBoot_get_dts_size(load_address) > 0) {
void* fit = (void*)load_address;
const char *kernel = NULL, *flat_dt = NULL;
const char *kernel = NULL, *flat_dt = NULL, *ramdisk = NULL;
wolfBoot_printf("Flattened uImage Tree: Version %d, Size %d\n",
fdt_version(fit), fdt_totalsize(fit));
(void)fit_find_images(fit, &kernel, &flat_dt);
(void)fit_find_images(fit, &kernel, &flat_dt, &ramdisk);
if (kernel != NULL) {
load_address = fit_load_image(fit, kernel, NULL);
}
@ -387,6 +387,45 @@ backup_on_failure:
memcpy(dts_addr, dts_ptr, dts_size);
}
}
#ifdef WOLFBOOT_FIT_RAMDISK
if (ramdisk != NULL) {
int rd_size = 0;
uint8_t *rd_ptr = (uint8_t*)fit_load_image(fit, ramdisk, &rd_size);
if (rd_ptr != NULL && rd_size > 0) {
uint8_t *rd_dst;
/* If WOLFBOOT_LOAD_RAMDISK_ADDRESS is set (nonzero), use it
* as the canonical destination (overrides the FIT's `load`
* property). Otherwise honor whatever fit_load_image
* returned (FIT-specified load addr or in-FIT pointer). */
if (WOLFBOOT_LOAD_RAMDISK_ADDRESS != 0) {
rd_dst = (uint8_t*)WOLFBOOT_LOAD_RAMDISK_ADDRESS;
if (rd_ptr != rd_dst) {
wolfBoot_printf("Loading ramdisk: %p -> %p (%d bytes)\n",
rd_ptr, rd_dst, rd_size);
memcpy(rd_dst, rd_ptr, rd_size);
}
else {
wolfBoot_printf("Loaded ramdisk: %p (%d bytes)\n",
rd_dst, rd_size);
}
}
else {
rd_dst = rd_ptr;
wolfBoot_printf("Loaded ramdisk: %p (%d bytes)\n",
rd_dst, rd_size);
}
if (dts_addr != NULL) {
(void)fdt_fixup_initrd((void*)dts_addr,
(uint64_t)(uintptr_t)rd_dst, (uint64_t)rd_size);
}
}
else {
wolfBoot_printf("FIT: ramdisk node present but load failed\n");
}
}
#else
(void)ramdisk;
#endif
}
else {
/* Load DTS to RAM */

View File

@ -76,6 +76,7 @@ ifeq ($(ARCH),)
WOLFBOOT_DTS_UPDATE_ADDRESS=0x50000
WOLFBOOT_LOAD_ADDRESS?=0x200000
WOLFBOOT_LOAD_DTS_ADDRESS?=0x400000
WOLFBOOT_LOAD_RAMDISK_ADDRESS?=0
WOLFBOOT_SMALL_STACK?=0
DELTA_UPDATES?=0
DELTA_BLOCK_SIZE?=256
@ -109,7 +110,8 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
WOLFBOOT_PARTITION_SWAP_ADDRESS WOLFBOOT_LOAD_ADDRESS \
WOLFBOOT_LOAD_DTS_ADDRESS WOLFBOOT_DTS_BOOT_ADDRESS WOLFBOOT_DTS_UPDATE_ADDRESS \
WOLFBOOT_LOAD_DTS_ADDRESS WOLFBOOT_LOAD_RAMDISK_ADDRESS \
WOLFBOOT_DTS_BOOT_ADDRESS WOLFBOOT_DTS_UPDATE_ADDRESS \
WOLFBOOT_SMALL_STACK DELTA_UPDATES DELTA_BLOCK_SIZE WOLFBOOT_IMG_HASH_ONESHOT \
WOLFBOOT_HUGE_STACK FORCE_32BIT\
ENCRYPT_WITH_CHACHA ENCRYPT_WITH_AES128 ENCRYPT_WITH_AES256 ARMORED \
@ -117,6 +119,7 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
WOLFBOOT_UNIVERSAL_KEYSTORE \
XMSS_PARAMS \
ELF BIG_ENDIAN \
GZIP RAMDISK \
NXP_CUSTOM_DCD NXP_CUSTOM_DCD_OBJS \
FLASH_OTP_KEYSTORE \
KEYVAULT_OBJ_SIZE \

View File

@ -372,9 +372,9 @@ void dts_parse_fit_image(void* fit, const char* image, const char* desc)
int dts_parse_fit(void* image)
{
const char *conf = NULL, *kernel = NULL, *flat_dt = NULL;
const char *conf = NULL, *kernel = NULL, *flat_dt = NULL, *ramdisk = NULL;
conf = fit_find_images(image, &kernel, &flat_dt);
conf = fit_find_images(image, &kernel, &flat_dt, &ramdisk);
if (conf != NULL) {
printf("FIT: Found '%s' configuration\n", conf);
dts_fit_image_item(image, fdt_find_node_offset(image, -1, conf),
@ -384,6 +384,9 @@ int dts_parse_fit(void* image)
/* dump image information */
dts_parse_fit_image(image, kernel, "Kernel");
dts_parse_fit_image(image, flat_dt, "FDT");
if (ramdisk != NULL) {
dts_parse_fit_image(image, ramdisk, "Ramdisk");
}
return 0;
}