Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/test-sunnyday-simulator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ jobs:
run: |
tools/scripts/sim-sunnyday-update.sh

- name: Cleanup before dualbank simulator test
run: |
make keysclean

- name: Build wolfboot.elf (dualbank simulator)
run: |
make clean
mv .config .config.orig
cp config/examples/sim-dualbank.config .config
make test-sim-internal-flash-with-update

- name: Run dualbank swap simulation
run: |
tools/scripts/sim-dualbank-swap-update.sh

- name: Cleanup before WOLFBOOT_SMALL_STACK test
run: |
make keysclean
mv .config.orig .config

- name: Build wolfboot.elf (ECC256, WOLFBOOT_SMALL_STACK)
run: |
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 WOLFBOOT_SMALL_STACK=1 SPMATH=1
Expand Down
18 changes: 18 additions & 0 deletions config/examples/sim-dualbank.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ARCH=sim
TARGET=sim
SIGN?=ED25519
HASH?=SHA256
WOLFBOOT_SMALL_STACK?=0
SPI_FLASH=0
DEBUG=1
DUALBANK_SWAP=1

# sizes should be multiple of system page size
WOLFBOOT_PARTITION_SIZE=0x40000
WOLFBOOT_SECTOR_SIZE=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x100000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x180000

# required for keytools
WOLFBOOT_FIXED_PARTITIONS=1
106 changes: 106 additions & 0 deletions hal/sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ int extFlashLocked = 1;
#define INTERNAL_FLASH_FILE "./internal_flash.dd"
#define EXTERNAL_FLASH_FILE "./external_flash.dd"

#ifdef DUALBANK_SWAP
#define SIM_REGISTER_FILE "./sim_registers.dd"
#define SIM_FLASH_OPTR_SWAP_BANK (1U << 20)
static uint32_t sim_flash_optr;
static void sim_dualbank_register_load(void);
static void sim_dualbank_register_store(void);
uint32_t hal_sim_get_dualbank_state(void);
#endif

/* global used to store command line arguments to forward to the test
* application */
char **main_argv;
Expand Down Expand Up @@ -224,6 +233,57 @@ static int mmap_file(const char *path, uint8_t *address, uint8_t** ret_address)
return 0;
}

#ifdef DUALBANK_SWAP
static void sim_dualbank_register_store(void)
{
int fd = open(SIM_REGISTER_FILE, O_RDWR | O_CREAT, 0644);
if (fd == -1) {
wolfBoot_printf("Failed to open %s: %s\n", SIM_REGISTER_FILE, strerror(errno));
return;
}

if (pwrite(fd, &sim_flash_optr, sizeof(sim_flash_optr), 0) !=
(ssize_t)sizeof(sim_flash_optr)) {
wolfBoot_printf("Failed to store dualbank swap state: %s\n",
strerror(errno));
}

close(fd);
}

static void sim_dualbank_register_load(void)
{
int fd = open(SIM_REGISTER_FILE, O_RDWR | O_CREAT, 0644);
uint32_t value = 0;
int rd;
if (fd == -1) {
wolfBoot_printf("Failed to open %s: %s\n", SIM_REGISTER_FILE,
strerror(errno));
exit(-1);
}

rd = pread(fd, &value, sizeof(value), 0);

if (rd == (int)sizeof(value)) {
sim_flash_optr = value;
} else {
sim_flash_optr = 0;
if (pwrite(fd, &sim_flash_optr, sizeof(sim_flash_optr), 0) !=
sizeof(sim_flash_optr)) {
wolfBoot_printf("Failed to initialize dualbank swap state: %s\n",
strerror(errno));
}
}

close(fd);
}

uint32_t hal_sim_get_dualbank_state(void)
{
return (sim_flash_optr & SIM_FLASH_OPTR_SWAP_BANK) ? 1U : 0U;
}
#endif

void hal_flash_unlock(void)
{
flashLocked = 0;
Expand All @@ -234,6 +294,46 @@ void hal_flash_lock(void)
flashLocked = 1;
}

