@@ -240,6 +240,58 @@ test-sim-rollback-flash: wolfboot.elf test-sim-internal-flash-with-update FORCE
240240 $(Q ) (test ` ./wolfboot.elf success get_version` -eq 1)
241241 $(Q ) (test ` ./wolfboot.elf get_version` -eq 1)
242242
243+ # Test bootloader self-update mechanism using simulator. Since simulator memmaps runtime addresses
244+ # the best we can do is ensure the self-update copies the intact self-update image to the expected location
245+ test-sim-self-update : wolfboot.bin FORCE
246+ @echo " === Simulator Self-Update Test ==="
247+ @# Create dummy payload (0xAA pattern) and sign as wolfBoot update v2
248+ $(Q ) dd if=/dev/zero bs=$$(wc -c < wolfboot.bin | awk '{print $$1}' ) count=1 2> /dev/null | tr ' \000' ' \252' > dummy_update.bin
249+ $(Q )$(SIGN_ENV ) $(SIGN_TOOL ) $(SIGN_OPTIONS ) --wolfboot-update dummy_update.bin $(PRIVATE_KEY ) 2
250+ @# Create update partition with signed update and "pBOOT" trailer. Necessary since there is no running
251+ @# app to trigger an initial update
252+ $(Q ) dd if=/dev/zero bs=$$(($(WOLFBOOT_PARTITION_SIZE ) ) ) count=1 2> /dev/null | tr ' \000' ' \377' > update_part.dd
253+ $(Q ) dd if=dummy_update_v2_signed.bin of=update_part.dd bs=1 conv=notrunc
254+ $(Q ) printf " pBOOT" | dd of=update_part.dd bs=1 seek=$$(($(WOLFBOOT_PARTITION_SIZE ) - 5 ) ) conv=notrunc
255+ @# Create erased boot and swap partitions
256+ $(Q ) dd if=/dev/zero bs=$$(($(WOLFBOOT_PARTITION_SIZE ) ) ) count=1 2> /dev/null | tr ' \000' ' \377' > boot_part.dd
257+ $(Q ) dd if=/dev/zero bs=$$(($(WOLFBOOT_SECTOR_SIZE ) ) ) count=1 2> /dev/null | tr ' \000' ' \377' > erased_sec.dd
258+ @# Assemble flash: wolfboot.bin at 0, empty boot partition, update partition, swap
259+ $(Q )$(BINASSEMBLE ) internal_flash.dd \
260+ 0 wolfboot.bin \
261+ $$(($(WOLFBOOT_PARTITION_BOOT_ADDRESS ) - $(ARCH_FLASH_OFFSET ) ) ) boot_part.dd \
262+ $$(($(WOLFBOOT_PARTITION_UPDATE_ADDRESS ) - $(ARCH_FLASH_OFFSET ) ) ) update_part.dd \
263+ $$(($(WOLFBOOT_PARTITION_SWAP_ADDRESS ) - $(ARCH_FLASH_OFFSET ) ) ) erased_sec.dd
264+ @# Run simulator - self-update runs before app boot, writes dummy to offset 0, then reboots
265+ $(Q ) ./wolfboot.elf get_version || true
266+ @# Verify dummy payload was written to bootloader region, indicating the self update swapped images as expected
267+ $(Q ) cmp -n $$(wc -c < dummy_update.bin | awk '{print $$1}' ) dummy_update.bin internal_flash.dd && echo " === Self-update test PASSED ==="
268+
269+ # Test bootloader self-update mechanism with external flash
270+ test-sim-self-update-ext : wolfboot.bin FORCE
271+ @echo " === Simulator Self-Update Test (External Flash) ==="
272+ @# Create dummy payload (0xAA pattern) and sign as wolfBoot update v2
273+ $(Q ) dd if=/dev/zero bs=$$(wc -c < wolfboot.bin | awk '{print $$1}' ) count=1 2> /dev/null | tr ' \000' ' \252' > dummy_update.bin
274+ $(Q )$(SIGN_ENV ) $(SIGN_TOOL ) $(SIGN_OPTIONS ) --wolfboot-update dummy_update.bin $(PRIVATE_KEY ) 2
275+ @# Create update partition with signed update and "pBOOT" trailer
276+ $(Q ) dd if=/dev/zero bs=$$(($(WOLFBOOT_PARTITION_SIZE ) ) ) count=1 2> /dev/null | tr ' \000' ' \377' > update_part.dd
277+ $(Q ) dd if=dummy_update_v2_signed.bin of=update_part.dd bs=1 conv=notrunc
278+ $(Q ) printf " pBOOT" | dd of=update_part.dd bs=1 seek=$$(($(WOLFBOOT_PARTITION_SIZE ) - 5 ) ) conv=notrunc
279+ @# Create erased boot and swap partitions
280+ $(Q ) dd if=/dev/zero bs=$$(($(WOLFBOOT_PARTITION_SIZE ) ) ) count=1 2> /dev/null | tr ' \000' ' \377' > boot_part.dd
281+ $(Q ) dd if=/dev/zero bs=$$(($(WOLFBOOT_SECTOR_SIZE ) ) ) count=1 2> /dev/null | tr ' \000' ' \377' > erased_sec.dd
282+ @# Assemble internal flash: wolfboot.bin at 0, empty boot partition
283+ $(Q )$(BINASSEMBLE ) internal_flash.dd \
284+ 0 wolfboot.bin \
285+ $$(($(WOLFBOOT_PARTITION_BOOT_ADDRESS ) - $(ARCH_FLASH_OFFSET ) ) ) boot_part.dd
286+ @# Assemble external flash: update partition, swap sector
287+ $(Q )$(BINASSEMBLE ) external_flash.dd \
288+ 0 update_part.dd \
289+ $(WOLFBOOT_PARTITION_SIZE ) erased_sec.dd
290+ @# Run simulator - self-update reads from external, writes to internal at offset 0
291+ $(Q ) ./wolfboot.elf get_version || true
292+ @# Verify dummy payload was written to bootloader region
293+ $(Q ) cmp -n $$(wc -c < dummy_update.bin | awk '{print $$1}' ) dummy_update.bin internal_flash.dd && echo " === Self-update test (External Flash) PASSED ==="
294+
243295test-self-update : FORCE
244296 @mv $(PRIVATE_KEY ) private_key.old
245297 @make clean factory.bin RAM_CODE=1 WOLFBOOT_VERSION=1 SIGN=$(SIGN )
0 commit comments