From a0b62c63a4c35436e1236872fde1e0e0f332a4f7 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 the TFM_BOARD by vendor name for better clarity. Signed-off-by: BUDKE Gerson Fernando --- modules/trusted-firmware-m/Kconfig.tfm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 55e08ee45e4a9..cf85cbf89077c 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -10,19 +10,19 @@ 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 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 default "arm/mps3/corstone300/an552" if BOARD_MPS3_CORSTONE300_AN552_NS + default "arm/mps3/corstone300/fvp" if BOARD_MPS3_CORSTONE300_FVP_NS default "arm/mps3/corstone310/an555" if BOARD_MPS3_CORSTONE310_AN555_NS - default "arm/mps3/corstone310/fvp" if BOARD_MPS3_CORSTONE310_FVP_NS + default "arm/mps3/corstone310/fvp" if BOARD_MPS3_CORSTONE310_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 "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 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 77a7b4101c81995fef626c1948d420c8174a9f32 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..236d86d69b7db 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 45d2ee41830d192c0ed15898bdd6ff0f9c3b94b0 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 This excludes the mps3/corstone300/an547/ns from psa tests becuase QEMU does not model the QSPI flash in MPS3 boards as real QSPI flash, but only as simple ROM, so attempting to rewrite the flash from the guest will fail. See more details in: 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 | 2 +- boards/arm/mps3/mps3_corstone300_an547_ns.yaml | 2 -- 3 files changed, 2 insertions(+), 4 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 e129eec1e345c..30d7977ec6333 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 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 518e2beaa64ad41fc21c6907a57f66806b8f7eab 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 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. In addition, the ISRAM was redefined to expose the correct size and values for both S and NS firmware. This makes clear to user how the momory was selected. 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..839361691bcbe 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 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 + 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 1e8167086159f7673fdae6632fcdc8243341fa13 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 241b08e628b979521ef7cf7ec5eea9286e0a7596 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 parritions from the stm32l562e_dk/stm32l562xx/ns board is not align 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 8c0ce365dbadf..5082cc15da25f 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 { @@ -41,24 +41,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 332da0fa0b5c4c57909ec7c76b2517a6ba11e544 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 5e066130b2627..dd1026d60bf5f 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -444,6 +444,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 chosen_flash 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 minimal 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) @@ -463,7 +496,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 36af79accff57c487fa9370713d9fcd00445e718 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 will helps to catch problems with flash overlap when merging images. If there is a missalignment from flash partitions usually the merge process will fail. This pick information from zephyr flash partitions and flash controller to automatically determine the max sectors value and apply it when singing 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 dd1026d60bf5f..72fce23c56e36 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -447,15 +447,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 chosen_flash 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() @@ -475,9 +477,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() @@ -497,6 +516,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}} @@ -537,7 +557,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 @@ -562,12 +582,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 c1c3c71b8186f1ab363912d303a858dee7912dfc 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 behaviour when signing an image is to set always --pad and --pad-header for all images unless TFM_USE_NS_APP is set. This does not allow easy creation of a signed image for FOTA applications. Rewrite the PAD parameter into HEADER and TRAILER to easy setup more signing options. The other important reason to do this change is that NS image when signed without --pad run in the hardware. However, it do not perform the MCUboot test image and the FWU never upgrade de image. This will fix the NS image signing process to correct allow 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 72fce23c56e36..213317a777a54 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -496,9 +496,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. @@ -557,7 +561,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 @@ -582,12 +586,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 aaf0904eeca903da928211075ffd8fc3014370be 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 behaviour from signing an image add --pad but do not confirm the image. This seems to be a mistake because user should inspect in the Firmware Upgrade software the image status. This means that if an image is not --confirmed the FSM can not infer correct states. This set the image as confirmed to fix this 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 213317a777a54..b001b74f24f90 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -496,7 +496,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) @@ -504,6 +504,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}}) @@ -523,6 +527,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} @@ -561,7 +566,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 @@ -586,12 +591,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 e695e597d90e51edd31b01e6009a8842edacbf7c 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 variable that define output files explicity quote HEX in the name. This is a refactor step to allow introduce BIN files out 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 b001b74f24f90..0c3196c942c7e 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -538,84 +538,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 7ffabb07d4617777860dd87240fcf2aabbce8cd2 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 One fundamental use of trusted-firmware-m is to allow IoT applications to have security and the firmware upgrade FOTA is almost 100% mandatory in these applications. The current state of files signing process do not produce the necessary binaries to use with multi image S/NS FWU once the hex images are not suitable for this use case. This introduces the missing signed binaries files to be used by FWU partition. The changes were tested in multi image FWU scenarios and single image can be easily extended 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 0c3196c942c7e..9e6198ff2be0b 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) @@ -543,13 +543,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) @@ -594,18 +598,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} @@ -617,7 +629,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 887a6a7c8b999c31fb922b8c3f65061430ffe50c 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() to be more idiomatic. This make the code more readable and make it easier to add 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 9e6198ff2be0b..aba751f2ef941 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -496,45 +496,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() @@ -570,8 +592,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 @@ -596,21 +619,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 eeace3ab2121a0fcfcbed0769c00fb83a92604bd 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 IntexHex class to save the content as a binary instead intelhex 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..ad554f647baed 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) + format = "bin" if output_bin else "hex" + ih.tofile(output, format=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 89bd831fafc9d9a4413aa5746cb8752a0498763a 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 prepare the content to introduce the generation of the tfm_merged.bin to be used 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 aba751f2ef941..cbb69b1a6ea4d 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -561,8 +561,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) @@ -592,28 +592,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 ef4f7d6bacb45b5faaeef8e74be1cb5309f9634f 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 the images will be merged. Currently there is no tfm_merged.bin file to be used in FOTA. This add the file generation to fulfill that need. 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 cbb69b1a6ea4d..eb76e2fefdefa 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -561,8 +561,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) @@ -595,6 +598,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 @@ -611,10 +617,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 5ad1a82115b52266dd259d18cdcaab3423e10370 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 note about BL2 (MCUboot) signing updates when board is build 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 4f9a8f7898127..ce99af4471867 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -255,5 +255,26 @@ Silabs * The separate ``em3`` power state was removed from Series 2 SoCs. The system automatically transitions to EM2 or EM3 depending on hardware peripheral requests for the oscillators. +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 ensures that when signing the hex/bin files all the + details will be present in the S and NS images. With this new constraint, the + image now has the details to allow the FWU state machine be correct and allow + FOTA. + (:github:`94470`) + + * The ``--align`` parameter was fixed and 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 c156984a06e982d5bc1a6c349f344ac92c622030 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 This extends the Signing Images details in the build documentation to highlight the details about confirmed and unconfirmed images in regards to 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..d6741c56609ee 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 onto 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 ======================