MCUBoot: Under the hood
Hello, in this post, we'll discover more about the MCUBoot bootloader and its integration into Zephyr/NCS.
What is MCUBoot?
MCUBoot is a lightweight bootloader capable of multiple tasks:
Boot an image stored in flash
Verify an image in flash
Swap images in slots
Launch the TFM environement
Wait for Serial recovery
...
It is board/OS agnostic and can be ported to any board with simple adaptations. In this post, we'll focus on its integration in the nRF Connect SDK (NCS).
Why using MCUBoot?
Having a bootloader is often a requirement for most project. It allows upgrade management as well as image integrity checks and a lot more features as we saw previously.
The basics images management is needed to offer an upgrade system to the user. As MCUBoot can be as trimmed down to ~24kB, it is suited for low memory system.
MCUBoot can also be upgraded if a first stage bootloader is present before it. In that case, it requires two MCUBoot slots to be able to perform verification and images swapping if needed.
Upgrade modes
MCUBoot allows multiple upgrade types:
Single slot: Only one application slot is available and is always overwritten in case of an upgrade. Upgrade only possible from MCUBoot
Dual slot: Two slots are reserved for the application. When upgrading, the slot 2 is written, then MCUBoot checks if the image is valid and swap it into slot 1, as only slot 1 can be executed.
Serial recovery: Allow MCUBoot to upgrade/overwrite an image by launching a SMP client, waiting on UART commands, containing the new image to write.
The most commonly used is the dual slot one, as it allows to keep a backup of the old application, as well as defining some rules to validate the new image. It's main disadvantage is that the application can only take up to 1/2 of the remaining memory (after MCUBoot and the other storage partitions are set).
How to use MCUBoot in NCS
In NCS, MCUBoot can be enabled using the sysbuild configuration by enabling:
SB_CONFIG_BOOTLOADER_MCUBOOT=yThis will compile MCUBoot for your project and automatically create the corresponding partitions if dynamic partitioning is used. More information about how to configure MCUBoot can be found on the official nRF documentation.
Image upgrade from an application
The classical and most common way of upgrading an application is through the DFU Target API available in an nRF application. It is only possible in a dual slots setup, as the application cannot erase itself if we are using a single slot.
Here is a pseudo-code using the DFU Target API:
/* Set the update buffer used by the DFU API */
dfu_target_mcuboot_set_buf(mcuboot_buf, MCUBOOT_BUF_SZ);
/* Initialize the DFU Target API with the image info (type, size)*/
dfu_target_init(DFU_TARGET_IMAGE_TYPE_MCUBOOT, 0, img_size, dfu_target_callback_handler);
/* Send images chunks */
while (images bytes left) {
bytes_to_write = read_image_from_sd(dec_buf);
dfu_target_write(dec_buf, bytes_to_write);
}
/* Notify that the flash is done and all chunks were sent */
dfu_target_done(true);
/* Ask MCUBoot to check for an update on all slots */
dfu_target_schedule_update(-1);
/* Reboot to let MCUBoot upgrade the system) */
sys_reboot(SYS_REBOOT_COLD);Once MCUBoot boots again, it will check for the image validity (version higher, correct slot, ...) and integrity (correct encryption key, correct signature, ...) and swap it if it is valid. Then the application can do some more checks (comparing values stored in NVS for example) to validate and confirm the upgrade using the following function:
boot_write_img_confirmed();
Conclusion
We now can setup and use MCUBoot to upgrade our system! This is the first step to consider when designing a system requiring upgrades, as it will determine:
What to enable
How to configure the upgrade
What sizes are available for my different system components (bootloader, application, TFM, NVS, ...)
How and if the upgrade can be recovered in case it fails
I hope you are now ready to dig deeper in MCUBoot and see what else it has to offer! Its code is always fully open-source and is a great way of learning the boot process and its capabilities. I also strongly encourage you to read the available MCUBoot samples from NRF!
Links:


