Boot: Use overwrite-only mode for image upgrade
- The swapping image upgrade is a two-step process (by default). First
it performs a "test" upgrade and boots the new image. Then the image can
mark itself as "OK" at runtime by setting the image_ok flag in the
flash. When this happens, the swap is made "permanent" and mcuboot will
then still choose to run it during the next boot. Currently TF-M does
not set the image_ok flag, therefore the bootloader will always perform
a "revert" (swap the images back) during the next boot. For this reason,
this patch sets the overwrite-only mode as the default image upgrade
strategy. However, this strategy does not provide the opportunity to
restore the previous image if the device crashes with the new firmware.
- Update secure boot documentation.
- Fix format specifier error in overwrite-only code.
- Fix the bootloader output message by reorganizing the
preprocessor directives in case of non-swapping firmware upgrade.
Change-Id: Ida1c7c7fc198e393e79d178269826cbfa052395d
Signed-off-by: David Vincze <david.vincze@arm.com>
diff --git a/docs/user_guides/tfm_secure_boot.rst b/docs/user_guides/tfm_secure_boot.rst
index 2a1fe3d..2aa91d4 100644
--- a/docs/user_guides/tfm_secure_boot.rst
+++ b/docs/user_guides/tfm_secure_boot.rst
@@ -13,10 +13,10 @@
*******************************
To implement secure boot functionality an external project MCUBoot has been
integrated to TF-M. For further information please refer to the
-`MCUBoot homepage <https://www.mcuboot.com/>`__. Original source-code is available at
-`GitHub <https://github.com/runtimeco/mcuboot>`__. This document contains
-information about MCUBoot modifications and how MCUBoot has been integrated to
-TF-M.
+`MCUBoot homepage <https://www.mcuboot.com/>`__. Original source-code is
+available at `GitHub <https://github.com/JuulLabs-OSS/mcuboot>`__. This document
+contains information about MCUBoot modifications and how MCUBoot has been
+integrated to TF-M.
Bootloader is started when CPU is released from reset. It runs in secure mode.
It authenticates the firmware image by hash (SHA-256) and digital signature
@@ -28,9 +28,9 @@
A default RSA key pair is stored in the repository, public key is in ``keys.c``
and private key is in ``root-rsa-2048.pem``.
-.. Warning::
- ``DO NOT use them in production code, they are exclusively for testing!``
+.. Warning::
+ DO NOT use them in production code, they are exclusively for testing!
Private key must be stored in a safe place outside of the repository.
``Imgtool.py`` can be used to generate new key pairs.
@@ -39,16 +39,15 @@
is contiguous in the device memory. At compile time these images are
concatenated and signed with RSA-2048 digital signature. Preparation of payload
is done by Python scripts: ``bl2/ext/mcuboot/scripts/``. At the end of a
-successful build signed TF-M payload can be found in::
-
- <build_dir>/install/outputs/fvp/tfm_sign.bin
+successful build signed TF-M payload can be found in:
+``<build_dir>/install/outputs/fvp/tfm_sign.bin``
*********************
Integration with TF-M
*********************
MCUBoot assumes a predefined memory layout which is described below (applicable
-for AN521). It is mandatory to define slot 0, slot 1 and scratch partitions, but
-their size can be changed::
+for AN521). It is mandatory to define slot 0 and slot 1 partitions, but their
+size can be changed::
- 0x0000_0000 - 0x0007_FFFF: BL2 bootloader - MCUBoot
- 0x0008_0000 - 0x000F_FFFF: Slot 0 : Single binary blob: Secure + Non-Secure
@@ -59,47 +58,74 @@
- 0x0010_0400 - 0x0010_xxxx: Non-secure image
- 0x0010_xxxx - 0x0010_xxxx: Hash value(SHA256) and RSA signature
of combined image
-
+
- 0x0018_0000 - 0x0027_FFFF: Slot 1 : Secure + Non-Secure image; Secondary
memory partition, structured identically to slot
0
- - 0x0028_0000 - 0x0037_FFFF: Scratch area, used during image swapping
+ - 0x0028_0000 - 0x0037_FFFF: Scratch area, only used during image swapping
**************************
Firmware upgrade operation
**************************
MCUBoot handles only the firmware authenticity check after start-up and the
firmware switch part of the firmware update process. Downloading the new version
-of the firmware is out-of-scope for MCUBoot. MCUBoot supports two different ways
-to switch to the new firmware and it is assumed that firmware images are
-executed-in-place (XIP). The default behaviour is the image swapping. In this
-case active firmware is always executed from slot 0 and slot 1 is a staging area
-for new images. Before executing the new firmware image, the content of the two
-memory slots must be physically swapped. The other option is the non-swapping
-version, which eliminates the complexity of image swapping and its
+of the firmware is out-of-scope for MCUBoot. MCUBoot supports three different
+ways to switch to the new firmware and it is assumed that firmware images are
+executed-in-place (XIP). The default behaviour is the overwrite-based image
+upgrade. In this case the active firmware is always executed from slot 0 and
+slot 1 is a staging area for new images. Before executing the new firmware
+image, the content of slot 0 must be overwritten with the content of slot 1
+(the new firmware image). The second option is the image swapping strategy when
+the content of the two memory slots must be physically swapped. This needs the
+scratch area to be defined in the memory layout. The third option is the
+non-swapping version, which eliminates the complexity of image swapping and its
administration. Active image can be executed from either memory slot, but new
firmware must be linked to the address space of the proper (currently inactive)
memory slot.
-Swapping operation
+Overwrite operation
==================
Active image is stored in slot 0, and this image is started always by the
-bootloader. Therefore images must be linked to slot 0. If the bootloader finds a
-valid image in slot 1, which is marked for upgrade, then contents of slot 0 and
-slot 1 will be swapped, before starting the new image from slot 0. Scratch area
-is used as a temporary storage place during image swapping. Update mark from
-slot 1 is removed when the swapping is successful. The boot loader can revert
-the swapping as a fall-back mechanism to recover the previous working firmware
-version after a faulty update. The swap operation is fail-safe and resistant to
-power-cut failures. For more details please refer to the MCUBoot
+bootloader. Therefore images must be linked to slot 0. If the bootloader finds
+a valid image in slot 1, which is marked for upgrade, then the content of slot 0
+will be simply overwritten with the content of slot 1, before starting the new
+image from slot 0. After the content of slot 0 has been successfully
+overwritten, the header and trailer of the new image in slot 1 is erased to
+prevent the triggering of another unncessary image uprade after a restart. The
+overwrite operation is fail-safe and resistant to power-cut failures. For more
+details please refer to the MCUBoot
`documentation <https://www.mcuboot.com/mcuboot/design.html>`__.
+Swapping operation
+==================
+This operation can be set with the ``MCUBOOT_UPGRADE_STRATEGY`` compile time
+switch (see `Build time configuration`_). With swapping image upgrade strategy
+the active image is also stored in slot 0 and it will always be started by the
+bootloader. If the bootloader finds a valid image in slot 1, which is marked for
+upgrade, then contents of slot 0 and slot 1 will be swapped, before starting the
+new image from slot 0. Scratch area is used as a temporary storage place during
+image swapping. Update mark from slot 1 is removed when the swapping is
+successful. The boot loader can revert the swapping as a fall-back mechanism to
+recover the previous working firmware version after a faulty update. The swap
+operation is fail-safe and resistant to power-cut failures. For more details
+please refer to the MCUBoot
+`documentation <https://www.mcuboot.com/mcuboot/design.html>`__.
+
+.. Note::
+
+ After a successful image upgrade the firmware can mark itself as "OK" at
+ runtime by setting the image_ok flag in the flash. When this happens, the
+ swap is made "permanent" and MCUBoot will then still choose to run it
+ during the next boot. Currently TF-M does not set the image_ok flag,
+ therefore the bootloader will always perform a "revert" (swap the images
+ back) during the next boot.
+
Non-swapping operation
======================
-This operation can be turned on with ``MCUBOOT_NO_SWAP`` compile time switch
-(see `Build time configuration`_). When enabling non-swapping operation then the
-active image flag is moved between slots during firmware upgrade. If firmware is
-executed-in-place (XIP), then two firmware images must be generated.
+This operation can be set with the ``MCUBOOT_UPGRADE_STRATEGY`` compile time
+switch (see `Build time configuration`_). When enabling non-swapping operation
+then the active image flag is moved between slots during firmware upgrade. If
+firmware is executed-in-place (XIP), then two firmware images must be generated.
One of them is linked to be executed from slot 0 memory region and the other
from slot 1. The firmware upgrade client, which downloads the new image, must be
aware, which slot hosts the active firmware and which acts as a staging area and
@@ -107,75 +133,76 @@
MCUBoot inspects the version number in the image header and passes execution to
the newer firmware version. New image must be marked for upgrade which is
automatically done by Python scripts at compile time. Image verification is done
-the same way in both operational modes. If new image fails during authentication
+the same way in all operational modes. If new image fails during authentication
then MCUBoot erases the memory slot and starts the other image, after successful
authentication.
At build time automatically two binaries are generated::
- <build_dir>/install/outputs/fvp/tfm_s_ns_signed_0.bin : Image linked for slot 0
- memory partition
- <build_dir>/install/outputs/fvp/tfm_s_ns_signed_1.bin : Image linked for slot 1
- memory partition
+ <build_dir>/install/outputs/fvp/tfm_s_ns_signed_0.bin : Image linked for slot 0 memory partition
+
+ <build_dir>/install/outputs/fvp/tfm_s_ns_signed_1.bin : Image linked for slot 1 memory partition
RAM Loading firmware upgrade
============================
-Musca A1 supports an image upgrade mode that is separate to both the swapping
-and non-swapping modes. This is the ``RAM loading`` mode (please refer to the
-table below). Like the non-swapping mode, this selects the newest image by
-reading the image version numbers in the image headers, but instead of
-executing it in place, the newest image is copied to RAM for execution. The
-load address, the location in RAM where the image is copied to, is stored
-in the image header.
+Musca-A supports an image upgrade mode that is separate to the other (overwrite,
+swapping and non-swapping) modes. This is the ``RAM loading`` mode (please refer
+to the table below). Like the non-swapping mode, this selects the newest image
+by reading the image version numbers in the image headers, but instead of
+executing it in place, the newest image is copied to RAM for execution. The load
+address, the location in RAM where the image is copied to, is stored in the
+image header.
Summary of different modes for image upgrade
============================================
Different implementations of the image upgrade operation (whether through
-swapping, non-swapping, or loading into RAM and executing from there) are
-supported by the platforms. The table below shows which of these
+overwriting, swapping, non-swapping or loading into RAM and executing from
+there) are supported by the platforms. The table below shows which of these
modes are supported by which platforms:
-+------------+-----------------+--------------+--------------+-----------------+
-| | Without BL2 [1]_| With BL2 [2]_| With BL2 [2]_| With BL2 [2]_ |
-+============+=================+==============+==============+=================+
-| | XIP | XIP | XIP | Not XIP |
-+------------+-----------------+--------------+--------------+-----------------+
-| | | Swap [3]_ | No-swap [4]_ | RAM loading [5]_|
-+------------+-----------------+--------------+--------------+-----------------+
-| AN521 | Yes | Yes | Yes | No |
-+------------+-----------------+--------------+--------------+-----------------+
-| AN519 | Yes | Yes | Yes | No |
-+------------+-----------------+--------------+--------------+-----------------+
-| Musca-A1 | No | No | No | Yes |
-+------------+-----------------+--------------+--------------+-----------------+
-| Musca-B1 | Yes | No | Yes | No |
-+------------+-----------------+--------------+--------------+-----------------+
++----------+-----------------+----------------------------------------------------------+
+| | Without BL2 [1]_| With BL2 [2]_ |
++==========+=================+===============+==========+=============+=================+
+| | XIP | XIP | XIP | XIP | Not XIP |
++----------+-----------------+---------------+----------+-------------+-----------------+
+| | | Overwrite [3]_| Swap [4]_| No-swap [5]_| RAM loading [6]_|
++----------+-----------------+---------------+----------+-------------+-----------------+
+| AN521 | Yes | Yes | Yes | Yes | No |
++----------+-----------------+---------------+----------+-------------+-----------------+
+| AN519 | Yes | Yes | Yes | Yes | No |
++----------+-----------------+---------------+----------+-------------+-----------------+
+| Musca-A | No | No | No | No | Yes |
++----------+-----------------+---------------+----------+-------------+-----------------+
+| Musca-B1 | Yes | No | No | Yes | No |
++----------+-----------------+---------------+----------+-------------+-----------------+
.. [1] To disable BL2, please turn off the ``BL2`` compiler switch in the
- top-level configuration files or in the command line
+ top-level configuration file or in the command line
.. [2] BL2 is enabled by default
-.. [3] The image executes in-place (XIP) and is in swapping mode for image
- update by default
+.. [3] The image executes in-place (XIP) and is in Overwrite mode for image
+ update by default
-.. [4] To enable XIP No-swap, set the configuration variable ``MCUBOOT_NO_SWAP``
- to ``True`` in the top-level configuration files, or include the
- ``MCUBOOT_NO_SWAP`` macro in the command line
+.. [4] To enable XIP Swap mode, assign the "SWAP" string to the
+ ``MCUBOOT_UPGRADE_STRATEGY`` configuration variable in the top-level
+ configuration file, or include this macro definition in the command line
-.. [5] To enable RAM loading, set the configuration variable
- ``MCUBOOT_RAM_LOADING`` to ``True`` in the top-level configuration files, or
- include the ``MCUBOOT_RAM_LOADING`` macro in the command line
+.. [5] To enable XIP No-swap, assign the "NO_SWAP" string to the
+ ``MCUBOOT_UPGRADE_STRATEGY`` configuration variable in the top-level
+ configuration file, or include this macro definition in the command line
+
+.. [6] To enable RAM loading, assign the "RAM_LOADING" string to the
+ ``MCUBOOT_UPGRADE_STRATEGY`` configuration variable in the top-level
+ configuration file, or include this macro definition in the command line
************************
Build time configuration
************************
MCUBoot related compile time switches can be set in the high level build
-configuration files::
+configuration file::
- ConfigDefault.cmake
- ConfigCoreTest.cmake
- ConfigRegression.cmake
+ CommonConfig.cmake
Compile time switches:
@@ -185,20 +212,19 @@
- **False:** TF-M built without bootloader. Secure image linked to the
beginning of the device memory and executed after reset. If it is false
then using any of the further compile time switches are invalid.
-- MCUBOOT_NO_SWAP (default: False):
- - **True:** Activate non-swapping firmware upgrade operation.
- - **False:** Original firmware upgrade operation with image swapping.
-- MCUBOOT_RAM_LOADING (default: False):
- - **True:** Activate RAM loading firmware upgrade operation, where latest
- image is copied to RAM and runs from there instead of being executed
- in-place.
- - **False:** Original firmware upgrade operation with image swapping.
+- MCUBOOT_UPGRADE_STRATEGY (default: "OVERWRITE_ONLY"):
+ - **"OVERWRITE_ONLY":** Default firmware upgrade operation with overwrite.
+ - **"SWAP":** Activate swapping firmware upgrade operation.
+ - **"NO_SWAP":** Activate non-swapping firmware upgrade operation.
+ - **"RAM_LOADING":** Activate RAM loading firmware upgrade operation, where
+ latest image is copied to RAM and runs from there instead of being
+ executed in-place.
Image versioning
================
An image version number is written to its header by one of the python scripts,
-and this number is used by the bootloader when the non-swapping mode is
-enabled.
+and this number is used by the bootloader when the non-swapping or RAM loading
+mode is enabled.
The version number of the image can manually be passed in through the command
line in the cmake configuration step::
@@ -228,10 +254,10 @@
programmed to the appropriate memory slots. To generate the original and a new
firmware package, TF-M is built twice with different build configurations.
-Swapping firmware upgrade
+Overwriting firmware upgrade
=========================
Run TF-M build twice with two different build configuration: default and
-regression. Save the artefacts between builds, because second run can overwrite
+regression. Save the artifacts between builds, because second run can overwrite
original binaries. Download default build to slot 0 and regression build to
slot 1.
@@ -266,33 +292,59 @@
IMAGE0ADDRESS: 0x00000000
IMAGE0FILE: \Software\mcuboot.axf ; BL2 bootloader
IMAGE1ADDRESS: 0x10080000
- IMAGE1FILE: \Software\tfm_sig1.bin ; TF-M example application binary blob
+ IMAGE1FILE: \Software\tfm_sig1.bin ; TF-M default test binary blob
IMAGE2ADDRESS: 0x10180000
IMAGE2FILE: \Software\tfm_sig2.bin ; TF-M regression test binary blob
+The following message will be shown in case of successful firmware upgrade:
+
+::
+
+ [INF] Starting bootloader
+ [INF] Swap type: test
+ [INF] Image upgrade slot1 -> slot0
+ [INF] Erasing slot0
+ [INF] Copying slot 1 to slot 0: 0x100000 bytes
+ [INF] Bootloader chainload address offset: 0x80000
+ [INF] Jumping to the first image slot
+ [Sec Thread] Secure image initializing!
+
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_SST_TEST_2XXX)...
+ ...
+
+Swapping firmware upgrade
+=============================
+Follow the same instructions and platform related configurations as in case of
+overwriting build including these changes:
+
+- Set MCUBOOT\_SWAP compile time switch to true before build.
+
The following message will be shown in case of successful firmware upgrade,
``Swap type: test`` indicates that images were swapped:
::
- [INF] Image 0: magic=good, copy_done=0xff, image_ok=0xff
- [INF] Scratch: magic=bad, copy_done=0x5, image_ok=0xcf
+ [INF] Starting bootloader
+ [INF] Image 0: magic= good, copy_done=0x3, image_ok=0x3
+ [INF] Scratch: magic= bad, copy_done=0x0, image_ok=0x2
[INF] Boot source: slot 0
[INF] Swap type: test
[INF] Bootloader chainload address offset: 0x80000
[INF] Jumping to the first image slot
[Sec Thread] Secure image initializing!
-Execute test suites for the secure storage service
---------------------------------------------------
-Running Test Suite SST secure interface tests (TFM_SST_TEST_2XXX)....
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_SST_TEST_2XXX)...
+ ...
Non-swapping firmware upgrade
=============================
-Follow the same instructions as in case of swapping build including these
+Follow the same instructions as in case of overwriting build including these
changes:
-- Set MCUBOOT_NO_SWAP compile time switch to true before build.
+- Set the ``MCUBOOT_UPGRADE_STRATEGY`` compile time switch to "NO_SWAP"
+ before build.
- Increase the image version number between the two build run.
Executing firmware upgrade on FVP_MPS2_AEMv8M
@@ -327,7 +379,7 @@
IMAGE0ADDRESS: 0x00000000
IMAGE0FILE: \Software\mcuboot.axf ; BL2 bootloader
IMAGE1ADDRESS: 0x10080000
- IMAGE1FILE: \Software\tfm_sig0.bin ; TF-M example application binary blob
+ IMAGE1FILE: \Software\tfm_sig0.bin ; TF-M default test binary blob
IMAGE2ADDRESS: 0x10180000
IMAGE2FILE: \Software\tfm_sig1.bin ; TF-M regression test binary blob
@@ -337,10 +389,12 @@
combined image using ``srec_cat``:
- Linux::
- srec_cat bl2/ext/mcuboot/mcuboot.bin -Binary -offset 0xA000000 tfm_sign_0.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA0E0000 -o tfm.hex -Intel
+
+ srec_cat bl2/ext/mcuboot/mcuboot.bin -Binary -offset 0xA000000 tfm_sign_0.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA0E0000 -o tfm.hex -Intel
- Windows::
- srec_cat.exe bl2\ext\mcuboot\mcuboot.bin -Binary -offset 0xA000000 tfm_sign_0.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA0E0000 -o tfm.hex -Intel
+
+ srec_cat.exe bl2\ext\mcuboot\mcuboot.bin -Binary -offset 0xA000000 tfm_sign_0.bin -Binary -offset 0xA020000 tfm_sign_1.bin -Binary -offset 0xA0E0000 -o tfm.hex -Intel
The following message will be shown in case of successful firmware upgrade,
notice that image with higher version number (``version=1.2.3.5``) is executed:
@@ -348,36 +402,38 @@
::
[INF] Starting bootloader
- [INF] Image 0: version=1.2.3.4, magic= good, image_ok=0xff
- [INF] Image 1: version=1.2.3.5, magic= good, image_ok=0xff
+ [INF] Image 0: version=1.2.3.4, magic= good, image_ok=0x3
+ [INF] Image 1: version=1.2.3.5, magic= good, image_ok=0x3
[INF] Booting image from slot 1
- [INF] Bootloader chainload address offset: 0x180000
+ [INF] Bootloader chainload address offset: 0xa0000
[INF] Jumping to the first image slot
[Sec Thread] Secure image initializing!
-Execute test suites for the Secure area
----------------------------------------
-Running Test Suite SST secure interface tests (TFM_SST_TEST_2XXX)...
+ #### Execute test suites for the Secure area ####
+ Running Test Suite PSA protected storage S interface tests (TFM_SST_TEST_2XXX)...
+ ...
RAM loading firmware upgrade
============================
-To enable RAM loading, please set ``MCUBOOT_RAM_LOADING`` to True (either in the
-configuration file or through the command line), and then specify a destination
-load address in RAM where the image can be copied to and executed from. The
-``IMAGE_LOAD_ADDRESS`` macro must be specified in the target dependent files,
-for example with Musca A1, its ``flash_layout.h`` file in the ``platform``
+To enable RAM loading, please set ``MCUBOOT_UPGRADE_STRATEGY`` to "RAM_LOADING"
+(either in the configuration file or through the command line), and then specify
+a destination load address in RAM where the image can be copied to and executed
+from. The ``IMAGE_LOAD_ADDRESS`` macro must be specified in the target dependent
+files, for example with Musca-A, its ``flash_layout.h`` file in the ``platform``
folder should include ``#define IMAGE_LOAD_ADDRESS #0x10020000``
-Executing firmware upgrade on Musca-A1 board
+Executing firmware upgrade on Musca-A board
--------------------------------------------
After two images have been built, they can be concatenated to create the
combined image using ``srec_cat``:
-- Linux:
- srec_cat bl2/ext/mcuboot/mcuboot.bin -Binary -offset 0x200000 tfm_sign_old.bin -Binary -offset 0x220000 tfm_sign_new.bin -Binary -offset 0x320000 -o tfm.hex -Intel
+- Linux::
+
+ srec_cat bl2/ext/mcuboot/mcuboot.bin -Binary -offset 0x200000 tfm_sign_old.bin -Binary -offset 0x220000 tfm_sign_new.bin -Binary -offset 0x320000 -o tfm.hex -Intel
- Windows::
- srec_cat.exe bl2\ext\mcuboot\mcuboot.bin -Binary -offset 0x200000 tfm_sign_old.bin -Binary -offset 0x220000 tfm_sign_new.bin -Binary -offset 0x320000 -o tfm.hex -Intel
+
+ srec_cat.exe bl2\ext\mcuboot\mcuboot.bin -Binary -offset 0x200000 tfm_sign_old.bin-Binary -offset 0x220000 tfm_sign_new.bin -Binary -offset 0x320000 -o tfm.hex -Intel
The following message will be shown in case of successful firmware upgrade when,
RAM loading is enabled, notice that image with higher version number
@@ -385,8 +441,9 @@
::
- [INF] Image 0: version=0.0.0.1, magic= good, image_ok=0xff
- [INF] Image 1: version=0.0.0.2, magic= good, image_ok=0xff
+ [INF] Starting bootloader
+ [INF] Image 0: version=0.0.0.1, magic= good, image_ok=0x3
+ [INF] Image 1: version=0.0.0.2, magic= good, image_ok=0x3
[INF] Image has been copied from slot 1 in flash to SRAM address 0x10020000
[INF] Booting image from SRAM at address 0x10020000
[INF] Bootloader chainload address offset: 0x20000