Skip to content

Commit a559b75

Browse files
authored
Merge pull request #629 from danielinux/sim-dualbank
Add simulator support for DUALBANK, test bank swap
2 parents 79fa066 + a6d0295 commit a559b75

File tree

5 files changed

+196
-0
lines changed

5 files changed

+196
-0
lines changed

.github/workflows/test-sunnyday-simulator.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,26 @@ jobs:
9090
run: |
9191
tools/scripts/sim-sunnyday-update.sh
9292
93+
- name: Cleanup before dualbank simulator test
94+
run: |
95+
make keysclean
96+
97+
- name: Build wolfboot.elf (dualbank simulator)
98+
run: |
99+
make clean
100+
mv .config .config.orig
101+
cp config/examples/sim-dualbank.config .config
102+
make test-sim-internal-flash-with-update
103+
104+
- name: Run dualbank swap simulation
105+
run: |
106+
tools/scripts/sim-dualbank-swap-update.sh
107+
108+
- name: Cleanup before WOLFBOOT_SMALL_STACK test
109+
run: |
110+
make keysclean
111+
mv .config.orig .config
112+
93113
- name: Build wolfboot.elf (ECC256, WOLFBOOT_SMALL_STACK)
94114
run: |
95115
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 WOLFBOOT_SMALL_STACK=1 SPMATH=1
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
ARCH=sim
2+
TARGET=sim
3+
SIGN?=ED25519
4+
HASH?=SHA256
5+
WOLFBOOT_SMALL_STACK?=0
6+
SPI_FLASH=0
7+
DEBUG=1
8+
DUALBANK_SWAP=1
9+
10+
# sizes should be multiple of system page size
11+
WOLFBOOT_PARTITION_SIZE=0x40000
12+
WOLFBOOT_SECTOR_SIZE=0x1000
13+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000
14+
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x100000
15+
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x180000
16+
17+
# required for keytools
18+
WOLFBOOT_FIXED_PARTITIONS=1

hal/sim.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ int extFlashLocked = 1;
7373
#define INTERNAL_FLASH_FILE "./internal_flash.dd"
7474
#define EXTERNAL_FLASH_FILE "./external_flash.dd"
7575

76+
#ifdef DUALBANK_SWAP
77+
#define SIM_REGISTER_FILE "./sim_registers.dd"
78+
#define SIM_FLASH_OPTR_SWAP_BANK (1U << 20)
79+
static uint32_t sim_flash_optr;
80+
static void sim_dualbank_register_load(void);
81+
static void sim_dualbank_register_store(void);
82+
uint32_t hal_sim_get_dualbank_state(void);
83+
#endif
84+
7685
/* global used to store command line arguments to forward to the test
7786
* application */
7887
char **main_argv;
@@ -224,6 +233,57 @@ static int mmap_file(const char *path, uint8_t *address, uint8_t** ret_address)
224233
return 0;
225234
}
226235

236+
#ifdef DUALBANK_SWAP
237+
static void sim_dualbank_register_store(void)
238+
{
239+
int fd = open(SIM_REGISTER_FILE, O_RDWR | O_CREAT, 0644);
240+
if (fd == -1) {
241+
wolfBoot_printf("Failed to open %s: %s\n", SIM_REGISTER_FILE, strerror(errno));
242+
return;
243+
}
244+
245+
if (pwrite(fd, &sim_flash_optr, sizeof(sim_flash_optr), 0) !=
246+
(ssize_t)sizeof(sim_flash_optr)) {
247+
wolfBoot_printf("Failed to store dualbank swap state: %s\n",
248+
strerror(errno));
249+
}
250+
251+
close(fd);
252+
}
253+
254+
static void sim_dualbank_register_load(void)
255+
{
256+
int fd = open(SIM_REGISTER_FILE, O_RDWR | O_CREAT, 0644);
257+
uint32_t value = 0;
258+
int rd;
259+
if (fd == -1) {
260+
wolfBoot_printf("Failed to open %s: %s\n", SIM_REGISTER_FILE,
261+
strerror(errno));
262+
exit(-1);
263+
}
264+
265+
rd = pread(fd, &value, sizeof(value), 0);
266+
267+
if (rd == (int)sizeof(value)) {
268+
sim_flash_optr = value;
269+
} else {
270+
sim_flash_optr = 0;
271+
if (pwrite(fd, &sim_flash_optr, sizeof(sim_flash_optr), 0) !=
272+
sizeof(sim_flash_optr)) {
273+
wolfBoot_printf("Failed to initialize dualbank swap state: %s\n",
274+
strerror(errno));
275+
}
276+
}
277+
278+
close(fd);
279+
}
280+
281+
uint32_t hal_sim_get_dualbank_state(void)
282+
{
283+
return (sim_flash_optr & SIM_FLASH_OPTR_SWAP_BANK) ? 1U : 0U;
284+
}
285+
#endif
286+
227287
void hal_flash_unlock(void)
228288
{
229289
flashLocked = 0;
@@ -234,6 +294,46 @@ void hal_flash_lock(void)
234294
flashLocked = 1;
235295
}
236296

