Skip to content

Commit d78163d

Browse files
authored
Merge pull request #940 from danielinux/fix-erase-lastsector
Disallow single-sector partitions in flash + CUSTOM_TRAILER support for STM32F4
2 parents ae804ad + 874a58e commit d78163d

24 files changed

Lines changed: 755 additions & 61 deletions

‎.github/workflows/test-build-cmake.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ jobs:
3737
- name: Run CMake build for STM32F407-DISCOVERY
3838
run: |
3939
rm -rf ./build
40-
cmake -B build -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000 -DCLOCK_SPEED=160000000 -DSTM32_PLLM=8 -DSTM32_PLLN=336 -DSTM32_PLLP=2 -DSTM32_PLLQ=7
40+
cmake -B build -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x60000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08080000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x080E0000 -DCLOCK_SPEED=160000000 -DSTM32_PLLM=8 -DSTM32_PLLN=336 -DSTM32_PLLP=2 -DSTM32_PLLQ=7
4141
- name: Build wolfBoot
4242
run: make -C build
4343

4444
- name: Run CMake build for STM32F411-BLACKPILL
4545
run: |
4646
rm -rf ./build
47-
cmake -B build -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000 -DCLOCK_SPEED=84000000 -DSTM32_PLLM=25 -DSTM32_PLLN=336 -DSTM32_PLLP=4 -DSTM32_PLLQ=7
47+
cmake -B build -DWOLFBOOT_TARGET=stm32f4 -DCUSTOM_PARTITION_TRAILER=yes -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000 -DCLOCK_SPEED=84000000 -DSTM32_PLLM=25 -DSTM32_PLLN=336 -DSTM32_PLLP=4 -DSTM32_PLLQ=7
4848
- name: Build wolfBoot
4949
run: make -C build
5050

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Renode STM32F411 Black Pill custom partition trailer
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
permissions:
10+
contents: read
11+
packages: read
12+
13+
jobs:
14+
blackpill-custom-trailer:
15+
runs-on: ubuntu-22.04
16+
timeout-minutes: 25
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
submodules: true
22+
23+
- name: Log in to GHCR
24+
uses: docker/login-action@v3
25+
with:
26+
registry: ghcr.io
27+
username: ${{ github.actor }}
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Renode update and rollback, single-sector partitions
31+
run: |
32+
docker run --rm -e WORK=/workspace/test_results \
33+
-v ${{ github.workspace }}:/workspace -w /workspace \
34+
ghcr.io/wolfssl/wolfboot-ci-renode:v1.5 \
35+
tools/scripts/renode-test-custom-trailer.sh
36+
37+
- name: Upload Output Dir
38+
if: always()
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: Renode Black Pill custom trailer results
42+
path: test_results/

