Skip to content

Add compressed firmware images: RAM-executed A/B slots and compressed updates - #951

Open
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:compressed_images
Open

dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:compressed_images

Conversation

@dgarske

@dgarske dgarske commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Description

Stores a gzip-compressed, signed firmware image, in two arrangements with different trade-offs.

COMPRESSED_RAM_SLOTS=1 keeps both A/B slots compressed and inflates the selected one into RAM to execute it there, so A/B redundancy costs about half the flash of two uncompressed slots and rollback is unchanged. RAM bounds the image in this mode.

COMPRESSED_UPDATE=1 keeps only the update partition compressed and inflates it into the boot partition, which goes on executing in place. The update partition is then sized for the container rather than for a second full copy, and the flash that frees goes to the application. There is no local copy of the outgoing image, so this trades rollback for flash: the container is verified before the first erase, and an interrupted install resumes from recorded progress because the update partition is only ever read.

What it adds

  • src/update_ram.c - manifest TLVs, capacity and overlap checks, inflate to WOLFBOOT_LOAD_ADDRESS
  • src/update_flash.c - the execute-in-place installer, built on the existing DISABLE_BACKUP path
  • src/gzip.c - a sink decoder with a bounded window, selected at build time, leaving the flat decoder the FIT path uses unchanged
  • src/compress_crypt.c - optional at-rest encryption of both RAM-executed slots
  • tools/keytools/sign.c - --compressed for an already-gzipped payload, and --compress[=bits] which compresses and signs the nested container
  • Example configs, docs/Compression.md, simulator tests, unit tests and CI

Fixes in shared code

  • wolfBoot_success() confirmed PART_BOOT unconditionally, so an image booted from the update slot was discarded on the next boot
  • wb_trailer_clear() cleared the update partition's trailer at the boot partition's size offset, which only matters once the two are sized independently
  • hal/stm32f4.c describes 1MB of flash, so a partition past that silently failed to erase; now refused at build time
  • DEBUG_UART=1 on TARGET=stm32f4 hung on the first print, because nothing initialized the port

Testing

Validated on a NUCLEO-F439ZI: both modes end to end, including the install, verification of the installed image, the update being consumed rather than repeated, and resume after an interrupted install. At-rest encryption is simulator-only. Simulator and unit tests cover both gzip decoders and the sink's window bound, ED25519/ECC256, and ChaCha20/AES-128/AES-256.

Scope

At-rest encryption of a compressed update partition is follow-on work and is rejected at build time for now: verification would need a decrypt seam in the image hashing path as well as in the inflater's input.

@dgarske dgarske self-assigned this Oct 26, 2026
@dgarske
dgarske requested a review from danielinux October 27, 2026 19:10
@dgarske dgarske changed the title Add compressed firmware images: gzip-compressed A/B slots executed from RAM Add compressed firmware images: RAM-executed A/B slots and compressed updates Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants