Skip to content

Commit

Permalink
merge-tfm-images: Add new function for merging images
Browse files Browse the repository at this point in the history
A new CMake module (MergeTfmImages.cmake) is introduced
to be used to merge Bootloader, TF-M secure, Non-secure
user application, secure and non-secure provisioning
images into one image to be loaded inside the ROM rather
than loading different images at their respective addresses.

CI is modified to archive the merged binary instead of
separate binaries which would be used the test stage of
the CI.

This change enhance re-usability and decrease code
duplication within the existing applications and applications
to be added.

Signed-off-by: Ahmed Ismail <[email protected]>
  • Loading branch information
AhmedIsmail02 authored and urutva committed Oct 11, 2023
1 parent dae01b8 commit 87b8ea1
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 43 deletions.
1 change: 1 addition & 0 deletions .github/.cSpellWords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ RIHN
RSAES
RSASSA
SECP
srecord
srtp
SRTP
tinycbor
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ jobs:
shell: bash
run: |
pip install cmake ninja imgtool cffi intelhex cbor2 cbor jinja2 PyYaml pyelftools
sudo apt-get -y update
sudo apt-get -y install srecord
- name: Install GNU Arm toolchain
shell: bash
run: |
sudo apt-get -y update
sudo apt-get -y install gcc-arm-none-eabi
- name: Generate dummy device credentials
shell: bash
Expand All @@ -55,10 +56,7 @@ jobs:
shell: bash
run: |
tar -czf gnu_build.tar.gz \
build/bootloader/bl2.axf \
build/secure_partition/tfm_s_signed.bin \
build/Projects/aws-iot-example/aws-iot-example.axf \
build/Projects/aws-iot-example/aws-iot-example_signed.bin \
build/Projects/aws-iot-example/aws-iot-example_merged.elf \
build/Projects/aws-iot-example/aws-iot-example-update_signed.bin \
build/Projects/aws-iot-example/update-signature.txt
- name: Upload Build Artifacts
Expand Down
7 changes: 1 addition & 6 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,9 @@ build-applications:
- ./Tools/scripts/build.sh aws-iot-example --toolchain $TOOLCHAIN --certificate_path $PWD/certificate.pem --private_key_path $PWD/private_key.pem
- |
tar -czf ${TOOLCHAIN}_build.tar.gz \
build/bootloader/bl2.axf \
build/secure_partition/tfm_s_signed.bin \
build/secure_partition/encrypted_provisioning_bundle.bin \
build/Projects/aws-iot-example/aws-iot-example.axf \
build/Projects/aws-iot-example/aws-iot-example_signed.bin \
build/Projects/aws-iot-example/aws-iot-example_merged.elf \
build/Projects/aws-iot-example/aws-iot-example-update_signed.bin \
build/Projects/aws-iot-example/update-signature.txt \
build/Projects/aws-iot-example/provisioning_data/provisioning_data.bin \
Config/aws_configs
artifacts:
paths:
Expand Down
9 changes: 9 additions & 0 deletions Bsp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

add_subdirectory(arm-corstone-platform-bsp)

# Target specific image loading addresses
if(ARM_CORSTONE_BSP_TARGET_PLATFORM STREQUAL "corstone300")
set(BL2_IMAGE_LOAD_ADDRESS 0x00000000 PARENT_SCOPE)
set(S_IMAGE_LOAD_ADDRESS 0x11000000 PARENT_SCOPE)
set(NS_IMAGE_LOAD_ADDRESS 0x01060000 PARENT_SCOPE)
set(S_PROVISIONING_BUNDLE_LOAD_ADDRESS 0x10022000 PARENT_SCOPE)
set(NS_PROVISIONING_BUNDLE_LOAD_ADDRESS 0x210FF000 PARENT_SCOPE)
endif()

# BSP serial library

add_library(fri-bsp STATIC)
Expand Down
6 changes: 6 additions & 0 deletions Docs/development-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ git submodule update --init --recursive
```bash
deactivate
```
* Installing required libraries

