From b3bb237700e8b3b58ff7f9de1bcc405e08b9bdd6 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 18 Aug 2025 20:05:37 +0200 Subject: [PATCH 01/18] modules: tf-m: Kconfig.tfm: Update TFM_BOARD Reorder TFM_BOARD entries by vendor name for improved clarity. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/Kconfig.tfm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 6c3ac64487f2e..a02b04071b418 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -10,7 +10,7 @@ config ZEPHYR_TRUSTED_FIRMWARE_M_MODULE config TFM_BOARD string - default "nxp/lpcxpresso55s69" if BOARD_LPCXPRESSO55S69_LPC55S69_CPU0_NS + default "adi/max32657" if BOARD_MAX32657EVKIT_MAX32657_NS || BOARD_MAX32658EVKIT_MAX32658_NS default "arm/mps2/an521" if BOARD_MPS2_AN521_CPU0_NS default "arm/mps3/corstone300/fvp" if BOARD_MPS3_CORSTONE300_FVP_NS default "arm/mps3/corstone300/an547" if BOARD_MPS3_CORSTONE300_AN547_NS @@ -19,13 +19,13 @@ config TFM_BOARD default "arm/mps3/corstone310/fvp" if BOARD_MPS3_CORSTONE310_FVP_NS default "arm/mps4/corstone315" if BOARD_MPS4_CORSTONE315_FVP_NS default "arm/mps4/corstone320" if BOARD_MPS4_CORSTONE320_FVP_NS + default "arm/musca_b1" if BOARD_V2M_MUSCA_B1 + default "arm/musca_s1" if BOARD_V2M_MUSCA_S1 + default "nxp/lpcxpresso55s69" if BOARD_LPCXPRESSO55S69_LPC55S69_CPU0_NS default "stm/b_u585i_iot02a" if BOARD_B_U585I_IOT02A default "stm/nucleo_l552ze_q" if BOARD_NUCLEO_L552ZE_Q default "stm/stm32l562e_dk" if BOARD_STM32L562E_DK default "stm/stm32wba65i_dk" if BOARD_NUCLEO_WBA65RI || BOARD_STM32WBA65I_DK1 - default "arm/musca_b1" if BOARD_V2M_MUSCA_B1 - default "arm/musca_s1" if BOARD_V2M_MUSCA_S1 - default "adi/max32657" if BOARD_MAX32657EVKIT_MAX32657_NS || BOARD_MAX32658EVKIT_MAX32658_NS default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf9160" if SOC_NRF9160 default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf9120" if SOC_NRF9120 default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf5340_cpuapp" if SOC_NRF5340_CPUAPP From b20651142169a905c6ad4117f952a54becfaa450 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Fri, 15 Aug 2025 09:00:03 +0200 Subject: [PATCH 02/18] boards: arm: mps2: Fix NS flash layout The mps2/an521/cpu0/ns define flash layouts in tf-m to allow CONFIG_TFM_MCUBOOT_IMAGE_NUMBER be 1 or 2. In the Zephyr project when building the samples the value selected is 2. The layout changes are necessary to allow use the --max-sectors options when signing the images. It ensures that flash layout is respected. To allow this the compatible "soc-nv-flash" was added in the reserved memory and the fixed-partitions were defined. Signed-off-by: BUDKE Gerson Fernando --- boards/arm/mps2/Kconfig.defconfig | 4 ++ boards/arm/mps2/mps2_an521_cpu0_ns.dts | 53 ++++++++++++++++++++------ 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/boards/arm/mps2/Kconfig.defconfig b/boards/arm/mps2/Kconfig.defconfig index 367e09c2a9a17..6d90cc522c454 100644 --- a/boards/arm/mps2/Kconfig.defconfig +++ b/boards/arm/mps2/Kconfig.defconfig @@ -46,6 +46,10 @@ choice NULL_POINTER_EXCEPTION_DETECTION endchoice +# Get flash configuration for NS image from dts flash partition +config USE_DT_CODE_PARTITION + default y if TRUSTED_EXECUTION_NONSECURE + # By default, if we build for a Non-Secure version of the board, # force building with TF-M as the Secure Execution Environment. config BUILD_WITH_TFM diff --git a/boards/arm/mps2/mps2_an521_cpu0_ns.dts b/boards/arm/mps2/mps2_an521_cpu0_ns.dts index a696d2aacd110..0315230f0d828 100644 --- a/boards/arm/mps2/mps2_an521_cpu0_ns.dts +++ b/boards/arm/mps2/mps2_an521_cpu0_ns.dts @@ -29,7 +29,8 @@ zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,sram = &ram; - zephyr,flash = &code; + zephyr,flash = &reserved_memory; + zephyr,code-partition = &slot0_ns_partition; }; leds { @@ -107,19 +108,49 @@ reg = <0x80000000 DT_SIZE_M(16)>; }; - reserved-memory { + reserved_memory: reserved-memory@0 { + compatible = "soc-nv-flash"; + reg = <0x0 DT_SIZE_M(4)>; + erase-block-size = <4096>; + write-block-size = <4>; #address-cells = <1>; #size-cells = <1>; - ranges; - /* This code memory region must match what the TF-M - * project has defined for that board - a single image boot is - * assumed. Please see the memory layout in: - * - * https://github.com/zephyrproject-rtos/trusted-firmware-m/blob/master/platform/ext/target/arm/mps2/an521/partition/flash_layout.h - */ - code: memory@100000 { - reg = <0x00100000 DT_SIZE_K(512)>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* This code memory region must match what the TF-M + * project has defined for that board - the milti-image + * boot is used in Zephyr. See memory layout details in: + * + * https://github.com/zephyrproject-rtos/trusted-firmware-m/blob/master/platform/ext/target/arm/mps2/an521/partition/flash_layout.h + */ + boot_partition: partition@0 { + reg = <0x00000000 DT_SIZE_K(512)>; + read-only; + }; + + slot0_partition: partition@80000 { + reg = <0x00080000 DT_SIZE_K(512)>; + }; + + slot0_ns_partition: partition@100000 { + reg = <0x00100000 DT_SIZE_K(512)>; + }; + + slot1_partition: partition@180000 { + reg = <0x00180000 DT_SIZE_K(512)>; + }; + + slot1_ns_partition: partition@200000 { + reg = <0x00200000 DT_SIZE_K(512)>; + }; + + scratch_partition: partition@280000 { + reg = <0x00280000 DT_SIZE_K(512)>; + }; }; /* This ram memory region's size is chosen to avoid conflict From a993e1e9c2ac0b807a55c2795ec0a487322f3da1 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Tue, 19 Aug 2025 07:44:21 +0200 Subject: [PATCH 03/18] boards: arm: mps3: Remove mps3/corstone300/an547/ns QEMU Exclude mps3/corstone300/an547/ns from PSA tests because QEMU does not model the QSPI flash in MPS3 boards as real QSPI flash, but only as simple ROM. Attempting to rewrite the flash from the guest will fail. https://github.com/zephyrproject-rtos/zephyr/pull/94470#issuecomment-3197729501 Signed-off-by: BUDKE Gerson Fernando --- boards/arm/mps3/Kconfig | 2 +- boards/arm/mps3/board.cmake | 4 ++-- boards/arm/mps3/mps3_corstone300_an547_ns.yaml | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/boards/arm/mps3/Kconfig b/boards/arm/mps3/Kconfig index 09a81d81b1b65..f6fcca22f8e68 100644 --- a/boards/arm/mps3/Kconfig +++ b/boards/arm/mps3/Kconfig @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_MPS3 - select QEMU_TARGET if BOARD_MPS3_CORSTONE300_AN547 || BOARD_MPS3_CORSTONE300_AN547_NS + select QEMU_TARGET if BOARD_MPS3_CORSTONE300_AN547 select TRUSTED_EXECUTION_NONSECURE if BOARD_MPS3_CORSTONE300_AN547_NS || \ BOARD_MPS3_CORSTONE300_AN552_NS || BOARD_MPS3_CORSTONE300_FVP_NS || \ BOARD_MPS3_CORSTONE310_AN555_NS || BOARD_MPS3_CORSTONE310_FVP_NS diff --git a/boards/arm/mps3/board.cmake b/boards/arm/mps3/board.cmake index 623074a308d14..e4899b1b3a6de 100644 --- a/boards/arm/mps3/board.cmake +++ b/boards/arm/mps3/board.cmake @@ -12,7 +12,7 @@ # -if(CONFIG_BOARD_MPS3_CORSTONE300_AN547 OR CONFIG_BOARD_MPS3_CORSTONE300_AN547_NS) +if(CONFIG_BOARD_MPS3_CORSTONE300_AN547) set(SUPPORTED_EMU_PLATFORMS qemu) # QEMU settings @@ -56,7 +56,7 @@ endif() board_set_debugger_ifnset(qemu) -if (CONFIG_BUILD_WITH_TFM) +if(CONFIG_BUILD_WITH_TFM) # Override the binary used by qemu, to use the combined # TF-M (Secure) & Zephyr (Non Secure) image (when running # in-tree tests). diff --git a/boards/arm/mps3/mps3_corstone300_an547_ns.yaml b/boards/arm/mps3/mps3_corstone300_an547_ns.yaml index 15e47f38110ab..1b94c22cee5d6 100644 --- a/boards/arm/mps3/mps3_corstone300_an547_ns.yaml +++ b/boards/arm/mps3/mps3_corstone300_an547_ns.yaml @@ -11,8 +11,6 @@ type: mcu arch: arm ram: 2048 flash: 512 -simulation: - - name: qemu toolchain: - gnuarmemb - zephyr From 34320df13b74f119d76d96a1c97e5d31d5fe5e19 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 1 Sep 2025 09:38:00 +0200 Subject: [PATCH 04/18] boards: arm: mps3: Fix NS flash layout and SRAM size The mps3/foo/ns configuration defines flash layouts in TF-M to support CONFIG_TFM_MCUBOOT_IMAGE_NUMBER values of 1 or 2. In the Zephyr project, when building samples, the selected value is 2. The layout changes are necessary to support the --max-sectors option when signing images, ensuring that the flash layout is respected. To enable this, the compatible "soc-nv-flash" was added to the reserved memory, and fixed-partitions were defined. Additionally, the ISRAM was redefined to expose the correct size and values for both S and NS firmware, clarifying memory selection for the user. For example, see general details in: https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/%2B/refs/heads/main/platform/ext/target/arm/mps3/corstone310/common/partition/region_defs.h#116 https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/%2B/refs/heads/main/platform/ext/target/arm/mps3/corstone310/common/config.cmake#13 Note: - Not all mps3 ISRAM have the same size and design should take that in consideration. Signed-off-by: BUDKE Gerson Fernando --- boards/arm/mps3/Kconfig.defconfig | 20 +++++++- boards/arm/mps3/mps3_common_ns.dtsi | 49 +++++++++++++++++++ boards/arm/mps3/mps3_corstone300_an547_ns.dts | 38 ++++++-------- .../arm/mps3/mps3_corstone300_an547_ns.yaml | 4 +- boards/arm/mps3/mps3_corstone300_an552_ns.dts | 38 ++++++-------- .../arm/mps3/mps3_corstone300_an552_ns.yaml | 4 +- boards/arm/mps3/mps3_corstone300_fvp_ns.dts | 38 ++++++-------- boards/arm/mps3/mps3_corstone300_fvp_ns.yaml | 4 +- boards/arm/mps3/mps3_corstone310_an555_ns.dts | 40 ++++++--------- .../arm/mps3/mps3_corstone310_an555_ns.yaml | 4 +- boards/arm/mps3/mps3_corstone310_fvp_ns.dts | 38 ++++++-------- boards/arm/mps3/mps3_corstone310_fvp_ns.yaml | 4 +- 12 files changed, 154 insertions(+), 127 deletions(-) create mode 100644 boards/arm/mps3/mps3_common_ns.dtsi diff --git a/boards/arm/mps3/Kconfig.defconfig b/boards/arm/mps3/Kconfig.defconfig index 014b80f307fb3..af3d5e9058457 100644 --- a/boards/arm/mps3/Kconfig.defconfig +++ b/boards/arm/mps3/Kconfig.defconfig @@ -2,7 +2,16 @@ # Copyright 2024-2025 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if BOARD_MPS3_CORSTONE300_AN547 || BOARD_MPS3_CORSTONE300_AN552 || BOARD_MPS3_CORSTONE300_FVP || BOARD_MPS3_CORSTONE310_AN555 || BOARD_MPS3_CORSTONE310_FVP +if BOARD_MPS3_CORSTONE300_AN547 || \ + BOARD_MPS3_CORSTONE300_AN547_NS || \ + BOARD_MPS3_CORSTONE300_AN552 || \ + BOARD_MPS3_CORSTONE300_AN552_NS || \ + BOARD_MPS3_CORSTONE300_FVP || \ + BOARD_MPS3_CORSTONE300_FVP_NS || \ + BOARD_MPS3_CORSTONE310_AN555 || \ + BOARD_MPS3_CORSTONE310_AN555_NS || \ + BOARD_MPS3_CORSTONE310_FVP || \ + BOARD_MPS3_CORSTONE310_FVP_NS # MPU-based null-pointer dereferencing detection cannot # be applied as the (0x0 - 0x400) is unmapped but QEMU @@ -12,6 +21,15 @@ choice NULL_POINTER_EXCEPTION_DETECTION default NULL_POINTER_EXCEPTION_DETECTION_NONE if QEMU_TARGET endchoice +# Get flash configuration for NS image from DT flash partition +config USE_DT_CODE_PARTITION + default y if TRUSTED_EXECUTION_NONSECURE + +# By default, if we build for a Non-Secure version of the board, +# force building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if TRUSTED_EXECUTION_NONSECURE + if SERIAL config UART_INTERRUPT_DRIVEN diff --git a/boards/arm/mps3/mps3_common_ns.dtsi b/boards/arm/mps3/mps3_common_ns.dtsi new file mode 100644 index 0000000000000..9fde22a3b9ef8 --- /dev/null +++ b/boards/arm/mps3/mps3_common_ns.dtsi @@ -0,0 +1,49 @@ +/* + * Copyright 2025 Leica Geosystem AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + reserved_memory: reserved-memory@28000000 { + compatible = "soc-nv-flash"; + reg = <0x28000000 DT_SIZE_M(8)>; + erase-block-size = <65536>; + write-block-size = <4>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* This code memory region must match what the TF-M + * project has defined for that board - the multi image + * boot is used in Zephyr. See memory layout details in: + * + * https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/+/refs/heads/main/platform/ext/target/arm/mps3/corstone300/common/partition/flash_layout.h + * https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/+/refs/heads/main/platform/ext/target/arm/mps3/corstone310/common/partition/flash_layout.h + */ + slot0_partition: partition@0 { + reg = <0x00000000 DT_SIZE_K(512)>; + }; + + slot0_ns_partition: partition@80000 { + reg = <0x00080000 DT_SIZE_M(3)>; + }; + + slot1_partition: partition@380000 { + reg = <0x00380000 DT_SIZE_K(512)>; + }; + + slot1_ns_partition: partition@400000 { + reg = <0x00400000 DT_SIZE_M(3)>; + }; + + scratch_partition: partition@700000 { + reg = <0x00700000 DT_SIZE_K(512)>; + }; + }; + }; +}; diff --git a/boards/arm/mps3/mps3_corstone300_an547_ns.dts b/boards/arm/mps3/mps3_corstone300_an547_ns.dts index 9540682e37b2b..1b2bec34e4cc8 100644 --- a/boards/arm/mps3/mps3_corstone300_an547_ns.dts +++ b/boards/arm/mps3/mps3_corstone300_an547_ns.dts @@ -12,6 +12,8 @@ #include #include +#include "mps3_common_ns.dtsi" + / { compatible = "arm,mps3-an547"; #address-cells = <1>; @@ -20,8 +22,9 @@ chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram = &ram; - zephyr,flash = &code; + zephyr,sram = &isram_ns; + zephyr,flash = &reserved_memory; + zephyr,code-partition = &slot0_ns_partition; }; cpus { @@ -63,30 +66,19 @@ zephyr,memory-region = "DTCM"; }; - isram: sram@21000000 { + /* The ISRAM blocks are used for both S and NS data. The S reserves 128k + * bytes and the remaining can be used by the NS firmware. + */ + isram_s: secure_data@21000000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x21000000 DT_SIZE_M(4)>; - zephyr,memory-region = "ISRAM"; + reg = <0x21000000 DT_SIZE_K(128)>; + zephyr,memory-region = "ISRAM-Secure"; }; - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - /* The memory regions defined below must match what the TF-M - * project has defined for that board - a single image boot is - * assumed. Please see the memory layout in: - * https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/platform/ext/target/mps3/corstone300/common/partition/flash_layout.h - */ - - code: memory@28080000 { - reg = <0x28080000 DT_SIZE_K(512)>; - }; - - ram: memory@21020000 { - reg = <0x21020000 DT_SIZE_M(2)>; - }; + isram_ns: non_secure_data@21020000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x21020000 (DT_SIZE_M(4) - DT_SIZE_K(128))>; + zephyr,memory-region = "ISRAM-Non-Secure"; }; soc { diff --git a/boards/arm/mps3/mps3_corstone300_an547_ns.yaml b/boards/arm/mps3/mps3_corstone300_an547_ns.yaml index 1b94c22cee5d6..11c508d4ec2e0 100644 --- a/boards/arm/mps3/mps3_corstone300_an547_ns.yaml +++ b/boards/arm/mps3/mps3_corstone300_an547_ns.yaml @@ -9,8 +9,8 @@ identifier: mps3/corstone300/an547/ns name: Arm MPS3-Corstone300-AN547_ns type: mcu arch: arm -ram: 2048 -flash: 512 +ram: 3968 +flash: 3072 toolchain: - gnuarmemb - zephyr diff --git a/boards/arm/mps3/mps3_corstone300_an552_ns.dts b/boards/arm/mps3/mps3_corstone300_an552_ns.dts index 7b8bab99ff6dc..e565c0798a66b 100644 --- a/boards/arm/mps3/mps3_corstone300_an552_ns.dts +++ b/boards/arm/mps3/mps3_corstone300_an552_ns.dts @@ -11,6 +11,8 @@ #include #include +#include "mps3_common_ns.dtsi" + / { compatible = "arm,mps3-an552"; #address-cells = <1>; @@ -19,8 +21,9 @@ chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram = &ram; - zephyr,flash = &code; + zephyr,sram = &isram_ns; + zephyr,flash = &reserved_memory; + zephyr,code-partition = &slot0_ns_partition; }; cpus { @@ -62,30 +65,19 @@ zephyr,memory-region = "DTCM"; }; - isram: sram@21000000 { + /* The ISRAM blocks are used for both S and NS data. The S reserves 128k + * bytes and the remaining can be used by the NS firmware. + */ + isram_s: secure_data@21000000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x21000000 DT_SIZE_M(2)>; - zephyr,memory-region = "ISRAM"; + reg = <0x21000000 DT_SIZE_K(128)>; + zephyr,memory-region = "ISRAM-Secure"; }; - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - /* The memory regions defined below must match what the TF-M - * project has defined for that board - a single image boot is - * assumed. Please see the memory layout in: - * https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/platform/ext/target/mps3/corstone300/common/partition/flash_layout.h - */ - - code: memory@28080000 { - reg = <0x28080000 DT_SIZE_K(512)>; - }; - - ram: memory@21020000 { - reg = <0x21020000 DT_SIZE_M(1)>; - }; + isram_ns: non_secure_data@21020000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x21020000 (DT_SIZE_M(2) - DT_SIZE_K(128))>; + zephyr,memory-region = "ISRAM-Non-Secure"; }; soc { diff --git a/boards/arm/mps3/mps3_corstone300_an552_ns.yaml b/boards/arm/mps3/mps3_corstone300_an552_ns.yaml index 229778378bd08..715b9a1119913 100644 --- a/boards/arm/mps3/mps3_corstone300_an552_ns.yaml +++ b/boards/arm/mps3/mps3_corstone300_an552_ns.yaml @@ -5,8 +5,8 @@ identifier: mps3/corstone300/an552/ns name: Arm MPS3-Corstone300-AN552_ns type: mcu arch: arm -ram: 2048 -flash: 512 +ram: 1920 +flash: 3072 toolchain: - gnuarmemb - zephyr diff --git a/boards/arm/mps3/mps3_corstone300_fvp_ns.dts b/boards/arm/mps3/mps3_corstone300_fvp_ns.dts index d2be764eb5020..705462b4b4135 100644 --- a/boards/arm/mps3/mps3_corstone300_fvp_ns.dts +++ b/boards/arm/mps3/mps3_corstone300_fvp_ns.dts @@ -11,6 +11,8 @@ #include #include +#include "mps3_common_ns.dtsi" + / { compatible = "arm,mps3-fvp"; #address-cells = <1>; @@ -19,8 +21,9 @@ chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram = &ram; - zephyr,flash = &code; + zephyr,sram = &isram_ns; + zephyr,flash = &reserved_memory; + zephyr,code-partition = &slot0_ns_partition; }; cpus { @@ -62,30 +65,19 @@ zephyr,memory-region = "DTCM"; }; - isram: sram@21000000 { + /* The ISRAM blocks are used for both S and NS data. The S reserves 128k + * bytes and the remaining can be used by the NS firmware. + */ + isram_s: secure_data@21000000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x21000000 DT_SIZE_M(2)>; - zephyr,memory-region = "ISRAM"; + reg = <0x21000000 DT_SIZE_K(128)>; + zephyr,memory-region = "ISRAM-Secure"; }; - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - /* The memory regions defined below must match what the TF-M - * project has defined for that board - a single image boot is - * assumed. Please see the memory layout in: - * https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/platform/ext/target/mps3/corstone300/common/partition/flash_layout.h - */ - - code: memory@28080000 { - reg = <0x28080000 DT_SIZE_K(512)>; - }; - - ram: memory@21020000 { - reg = <0x21020000 DT_SIZE_M(1)>; - }; + isram_ns: non_secure_data@21020000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x21020000 (DT_SIZE_M(2) - DT_SIZE_K(128))>; + zephyr,memory-region = "ISRAM-Non-Secure"; }; soc { diff --git a/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml b/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml index f0561b716c3fd..82b4a5e83da22 100644 --- a/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml +++ b/boards/arm/mps3/mps3_corstone300_fvp_ns.yaml @@ -5,8 +5,8 @@ identifier: mps3/corstone300/fvp/ns name: Arm MPS3-Corstone300-FVP_ns type: mcu arch: arm -ram: 2048 -flash: 512 +ram: 1920 +flash: 3072 toolchain: - gnuarmemb - zephyr diff --git a/boards/arm/mps3/mps3_corstone310_an555_ns.dts b/boards/arm/mps3/mps3_corstone310_an555_ns.dts index 4a910777e113b..b797d7143f4f3 100644 --- a/boards/arm/mps3/mps3_corstone310_an555_ns.dts +++ b/boards/arm/mps3/mps3_corstone310_an555_ns.dts @@ -11,6 +11,8 @@ #include #include +#include "mps3_common_ns.dtsi" + / { compatible = "arm,mps3-an555"; #address-cells = <1>; @@ -19,8 +21,9 @@ chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram = &ram; - zephyr,flash = &code; + zephyr,sram = &isram_ns; + zephyr,flash = &reserved_memory; + zephyr,code-partition = &slot0_ns_partition; }; cpus { @@ -58,34 +61,23 @@ dtcm: dtcm@20000000 { compatible = "zephyr,memory-region"; - reg = <0x20000000 DT_SIZE_K(512)>; + reg = <0x20000000 DT_SIZE_K(32)>; zephyr,memory-region = "DTCM"; }; - isram: sram@21000000 { + /* The ISRAM blocks are used for both S and NS data. The S reserves 128k + * bytes and the remaining can be used by the NS firmware. + */ + isram_s: secure_data@21000000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x21000000 DT_SIZE_M(4)>; - zephyr,memory-region = "ISRAM"; + reg = <0x21000000 DT_SIZE_K(128)>; + zephyr,memory-region = "ISRAM-Secure"; }; - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - /* The memory regions defined below must match what the TF-M - * project has defined for that board - a single image boot is - * assumed. Please see the memory layout in: - * https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/platform/ext/target/mps3/corstone310/common/partition/flash_layout.h - */ - - code: memory@1000000 { - reg = <0x01000000 DT_SIZE_M(2)>; - }; - - ram: memory@21000000 { - reg = <0x21000000 DT_SIZE_M(4)>; - }; + isram_ns: non_secure_data@21020000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x21020000 (DT_SIZE_M(4) - DT_SIZE_K(128))>; + zephyr,memory-region = "ISRAM-Non-Secure"; }; soc { diff --git a/boards/arm/mps3/mps3_corstone310_an555_ns.yaml b/boards/arm/mps3/mps3_corstone310_an555_ns.yaml index 80423596e316c..66eb44ea19350 100644 --- a/boards/arm/mps3/mps3_corstone310_an555_ns.yaml +++ b/boards/arm/mps3/mps3_corstone310_an555_ns.yaml @@ -5,8 +5,8 @@ identifier: mps3/corstone310/an555/ns name: Arm MPS3-Corstone310-AN555_ns type: mcu arch: arm -ram: 32 -flash: 32 +ram: 3968 +flash: 3072 toolchain: - gnuarmemb - zephyr diff --git a/boards/arm/mps3/mps3_corstone310_fvp_ns.dts b/boards/arm/mps3/mps3_corstone310_fvp_ns.dts index 9cd73ee3959fa..7a58b4dbf124a 100644 --- a/boards/arm/mps3/mps3_corstone310_fvp_ns.dts +++ b/boards/arm/mps3/mps3_corstone310_fvp_ns.dts @@ -11,6 +11,8 @@ #include #include +#include "mps3_common_ns.dtsi" + / { compatible = "arm,mps3-fvp"; #address-cells = <1>; @@ -19,8 +21,9 @@ chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; - zephyr,sram = &ram; - zephyr,flash = &code; + zephyr,sram = &isram_ns; + zephyr,flash = &reserved_memory; + zephyr,code-partition = &slot0_ns_partition; }; cpus { @@ -62,30 +65,19 @@ zephyr,memory-region = "DTCM"; }; - isram: sram@21000000 { + /* The ISRAM blocks are used for both S and NS data. The S reserves 128k + * bytes and the remaining can be used by the NS firmware. + */ + isram_s: secure_data@21000000 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x21000000 DT_SIZE_M(4)>; - zephyr,memory-region = "ISRAM"; + reg = <0x21000000 DT_SIZE_K(128)>; + zephyr,memory-region = "ISRAM-Secure"; }; - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - /* The memory regions defined below must match what the TF-M - * project has defined for that board - a single image boot is - * assumed. Please see the memory layout in: - * https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/tree/platform/ext/target/mps3/corstone310/common/partition/flash_layout.h - */ - - code: memory@28080000 { - reg = <0x28080000 DT_SIZE_K(512)>; - }; - - ram: memory@21020000 { - reg = <0x21020000 DT_SIZE_M(1)>; - }; + isram_ns: non_secure_data@21020000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x21020000 (DT_SIZE_M(4) - DT_SIZE_K(128))>; + zephyr,memory-region = "ISRAM-Non-Secure"; }; soc { diff --git a/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml b/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml index bfbc54dc16b8c..b8dc89a6fad83 100644 --- a/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml +++ b/boards/arm/mps3/mps3_corstone310_fvp_ns.yaml @@ -5,8 +5,8 @@ identifier: mps3/corstone310/fvp/ns name: Arm MPS3-Corstone310-FVP_ns type: mcu arch: arm -ram: 32 -flash: 32 +ram: 3968 +flash: 3072 toolchain: - gnuarmemb - zephyr From fd61f3d97e5abfc0addd3f625994bcebbbd82948 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Fri, 15 Aug 2025 09:42:54 +0200 Subject: [PATCH 05/18] boards: st: stm32l562e_dk: Move external partitions The external partitions are defined dependent from S and NS images. This move the external partitions from common to the S image. The NS image will be defined in future to allow correct usage of MCUboot. Signed-off-by: BUDKE Gerson Fernando --- boards/st/stm32l562e_dk/stm32l562e_dk.dts | 12 ++++++++++++ boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi | 10 ---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/boards/st/stm32l562e_dk/stm32l562e_dk.dts b/boards/st/stm32l562e_dk/stm32l562e_dk.dts index e64ef2cfd26bd..dfc57e76dc94c 100644 --- a/boards/st/stm32l562e_dk/stm32l562e_dk.dts +++ b/boards/st/stm32l562e_dk/stm32l562e_dk.dts @@ -55,3 +55,15 @@ }; }; }; + +&mx25lm51245 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x00000000 DT_SIZE_M(64)>; + }; + }; +}; diff --git a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi index fa2bc688ca160..4db30a905651c 100644 --- a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi +++ b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi @@ -261,16 +261,6 @@ stm32_lp_tick_source: &lptim1 { 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7f ef ff ff 21 5c dc ff]; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - reg = <0x00000000 DT_SIZE_M(64)>; - }; - }; }; }; From a27d5a0ccf3e1d11d2ad41a1f5f6c009de063d1d Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Fri, 15 Aug 2025 10:36:07 +0200 Subject: [PATCH 06/18] boards: st: stm32l562e_dk: ns: Align partitions The partitions for the stm32l562e_dk/stm32l562xx/ns board are not aligned with TF-M. This fixes the partition alignment. Signed-off-by: BUDKE Gerson Fernando --- .../stm32l562e_dk_stm32l562xx_ns.dts | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/boards/st/stm32l562e_dk/stm32l562e_dk_stm32l562xx_ns.dts b/boards/st/stm32l562e_dk/stm32l562e_dk_stm32l562xx_ns.dts index 2203d247ed98b..11a050f1b92ce 100644 --- a/boards/st/stm32l562e_dk/stm32l562e_dk_stm32l562xx_ns.dts +++ b/boards/st/stm32l562e_dk/stm32l562e_dk_stm32l562xx_ns.dts @@ -19,7 +19,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,code-partition = &slot1_ns_partition; + zephyr,code-partition = &slot0_ns_partition; }; aliases { @@ -46,24 +46,64 @@ #address-cells = <1>; #size-cells = <1>; + /* + * Flash layout: + * - BL2 - Multi image boot + * - internal + * - external + * - Scratch + */ boot_partition: partition@0 { - reg = <0x00000000 DT_SIZE_K(100)>; + reg = <0x00000000 DT_SIZE_K(68)>; read-only; }; - /* Secure image primary slot */ + scratch_partition: partition@11000 { + reg = <0x00011000 DT_SIZE_K(8)>; + }; + + otp_partition: partition@13000 { + reg = <0x00013000 DT_SIZE_K(8)>; + }; + + general_secure_storage_partition: partition@15000 { + reg = <0x00015000 DT_SIZE_K(8)>; + }; + + internal_secure_storage_partition: partition@17000 { + reg = <0x00017000 DT_SIZE_K(8)>; + }; + slot0_partition: partition@19000 { reg = <0x00019000 DT_SIZE_K(240)>; }; - /* Non-secure image primary slot */ - slot1_ns_partition: partition@55000 { - reg = <0x00055000 DT_SIZE_K(168)>; + slot0_ns_partition: partition@55000 { + reg = <0x00055000 DT_SIZE_K(172)>; + }; + }; +}; + +&mx25lm51245 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot1_partition: partition@0 { + reg = <0x00000000 DT_SIZE_K(240)>; + }; + + unused: partition@3c000 { + reg = <0x0003c000 DT_SIZE_K(32)>; + }; + + slot1_ns_partition: partition@44000 { + reg = <0x00044000 DT_SIZE_K(172)>; }; - /* 4KB at the end of 512KB flash is set for storage */ - storage_partition: partition@7f000 { - reg = <0x0007f000 DT_SIZE_K(4)>; + storage_partition: partition@6f000 { + reg = <0x0006f000 (DT_SIZE_M(64) - DT_SIZE_K(444))>; }; }; }; From 5dd597413f4dd1a3cd308672888602466960d092 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 21 Jul 2025 13:36:48 +0200 Subject: [PATCH 07/18] trusted-firmware-m: Set --align when signing The current version of TF-M script that sign MCUboot image uses a default alignment of 1. This value varies between flash devices and not all accept the default 1. This improve the script picking the write-block-size property from the current flash controller and pass as the --align parameter when signing an image. Note: This solution works out-of-box for the vast majority of devices in the Zephyr tree and an exception will throw when a device is not supported. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 35 ++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index a366fbb50bdab..70481a4df75e5 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -450,6 +450,39 @@ if (CONFIG_BUILD_WITH_TFM) set(HEX_ADDR_ARGS_NS "--hex-addr=${TFM_HEX_BASE_ADDRESS_NS}") endif() + if(CONFIG_TFM_BL2) + set(image_alignment 1) + set(flash_write_block_size 1) + + dt_chosen(chosen_flash PROPERTY "zephyr,flash") + if(DEFINED chosen_flash AND chosen_flash) + dt_prop(flash_write_block_size PATH ${chosen_flash} PROPERTY write-block-size) + else() + message(WARNING + "The 'zephyr,flash' chosen property is not defined! + Using flash_write_block_size default value possible differs from + TF-M board definitions resulting in improver sign." + ) + endif() + + # The alignment is determined by the minimal amount of bytes necessary to + # be written in the flash sector. Ex., assuming that the sector erase + # operation is 1KiB and, on that sector, the minimum amount of bytes that + # must be written is 8 bytes then the alignment is 8. + # + # Current MCUboot maximum alignment is 32 bytes. + if(flash_write_block_size GREATER 0) + if(flash_write_block_size GREATER 32) + message(WARNING + "imgtool max alignment is 32 and current value is ${flash_write_block_size}. + Keep default image alignment of 1." + ) + else() + set(image_alignment ${flash_write_block_size}) + endif() + endif() + endif() + function(tfm_sign OUT_ARG SUFFIX PAD INPUT_FILE OUTPUT_FILE) if(PAD) set(pad_args --pad --pad-header) @@ -469,7 +502,7 @@ if (CONFIG_BUILD_WITH_TFM) --layout ${layout_file} -k ${CONFIG_TFM_KEY_FILE_${SUFFIX}} --public-key-format ${TFM_PUBLIC_KEY_FORMAT} - --align 1 + --align ${image_alignment} -v ${CONFIG_TFM_IMAGE_VERSION_${SUFFIX}} ${pad_args} ${HEX_ADDR_ARGS_${SUFFIX}} From 6bb538f43bacf7955da2c6ec981186f67ef57b2e Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 21 Jul 2025 15:58:47 +0200 Subject: [PATCH 08/18] trusted-firmware-m: Set --max-sectors when signing The --max-sectors option helps catch problems with flash overlap when merging images. If there is a misalignment in flash partitions, the merge process usually fails. This uses information from Zephyr flash partitions and the flash controller to automatically determine the max sectors value and apply it when signing an image. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 35 ++++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 70481a4df75e5..fff9ac0610040 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -453,15 +453,17 @@ if (CONFIG_BUILD_WITH_TFM) if(CONFIG_TFM_BL2) set(image_alignment 1) set(flash_write_block_size 1) + set(flash_erase_block_size 1) dt_chosen(chosen_flash PROPERTY "zephyr,flash") if(DEFINED chosen_flash AND chosen_flash) dt_prop(flash_write_block_size PATH ${chosen_flash} PROPERTY write-block-size) + dt_prop(flash_erase_block_size PATH ${chosen_flash} PROPERTY erase-block-size) else() message(WARNING "The 'zephyr,flash' chosen property is not defined! - Using flash_write_block_size default value possible differs from - TF-M board definitions resulting in improver sign." + Using flash_write_block_size and flash_erase_block_size default values + that may differ from TF-M board definitions resulting in invalid signatures." ) endif() @@ -481,9 +483,26 @@ if (CONFIG_BUILD_WITH_TFM) set(image_alignment ${flash_write_block_size}) endif() endif() + + # Calculate the maximum number of sectors necessary to store the image. + dt_nodelabel(s_partition_node NODELABEL "slot0_partition" REQUIRED) + dt_nodelabel(ns_partition_node NODELABEL "slot0_ns_partition" REQUIRED) + dt_reg_size(s_partition_size PATH ${s_partition_node}) + dt_reg_size(ns_partition_size PATH ${ns_partition_node}) + math(EXPR S_MAX_SECTORS "${s_partition_size} / ${flash_erase_block_size}") + math(EXPR NS_MAX_SECTORS "${ns_partition_size} / ${flash_erase_block_size}") + if(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1") + math(EXPR S_NS_MAX_SECTORS "${S_MAX_SECTORS} + ${NS_MAX_SECTORS}") + else() + if(${S_MAX_SECTORS} GREATER ${NS_MAX_SECTORS}) + set(S_NS_MAX_SECTORS ${S_MAX_SECTORS}) + else() + set(S_NS_MAX_SECTORS ${NS_MAX_SECTORS}) + endif() + endif() endif() - function(tfm_sign OUT_ARG SUFFIX PAD INPUT_FILE OUTPUT_FILE) + function(tfm_sign OUT_ARG SUFFIX PAD MAX_SECTORS INPUT_FILE OUTPUT_FILE) if(PAD) set(pad_args --pad --pad-header) endif() @@ -503,6 +522,7 @@ if (CONFIG_BUILD_WITH_TFM) -k ${CONFIG_TFM_KEY_FILE_${SUFFIX}} --public-key-format ${TFM_PUBLIC_KEY_FORMAT} --align ${image_alignment} + --max-sectors ${MAX_SECTORS} -v ${CONFIG_TFM_IMAGE_VERSION_${SUFFIX}} ${pad_args} ${HEX_ADDR_ARGS_${SUFFIX}} @@ -543,7 +563,7 @@ if (CONFIG_BUILD_WITH_TFM) ) elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1") - tfm_sign(sign_cmd S_NS TRUE ${S_NS_FILE} ${S_NS_SIGNED_FILE}) + tfm_sign(sign_cmd S_NS TRUE ${S_NS_MAX_SECTORS} ${S_NS_FILE} ${S_NS_SIGNED_FILE}) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py @@ -568,12 +588,13 @@ if (CONFIG_BUILD_WITH_TFM) else() if (CONFIG_TFM_USE_NS_APP) - tfm_sign(sign_cmd_ns NS TRUE ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns NS TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) else() - tfm_sign(sign_cmd_ns NS FALSE ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns NS FALSE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) endif() - tfm_sign(sign_cmd_s S TRUE $ ${S_SIGNED_FILE}) + tfm_sign(sign_cmd_s S TRUE ${S_NS_MAX_SECTORS} $ + ${S_SIGNED_FILE}) #Create and sign for concatenated binary image, should align with the TF-M BL2 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands From e402ea2073abc12cfa9db8ad5c39a988164ebd3a Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 21 Jul 2025 16:18:31 +0200 Subject: [PATCH 09/18] trusted-firmware-m: Define header and trailer options The current behavior when signing an image is to always set --pad and --pad-header for all images unless TFM_USE_NS_APP is set. This does not allow for easy creation of signed images for FOTA applications. Rewrite the PAD parameter as HEADER and TRAILER to simplify the setup of more signing options. Another important reason for this change is that the NS image, when signed without --pad, runs on the hardware but does not perform the MCUboot test, and the FWU never upgrades the image. This fixes the NS image signing process to correctly support TF-M FWU using the PSA API functions. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index fff9ac0610040..f34a418269f39 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -502,9 +502,13 @@ if (CONFIG_BUILD_WITH_TFM) endif() endif() - function(tfm_sign OUT_ARG SUFFIX PAD MAX_SECTORS INPUT_FILE OUTPUT_FILE) - if(PAD) + function(tfm_sign OUT_ARG SUFFIX HEADER TRAILER MAX_SECTORS INPUT_FILE OUTPUT_FILE) + if(HEADER AND TRAILER) set(pad_args --pad --pad-header) + elseif(HEADER) + set(pad_args --pad-header) + elseif(TRAILER) + set(pad_args --pad) endif() # Secure + Non-secure images are signed the same way as a secure only # build, but with a different layout file. @@ -563,7 +567,7 @@ if (CONFIG_BUILD_WITH_TFM) ) elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1") - tfm_sign(sign_cmd S_NS TRUE ${S_NS_MAX_SECTORS} ${S_NS_FILE} ${S_NS_SIGNED_FILE}) + tfm_sign(sign_cmd S_NS TRUE TRUE ${S_NS_MAX_SECTORS} ${S_NS_FILE} ${S_NS_SIGNED_FILE}) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py @@ -588,12 +592,12 @@ if (CONFIG_BUILD_WITH_TFM) else() if (CONFIG_TFM_USE_NS_APP) - tfm_sign(sign_cmd_ns NS TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns NS TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) else() - tfm_sign(sign_cmd_ns NS FALSE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns NS FALSE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) endif() - tfm_sign(sign_cmd_s S TRUE ${S_NS_MAX_SECTORS} $ + tfm_sign(sign_cmd_s S TRUE TRUE ${S_NS_MAX_SECTORS} $ ${S_SIGNED_FILE}) #Create and sign for concatenated binary image, should align with the TF-M BL2 From 376b0060f94b53b1813669746a287726c3f194f8 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 21 Jul 2025 16:25:23 +0200 Subject: [PATCH 10/18] trusted-firmware-m: Set --confirm when signing The current behavior when signing an image adds --pad but does not confirm the image. This appears to be a mistake, as the user should inspect the image status in the Firmware Upgrade software. If an image is not --confirmed, the FSM cannot infer the correct states. This sets the image as confirmed to resolve the issue. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index f34a418269f39..86ae986e20a91 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -502,7 +502,7 @@ if (CONFIG_BUILD_WITH_TFM) endif() endif() - function(tfm_sign OUT_ARG SUFFIX HEADER TRAILER MAX_SECTORS INPUT_FILE OUTPUT_FILE) + function(tfm_sign OUT_ARG SUFFIX HEADER TRAILER CONFIRM MAX_SECTORS INPUT_FILE OUTPUT_FILE) if(HEADER AND TRAILER) set(pad_args --pad --pad-header) elseif(HEADER) @@ -510,6 +510,10 @@ if (CONFIG_BUILD_WITH_TFM) elseif(TRAILER) set(pad_args --pad) endif() + if(CONFIRM) + # --confirm imply PAD + set(confirm --confirm) + endif() # Secure + Non-secure images are signed the same way as a secure only # build, but with a different layout file. set(layout_file ${PREPROCESSED_FILE_${SUFFIX}}) @@ -529,6 +533,7 @@ if (CONFIG_BUILD_WITH_TFM) --max-sectors ${MAX_SECTORS} -v ${CONFIG_TFM_IMAGE_VERSION_${SUFFIX}} ${pad_args} + ${confirm} ${HEX_ADDR_ARGS_${SUFFIX}} ${ADD_${SUFFIX}_IMAGE_MIN_VER} -s ${CONFIG_TFM_IMAGE_SECURITY_COUNTER} @@ -567,7 +572,7 @@ if (CONFIG_BUILD_WITH_TFM) ) elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1") - tfm_sign(sign_cmd S_NS TRUE TRUE ${S_NS_MAX_SECTORS} ${S_NS_FILE} ${S_NS_SIGNED_FILE}) + tfm_sign(sign_cmd S_NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${S_NS_FILE} ${S_NS_SIGNED_FILE}) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py @@ -592,12 +597,12 @@ if (CONFIG_BUILD_WITH_TFM) else() if (CONFIG_TFM_USE_NS_APP) - tfm_sign(sign_cmd_ns NS TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) else() - tfm_sign(sign_cmd_ns NS FALSE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns NS FALSE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) endif() - tfm_sign(sign_cmd_s S TRUE TRUE ${S_NS_MAX_SECTORS} $ + tfm_sign(sign_cmd_s S TRUE TRUE TRUE ${S_NS_MAX_SECTORS} $ ${S_SIGNED_FILE}) #Create and sign for concatenated binary image, should align with the TF-M BL2 From ab04b7f81c76e24298f24a102bf5877a4f0213b9 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 21 Jul 2025 16:31:53 +0200 Subject: [PATCH 11/18] trusted-firmware-m: Make hex files variables explicit Make variables that define output files explicitly include 'HEX' in the name. This refactoring step allows for the introduction of BIN file generation. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 65 ++++++++++++----------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 86ae986e20a91..a4cbfa030f752 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -544,84 +544,87 @@ if (CONFIG_BUILD_WITH_TFM) PARENT_SCOPE) endfunction() - set(MERGED_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_merged.hex) - set(S_NS_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns.hex) - set(S_NS_SIGNED_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_signed.hex) - set(NS_SIGNED_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.hex) - set(S_SIGNED_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_signed.hex) + set(MERGED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_merged.hex) + set(S_NS_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns.hex) + set(S_NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_signed.hex) + set(NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.hex) + set(S_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_signed.hex) if (CONFIG_TFM_USE_NS_APP) # Use the TF-M NS binary as the Non-Secure application firmware image - set(NS_APP_FILE $) + set(NS_HEX_APP_FILE $) else() # Use the Zephyr binary as the Non-Secure application firmware image - set(NS_APP_FILE ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME}) + set(NS_HEX_APP_FILE ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME}) endif() if (NOT CONFIG_TFM_BL2) # Merge tfm_s and zephyr (NS) image to a single binary. set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py - -o ${MERGED_FILE} + -o ${MERGED_HEX_FILE} $ - ${NS_APP_FILE} + ${NS_HEX_APP_FILE} ) set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts - ${MERGED_FILE} + ${MERGED_HEX_FILE} ) elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1") - tfm_sign(sign_cmd S_NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${S_NS_FILE} ${S_NS_SIGNED_FILE}) + tfm_sign(sign_cmd_s_ns_hex S_NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${S_NS_HEX_FILE} + ${S_NS_SIGNED_HEX_FILE}) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py - -o ${S_NS_FILE} + -o ${S_NS_HEX_FILE} $ - ${NS_APP_FILE} + ${NS_HEX_APP_FILE} - COMMAND ${sign_cmd} + COMMAND ${sign_cmd_s_ns_hex} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py - -o ${MERGED_FILE} + -o ${MERGED_HEX_FILE} $<$:$> $<$>:$> - ${S_NS_SIGNED_FILE} + ${S_NS_SIGNED_HEX_FILE} ) set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts - ${S_NS_FILE} - ${S_NS_SIGNED_FILE} - ${MERGED_FILE} + ${S_NS_HEX_FILE} + ${S_NS_SIGNED_HEX_FILE} + ${MERGED_HEX_FILE} ) else() if (CONFIG_TFM_USE_NS_APP) - tfm_sign(sign_cmd_ns NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns_hex NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_HEX_APP_FILE} + ${NS_SIGNED_HEX_FILE}) else() - tfm_sign(sign_cmd_ns NS FALSE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_APP_FILE} ${NS_SIGNED_FILE}) + tfm_sign(sign_cmd_ns NS FALSE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_HEX_APP_FILE} + ${NS_SIGNED_HEX_FILE}) endif() - tfm_sign(sign_cmd_s S TRUE TRUE TRUE ${S_NS_MAX_SECTORS} $ - ${S_SIGNED_FILE}) + tfm_sign(sign_cmd_s_hex S TRUE TRUE TRUE ${S_NS_MAX_SECTORS} + $ ${S_SIGNED_HEX_FILE}) #Create and sign for concatenated binary image, should align with the TF-M BL2 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${sign_cmd_ns} - COMMAND ${sign_cmd_s} + COMMAND ${sign_cmd_ns_hex} + COMMAND ${sign_cmd_s_hex} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py - -o ${MERGED_FILE} + -o ${MERGED_HEX_FILE} $<$:$> $<$>:$> - ${S_SIGNED_FILE} - ${NS_SIGNED_FILE} + ${S_SIGNED_HEX_FILE} + ${NS_SIGNED_HEX_FILE} ) set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts - ${S_SIGNED_FILE} - ${NS_SIGNED_FILE} - ${MERGED_FILE} + ${S_SIGNED_HEX_FILE} + ${NS_SIGNED_HEX_FILE} + ${MERGED_HEX_FILE} ) endif() From 46256737b5521e693702386335d5160dd00d597f Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 21 Jul 2025 18:02:25 +0200 Subject: [PATCH 12/18] trusted-firmware-m: Create multi image bin files A fundamental use of Trusted Firmware-M is to provide security for IoT applications, where firmware upgrades (FOTA) are almost always mandatory. The current file signing process does not produce the necessary binaries for multi-image S/NS FWU, since hex images are not suitable for this use case. This introduces the missing signed binary files for use by the FWU partition. The changes were tested in multi-image FWU scenarios, and support for single-image scenarios can be easily added in the future. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index a4cbfa030f752..fe7b7fb929f6d 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -183,7 +183,7 @@ if (CONFIG_BUILD_WITH_TFM) set(TFM_S_ELF_FILE ${TFM_BINARY_DIR}/bin/tfm_s.elf) set(TFM_S_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s.bin) set(TFM_S_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_s.hex) - set(TFM_NS_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.bin) + set(TFM_NS_BIN_FILE ${CMAKE_BINARY_DIR}/tfm_ns/bin/tfm_ns.bin) set(TFM_NS_HEX_FILE ${CMAKE_BINARY_DIR}/tfm_ns/bin/tfm_ns.hex) set(TFM_S_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_signed.bin) set(TFM_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns_signed.bin) @@ -549,13 +549,17 @@ if (CONFIG_BUILD_WITH_TFM) set(S_NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_signed.hex) set(NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.hex) set(S_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_signed.hex) + set(NS_SIGNED_BIN_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.bin) + set(S_SIGNED_BIN_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_signed.bin) if (CONFIG_TFM_USE_NS_APP) # Use the TF-M NS binary as the Non-Secure application firmware image set(NS_HEX_APP_FILE $) + set(NS_BIN_APP_FILE $) else() # Use the Zephyr binary as the Non-Secure application firmware image set(NS_HEX_APP_FILE ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME}) + set(NS_BIN_APP_FILE ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_BIN_NAME}) endif() if (NOT CONFIG_TFM_BL2) @@ -600,18 +604,26 @@ if (CONFIG_BUILD_WITH_TFM) if (CONFIG_TFM_USE_NS_APP) tfm_sign(sign_cmd_ns_hex NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_HEX_APP_FILE} ${NS_SIGNED_HEX_FILE}) + tfm_sign(sign_cmd_ns_bin NS TRUE TRUE FALSE ${S_NS_MAX_SECTORS} ${NS_BIN_APP_FILE} + ${NS_SIGNED_BIN_FILE}) else() tfm_sign(sign_cmd_ns NS FALSE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_HEX_APP_FILE} ${NS_SIGNED_HEX_FILE}) + tfm_sign(sign_cmd_ns_bin NS FALSE FALSE FALSE ${S_NS_MAX_SECTORS} ${NS_BIN_APP_FILE} + ${NS_SIGNED_BIN_FILE}) endif() tfm_sign(sign_cmd_s_hex S TRUE TRUE TRUE ${S_NS_MAX_SECTORS} $ ${S_SIGNED_HEX_FILE}) + tfm_sign(sign_cmd_s_bin S TRUE TRUE FALSE ${S_NS_MAX_SECTORS} + $ ${S_SIGNED_BIN_FILE}) #Create and sign for concatenated binary image, should align with the TF-M BL2 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${sign_cmd_ns_hex} + COMMAND ${sign_cmd_ns_bin} COMMAND ${sign_cmd_s_hex} + COMMAND ${sign_cmd_s_bin} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py -o ${MERGED_HEX_FILE} @@ -623,7 +635,9 @@ if (CONFIG_BUILD_WITH_TFM) set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts ${S_SIGNED_HEX_FILE} + ${S_SIGNED_BIN_FILE} ${NS_SIGNED_HEX_FILE} + ${NS_SIGNED_BIN_FILE} ${MERGED_HEX_FILE} ) endif() From 0e380ecc5868db7a4d741163184b706adf0a8973 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Tue, 19 Aug 2025 11:42:16 +0200 Subject: [PATCH 13/18] trusted-firmware-m: Use cmake_parse_arguments in tfm_sign Use cmake_parse_arguments() for more idiomatic code. This makes the code more readable and easier to extend with new options. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 97 +++++++++++++++-------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index fe7b7fb929f6d..6350b8bfe9d55 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -502,45 +502,67 @@ if (CONFIG_BUILD_WITH_TFM) endif() endif() - function(tfm_sign OUT_ARG SUFFIX HEADER TRAILER CONFIRM MAX_SECTORS INPUT_FILE OUTPUT_FILE) - if(HEADER AND TRAILER) + function(tfm_sign OUT_ARG) + set(options HEADER TRAILER CONFIRM) + set(oneValueArgs SUFFIX MAX_SECTORS INPUT_FILE OUTPUT_FILE) + set(multiValueArgs "") + + cmake_parse_arguments( + TFM_SIGN_ARG + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + if(NOT DEFINED TFM_SIGN_ARG_SUFFIX OR + NOT DEFINED TFM_SIGN_ARG_INPUT_FILE OR + NOT DEFINED TFM_SIGN_ARG_OUTPUT_FILE) + message(FATAL_ERROR "SUFFIX, INPUT_FILE and OUTPUT_FILE are required arguments") + endif() + + set(pad_args "") + if(TFM_SIGN_ARG_HEADER AND TFM_SIGN_ARG_TRAILER) set(pad_args --pad --pad-header) - elseif(HEADER) + elseif(TFM_SIGN_ARG_HEADER) set(pad_args --pad-header) - elseif(TRAILER) + elseif(TFM_SIGN_ARG_TRAILER) set(pad_args --pad) endif() - if(CONFIRM) - # --confirm imply PAD + + set(confirm "") + if(TFM_SIGN_ARG_CONFIRM) set(confirm --confirm) endif() + # Secure + Non-secure images are signed the same way as a secure only # build, but with a different layout file. - set(layout_file ${PREPROCESSED_FILE_${SUFFIX}}) - if(SUFFIX STREQUAL "S_NS") - set(SUFFIX "S") + set(layout_file ${PREPROCESSED_FILE_${TFM_SIGN_ARG_SUFFIX}}) + if(TFM_SIGN_ARG_SUFFIX STREQUAL "S_NS") + set(TFM_SIGN_ARG_SUFFIX "S") endif() - set (${OUT_ARG} + + set(${OUT_ARG} # Add the MCUBoot script to the path so that if there is a version of imgtool in there then # it gets used over the system imgtool. Used so that imgtool from upstream # mcuboot is preferred over system imgtool ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py --layout ${layout_file} - -k ${CONFIG_TFM_KEY_FILE_${SUFFIX}} + -k ${CONFIG_TFM_KEY_FILE_${TFM_SIGN_ARG_SUFFIX}} --public-key-format ${TFM_PUBLIC_KEY_FORMAT} --align ${image_alignment} - --max-sectors ${MAX_SECTORS} - -v ${CONFIG_TFM_IMAGE_VERSION_${SUFFIX}} + --max-sectors ${TFM_SIGN_ARG_MAX_SECTORS} + -v ${CONFIG_TFM_IMAGE_VERSION_${TFM_SIGN_ARG_SUFFIX}} ${pad_args} ${confirm} - ${HEX_ADDR_ARGS_${SUFFIX}} - ${ADD_${SUFFIX}_IMAGE_MIN_VER} + ${HEX_ADDR_ARGS_${TFM_SIGN_ARG_SUFFIX}} + ${ADD_${TFM_SIGN_ARG_SUFFIX}_IMAGE_MIN_VER} -s ${CONFIG_TFM_IMAGE_SECURITY_COUNTER} --measured-boot-record -H ${CONFIG_ROM_START_OFFSET} - ${INPUT_FILE} - ${OUTPUT_FILE} + ${TFM_SIGN_ARG_INPUT_FILE} + ${TFM_SIGN_ARG_OUTPUT_FILE} PARENT_SCOPE) endfunction() @@ -576,8 +598,9 @@ if (CONFIG_BUILD_WITH_TFM) ) elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1") - tfm_sign(sign_cmd_s_ns_hex S_NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${S_NS_HEX_FILE} - ${S_NS_SIGNED_HEX_FILE}) + tfm_sign(sign_cmd_s_ns_hex SUFFIX "S_NS" + HEADER TRAILER CONFIRM MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE ${S_NS_HEX_FILE} OUTPUT_FILE ${S_NS_SIGNED_HEX_FILE}) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py @@ -602,21 +625,33 @@ if (CONFIG_BUILD_WITH_TFM) else() if (CONFIG_TFM_USE_NS_APP) - tfm_sign(sign_cmd_ns_hex NS TRUE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_HEX_APP_FILE} - ${NS_SIGNED_HEX_FILE}) - tfm_sign(sign_cmd_ns_bin NS TRUE TRUE FALSE ${S_NS_MAX_SECTORS} ${NS_BIN_APP_FILE} - ${NS_SIGNED_BIN_FILE}) + tfm_sign(sign_cmd_ns_hex SUFFIX "NS" + HEADER TRAILER CONFIRM MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE ${NS_HEX_APP_FILE} + OUTPUT_FILE ${NS_SIGNED_HEX_FILE}) + tfm_sign(sign_cmd_ns_bin SUFFIX "NS" + HEADER TRAILER MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE ${NS_BIN_APP_FILE} + OUTPUT_FILE ${NS_SIGNED_BIN_FILE}) else() - tfm_sign(sign_cmd_ns NS FALSE TRUE TRUE ${S_NS_MAX_SECTORS} ${NS_HEX_APP_FILE} - ${NS_SIGNED_HEX_FILE}) - tfm_sign(sign_cmd_ns_bin NS FALSE FALSE FALSE ${S_NS_MAX_SECTORS} ${NS_BIN_APP_FILE} - ${NS_SIGNED_BIN_FILE}) + tfm_sign(sign_cmd_ns_hex SUFFIX "NS" + TRAILER CONFIRM MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE ${NS_HEX_APP_FILE} + OUTPUT_FILE ${NS_SIGNED_HEX_FILE}) + tfm_sign(sign_cmd_ns_bin SUFFIX "NS" + MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE ${NS_BIN_APP_FILE} + OUTPUT_FILE ${NS_SIGNED_BIN_FILE}) endif() - tfm_sign(sign_cmd_s_hex S TRUE TRUE TRUE ${S_NS_MAX_SECTORS} - $ ${S_SIGNED_HEX_FILE}) - tfm_sign(sign_cmd_s_bin S TRUE TRUE FALSE ${S_NS_MAX_SECTORS} - $ ${S_SIGNED_BIN_FILE}) + tfm_sign(sign_cmd_s_hex SUFFIX "S" + HEADER TRAILER CONFIRM MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE $ + OUTPUT_FILE ${S_SIGNED_HEX_FILE}) + tfm_sign(sign_cmd_s_bin SUFFIX "S" + HEADER TRAILER MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE $ + OUTPUT_FILE ${S_SIGNED_BIN_FILE}) #Create and sign for concatenated binary image, should align with the TF-M BL2 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands From 7f97575d7a6a13643bbd151c0960d0d60f03270a Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Tue, 23 Sep 2025 08:54:35 +0200 Subject: [PATCH 14/18] scripts: build: mergehex: Add --output-bin parameter The optional --output-bin parameter instructs the IntelHex class to save the content as a binary file instead of the Intel Hex format. Signed-off-by: BUDKE Gerson Fernando --- scripts/build/mergehex.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/build/mergehex.py b/scripts/build/mergehex.py index 6d81dbe1833d6..48cb7911c3757 100755 --- a/scripts/build/mergehex.py +++ b/scripts/build/mergehex.py @@ -13,7 +13,7 @@ import argparse -def merge_hex_files(output, input_hex_files, overlap): +def merge_hex_files(output, input_hex_files, overlap, output_bin): ih = IntelHex() for hex_file_path in input_hex_files: @@ -29,7 +29,8 @@ def merge_hex_files(output, input_hex_files, overlap): except AddressOverlapError: raise AddressOverlapError("{} has merge issues".format(hex_file_path)) - ih.write_hex_file(output) + output_format = "bin" if output_bin else "hex" + ih.tofile(output, format=output_format) def parse_args(): @@ -37,11 +38,12 @@ def parse_args(): description="Merge hex files.", formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) parser.add_argument("-o", "--output", required=False, default="merged.hex", - type=argparse.FileType('w', encoding='UTF-8'), help="Output file name.") parser.add_argument("--overlap", default="error", help="What to do when files overlap (error, ignore, replace). " "See IntelHex.merge() for more info.") + parser.add_argument("--output-bin", default=False, + help="Save the merged content as binary file.") parser.add_argument("input_files", nargs='*') return parser.parse_args() @@ -49,7 +51,7 @@ def parse_args(): def main(): args = parse_args() - merge_hex_files(args.output, args.input_files, args.overlap) + merge_hex_files(args.output, args.input_files, args.overlap, args.output_bin) if __name__ == "__main__": From bfecfb9a796cae60bdae4de2634dc11cc7ee4870 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Tue, 23 Sep 2025 09:00:16 +0200 Subject: [PATCH 15/18] trusted-firmware-m: Prepare to generate tfm_merged.bin When CONFIG_TFM_MCUBOOT_IMAGE_NUMBER is 1, the process to create the final tfm_merged.bin file is more complex. This prepares the content to introduce the generation of tfm_merged.bin for use in FOTA applications. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 6350b8bfe9d55..18eb92e3c45b6 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -567,8 +567,8 @@ if (CONFIG_BUILD_WITH_TFM) endfunction() set(MERGED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_merged.hex) - set(S_NS_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns.hex) - set(S_NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_signed.hex) + set(S_NS_CONFIRMED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_confirmed.hex) + set(S_NS_SIGNED_CONFIRMED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_confirmed_signed.hex) set(NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.hex) set(S_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_signed.hex) set(NS_SIGNED_BIN_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.bin) @@ -598,28 +598,28 @@ if (CONFIG_BUILD_WITH_TFM) ) elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1") - tfm_sign(sign_cmd_s_ns_hex SUFFIX "S_NS" + tfm_sign(sign_cmd_s_ns_confirm_hex SUFFIX "S_NS" HEADER TRAILER CONFIRM MAX_SECTORS ${S_NS_MAX_SECTORS} - INPUT_FILE ${S_NS_HEX_FILE} OUTPUT_FILE ${S_NS_SIGNED_HEX_FILE}) + INPUT_FILE ${S_NS_CONFIRMED_HEX_FILE} OUTPUT_FILE ${S_NS_SIGNED_CONFIRMED_HEX_FILE}) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py - -o ${S_NS_HEX_FILE} + -o ${S_NS_CONFIRMED_HEX_FILE} $ ${NS_HEX_APP_FILE} - COMMAND ${sign_cmd_s_ns_hex} + COMMAND ${sign_cmd_s_ns_confirm_hex} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py -o ${MERGED_HEX_FILE} $<$:$> $<$>:$> - ${S_NS_SIGNED_HEX_FILE} + ${S_NS_SIGNED_CONFIRMED_HEX_FILE} ) set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts - ${S_NS_HEX_FILE} - ${S_NS_SIGNED_HEX_FILE} + ${S_NS_CONFIRMED_HEX_FILE} + ${S_NS_SIGNED_CONFIRMED_HEX_FILE} ${MERGED_HEX_FILE} ) From fea3b9a8578dc32f4b39841936b82d508a99feaf Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Tue, 23 Sep 2025 09:49:22 +0200 Subject: [PATCH 16/18] trusted-firmware-m: Generate tfm_merged.bin When CONFIG_TFM_MCUBOOT_IMAGE_NUMBER is 1, all images are merged. Currently, there is no tfm_merged.bin file for use in FOTA. This adds file generation to fulfill that requirement. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/CMakeLists.txt | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 18eb92e3c45b6..f81ca977b01fb 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -567,8 +567,11 @@ if (CONFIG_BUILD_WITH_TFM) endfunction() set(MERGED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_merged.hex) + set(MERGED_BIN_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_merged.bin) set(S_NS_CONFIRMED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_confirmed.hex) set(S_NS_SIGNED_CONFIRMED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_confirmed_signed.hex) + set(S_NS_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns.hex) + set(S_NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_signed.hex) set(NS_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.hex) set(S_SIGNED_HEX_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_signed.hex) set(NS_SIGNED_BIN_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.bin) @@ -601,6 +604,9 @@ if (CONFIG_BUILD_WITH_TFM) tfm_sign(sign_cmd_s_ns_confirm_hex SUFFIX "S_NS" HEADER TRAILER CONFIRM MAX_SECTORS ${S_NS_MAX_SECTORS} INPUT_FILE ${S_NS_CONFIRMED_HEX_FILE} OUTPUT_FILE ${S_NS_SIGNED_CONFIRMED_HEX_FILE}) + tfm_sign(sign_cmd_s_ns_hex SUFFIX "S_NS" + HEADER TRAILER MAX_SECTORS ${S_NS_MAX_SECTORS} + INPUT_FILE ${S_NS_HEX_FILE} OUTPUT_FILE ${S_NS_SIGNED_HEX_FILE}) set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py @@ -617,10 +623,28 @@ if (CONFIG_BUILD_WITH_TFM) ${S_NS_SIGNED_CONFIRMED_HEX_FILE} ) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${S_NS_HEX_FILE} + $ + ${NS_HEX_APP_FILE} + + COMMAND ${sign_cmd_s_ns_hex} + + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${MERGED_BIN_FILE} --output-bin + $<$:$> + $<$>:$> + ${S_NS_SIGNED_HEX_FILE} + ) + set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts ${S_NS_CONFIRMED_HEX_FILE} ${S_NS_SIGNED_CONFIRMED_HEX_FILE} + ${S_NS_HEX_FILE} + ${S_NS_SIGNED_HEX_FILE} ${MERGED_HEX_FILE} + ${MERGED_BIN_FILE} ) else() From 083d32c3a3b3d2fb89276a15e9d1d74ef9ce97bd Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Tue, 19 Aug 2025 08:26:42 +0200 Subject: [PATCH 17/18] docs: migration-guide-4.3: Add TF-M sign note Add a note about BL2 (MCUboot) signing updates when the board is built as TF-M NS. Signed-off-by: BUDKE Gerson Fernando --- doc/releases/migration-guide-4.3.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index 930bcf3d60d2b..46de9110cb7ca 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -443,5 +443,26 @@ LED Strip * Renamed ``arduino,modulino-smartleds`` to :dtcompatible:`arduino,modulino-pixels` +Trusted Firmware-M +================== + +* The signing process for BL2 (MCUboot) was updated. The boards that run using + TF-M NS and require BL2 must have their flash layout with the flash controller + information. This will ensure that when signing the hex/bin files all the + details will be present in the S and NS images. The image now has the details + to allow the FWU state machine be correct and allow FOTA. + (:github:`94470`) + + * The ``--align`` parameter was fixed to 1. Now, it's set to the flash DT ``write_block_size`` + property, but still provides 1 as a fallback for specific vendors. + * The ``--max-sectors`` value is now calculated based on the number of images, taking into + consideration the largest image size. + * The ``--confirm`` option now confirms both S and NS HEX images, ensuring that any image + that runs is valid for production and development. + * S and NS BIN images are now available. These are the correct images to be used in FOTA. Note + that S and NS images are unconfirmed by default, and the application is responsible for + confirming them with ``psa_fwu_accept()``. Otherwise, the images will roll back on the next + reboot. + Architectures ************* From a726b06f7793c82d1b1421338701fb40a483e1d7 Mon Sep 17 00:00:00 2001 From: BUDKE Gerson Fernando Date: Mon, 22 Sep 2025 14:56:38 +0200 Subject: [PATCH 18/18] docs: services: tfm: Add note about confirmed images Extend the Signing Images section in the build documentation to highlight the differences between confirmed and unconfirmed images with respect to the PSA Certified Firmware Update API. Signed-off-by: BUDKE Gerson Fernando --- doc/services/tfm/build.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/services/tfm/build.rst b/doc/services/tfm/build.rst index 7f8f75d56849a..d0b70333b74af 100644 --- a/doc/services/tfm/build.rst +++ b/doc/services/tfm/build.rst @@ -61,6 +61,12 @@ When :kconfig:option:`CONFIG_TFM_BL2` is set to ``y``, TF-M uses a secure bootlo is validated by the bootloader during updates using the corresponding public key, which is stored inside the secure bootloader firmware image. +During the signing procedure, all HEX files are marked as ``confirmed``, +whereas all BIN files remain ``unconfirmed``. This guarantees that any image +flashed into a device possesses the required properties for compatibility +with the `PSA Certified Firmware Update API`_. The corresponding BIN file +can then be used as the payload in the Firmware Update procedure. + By default, ``/bl2/ext/mcuboot/root-rsa-3072.pem`` is used to sign secure images, and ``/bl2/ext/mcuboot/root-rsa-3072_1.pem`` is used to sign non-secure images. These default .pem keys can (and **should**) be overridden @@ -94,6 +100,8 @@ hex file can then be flashed to your development board or run in QEMU. .. _PSA Certified Level 1: https://www.psacertified.org/security-certification/psa-certified-level-1/ +.. _PSA Certified Firmware Update API: + https://arm-software.github.io/psa-api/fwu/ Custom CMake arguments ======================