mirror of https://github.com/wolfSSL/wolfBoot.git
new design/API: Updated documentation
parent
1f196bd64c
commit
7cb51a4255
50
README.md
50
README.md
|
@ -2,11 +2,11 @@
|
|||
wolfSSL Secure Bootloader
|
||||
|
||||
wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers,
|
||||
relying on wolfCrypt for firmware authentication, providing firmware upgrade mechanisms.
|
||||
relying on wolfCrypt for firmware authentication, providing firmware update mechanisms.
|
||||
|
||||
Due to the minimalist design of the bootloader and the tiny HAL API, wolfBoot is completely independent
|
||||
from any OS or bare-metal application, and can be easily ported and integrated in existing embedded software
|
||||
projects to provide a secure firmware upgrade mechanism.
|
||||
projects to provide a secure firmware update mechanism.
|
||||
|
||||
|
||||
## Features
|
||||
|
@ -14,60 +14,66 @@ projects to provide a secure firmware upgrade mechanism.
|
|||
- Integrity verification of the firmware image(s)
|
||||
- Authenticity verification of the firmware image(s) using wolfCrypt's Digital Signature Algorithms (DSA)
|
||||
- Minimalist hardware abstraction layer (HAL) interface to facilitate portability across different vendors/MCUs
|
||||
- Copy/swap images from secondary slots into the primary slots to consent firmware update operations
|
||||
- In-place chain-loading of the firmware image in the primary slot
|
||||
- Copy/swap images from secondary slots into the primary slots to consent firmware upgrade operations
|
||||
|
||||
## Components
|
||||
|
||||
This repository contains the following components:
|
||||
- the bootloader
|
||||
- the wolfBoot bootloader
|
||||
- Ed25519 key generator and image signing tools
|
||||
- Baremetal test applications
|
||||
|
||||
### The bootloader
|
||||
### wolfBoot bootloader
|
||||
|
||||
The bootloader is a memory-safe standalone bare-metal application, designed to run on a generic 32bit MCU,
|
||||
with no dynamic memory allocation mechanism or linkage to any standard C library.
|
||||
woldBoot is a memory-safe standalone bare-metal application, designed to run on a generic microcontroller,
|
||||
with no dynamic memory allocation mechanism or linkage to any standard C library.
|
||||
|
||||
The core application depends on the following libraries:
|
||||
The bootloader consists of the following components:
|
||||
- wolfCrypt, which is used to verify the Ed25519 signature of the images
|
||||
- A minimalist Hardware Abstraction Layer, with an implementation provided for the supported target, which is in charge for IAP flash access and clock setting on the specific MCU
|
||||
- The core bootloader
|
||||
- A small application library to interact with the bootloader
|
||||
- The core bootloader
|
||||
- A small application library used by the application to interact with the bootloader [src/libwolfboot.c](src/libwolfboot.c)
|
||||
|
||||
The goal of this application is to perform image verification and/or requested firmware upgrade tasks
|
||||
before chain-loading the actual firmware from a specific location in flash.
|
||||
|
||||
Only ARM Cortex-M is supported at this stage. Support for more architectures and
|
||||
microcontrollers will be added later.
|
||||
Only ARM Cortex-M boot mechanism is supported at this stage. Support for more architectures and
|
||||
microcontrollers will be added later. Relocating the interrupt vector can be disabled if needed.
|
||||
|
||||
## Integrating wolfBoot in an existing project
|
||||
|
||||
Requirements:
|
||||
### Required steps
|
||||
|
||||
- Provide a HAL implementation for the target platform (see [Hardware Abstraction Layer](docs/HAL.md))
|
||||
- Decide a flash partition strategy and modify `include/target.h` accordingly (see [Flash partitions](docs/flash_partitions.md))
|
||||
- Change the entry point of the firmware image to account for bootloader presence
|
||||
- Equip the application with the [wolfBoot library](docs/API.md) to interact with the bootloader
|
||||
|
||||
### Examples provided
|
||||
|
||||
The following steps are automated in the default `Makefile` target, using the baremetal test
|
||||
application as an example to create the factory image:
|
||||
application as an example to create the factory image. By running `make`, the build system will:
|
||||
|
||||
- Create a Ed25519 Key-pair using the `ed25519_keygen` tool
|
||||
- Compile the bootloader. The public key generated in the step above is included in the build
|
||||
- Compile the firmware image
|
||||
- Compile the firmware image from the test application in [test\_app](test-app/)
|
||||
- Re-link the firmware to change the entry-point to the start address of the primary partition
|
||||
- Sign the firmware image using the `ed25519_sign` tool
|
||||
- Create a factory image by concatenating the bootloader and the firmware image
|
||||
- Flash the factory image to the target
|
||||
|
||||
The factory image can be flashed to the target device. It contains the bootloader and the signed initial
|
||||
firmware at the specified address on the flash.
|
||||
|
||||
The `ed25519_sign` tool transforms a bootable firmware image to comply with the firmware image format required by the bootloader.
|
||||
|
||||
For more detailed information about the firmware image format, see [Firmware image](docs/firmware_image.md)
|
||||
|
||||
## Upgrading the firmware
|
||||
### Upgrading the firmware
|
||||
|
||||
- Compile the new firmware image, and link it so that its entry point is at the start address of the primary partition
|
||||
- Sign the firmware using the `ed25519_sign` tool and the private key generated for the factory image
|
||||
- Transfer the image using a secure connection, and store it to the secondary firmware slot
|
||||
- Trigger the image swap using bootutil's `boot_set_pending()` function
|
||||
- Trigger the image swap using libwolfboot `wolfBoot_update()` function. See [wolfBoot library API](docs/API.md) for a description of the operation
|
||||
- Reboot to let the bootloader begin the image swap
|
||||
- Confirm the success of the update using libwolfboot `wolfBoot_success()` function. See [wolfBoot library API](docs/API.md) for a description of the operation
|
||||
|
||||
For more detailed information about firmware upgrade procedures, see [Firmware Upgrade](docs/firmware_upgrade.md)
|
||||
For more detailed information about firmware update implementation, see [Firmware Update](docs/firmware_update.md)
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# Application interface for interactions with the bootloader
|
||||
|
||||
wolfBoot offers a small interface to interact with the images stored in the partition,
|
||||
explicitly initiate an update and confirm the success of a previously scheduled update.
|
||||
|
||||
## Compiling and linking with libwolfboot
|
||||
|
||||
An application that requires interactions with wolfBoot must include the header file:
|
||||
|
||||
`#include <wolfboot/wolfboot.h>`
|
||||
|
||||
Which exports the API function declarations, and the predefined values for the flags
|
||||
and the tags stored together with the firmware images in the two partitions.
|
||||
|
||||
For more information about flash partitions, flags and states see [Flash partitions](flash_partitions.md).
|
||||
|
||||
## API
|
||||
|
||||
libwolfboot provides low-level access interface to flash partition states. The state
|
||||
of each partition can be retrieved and altered by the application.
|
||||
|
||||
Basic interaction from the application is provided via the two high-level function calls:
|
||||
|
||||
`void wolfBoot_update(void)`
|
||||
|
||||
and
|
||||
|
||||
`void wolfBoot_success(void)`
|
||||
|
||||
### Trigger an update
|
||||
|
||||
- `wolfBoot_update()` is used to trigger an update upon the next reboot, and it is normally used by
|
||||
an update application that has retrieved a new version of the running firmware, and has
|
||||
stored it in the UPDATE partition on the flash. This function will set the state of the UPDATE partition
|
||||
to `ST_UPDATE`, instructing the bootloader to perform the update upon the next execution (after reboot).
|
||||
|
||||
wolfBoot update process consist in swapping the content of the UPDATE and the BOOT partitions, using a temporary
|
||||
single-block SWAP space.
|
||||
|
||||
- `wolfBoot_success()` indicates a successful boot of a new firmware. This can be called by the application
|
||||
at any time, but it will only be effective to mark the current firmware (in the BOOT partition) with the state
|
||||
`ST_SUCCESS`, indicating that no roll-back is required. An application should typically call `wolfBoot_success()`
|
||||
only after verifying that the basic system features are up and running, including the possibility to retrieve
|
||||
a new firmware for the next upgrade.
|
||||
|
||||
If after an upgrade wolfBoot detects that the active firmware is still in `ST_TESTING` state, it means that
|
||||
a successful boot has not been confirmed for the application, and will attempt to revert the update by swapping
|
||||
the two images again.
|
||||
|
||||
For more information about the update process, see [Firmware Update](firmware_update.md)
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ ensuring that the MCU is running at full speed during boot, to optimize the
|
|||
verification of the signatures.
|
||||
|
||||
The implementation of the hardware-specific calls for each platform are grouped in
|
||||
a single c file in the [hal](hal) directory.
|
||||
a single c file in the [hal](../hal) directory.
|
||||
|
||||
The directory also contains a platform-specific linker script for each supported MCU,
|
||||
with the same name and the `.ld` extension. This is used to link the bootloader's
|
||||
|
|
|
@ -6,8 +6,8 @@ WolfBoot can only chain-load and execute firmware images from a specific entry p
|
|||
which must be specified as the origin of the FLASH memory in the linker script of the embedded
|
||||
application. This correspond to the first partition in the flash memory.
|
||||
|
||||
Multiple firmware images can be created this way, and stored in different partitions. The bootloader
|
||||
will take care of moving the selected firmware to the first boot partition before chain-loading the image.
|
||||
Multiple firmware images can be created this way, and stored in two different partitions. The bootloader
|
||||
will take care of moving the selected firmware to the first (BOOT) partition before chain-loading the image.
|
||||
|
||||
Due to the presence of an image header, the entry point of the application has a fixed additional offset
|
||||
of 256B from the beginning of the flash partition.
|
||||
|
@ -24,24 +24,48 @@ chain-loading the firmware the interrupt continue to work properly after the boo
|
|||
|
||||
*The image header is stored at the beginning of the slot and the actual firmware image starts 256 Bytes after it*
|
||||
|
||||
### Image header: Tags
|
||||
|
||||
## Firmware trailer
|
||||
The **image header** is prepended with a single 4-byte magic number, followed by a 4-byte field indicating the
|
||||
firmware image (excluding the header). All numbers in the header are stored in Little-endian format.
|
||||
|
||||
At the end of the actual firmware image, the signing tool stores three trailer "TLV" (type-length-value) records,
|
||||
respectively containing:
|
||||
- A hash digest of the firmware, including its firmware header, obtained using SHA-256
|
||||
- A hash digest of the public key that can be used by the bootloader to verify the authenticity of the firmware. The key must already be stored with the bootloader, and this field is only used as sanity check.
|
||||
- The signature obtained by signing the hash digest of the firmware with the factory private key
|
||||
The two fixed fields are followed by one or more tags. Each TAG is structured as follows:
|
||||
|
||||
These three fields are required by the bootloader to verify the integrity and the origin of the firmware image.
|
||||
- 1 Byte indicating the **Type**
|
||||
- 1 Byte indicating the **size** of the tag, excluding the type and size bytes
|
||||
- ***N*** bytes of tag content
|
||||
|
||||

