In the context of TF-M(Trusted Firmware-M), BL2 refers to the second stage bootloader. When using TF-M, the BL2 is based on open-source MCUBoot. It is responsible for verifying and loading the secure and non-secure images.
Our MCUXpresso SDK takes the open-source MCUBoot and leverages the HW features available to the specific SoC that is being used. In addition, TF-M support for the SoC is also available in the SDK package. Current configuration of TF-M within the SDK does not support enabling BL2.
The following steps demonstrate how to configure the TF-M project in the SDK, so that it can be linked directly with MCUBOOT from our SDK without enabling BL2.
Import MCUBOOT_OPENSOURCE example
Select Import SDK Example and select the board you are working with. Browse the ota_examples to find the mcuboot_opensource example. Select this and press Next.
The following window will contain the memory configuration of the example. It is important to change the Location address(0x18000000) to the secure alias and the Driver(*_S.cfx) to the secure version of the driver. Then press Finish.
Locate the flash_partioning.h header file within the project to determine the start address of where the TF-M secure image will be located. This will be represented by the BOOT_FLASH_ACT_APP macro. #define BOOT_FLASH_ACT_APP 0x18020000. In this example, I know that the secure image should be located in the offset 0x20000. Additionally, using MCUBoot means that we will have a header attached to the image when signed, this will add an addition 0x400. In total my offset will be 0x20400.
Open the preprocessor configurations in the project by right clicking the project and select Properties. With the window open navigate to the following location: C/C++ Build -> Settings -> MCU C Compiler -> Preprocessor Set BOOT_HEADER_ENABLE = 0
Press Apply and Close. Build mcuboot image.
Import TFM_DEMO_S/NS example
Select Import SDK Example and select the board you are working with. Browse the tfm_examples to find the tfm_demo_s/ns examples. Select these and import.
Open the preprocessor configurations in the project by right clicking the project and select Properties. With the window open navigate to the following location: C/C++ Build -> Settings -> MCU C Compiler -> Preprocessor Set BOOT_HEADER_ENABLE = 0
Open the flash_layout.h header file under the following folder in the tfm_demo_s project: tf-m/platform/ext/target/nxp/*board*/partition/
Edit the FLASH_IMAGE_HEADER_SIZE macro. Since we know that MCUBoot uses a header this will be equal to 0x400. #define FLASH_IMAGE_HEADER_SIZE (0x400)
Open the region_defs.h header file under the following folder: tf-m/platform/ext/target/nxp/*board*/partition/
Edit the S_IMAGE_PRIMARY_PARTITION_OFFSET macro. Based on the calculated above, the offset used in this example of the primary image will be 0x20400. #define S_IMAGE_PRIMARY_PARTITION_OFFSET (0x20400)
Edit the M_BOOT_FLASH_CONF_START macro. This should be the same as the base address being used in MCUBoot's BOOT_FLASH_ACT_APP. #define M_BOOT_FLASH_CONF_START (0x18020000)
Open the startup_*board*.c source file under the following folder: tf-m/platform/ext/target/nxp/*board*/Device/Source
Edit the void Reset_Handler(void) function. Add the VTOR configuration so that it points to the top of the vector table.
// Config VTOR & MSPLIM register
__asm volatile ("LDR R0, =0xE000ED08 \n"
"STR %0, [R0] \n"
"LDR R1, [%0] \n"
"MSR MSP, R1 \n"
"MSR MSPLIM, %1 \n"
:
: "r"(__VECTOR_TABLE), "r"(__STACK_LIMIT)
: "r0", "r1");
*Note: This step is only done on the secure image.
Press Apply and Close. Build secure image.
Repeat the same steps 2- 8 in this section for the non-secure image and build.
Generate Binaries
Under the Debug folder you will find the .axf file generated automatically by MCUXpresso IDE under the secure project.
Right click on this and navigate to Binary Utilities -> Create Binary.
Repeat for non-secure image.
Merge Binaries
Note: This article does not show detailed steps of using the SPSDK command line tool. If detailed steps are needed please refer to spsdk.readthedocs.io.
Use the following command to generate the template to merge the binaries. nxpimage utils binary-image get-template -o binary_merge_template.yaml
Edit the template. Calculate the offset of the location of the non-secure image using FLASH_S_PARTITION_SIZE from the flash_layout.h header file. In this example the value is 0x9FC00.
Use the following command to merge the binaries. nxpimage utils binary-image merge -c binary_merge_template.yaml -o merged_tfm_demo.bin
Use Secure Provisioning Tool to Sign Images
Note: This article does not show detailed steps of using MCUXpresso Secure Provisioning Tool. If detailed steps are needed please refer to the its user guide available in the Help Menu of the tool.
Select the MCUBOOT_OPENSOURCE image as your source.
Open the MCUBoot -> Sign Image tool.
Select the merged binary as your source. The output image should be filled automatically to the bootable_images folder of the secure provisioning workspace. Select the key used to authenticate the image. In mcuboot_opensource workspace there is a key folders that contain example keys used for development.
4. Press Sign, then make sure that the target address matches the based address defined in the mcuboot for the primary partition, then save & close.
5. Build and Write Image accordingly with the Secure Provisioning Tool.
Run Application
View full article