woz_dfu.h
@file…
Overview
The on-flash contract between the application and the bootloader for a delta firmware update. The application receives a patch over Bluetooth and writes it into the patch_staging partition. MCUboot reads it on the next boot and applies it onto the primary slot. Nothing else connects the two, so this header IS the interface: a change here that is not made on both sides produces a board that stages an update and then silently declines to install it. Plain C11 with no Zephyr dependency, so the host tests and the patch builder can include it and agree on the layout by construction rather than by transcription.
@file
used by dfu_applier.c dfu_receiver.c dfu_smp_img.c
API
Cstruct woz_dfu_hdr
The staged-update header.
Integrity here is CRC-32, not a hash, and that is deliberate. AUTHENTICITY is
checked by the APPLICATION, which has PSA ECDSA-P256 already linked for
Aliro, before it ever writes this header. The bootloader is the flash-starved
image and only has to answer a narrower question: did the bytes I am about to
apply arrive intact, and do they belong to the image I am running? A CRC
answers both.
The floor underneath both is MCUboot's own image validation:
CONFIG_BOOT_VALIDATE_SLOT0=y re-verifies the P-256 signature of the
RESULT before booting it. So a forged header cannot install code -- it can
only destroy the current image, and CONFIG_BOOT_SERIAL_NO_APPLICATION=y
catches that in recovery rather than in a boot loop.
Every field is little-endian. Total 32 bytes, word-aligned throughout,
because the nRF flash driver writes words.
##define WOZ_DFU_MAGIC 0x55464457u
"WDFU" read as a little-endian word.
##define WOZ_DFU_ABI_VERSION 1u
Bumped whenever the layout below changes in any way.
##define WOZ_DFU_PAGE_SIZE 4096u
Layout of the staging partition. Page-granular because the erase unit is a page, and the three regions have different write patterns: the header is written once, the step log is appended to during the apply, and the patch is written once. Sharing a page between any two of them would mean erasing one to update another.
##define WOZ_DFU_HDR_OFFSET 0u
Page 0: @ref woz_dfu_hdr, written by the application.
##define WOZ_DFU_STEP_OFFSET WOZ_DFU_PAGE_SIZE
Page 1: the step log, written by the bootloader. One 32-bit word per completed patch step, appended in order, never erased mid-apply. An erased word (0xffffffff) marks the end. This is what makes a power cut survivable: detools re-reads the last completed step and skips everything already done (detools.c:1559) instead of restarting the patch against a half-patched image.
##define WOZ_DFU_PATCH_OFFSET (2u * WOZ_DFU_PAGE_SIZE)
Page 2 onward: the patch itself.
##define WOZ_DFU_STEP_ERASED 0xffffffffu
Value of an erased flash word, and so the end marker of the step log.
##define WOZ_DFU_HDR_CRC_LEN 28u
Bytes of @ref woz_dfu_hdr covered by @ref woz_dfu_hdr.hdr_crc32: everything ahead of the field itself. The whole struct is 32 bytes, so this is 28.
##define WOZ_DFU_HDR_LEN 32u
Wire and on-flash size of @ref woz_dfu_hdr. Asserted against sizeof().
##define WOZ_DFU_SIG_LEN 64u
Raw P-256 signature, r||s, over all @ref WOZ_DFU_HDR_LEN header bytes.