#ifdef DUALBANK_SWAP
void hal_flash_dualbank_swap(void)
{
uint8_t *boot = (uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS;
uint8_t *update = (uint8_t *)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
uint8_t *buffer;
int was_locked = flashLocked;

buffer = (uint8_t *)malloc(WOLFBOOT_PARTITION_SIZE);
if (buffer == NULL) {
wolfBoot_printf("Simulator dualbank swap failed: out of memory\n");
exit(-1);
}

if (was_locked)
hal_flash_unlock();

memcpy(buffer, boot, WOLFBOOT_PARTITION_SIZE);
memcpy(boot, update, WOLFBOOT_PARTITION_SIZE);
memcpy(update, buffer, WOLFBOOT_PARTITION_SIZE);

if (msync(boot, WOLFBOOT_PARTITION_SIZE, MS_SYNC) != 0) {
wolfBoot_printf("msync boot partition failed: %s\n", strerror(errno));
}
if (msync(update, WOLFBOOT_PARTITION_SIZE, MS_SYNC) != 0) {
wolfBoot_printf("msync update partition failed: %s\n", strerror(errno));
}

free(buffer);

sim_flash_optr ^= SIM_FLASH_OPTR_SWAP_BANK;
sim_dualbank_register_store();
wolfBoot_printf("Simulator dualbank swap complete, register=%u\n",
hal_sim_get_dualbank_state());

if (was_locked)
hal_flash_lock();
}
#endif

void hal_prepare_boot(void)
{
/* no op */
Expand Down Expand Up @@ -312,6 +412,10 @@ void hal_init(void)
}
#endif /* EXT_FLASH */

#ifdef DUALBANK_SWAP
sim_dualbank_register_load();
#endif

for (i = 1; i < main_argc; i++) {
if (strcmp(main_argv[i], "powerfail") == 0) {
erasefail_address = strtol(main_argv[++i], NULL, 16);
Expand Down Expand Up @@ -480,6 +584,7 @@ void do_boot(const uint32_t *app_offset)
#endif
#endif

#if !defined(WOLFBOOT_DUALBOOT)
int wolfBoot_fallback_is_possible(void)
{
return 0;
Expand All @@ -489,6 +594,7 @@ int wolfBoot_dualboot_candidate(void)
{
return 0;
}
#endif

#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT

Expand Down
10 changes: 10 additions & 0 deletions test-app/app_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@

#include "wolfboot/wolfboot.h"

#ifdef DUALBANK_SWAP
uint32_t hal_sim_get_dualbank_state(void);
#endif

#ifdef TARGET_sim

/* Matches all keys:
Expand Down Expand Up @@ -72,6 +76,12 @@ int do_cmd(const char *cmd)
wolfBoot_success();
return 0;
}
#ifdef DUALBANK_SWAP
if (strcmp(cmd, "get_swap_state") == 0) {
printf("%u\n", hal_sim_get_dualbank_state());
return 0;
}
#endif
if (strcmp(cmd, "update_trigger") == 0) {
#if EXT_ENCRYPTED
wolfBoot_set_encrypt_key((uint8_t *)enc_key,(uint8_t *)(enc_key + 32));
Expand Down
42 changes: 42 additions & 0 deletions tools/scripts/sim-dualbank-swap-update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
set -euo pipefail

if [ ! -f ".config" ]; then
echo "Missing .config. Run make config first." >&2
exit 1
fi

if ! grep -Eq '^(DUALBANK_SWAP(\?|)=1)' .config; then
echo "DUALBANK_SWAP=1 is required for this simulation." >&2
exit 1
fi

if [ ! -x "./wolfboot.elf" ]; then
echo "wolfboot.elf not found. Build the simulator first." >&2
exit 1
fi

rm -f sim_registers.dd

mapfile -t lines < <(./wolfboot.elf get_swap_state get_version 2>/dev/null)
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
echo "Unexpected output on first boot (got: ${lines[*]-})" >&2
exit 1
fi
echo "dualbank: first boot reports swap=${lines[0]} active_version=${lines[1]}"

mapfile -t lines < <(./wolfboot.elf success get_swap_state get_version 2>/dev/null)
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
echo "Unexpected output while confirming update (got: ${lines[*]-})" >&2
exit 1
fi
echo "dualbank: after wolfBoot_success swap=${lines[0]} active_version=${lines[1]}"

mapfile -t lines < <(./wolfboot.elf get_swap_state get_version 2>/dev/null)
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
echo "Unexpected output after confirmation (got: ${lines[*]-})" >&2
exit 1
fi
echo "dualbank: persistent swap state confirmed swap=${lines[0]} active_version=${lines[1]}"

echo "Dualbank swap simulation successful."