Planning an Update port
Tip: If you cannot access any of the repositories referenced in this section, please contact us to request access.
There are some special considerations if you want to enable firmware update capability on a new target. The key aspects to consider are:
- The memory layout.
- The bootloader.
Designing memory layout
To enable firmware update capability on a given device, the following components need to be in place and work together:
-
A bootloader:
- Needs to be the first thing that executes during boot.
- Can forward control to a user application.
- Can read the storage area for new firmware.
- Can rewrite a user application (optional).
-
An active user application:
- At a location known to the bootloader.
- Contains Device Management Client.
-
A storage area for the new firmware:
- Must be large enough to store the firmware.
- At a location known to the bootloader and the user application.
When porting to a new target, you first need to decide whether your application will use Position-Independent-Code (PIC) or execute code from a fixed memory location. PIC is easier to update because the bootloader only needs to forward control to the new firmware image when it has been downloaded (as long as it is stored in non-volatile memory that supports execute-in-place). The downside of PIC is the added runtime overhead caused by the relative addressing, which makes the code run slower. If you decide to use fixed memory location, a new firmware will have to be copied over the currently active firmware image before it can be executed.
The Update client is agnostic to whether the code is position independent or not; if the compiled code matches what the bootloader expects and what the underlying storage supports, the application can be updated using the Update Service.
Deciding on an execution model will also help you decide where to put the storage area for the new firmware, the active application, and the bootloader. The easiest option is to put them all on the micro-controller's internal flash. You can disable the JTAG pins for production devices to fully protect your firmware. Sometimes there is not enough space on the internal flash, so you might want to put the storage area on an external peripheral. It's then important to have the storage area encrypted to ensure that your firmware is safe. You also need to decide their relative positions so that they can work with each other. An example layout will be introduced later to explain this further.
The bootloader
The bootloader is executed first on the reboot.
For an application executing at a fixed location, the bootloader:
- Checks the integrity of the active application. It calculates the hash of the active image and compares it to the one in the metadata header.
- Checks the integrity of one or more images in the firmware storage area, by checking the hash against a metadata header as well.
- If newer, applicable images exist, the bootloader copies the newest image to the active application storage region.
- Forwards the control to the start of the application binary.
For a PIC application, all storage locations that support execute-in-place are potential candidates and the bootloader's actions can be simplified so that it:
- Checks the integrity of all images in the firmware storage areas that support execute-in-place, as it does for a fixed location application.
- The newest, applicable image is chosen and the bootloader forwards control to the start of the application binary.
Assumptions
- Mbed OS provides the interface to the storage for the downloaded image and associated metadata.
- The bootloader has access to this storage location (or locations).
Features
The bootloader should have a minimal feature-set to increase the likelihood of correct operation, because boot sequence failures are expensive to recover from. The bootloader needs to contain the following features.
Transferring control
The bootloader needs to know the target jump location of the application. The actual mechanism of transferring control to the next stage is platform-specific. It may involve:
- Being able to set main stack pointer (MSP).
- Being able to update vector table offset register (VTOR).
- Being able to set program counter.
Applying an update
To protect against unintentional reboots that make the device unusable, the bootloader must be capable of applying the new firmware. For applications executing from a fixed location, applying an update means overwriting the application currently placed at that fixed location with a newer one. For PIC applications, applying an update means forwarding control to the new firmware instead of the old one.
Fault detection
The bootloader needs to:
- Verify the integrity of any given firmware to prevent upgrading to a corrupted image. It can use a metadata header that contains the hash of the firmware; the integrity of the header itself needs to be verified separately.
- Retain at least one known stable version of firmware at any point during the update process. If the system becomes unstable, the bootloader will revert the active image to the previously known stable version.
Boot sequence
- The bootloader runs before the main image is loaded.
- (non-PIC) The bootloader has access to the main image (user application).
- (non-PIC) The bootloader can access the stored values for the version and SHA256 hash of the main image.
- The bootloader has access to the downloaded images.
- The bootloader can access the stored values for the version and SHA256 hash of the downloaded images.
- The bootloader must verify both the main image and the downloaded images's integrity using SHA256 with their stored hash values.
- (non-PIC) The bootloader must overwrite the main image if the version number of one of the downloaded images is higher and it passes the integrity check.
- (non-PIC) The bootloader detects corruption of the main image due to power failure and restarts overwriting the main image with the downloaded image.
- (non-PIC) If an overwrite is successfully completed the bootloader should update the current version and hash.
- The bootloader transfers execution to the main image.
Note: Both the Device Management Client Update component and the bootloader should share the location of the downloaded firmware and update metadata (version and hash).