This repository contains a two-image firmware setup for STM32F407G-DISC1:
f4_bootloader: first-stage bootloader at flash base0x08000000f4_app: application image relocated to0x08004000
Current implementation includes robust jump handoff and phase-1 secure image validation (fixed header + SHA-256 integrity check).
- Board:
STM32F407G-DISC1 - UART debug:
USART2(PA2=TX,PA3=RX) - FTDI wiring:
- FTDI
RXD->PA2 - FTDI
TXD->PA3 - FTDI
GND->GND
- FTDI
- USER button: blue button (
PA0) - Reset button: black button (
NRST)
- Bootloader:
0x08000000->0x08003FFF(16 KB, sector 0) - App slot:
0x08004000->0x080FFFFF(remaining flash)
f4_bootloader/- STM32CubeIDE bootloader projectf4_app/- STM32CubeIDE app projecttools/sign_f4_app.py- post-build app signing/hash tool
Bootloader jump is allowed only when all checks pass:
- App header
magicandheader_versionare valid. - App image size is in slot bounds.
- Vector table values are structurally valid:
- MSP in SRAM range
- reset handler in flash, Thumb mode, and in image range
- SHA-256 over app image matches hash stored in header.
App header is placed at fixed address APP_BASE + 0x200 (0x08004200).
- STM32CubeIDE (tested with
1.18.1) - GNU Arm toolchain from STM32CubeIDE
- ST-LINK connection for flashing/debugging
Build both projects in STM32CubeIDE (Debug configuration):
- Build
f4_app - Build
f4_bootloader
After building f4_app, generate signed app artifacts:
python C:\STM_Exps\tools\sign_f4_app.py `
--input-elf C:\STM_Exps\f4_app\Debug\f4_app.elf `
--output-bin C:\STM_Exps\f4_app\Debug\f4_app_signed.bin `
--output-hex C:\STM_Exps\f4_app\Debug\f4_app_signed.hexOutput:
f4_app_signed.binf4_app_signed.hex
- Program
f4_bootloaderimage (base0x08000000). - Program
f4_app_signed.hex(app slot at0x08004000). - Open serial terminal on
COM10,115200 8N1. - Press black reset button.
Bootloader behavior:
- Blue button held during reset -> stay in bootloader (
force_boot=1) - Blue button not held + valid signed app -> jump to app
- Invalid app -> stay in bootloader
Expected logs:
- Boot mode:
BOOT: ... force_boot=1 app_valid=1 ...BOOT: staying in bootloaderBOOT: waiting...
- App mode:
BOOT: ... force_boot=0 app_valid=1 ...BOOT: jumping to appAPP: startup at 0x08004000APP: running
err=<n> in boot logs maps to:
1bad app magic2bad header version3invalid image size4invalid MSP5invalid reset vector/range6SHA-256 mismatch
- If you flash plain
f4_app.elfwithout signing, bootloader is expected to reject app hash validation. - If you run
f4_appdirectly from debugger, you bypass bootloader checks.