```bash
sudo apt install srecord
sudo apt install binutils
```
* Installing a toolchain

This project supports the Arm Compiler for Embedded (armclang) and the Arm
Expand Down
50 changes: 50 additions & 0 deletions Middleware/ARM/TF-M/cmake/MergeTfmImages.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2023 Arm Limited and/or its affiliates
# <[email protected]>
# SPDX-License-Identifier: MIT

include(ConvertElfToBin)
include(ExternalProject)

ExternalProject_Get_Property(tf-m-build BINARY_DIR)

# To merge the bootloader image, TF-M secure image, non-secure user application image,
# secure and non-secure provsioning bundle images into one image, their addresses are
# needed. As the addresses are defined in their respective linker scripts, there is no
# simple way to programmatically get them, so they need to be specified by the user project.
# Order: <bootloader>, <signed secure TF-M firmware>, <signed non-secure user app>, <secure provisioning bundle address>, <non-secure provisioning data load address> (optional), <non-secure provisioning data path> (optional).

# This function is making use of CMake optional arguments feature, the reason why this feature
# is used is that not every application will need to pass the non-secure provisioning data load address
# and the non-secure provisioning data path to this function.
# ARGV5 is mapped to non-secure provisioning data load address.
# ARGV6 is mapped to non-secure provisioning data path.
function(iot_reference_arm_corstone3xx_tf_m_merge_images target bl2_address tfm_s_address ns_address s_prov_bundle_address)
if(DEFINED ARGV5)
set(ns_provisioning_data_param ${ARGV6} -Binary -offset ${ARGV5})
else()
set(ns_provisioning_data_param "")
endif()
find_program(srec_cat NAMES srec_cat REQUIRED)
find_program(objcopy NAMES arm-none-eabi-objcopy objcopy REQUIRED)
add_custom_command(
TARGET
${target}
POST_BUILD
DEPENDS
$<TARGET_FILE_DIR:${target}>/${target}_signed.bin
COMMAND
${srec_cat} ${BINARY_DIR}/install/outputs/bl2.bin -Binary -offset ${bl2_address}
${BINARY_DIR}/install/outputs/tfm_s_signed.bin -Binary -offset ${tfm_s_address}
$<TARGET_FILE_DIR:${target}>/${target}_signed.bin -Binary -offset ${ns_address}
${ns_provisioning_data_param}
${CMAKE_BINARY_DIR}/Middleware/ARM/TF-M/tf-m-build-prefix/src/tf-m-build-build/install/outputs/encrypted_provisioning_bundle.bin -Binary -offset ${s_prov_bundle_address}
-o $<TARGET_FILE_DIR:${target}>/${target}_merged.hex
COMMAND
${objcopy} -I ihex -O elf32-little
$<TARGET_FILE_DIR:${target}>/${target}_merged.hex
$<TARGET_FILE_DIR:${target}>/${target}_merged.elf
COMMAND
${CMAKE_COMMAND} -E echo "-- merged: $<TARGET_FILE_DIR:${target}>/${target}_merged.elf"
VERBATIM
)
endfunction()
15 changes: 0 additions & 15 deletions Middleware/ARM/TF-M/cmake/SignTfmImage.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,6 @@ function(iot_reference_arm_corstone3xx_tf_m_sign_image target signed_target_name
--confirm
$<TARGET_FILE_DIR:${target}>/${target}_unsigned.bin
$<TARGET_FILE_DIR:${target}>/${signed_target_name}.bin
COMMAND
# Copy the bootloader image
${CMAKE_COMMAND} -E copy
${BINARY_DIR}/install/outputs/bl2.axf
${CMAKE_BINARY_DIR}/bootloader/bl2.axf
COMMAND
# Copy the signed TF-M image
${CMAKE_COMMAND} -E copy
${BINARY_DIR}/install/outputs/tfm_s_signed.bin
${CMAKE_BINARY_DIR}/secure_partition/tfm_s_signed.bin
COMMAND
# Copy the encrypted provisioning bundle image
${CMAKE_COMMAND} -E copy
${BINARY_DIR}/install/outputs/encrypted_provisioning_bundle.bin
${CMAKE_BINARY_DIR}/secure_partition/encrypted_provisioning_bundle.bin

COMMAND
${CMAKE_COMMAND} -E echo "-- signed: $<TARGET_FILE_DIR:${target}>/${signed_target_name}.bin"
Expand Down
7 changes: 7 additions & 0 deletions Projects/aws-iot-example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ endif()

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Middleware/ARM/TF-M/cmake)
include(SignTfmImage)
include(MergeTfmImages)

