Generic bootloader design
Overview
General requirements of bootloader are:
- The bootloader will be in secured memory.
- The application firmware resides in user memory where bootloader in secured memory will jump into after boot initialization finishes
- The bootloader needs to be aware of primary/secondary images on the external SPI flash.
- If on-chip RAM is large enough to contain image sections, the image is loaded into on-chip RAM.
- If firmware image is too big to fit into internal on-chip RAM spaces, the image needs to be loaded into external SDRAM.
- Special boot initialization code is sometimes required to initialize system in early phase. A typical application is NTA system restoration. Boot initialization code needs to be modular and built into main bootloader code on demand.
- Secure boot mechanism needs to be considered as security feature gets more attention recently
Since Zephyr integrates MCUboot as a general bootloader project, it is worth studying architecture of MCUboot and direct using MCUboot as Zoysia bootloader.
ST Microcontrollers
For STM32H7 or similar ones, the extended system memory can only be erased/programed by secure firmware, which prevents bootloader code from being corrupted accidentally by application firmware. For STM32G4 or similar ones, the bootloader can be placed at address 0 of the main memory. The boot process of ST MCU is controlled by BOOT and option bytes. The following sections are worth reading
2.4 Embedded SRAM2.6 Boot configuration4 Embedded Flash memory (FLASH)5 Secure memory management (SMM)
Design
- The firmware code is signed by imgtool and generally follow MCUBoot's metadata rule
- For MCU without dual-bank flash remap supported, images in the two banks must use different link address
- For MCU with dual-bank flash remap supported, bootloader image and key authentication key (KAK) must be programmed into both unmapped and remapped address
- The flash block should include both firmware image and supplements such as commitId with CRC32 checksum
- The bootloader reads boot type/bank request in the persist memory made by application code
- The bootloader validates SHA256 image hash and flash block CRC32 as minimal check
- The bootloader checks commitId (-1 by default) to determine the image to be loaded
- Two flash blocks (primary and secondary) are planned for selection by bootloader
- If both banks are valid, the last committed (largest commitId) firmware is loaded
- If either one firmware partition is corrupted, the bootloader will load the other bank
- If both banks are committed, the bootloader enters a console, allowing flashing images
- If new firmware crashes or hangs up after upgrade, it won't be committed, so the next boot (either watchdog reset hard reset or power cycle) would load the previously committed firmware on the other bank
- The bootloader saves actual boot bank and swap info in persist memory for awareness in application
- The application firmware has the ability to escape into bootloader from backdoor
- Configuration, calibration and key (excluding KAK) flash blocks can be erased in bootloader
- Read-protect level (RDP) is raised to disable internal flash access from debug port. Attempts to degrade RDP wipes out everything on the internal flash
Command
- I - Display flash bank information
- M - Download image to RAM
- K - Download key to flash bank0
- L - Download key to flash bank1
- P - Download image to flash bank0
- S - Download image to flash bank1
- F - Erase cfg block
- A - Erase cal block
- 0 - Boot from RAM or auto select flash bank
- 1 - Boot from flash bank0
- 2 - Boot from flash bank1
由 Victor Chen 编辑于