|
||||
With the following two exception:
|
||||
- A '0' in the Type field indicate the end of the Tag. The rest of the header carries no more Tags. The 'end of tags' type has no **size** field.
|
||||
- A '0xFF' in the Type field indicate a simple padding byte. The 'padding' byte has no **size** field, and the next byte should be processed as **Type** again.
|
||||
|
||||
*The trailer of a signed firmware contains a TLV header and three TLV records that are used by the bootloader to verify the image*
|
||||
Each **Type** has a different meaning, and integrate information about the firmware. The following Tags are mandatory for validating the firmware image:
|
||||
|
||||
- A 'version' Tag (type: 0x01, size: 4 Bytes) indicating the version number for the firmware stored in the image
|
||||
- A 'timestamp' Tag (type: 0x02, size 8 Bytes) indicating the timestamp in unix seconds for the creation of the firmware
|
||||
- A 'sha256 digest' Tag (type: 0x03, size: 32 Bytes) used for integrity check of the firmware
|
||||
- A 'firmware signature' Tag (type: 0x20, size: 64 Bytes) used to validate the signature stored with the firmware against a known public key
|
||||
|
||||
Optionally, a 'public key hint digest' Tag can be transmitted in the header (type: 0x10, size:32 Bytes). This Tag contains the SHA256 digest of the public key used
|
||||
by the signing tool. The bootloader may use this field to locate the correct public key in case of multiple keys available.
|
||||
|
||||
wolfBoot will, in all cases, refuse to boot an image that cannot be verified and authenticated using the built-in digital signature authentication mechanism.
|
||||
|
||||
|
||||
### Image signing tool
|
||||
|
||||
The image signing tool generates the header with all the required Tags for the compiled image, and add them to the output file that can be then
|
||||
stored on the primary slot on the device, or transmitted later to the device through a secure channel to initiate an update.
|
||||
|
||||
### Storing firmware image
|
||||
|
||||
Firmware images are stored with their full header at the beginning of any of the partitions on the system.
|
||||
wolfBoot can only boot images from the BOOT partition, while keeping a second firmware image in the UPDATE partition.
|
||||
|
||||
In order to boot a different image, wolfBoot will have to swap the content of the two images.
|
||||
|
||||
For more information on how firmware images are stored and managed within the two partitions, see [Flash partitions](flash_partitions.md)
|
||||
|
||||
## Image signing tool
|
||||
|
||||
The image signing tool generates the header and trailers for the compiled image, and add them to the output file that can be then
|
||||
stored on the primary slot on the device.
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# Firmware update
|
||||
|
||||
This section documents the complete firmware update procedure, enabling secure boot
|
||||
for an existing embedded application.
|
||||
|
||||
The steps to follow to complete a firmware update with wolfBoot are:
|
||||
- Compile the firmware with the correct entry point
|
||||
- Sign the firmware
|
||||
- Transfer the image using a secure connection, and store it to the secondary firmware slot
|
||||
- Trigger the image swap
|
||||
- Reboot to let the bootloader begin the image swap
|
||||
|
||||
At any given time, an application or OS running on a wolfBoot system can receive an updated version of itself,
|
||||
and store the updated image in the second partition in the FLASH memory.
|
||||
|
||||
Applications or OS threads can be linked to the [libwolfboot library](API.md), which exports the API to trigger
|
||||
the update at the next reboot, and some helper functions to access the flash partition for
|
||||
erase/write through the target specific [HAL](HAL.md).
|
||||
|
||||
## Update procedure description
|
||||
|
||||
Using the [API](API.md) provided to the application, wolfBoot offers the possibility to initiate, confirm or
|
||||
rollback an update.
|
||||
|
||||
After storing the new firmware image in the UPDATE partition, the application should initiate the update by calling
|
||||
`wolfBoot_update()`. By doing so, the UPDATE partition is marked for update. Upon the next reboot, wolfBoot will:
|
||||
- Validate the new firmware image stored in the UPDATE partition
|
||||
- Verify the signature attached against a known public key stored in the bootloader image
|
||||
- Swap the content of the BOOT and the UPDATE partitions
|
||||
- Mark the new firmware in the BOOT partition as in state `ST_TESTING`
|
||||
- Boot into the newly received firmware
|
||||
|
||||
### Successful boot
|
||||
|
||||
Upon a successful boot, the application should inform the bootloader by calling `wolfBoot_success()`, after verifying that
|
||||
the system is up and running again. This operation confirms the update to a new firmware.
|
||||
|
||||
Failing to set the BOOT partition to `ST_SUCCESS` before the next reboot triggers a roll-back operation.
|
||||
Roll-back is initiated by the bootloader by triggering a new update, this time starting from the backup copy of the original
|
||||
(pre-update) firmware, which is now stored in the UPDATE partition due to the swap occurring earlier.
|
||||
|
||||
|
||||
### Building a new firmware image
|
||||
|
||||
Firmware images are position-dependent, and can only boot from the origin of the **BOOT** partition in FLASH.
|
||||
This design constraint implies that the chosen firmware is always stored in the **BOOT** partition, and wolfBoot
|
||||
is responsible for pre-validating an update image and copy it to the correct address.
|
||||
|
||||
All the firmware images must therefore have their entry point set to the address corresponding to the beginning
|
||||
of the **BOOT** partition, plus an offset of 256 Bytes to account for the image header.
|
||||
|
||||
Once the firmware is compiled and linked, it must be signed using the `ed25519_sign` tool. The tool produces
|
||||
a signed image that can be transferred to the target using a secure connection, using the same key corresponding
|
||||
to the public key currently used for verification.
|
||||
|
||||
The tool also adds all the required Tags to the image header, containing the signatures and the SHA256 hash of
|
||||
the firmware.
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
# Firmware upgrade
|
||||
|
||||
This section documents the complete firmware upgrade procedure, enabling secure boot
|
||||
for an existing embedded application.
|
||||
|
||||
The steps to follow to complete a firmware upgrade with wolfBoot are:
|
||||
- Compile the firmware with the correct entry point
|
||||
- Sign the firmware
|
||||
- Transfer the image using a secure connection, and store it to the secondary firmware slot
|
||||
- Trigger the image swap
|
||||
- Reboot to let the bootloader begin the image swap
|
||||
|
||||
|
||||
An application can be linked to wolfBoot `bootutil` library, which exports the API to trigger
|
||||
the upgrade at the next reboot, and some helper functions to access the flash partition for
|
||||
erase/write through the target specific [HAL](HAL.md).
|
||||
|
||||
## Upgrade mode
|
||||
|
||||
wolfBoot can be compiled to provide two different types of upgrade:
|
||||
- Overwrite-only mode
|
||||
- Swap mode
|
||||
|
||||
### Overwrite-only mode
|
||||
|
||||
If wolfBoot is compiled with the `SWAP=0` command line option, no swap partition is required.
|
||||
In this case, every time that a firmware upgrade is triggered, there is no way to revert the upgrade.
|
||||
|
||||
After the received firmware image is marked as 'pending' from the application, wolfBoot will verify its
|
||||
authenticity and integrity, and overwrite the boot partition by storing the new image.
|
||||
|
||||
No firmware image rollback option is present in this configuration.
|
||||
|
||||
### Swap mode
|
||||
|
||||
Using the default configuration, wolfBoot offers the possibility to initiate, confirm or rollback an upgrade.
|
||||
|
||||
This mode requires an additional partition (swap) that can be used as a temporary storage. The swap partition
|
||||
is also able to track the status of the flash operations, so that in case of power failure it can restart
|
||||
the interrupted upgrade operation.
|
||||
|
||||
The application can trigger temporary or permanent upgrades.
|
||||
|
||||
|
||||
## Building a new firmware image
|
||||
|
||||
Firmware images are position-dependent, and can only boot from the origin of the **boot** partition in the FLASH.
|
||||
This design choice means that the chosen firmware is always stored in the **boot** partition, and the bootloader
|
||||
is responsible for pre-validating an upgrade image and copy it to the correct address.
|
||||
|
||||
All the firmware images must therefore have their entry point set to the address corresponding to the beginning
|
||||
of the **boot** partition, plus an offset of 256 Bytes to account for the firmware header.
|
||||
|
||||
Once the firmware is compiled and linked, it must be signed using the `ed25519_sign` tool. The tool produces
|
||||
a signed image that can be transferred to the target using a secure connection, using the same key corresponding
|
||||
to the public key currently used for verification.
|
||||
|
||||
The tool also appends the TLV at the end of the image, containing the signatures and the SHA256 hash of the firmware.
|
||||
|
||||
## Embedded application
|
||||
|
||||
At any given time, an application or OS running on a wolfBoot system can receive an updated version of itself,
|
||||
and store the updated image in the second partition in the FLASH memory.
|
||||
|
||||
In order to communicate with the bootloader, the application can be linked with the `bootutil` library, by
|
||||
including the source file [lib/bootutil/bootutil\_misc.c](../lib/bootutil/bootutil_misc.c) and the back-end of
|
||||
the [Hardware Abstraction Layer](docs/HAL.md) in use by wolfBoot for the target.
|
||||
|
||||
If the running application lacks support for FLASH IAP operations, *bootutil* can also be used to easily access
|
||||
the flash for erasing/writing.
|
||||
|
||||
### Storing the update image
|
||||
|
||||
The application can access the flash area using the following API:
|
||||
|
||||
|
||||
#### Flash access
|
||||
|
||||
The following functions are declared in `include/flash.h`:
|
||||
|
||||
`int flash_area_open(uint8_t id, const struct flash_area **area)`
|
||||
|
||||
Initialize a `flash_area` object associated to the partition associated to identifier
|
||||
`id`.
|
||||
|
||||
Possible identifiers are:
|
||||
- `1` for the **boot** partition
|
||||
- `2` for the **upgrade** partition
|
||||
- `3` for the **swap** partition, if present.
|
||||
|
||||
This function must be called before using any other `flash_area_*` function.
|
||||
Returns 0 on success.
|
||||
|
||||
`void flash_area_close(const struct flash_area *area)`
|
||||
Stop using a flash area associated to the structure passed as argument.
|
||||
|
||||
|
||||
`int flash_area_read(const struct flash_area *, uint32_t off, void *dst, uint32_t len)`
|
||||
`int flash_area_write(const struct flash_area *, uint32_t off, const void *src, uint32_t len)`
|
||||
`int flash_area_erase(const struct flash_area *, uint32_t off, uint32_t len)`
|
||||
|
||||
Read/Write/Erase a portion of the flash area, starting at offset `off` relative to the beginning
|
||||
of the partition.
|
||||
|
||||
#### Triggering an upgrade
|
||||
|
||||
The following function is exported by the bootutil library and declared in `include/bootutil.h`:
|
||||
|
||||
`int boot_set_pending(int permanent);`
|
||||
Trigger a firmware upgrade after the next reboot. If the permanent flag is not active and wolfBoot
|
||||
is compiled in "swap" mode, the change will require to be confirmed via `boot_set_confirmed()` after
|
||||
a successful boot, otherwise the original image will be rolled back after another reboot.
|
||||
|
||||
`int boot_set_confirmed(void);`
|
||||
Confirm a previously triggered temporary upgrade. Only available when wolfBoot is compiled in swap mode.
|
||||
|
||||
To boot into the image stored in the upgrade partition, it is sufficient to call:
|
||||
|
||||
`boot_set_pending(1);`
|
||||
|
||||
and reboot the system to initiate the upgrade.
|
||||
|
|
@ -1,20 +1,29 @@
|
|||
# Flash partitions
|
||||
|
||||
|
||||
## Flash memory partitions
|
||||
|
||||
To integrate wolfBoot you need to partition the flash into
|
||||
separate areas (slots), according to the geometry of the flash memory.
|
||||
separate areas (partitions), taking into account the geometry of the flash memory.
|
||||
|
||||
Images boundaries **must** be aligned to physical sectors, because the
|
||||
bootloader erases all the flash sectors before storing a firmware image.
|
||||
bootloader erases all the flash sectors before storing a new firmware image, and
|
||||
swaps the content of the two partitions, one sector at a time.
|
||||
|
||||
For this reason, before proceeding with partitioning on a target system, the
|
||||
following aspects must be considered:
|
||||
|
||||
- BOOT partition and UPDATE partition must have the same size, and be able to contain the running system
|
||||
- SWAP partition must be as big as the largest sector in both BOOT and UPDATE partition.
|
||||
|
||||
The flash memory of the target is partitioned into the following areas:
|
||||
|
||||
- Bootloader partition, at the beginning of the flash
|
||||
- Primary slot (boot partition) starting at address `FLASH_AREA_IMAGE_0_OFFSET`
|
||||
- Secondary slot (upgrade partition) starting at address `FLASH_AREA_IMAGE_1_OFFSET`
|
||||
- Scratch space (swap partition) starting at address `FLASH_AREA_IMAGE_SCRATCH_OFFSET`
|
||||
- Bootloader partition, at the beginning of the flash, generally very small (16-32KB)
|
||||
- Primary slot (BOOT partition) starting at address `WOLFBOOT_PARTITION_BOOT_ADDRESS`
|
||||
- Secondary slot (UPDATE partition) starting at address `WOLFBOOT_PARTITION_UPDATE_ADDRESS`
|
||||
- both partitions share the same size, defined as `WOLFBOOT_PARTITION_SIZE`
|
||||
- Swapping space (SWAP partition) starting at address `WOLFBOOT_PARTITION_SWAP_ADDRESS`
|
||||
- the swap space size is defined as `WOLFBOOT_SECTOR_SIZE` and must be as big as the
|
||||
largest sector used in either BOOT/UPDATE partitions.
|
||||
|
||||
A proper partitioning configuration must be set up for the specific use, by setting
|
||||
the values for offsets and sizes in [include/target.h](../include/target.h).
|
||||
|
@ -25,18 +34,22 @@ This partition is usually very small, and only contains the bootloader code and
|
|||
Public keys pre-authorized during factory image creations are automatically stored
|
||||
as part of the firmware image.
|
||||
|
||||
### Primary slot (boot partition)
|
||||
### BOOT partition
|
||||
|
||||
This is the only partition from where it is possible to chain-load and execute a
|
||||
firmware image. The firmware image must be linked so that its entry-point is at address
|
||||
`FLASH_AREA_IMAGE_0_OFFSET + 256`.
|
||||
`WOLFBOOT_PARTITION_BOOT_ADDRESS + 256`.
|
||||
|
||||
### Secondary slot (upgrade partition)
|
||||
### UPDATE partition
|
||||
|
||||
The running firmware is responsible of transferring a new firmware image through a secure channel,
|
||||
and store it in the secondary slot. If an upgrade is initiated, the bootloader will replace or swap
|
||||
and store it in the secondary slot. If an update is initiated, the bootloader will replace or swap
|
||||
the firmware in the boot partition at the next reboot.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Example 512KB partitioning on STM32-F407
|
||||
|
||||
The example firmware provided in the `test-app` is configured to boot from the primary partition
|
||||
|
@ -44,12 +57,12 @@ starting at address 0x20000. The flash layout is provided by the default example
|
|||
configuration in `target.h`:
|
||||
|
||||
```C
|
||||
#define FLASH_AREA_IMAGE_0_OFFSET 0x20000
|
||||
#define FLASH_AREA_IMAGE_0_SIZE 0x20000
|
||||
#define FLASH_AREA_IMAGE_1_OFFSET 0x40000
|
||||
#define FLASH_AREA_IMAGE_1_SIZE 0x20000
|
||||
#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x60000
|
||||
#define FLASH_AREA_IMAGE_SCRATCH_SIZE 0x20000
|
||||
#define WOLFBOOT_SECTOR_SIZE 0x20000
|
||||
#define WOLFBOOT_PARTITION_SIZE 0x20000
|
||||
|
||||
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x20000
|
||||
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x40000
|
||||
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x60000
|
||||
```
|
||||
|
||||
which results in the following partition configuration:
|
||||
|
@ -64,4 +77,26 @@ The entry point for all the runnable firmware images on this target will be `0x2
|
|||
of the firmware image header at the beginning of the partition, as explained more in details
|
||||
in [Firmware image](firmware_image.md)
|
||||
|
||||
In this particular case, due to the flash geometry, the swap space must be as big as 64KB, to account for proper sector swapping between the two images.
|
||||
|
||||
On other systems, the SWAP space can be as small as 512B, if multiple smaller flash blocks are used.
|
||||
|
||||
More information about the geometry of the flash and in-application programming (IAP) can be found in the manufacturer manual of each target device.
|
||||
|
||||
## Partition status and sector flags
|
||||
|
||||
Partitions are used to store firmware images currently in use (BOOT) or ready to swap in (UPDATE).
|
||||
In order to track the status of the firmware in each partition, a 1-Byte state field is stored at the end of
|
||||
each partition space. This byte is initialized when the partition is erased and accessed for the first time.
|
||||
|
||||
Possible states are:
|
||||
- `STATE_NEW` (0xFF): The image was never staged for boot, or triggered for an update. If an image is present, no flags are active.
|
||||
- `STATE_UPDATING` (0x70): Only valid in the UPDATE partition. The image is marked for update and should replace the current image in BOOT.
|
||||
- `STATE_TESTING` (0x10): Only valid in the BOOT partition. The image has been just updated, and never completed its boot. If present after reboot, it means that the updated image failed to boot, despite being correctly verified. This particular situation triggers a rollback.
|
||||
- `STATE_SUCCESS` (0x00): Only valid in the BOOT partition. The image stored in BOOT has been successfully staged at least once, and the update is now complete.
|
||||
|
||||
Starting from the State byte and growing backwards, the bootloader keeps track of the state of each sector, using 4 bits per sector at the end of the UPDATE partition. Whenever an update is initiated, the firmware is transferred from UPDATE to BOOT one sector at a time, and storing a backup of the original firmware from BOOT to UPDATE. Each flash access operation correspond to a different value of the flags for the sector in the sector flags area, so that if the operation is interrupted, it can be resumed upon reboot.
|
||||
|
||||
## Overview of the content of the FLASH partitions
|
||||
|
||||

|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 37 KiB |
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
Loading…
Reference in New Issue