# The non-secure application image should be padded while being signed
# Hence, passing "TRUE" as the input parameter to the pad option of sign function.
Expand All @@ -258,6 +259,12 @@ iot_reference_arm_corstone3xx_tf_m_sign_image(aws-iot-example aws-iot-example_si
# Hence, passing "FALSE" as the input parameter for the pad option to the sign function.
iot_reference_arm_corstone3xx_tf_m_sign_image(aws-iot-example aws-iot-example-update_signed ${MCUBOOT_IMAGE_VERSION_NS_UPDATE} FALSE)

# A user project that consumes the ARM FRI needs to explicitly provide
# addresses in order to merge images for TF-M. The addresses cannot
# be easily programmatically extracted as they are defined in the linker
# scripts.
iot_reference_arm_corstone3xx_tf_m_merge_images(aws-iot-example ${BL2_IMAGE_LOAD_ADDRESS} ${S_IMAGE_LOAD_ADDRESS} ${NS_IMAGE_LOAD_ADDRESS} ${S_PROVISIONING_BUNDLE_LOAD_ADDRESS} ${NS_PROVISIONING_BUNDLE_LOAD_ADDRESS} ${CMAKE_BINARY_DIR}/Projects/aws-iot-example/provisioning_data/provisioning_data.bin)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Middleware/AWS/cmake)
include(GenerateAWSUpdateDigestAndSignature)

Expand Down
7 changes: 7 additions & 0 deletions Projects/blinky/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,14 @@ endif()

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Middleware/ARM/TF-M/cmake)
include(SignTfmImage)
include(MergeTfmImages)

# The non-secure application image should be padded while being signed
# Hence, passing "TRUE" as the input parameter to the pad option of sign function.
iot_reference_arm_corstone3xx_tf_m_sign_image(blinky blinky_signed 0.0.1 TRUE)