‎CMakeLists.txt‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,9 @@ add_option("NO_XIP" "Disable execute-in-place (default: disabled)" "no" "yes;no"
464464
add_option(
465465
"NVM_FLASH_WRITEONCE"
466466
"Enable the workaround for 'write once' internal flash (default: disabled)" "no" "yes;no")
467+
add_option(
468+
"CUSTOM_PARTITION_TRAILER"
469+
"Keep the partition trailers outside the partitions (default: disabled)" "no" "yes;no")
467470
add_option(
468471
"RAM_CODE"
469472
"Move all code accessing internal flash for writing into a section in RAM (default: disabled)"
@@ -1088,6 +1091,10 @@ if(NVM_FLASH_WRITEONCE)
10881091
list(APPEND WOLFBOOT_DEFS NVM_FLASH_WRITEONCE)
10891092
endif()
10901093

1094+
if(CUSTOM_PARTITION_TRAILER)
1095+
list(APPEND WOLFBOOT_DEFS CUSTOM_PARTITION_TRAILER)
1096+
endif()
1097+
10911098
if(DISABLE_BACKUP)
10921099
message(WARNING "DISABLE_BACKUP=1 disables power-fail-safe updates; losing power during an update can leave BOOT partially written and unrecoverable")
10931100
list(APPEND WOLFBOOT_DEFS DISABLE_BACKUP)
@@ -1434,6 +1441,10 @@ list(APPEND WOLFBOOT_INCLUDE_DIRS ${WOLFBOOT_ROOT} ${WOLFBOOT_ROOT}/include)
14341441

14351442
# set default linker script
14361443
set(WOLFBOOT_LSCRIPT_TEMPLATE hal/${WOLFBOOT_TARGET}.ld)
1444+
# Partition trailers in sectors 1-2, see hal/stm32f4.c
1445+
if(WOLFBOOT_TARGET STREQUAL "stm32f4" AND CUSTOM_PARTITION_TRAILER)
1446+
set(WOLFBOOT_LSCRIPT_TEMPLATE hal/stm32f4-trailer.ld)
1447+
endif()
14371448

14381449
#---------------------------------------------------------------------------------------------
14391450
# wolfcrypt

‎CMakePresets.json‎

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,11 @@
206206
"WOLFBOOT_VERSION": "OFF",
207207
"SPMATH": "ON",
208208
"RAM_CODE": "OFF",
209-
"WOLFBOOT_PARTITION_SIZE": "0x4000",
210-
"WOLFBOOT_SECTOR_SIZE": "0x4000",
211-
"WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x8000",
212-
"WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x00000",
213-
"WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x4000",
214-
"WOLFBOOT_LOAD_ADDRESS": "0x200000",
215-
"WOLFBOOT_LOAD_DTS_ADDRESS": "0x400000",
209+
"WOLFBOOT_PARTITION_SIZE": "0x60000",
210+
"WOLFBOOT_SECTOR_SIZE": "0x20000",
211+
"WOLFBOOT_PARTITION_BOOT_ADDRESS": "0x08020000",
212+
"WOLFBOOT_PARTITION_UPDATE_ADDRESS": "0x08080000",
213+
"WOLFBOOT_PARTITION_SWAP_ADDRESS": "0x080E0000",
216214
"CLOCK_SPEED": "160000000",
217215
"STM32_PLLM": "8",
218216
"STM32_PLLN": "336",

‎Makefile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ SIGN_ENV=IMAGE_HEADER_SIZE=$(IMAGE_HEADER_SIZE) \
367367
WOLFBOOT_SECTOR_SIZE=$(WOLFBOOT_SECTOR_SIZE) \
368368
NVM_FLASH_WRITEONCE=$(NVM_FLASH_WRITEONCE) \
369369
NVM_FLASH_JOURNAL_DUAL=$(NVM_FLASH_JOURNAL_DUAL) \
370+
CUSTOM_PARTITION_TRAILER=$(CUSTOM_PARTITION_TRAILER) \
370371
ML_DSA_LEVEL=$(ML_DSA_LEVEL) \
371372
IMAGE_SIGNATURE_SIZE=$(IMAGE_SIGNATURE_SIZE) \
372373
LMS_LEVELS=$(LMS_LEVELS) \

‎arch.mk‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,10 @@ ifeq ($(ARCH),ARM)
508508
ifeq ($(TARGET),stm32f4)
509509
ARCH_FLASH_OFFSET=0x08000000
510510
SPI_TARGET=stm32
511+
# Partition trailers in sectors 1-2, see hal/stm32f4.c
512+
ifeq ($(CUSTOM_PARTITION_TRAILER),1)
513+
LSCRIPT_IN=hal/stm32f4-trailer.ld
514+
endif
511515
endif
512516

513517
ifeq ($(TARGET),max32666)

‎config/examples/stm32f4-small-blocks-uart-update.config‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ RAM_CODE?=0
2020
DUALBANK_SWAP?=0
2121
PKA?=1
2222
WOLFTPM?=0
23-
WOLFBOOT_PARTITION_SIZE?=0x4000
23+
WOLFBOOT_PARTITION_SIZE?=0x8000
2424
WOLFBOOT_SECTOR_SIZE?=0x4000
2525
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8000
2626
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x00000
27-
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x4000
27+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x8000
2828
WOLFBOOT_LOAD_ADDRESS?=0x200000
2929
WOLFBOOT_LOAD_DTS_ADDRESS?=0x400000
3030
CLOCK_SPEED?=160000000

‎config/examples/stm32f407-discovery.config‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ SIGN?=ED25519
44
HASH?=SHA256
55
VTOR?=1
66
SPMATH?=1
7-
WOLFBOOT_PARTITION_SIZE?=0x20000
7+
# Trailers in sectors 1-2 (hal/stm32f4.c): the image can fill the partition
8+
CUSTOM_PARTITION_TRAILER?=1
9+
WOLFBOOT_PARTITION_SIZE?=0x60000
810
WOLFBOOT_SECTOR_SIZE?=0x20000
911
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08020000
10-
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08040000
11-
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08060000
12+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08080000
13+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x080E0000
1214
CLOCK_SPEED?=160000000
1315
STM32_PLLM?=8
1416
STM32_PLLN?=336

‎config/examples/stm32f411-blackpill.config‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ HASH?=SHA256
55
VTOR?=1
66
SPMATH?=1
77
WOLFBOOT_ORIGIN?=0x08000000
8+
# Single-sector partitions: the trailers are in sectors 1-2 (hal/stm32f4.c)
9+
CUSTOM_PARTITION_TRAILER?=1
810
WOLFBOOT_PARTITION_SIZE?=0x20000
911
WOLFBOOT_SECTOR_SIZE?=0x20000
1012
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08020000

‎docs/flash_partitions.md‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,36 @@ If the `FLAGS_HOME` build option is used then all flags are placed at the end of
124124
flag
125125
```
126126

127+
The trailer sector is erased independently from the image, so it can never hold any part of it,
128+
and the final step of the swap needs one more sector to stage the image tail. For this reason each
129+
partition must be at least two sectors long (three with `NVM_FLASH_WRITEONCE`, which keeps two
130+
copies of the trailer), and the image can use the partition up to the trailer sector(s). The build
131+
fails if `WOLFBOOT_PARTITION_SIZE` is smaller, unless `CUSTOM_PARTITION_TRAILER` is used.
132+
133+
### Custom partition trailer
134+
127135
You can use the `CUSTOM_PARTITION_TRAILER` option to implement your own functions for: `get_trailer_at`, `set_trailer_at` and `set_partition_magic`.
136+
The trailers are then stored outside of the BOOT and UPDATE partitions, so:
137+
138+
- the image can use the whole partition, which may be a single sector long;
139+
- triggering an update does not erase anything in the UPDATE partition;
140+
- at the end of the swap, the bootloader resets the sector flags and the UPDATE state itself.
141+
142+
`set_trailer_at` may be asked to set bits back to 1 (e.g. resetting the flags to `SECT_FLAG_NEW`),
143+
so on flash it has to erase and rewrite the storage where needed. The flash is unlocked when it is called.
128144

129145
To enable:
130-
1) Add the `CUSTOM_PARTITION_TRAILER` build option to your `.config`: `CFLAGS_EXTRA+=--DCUSTOM_PARTITION_TRAILER`
146+
1) Add `CUSTOM_PARTITION_TRAILER=1` to your `.config` (or `CFLAGS_EXTRA+=-DCUSTOM_PARTITION_TRAILER`,
147+
in which case also export `CUSTOM_PARTITION_TRAILER=1` when running the `sign` tool, so it allows images as
148+
large as the partition)
131149
2) Add your own .c file using `OBJS_EXTRA`. For example for your own `src/custom_trailer.c` add this to your `.config`: `OBJS_EXTRA=src/custom_trailer.o`.
132150

151+
STM32F4 provides its own implementation in `hal/stm32f4.c`: the boot and update trailers are stored in
152+
the 16KB flash sectors 1 and 2 (0x08004000 and 0x08008000, overridable with
153+
`STM32F4_TRAILER_BOOT_ADDRESS` / `STM32F4_TRAILER_UPDATE_ADDRESS`), and wolfBoot is linked around them
154+
(`hal/stm32f4-trailer.ld`: vector table in sector 0, code from sector 3). This allows the BOOT and UPDATE
155+
partitions to use the 128KB sectors without wasting one of them for each trailer, see
156+
`config/examples/stm32f407-discovery.config` and `config/examples/stm32f411-blackpill.config`.
133157

134158
## Overview of the content of the FLASH partitions
135159

0 commit comments

Comments
 (0)