297+
#ifdef DUALBANK_SWAP
298+
void hal_flash_dualbank_swap(void)
299+
{
300+
uint8_t *boot = (uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS;
301+
uint8_t *update = (uint8_t *)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
302+
uint8_t *buffer;
303+
int was_locked = flashLocked;
304+
305+
buffer = (uint8_t *)malloc(WOLFBOOT_PARTITION_SIZE);
306+
if (buffer == NULL) {
307+
wolfBoot_printf("Simulator dualbank swap failed: out of memory\n");
308+
exit(-1);
309+
}
310+
311+
if (was_locked)
312+
hal_flash_unlock();
313+
314+
memcpy(buffer, boot, WOLFBOOT_PARTITION_SIZE);
315+
memcpy(boot, update, WOLFBOOT_PARTITION_SIZE);
316+
memcpy(update, buffer, WOLFBOOT_PARTITION_SIZE);
317+
318+
if (msync(boot, WOLFBOOT_PARTITION_SIZE, MS_SYNC) != 0) {
319+
wolfBoot_printf("msync boot partition failed: %s\n", strerror(errno));
320+
}
321+
if (msync(update, WOLFBOOT_PARTITION_SIZE, MS_SYNC) != 0) {
322+
wolfBoot_printf("msync update partition failed: %s\n", strerror(errno));
323+
}
324+
325+
free(buffer);
326+
327+
sim_flash_optr ^= SIM_FLASH_OPTR_SWAP_BANK;
328+
sim_dualbank_register_store();
329+
wolfBoot_printf("Simulator dualbank swap complete, register=%u\n",
330+
hal_sim_get_dualbank_state());
331+
332+
if (was_locked)
333+
hal_flash_lock();
334+
}
335+
#endif
336+
237337
void hal_prepare_boot(void)
238338
{
239339
/* no op */
@@ -312,6 +412,10 @@ void hal_init(void)
312412
}
313413
#endif /* EXT_FLASH */
314414

415+
#ifdef DUALBANK_SWAP
416+
sim_dualbank_register_load();
417+
#endif
418+
315419
for (i = 1; i < main_argc; i++) {
316420
if (strcmp(main_argv[i], "powerfail") == 0) {
317421
erasefail_address = strtol(main_argv[++i], NULL, 16);
@@ -480,6 +584,7 @@ void do_boot(const uint32_t *app_offset)
480584
#endif
481585
#endif
482586

587+
#if !defined(WOLFBOOT_DUALBOOT)
483588
int wolfBoot_fallback_is_possible(void)
484589
{
485590
return 0;
@@ -489,6 +594,7 @@ int wolfBoot_dualboot_candidate(void)
489594
{
490595
return 0;
491596
}
597+
#endif
492598

493599
#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
494600

test-app/app_sim.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030

3131
#include "wolfboot/wolfboot.h"
3232

33+
#ifdef DUALBANK_SWAP
34+
uint32_t hal_sim_get_dualbank_state(void);
35+
#endif
36+
3337
#ifdef TARGET_sim
3438

3539
/* Matches all keys:
@@ -72,6 +76,12 @@ int do_cmd(const char *cmd)
7276
wolfBoot_success();
7377
return 0;
7478
}
79+
#ifdef DUALBANK_SWAP
80+
if (strcmp(cmd, "get_swap_state") == 0) {
81+
printf("%u\n", hal_sim_get_dualbank_state());
82+
return 0;
83+
}
84+
#endif
7585
if (strcmp(cmd, "update_trigger") == 0) {
7686
#if EXT_ENCRYPTED
7787
wolfBoot_set_encrypt_key((uint8_t *)enc_key,(uint8_t *)(enc_key + 32));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
if [ ! -f ".config" ]; then
5+
echo "Missing .config. Run make config first." >&2
6+
exit 1
7+
fi
8+
9+
if ! grep -Eq '^(DUALBANK_SWAP(\?|)=1)' .config; then
10+
echo "DUALBANK_SWAP=1 is required for this simulation." >&2
11+
exit 1
12+
fi
13+
14+
if [ ! -x "./wolfboot.elf" ]; then
15+
echo "wolfboot.elf not found. Build the simulator first." >&2
16+
exit 1
17+
fi
18+
19+
rm -f sim_registers.dd
20+
21+
mapfile -t lines < <(./wolfboot.elf get_swap_state get_version 2>/dev/null)
22+
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
23+
echo "Unexpected output on first boot (got: ${lines[*]-})" >&2
24+
exit 1
25+
fi
26+
echo "dualbank: first boot reports swap=${lines[0]} active_version=${lines[1]}"
27+
28+
mapfile -t lines < <(./wolfboot.elf success get_swap_state get_version 2>/dev/null)
29+
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
30+
echo "Unexpected output while confirming update (got: ${lines[*]-})" >&2
31+
exit 1
32+
fi
33+
echo "dualbank: after wolfBoot_success swap=${lines[0]} active_version=${lines[1]}"
34+
35+
mapfile -t lines < <(./wolfboot.elf get_swap_state get_version 2>/dev/null)
36+
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
37+
echo "Unexpected output after confirmation (got: ${lines[*]-})" >&2
38+
exit 1
39+
fi
40+
echo "dualbank: persistent swap state confirmed swap=${lines[0]} active_version=${lines[1]}"
41+
42+
echo "Dualbank swap simulation successful."

0 commit comments

Comments
 (0)