# A user project that consumes the ARM FRI needs to explicitly provide
# addresses in order to merge images for TF-M. The addresses cannot
# be easily programmatically extracted as they are defined in the linker
# scripts.
iot_reference_arm_corstone3xx_tf_m_merge_images(blinky ${BL2_IMAGE_LOAD_ADDRESS} ${S_IMAGE_LOAD_ADDRESS} ${NS_IMAGE_LOAD_ADDRESS} ${S_PROVISIONING_BUNDLE_LOAD_ADDRESS})
16 changes: 4 additions & 12 deletions Tools/scripts/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,12 @@ done
case "$TARGET" in
corstone300 )
FVP_BIN="VHT_Corstone_SSE-300_Ethos-U55"
FVP_S_IMAGE_LOAD_ADDRESS=0x11000000
FVP_NS_IMAGE_LOAD_ADDRESS=0x01060000
FVP_S_PROVISIONING_BUNDLE_LOAD_ADDRESS=0x10022000
FVP_NS_PROVISIONING_BUNDLE_LOAD_ADDRESS=0x210FF000
;;
corstone310 )
FVP_BIN="VHT_Corstone_SSE-310"
FVP_S_IMAGE_LOAD_ADDRESS=0x38000000
FVP_NS_IMAGE_LOAD_ADDRESS=0x28080000
FVP_S_PROVISIONING_BUNDLE_LOAD_ADDRESS=0x11022000
FVP_NS_PROVISIONING_BUNDLE_LOAD_ADDRESS=0x213FF000
;;
*)
echo "Invalid target <Ccorstone300|corstone310>"
echo "Invalid target <Corstone300|corstone310>"
show_usage
exit 2
;;
Expand All @@ -81,11 +73,11 @@ esac
case "$1" in
blinky)
EXAMPLE="$1"
FVP_IMAGE_OPTIONS="cpu0*="$BUILD_PATH/bootloader/bl2.axf" --data "$BUILD_PATH/secure_partition/tfm_s_signed.bin"@$FVP_S_IMAGE_LOAD_ADDRESS --data "$BUILD_PATH/Projects/$1/$1_signed.bin"@$FVP_NS_IMAGE_LOAD_ADDRESS --data "$BUILD_PATH/Middleware/ARM/TF-M/tf-m-build-prefix/src/tf-m-build-build/install/outputs/encrypted_provisioning_bundle.bin"@$FVP_S_PROVISIONING_BUNDLE_LOAD_ADDRESS"
MERGED_IMAGE_PATH="$BUILD_PATH/Projects/$EXAMPLE/blinky_merged.elf"
;;
aws-iot-example)
EXAMPLE="$1"
FVP_IMAGE_OPTIONS="cpu0*="$BUILD_PATH/bootloader/bl2.axf" --data "$BUILD_PATH/secure_partition/tfm_s_signed.bin"@$FVP_S_IMAGE_LOAD_ADDRESS --data "$BUILD_PATH/Projects/$1/$1_signed.bin"@$FVP_NS_IMAGE_LOAD_ADDRESS --data "$BUILD_PATH/Projects/$EXAMPLE/provisioning_data/provisioning_data.bin"@$FVP_NS_PROVISIONING_BUNDLE_LOAD_ADDRESS --data "$BUILD_PATH/Middleware/ARM/TF-M/tf-m-build-prefix/src/tf-m-build-build/install/outputs/encrypted_provisioning_bundle.bin"@$FVP_S_PROVISIONING_BUNDLE_LOAD_ADDRESS"
MERGED_IMAGE_PATH="$BUILD_PATH/Projects/$EXAMPLE/aws-iot-example_merged.elf"
;;
*)
echo "Usage: $0 <blinky,aws-iot-example>" >&2
Expand All @@ -96,4 +88,4 @@ esac
OPTIONS="-C mps3_board.visualisation.disable-visualisation=1 -C mps3_board.smsc_91c111.enabled=1 -C mps3_board.hostbridge.userNetworking=1 -C mps3_board.telnetterminal0.start_telnet=0 -C mps3_board.uart0.out_file="-" -C mps3_board.uart0.unbuffered_output=1 --stat -C mps3_board.DISABLE_GATING=1"

# Start the FVP
$FVP_BIN $OPTIONS -a $FVP_IMAGE_OPTIONS
$FVP_BIN $OPTIONS -a $MERGED_IMAGE_PATH
6 changes: 1 addition & 5 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@ def fvp(fvp_path, build_path, vsi_script_path, fvp_options):
# Note: It can take few seconds to terminate the FVP
cmdline = [
fvp_path,
"-a", f"cpu0*={build_path}/bootloader/bl2.axf",
"--data", f"{build_path}/secure_partition/tfm_s_signed.bin@0x11000000",
"--data", f"{build_path}/Projects/aws-iot-example/aws-iot-example_signed.bin@0x01060000",
"--data", f"{build_path}/Projects/aws-iot-example/provisioning_data/provisioning_data.bin@0x210FF000",
"--data", f"{build_path}/secure_partition/encrypted_provisioning_bundle.bin@0x10022000",
"-a", f"{build_path}/Projects/aws-iot-example/aws-iot-example_merged.elf",
"-C", "core_clk.mul=200000000",
"-C", "mps3_board.visualisation.disable-visualisation=1",
"-C", "mps3_board.telnetterminal0.start_telnet=0",
Expand Down

0 comments on commit 87b8ea1

Please sign in to comment.