Skip to content

Commit d3080f1

Browse files
multiplemonomialsnordicjm
authored andcommitted
Update Mbed CMakeLists.txt for Mbed CE
Signed-off-by: Jamie Smith <[email protected]>
1 parent 1c32c9b commit d3080f1

File tree

7 files changed

+273
-38
lines changed

7 files changed

+273
-38
lines changed

boot/mbed/CMakeLists.txt

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Copyright (c) 2021 ARM Limited. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
# Mbed-MCUboot Port
4+
# Pull in functions for working with imgtool
5+
include(mcuboot_imgtool.cmake)
56

7+
# Mbed-MCUboot Port
68
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
7-
89
get_filename_component(BOOT_UTIL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../bootutil REALPATH)
910

1011
set(LIB_TARGET mbed-mcuboot)
@@ -13,49 +14,46 @@ set(LIB_BOOTUTIL bootutil)
1314
add_library(${LIB_TARGET} STATIC)
1415

1516
target_include_directories(${LIB_TARGET}
16-
PUBLIC
17-
include
18-
${BOOT_UTIL_DIR}/include
19-
${BOOT_UTIL_DIR}/src
17+
PUBLIC
18+
include
19+
${BOOT_UTIL_DIR}/src
2020
)
2121

2222
target_sources(${LIB_TARGET}
23-
PRIVATE
24-
mcuboot_main.cpp
25-
app_enc_keys.c
26-
src/flash_map_backend.cpp
27-
src/secondary_bd.cpp
23+
PRIVATE
24+
mcuboot_main.cpp
25+
app_enc_keys.c
26+
src/flash_map_backend.cpp
27+
src/secondary_bd.cpp
2828
)
2929

3030
target_link_libraries(${LIB_TARGET}
31-
PUBLIC
32-
bootutil # Cross-dependency
33-
mbed-mbedtls
34-
mbed-storage-flashiap
35-
mbed-storage-blockdevice
31+
PUBLIC
32+
bootutil # Cross-dependency
33+
mbed-mbedtls
34+
mbed-storage-flashiap
35+
mbed-storage-blockdevice
36+
mbed-core-flags
3637
)
3738

38-
if("_RTE_" IN_LIST MBED_CONFIG_DEFINITIONS)
39-
target_link_libraries(${LIB_TARGET}
40-
PUBLIC
41-
mbed-os
42-
)
43-
else()
44-
target_link_libraries(${LIB_TARGET}
45-
PUBLIC
46-
mbed-baremetal
47-
)
39+
# Add signing key generated source file
40+
mcuboot_generate_signing_keys_file(${CMAKE_CURRENT_BINARY_DIR}/signing_keys.c)
41+
target_sources(${LIB_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/signing_keys.c)
42+
43+
if("MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS)
44+
mcuboot_generate_encryption_key_file(${CMAKE_CURRENT_BINARY_DIR}/enc_keys.c)
45+
target_sources(${LIB_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/enc_keys.c)
4846
endif()
4947

5048
# The cross-dependency requires that bootutil have access to the mbed port's
5149
# include directory and is linked with the appropriate mbed-specific libraries.
5250
target_include_directories(${LIB_BOOTUTIL}
53-
PUBLIC
54-
include
51+
PUBLIC
52+
include
5553
)
5654

5755
target_link_libraries(${LIB_BOOTUTIL}
58-
PUBLIC
59-
mbed-mcuboot
60-
mbed-mbedtls
56+
PUBLIC
57+
mbed-mcuboot
58+
mbed-mbedtls
6159
)

boot/mbed/include/flash_map_backend/flash_map_backend.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ uint8_t flash_area_erased_val(const struct flash_area * fap);
152152

153153
/*
154154
* Given flash area ID, return info about sectors within the area.
155+
*
156+
* Note: the sectors array has size MCUBOOT_MAX_IMG_SECTORS, and only that many elements should
157+
* be stored into it. However, if the flash area has more than MCUBOOT_MAX_IMG_SECTORS sectors,
158+
* the count variable should be set to indicate the real sector count. This will trigger the appropriate
159+
* warning to be printed.
155160
*/
156161
int flash_area_get_sectors(int fa_id, uint32_t *count,
157162
struct flash_sector *sectors);

boot/mbed/include/mcuboot_config/mcuboot_logging.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#define MCUBOOT_LOG_LEVEL MCUBOOT_LOG_LEVEL_OFF
3737
#endif
3838

39+
// Set Mbed log level appropriately if not already set
40+
#ifndef MBED_TRACE_MAX_LEVEL
3941
#if MCUBOOT_LOG_LEVEL == MCUBOOT_LOG_LEVEL_ERROR
4042
#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_ERROR
4143
#elif MCUBOOT_LOG_LEVEL == MCUBOOT_LOG_LEVEL_WARNING
@@ -45,6 +47,7 @@
4547
#elif MCUBOOT_LOG_LEVEL == MCUBOOT_LOG_LEVEL_DEBUG
4648
#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_DEBUG
4749
#endif
50+
#endif
4851

4952
#define TRACE_GROUP "MCUb"
5053
#include "mbed-trace/mbed_trace.h"

boot/mbed/mbed_lib.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"value": true
8989
},
9090
"max-img-sectors": {
91-
"help": "Maximum number of flash sectors per image slot. Target-dependent, please set on a per-target basis.",
91+
"help": "Maximum number of flash sectors per image slot. This should be set to account for the sector sizes of both the main and secondary block devices. Target-dependent, please set on a per-target basis.",
9292
"macro_name": "MCUBOOT_MAX_IMG_SECTORS",
9393
"required": true
9494
},
@@ -119,7 +119,7 @@
119119
"value": null
120120
},
121121
"encrypt-rsa": {
122-
"help": "Encrypt images using RSA (NOT TESTED)",
122+
"help": "Encrypt update images using RSA",
123123
"macro_name": "MCUBOOT_ENCRYPT_RSA",
124124
"accepted_values": [true, null],
125125
"value": null
@@ -189,6 +189,11 @@
189189
"xip-secondary-slot-address": {
190190
"help": "Specify start address for secondary slot address in XIP-accessible memory. This is required if direct-xip is enabled.",
191191
"value": null
192+
},
193+
"flash-block-size": {
194+
"help": "Size in bytes of a programmable block of the flash memory.",
195+
"macro_name": "MCUBOOT_BOOT_MAX_ALIGN",
196+
"value": 8
192197
}
193198
}
194199
}

boot/mbed/mcuboot_imgtool.cmake

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Copyright (c) 2024 Jamie Smith
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
check_python_package(imgtool.main MCUBOOT_IMGTOOL_FOUND)
5+
6+
get_filename_component(IMGTOOL_SCRIPTS_DIR ${CMAKE_CURRENT_LIST_DIR}/../../scripts REALPATH)
7+
8+
# Find or install imgtool
9+
10+
if(NOT MCUBOOT_IMGTOOL_FOUND)
11+
# If we are using the Mbed venv, we can install asn1tools automatically
12+
if(MBED_CREATE_PYTHON_VENV)
13+
message(STATUS "mcuboot: Installing imgtool into Mbed's Python virtualenv")
14+
execute_process(
15+
COMMAND ${Python3_EXECUTABLE} -m pip install ${IMGTOOL_SCRIPTS_DIR}
16+
COMMAND_ERROR_IS_FATAL ANY
17+
)
18+
else()
19+
message(FATAL_ERROR "The mcuboot imgtool python package needs to be installed (from mcuboot/scripts/) into Mbed's python interpreter (${Python3_EXECUTABLE})")
20+
endif()
21+
endif()
22+
23+
# Signing key
24+
set(MCUBOOT_SIGNING_KEY "" CACHE STRING "Path to key file (.pem) used to sign firmware updates for your device. The public key will be stored in the bootloader. This file must be kept safe!")
25+
26+
# Make sure the signing key path is absolute for EXISTS, relative to the top level build dir
27+
get_filename_component(MCUBOOT_SIGNING_KEY_ABSPATH "${MCUBOOT_SIGNING_KEY}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
28+
set(MCUBOOT_SIGNING_KEY_ABSPATH ${MCUBOOT_SIGNING_KEY_ABSPATH} CACHE INTERNAL "Absolute version of MCUBOOT_SIGNING_KEY" FORCE)
29+
30+
if("${MCUBOOT_SIGNING_KEY}" STREQUAL "" OR NOT EXISTS "${MCUBOOT_SIGNING_KEY_ABSPATH}")
31+
message(FATAL_ERROR "Must specify path to valid image signing key via MCUBOOT_SIGNING_KEY CMake option in order to build this project.")
32+
endif()
33+
34+
# Encryption key
35+
if("MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS)
36+
set(MCUBOOT_ENCRYPTION_KEY "" CACHE STRING "Path to key file (.pem) used to encrypt firmware updates for your device. The private key will be stored in the bootloader. This file must be kept safe!")
37+
38+
# Make sure the signing key path is absolute for EXISTS, relative to the top level build dir
39+
get_filename_component(MCUBOOT_ENCRYPTION_KEY_ABSPATH "${MCUBOOT_ENCRYPTION_KEY}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
40+
set(MCUBOOT_ENCRYPTION_KEY_ABSPATH ${MCUBOOT_ENCRYPTION_KEY_ABSPATH} CACHE INTERNAL "Absolute version of MCUBOOT_ENCRYPTION_KEY" FORCE)
41+
42+
if("${MCUBOOT_ENCRYPTION_KEY}" STREQUAL "" OR NOT EXISTS "${MCUBOOT_ENCRYPTION_KEY_ABSPATH}")
43+
message(FATAL_ERROR "Since mcuboot.encrypt-rsa is enabled, you must specify the path to a valid image encryption key via the MCUBOOT_ENCRYPTION_KEY CMake option in order to build this project.")
44+
endif()
45+
endif()
46+
47+
# Imgtool usage functions
48+
49+
#
50+
# Generate a signed image hex file for the given executable target.
51+
#
52+
function(_mcuboot_generate_image TARGET IMAGE_TYPE IMAGE_BASE_PATH)
53+
if("${MBED_OUTPUT_EXT}" STREQUAL "bin")
54+
message(FATAL_ERROR "Hex file output must be enabled to use mcuboot. Set MBED_OUTPUT_EXT to empty string after including app.cmake in your top level CMakeLists.txt!")
55+
endif()
56+
57+
if("${PROJECT_VERSION}" STREQUAL "")
58+
message(FATAL_ERROR "You must set the project version to sign images by passing a version number into your app's project() command!")
59+
endif()
60+
61+
# mbed_generate_bin_hex() puts the hex file at the following path
62+
set(TARGET_HEX_FILE ${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_BASE_NAME:${TARGET}>.hex)
63+
64+
# Grab header size
65+
if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_HEADER_SIZE=(0x[0-9A-Fa-f]+)")
66+
message(FATAL_ERROR "Couldn't find MCUBOOT_HEADER_SIZE in Mbed configuration!")
67+
endif()
68+
set(HEADER_SIZE_HEX ${CMAKE_MATCH_1})
69+
70+
# Grab slot size
71+
if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_SLOT_SIZE=(0x[0-9A-Fa-f]+)")
72+
message(FATAL_ERROR "Couldn't find MCUBOOT_SLOT_SIZE in Mbed configuration!")
73+
endif()
74+
set(SLOT_SIZE_HEX ${CMAKE_MATCH_1})
75+
76+
get_property(objcopy GLOBAL PROPERTY ELF2BIN)
77+
78+
if(${IMAGE_TYPE} STREQUAL "update" AND "MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS)
79+
set(IMGTOOL_EXTRA_ARGS --encrypt ${MCUBOOT_ENCRYPTION_KEY_ABSPATH})
80+
elseif(${IMAGE_TYPE} STREQUAL "initial" AND "MCUBOOT_ENCRYPT_RSA=1" IN_LIST MBED_CONFIG_DEFINITIONS)
81+
# If encryption is enabled, generate unencrypted initial image which supports encryption.
82+
# See https://github.com/mbed-ce/mbed-os/issues/401#issuecomment-2567099213
83+
set(IMGTOOL_EXTRA_ARGS --clear)
84+
else()
85+
set(IMGTOOL_EXTRA_ARGS "")
86+
endif()
87+
88+
add_custom_command(
89+
TARGET ${TARGET}
90+
POST_BUILD
91+
DEPENDS ${MCUBOOT_SIGNING_KEY_ABSPATH}
92+
COMMAND
93+
${Python3_EXECUTABLE} -m imgtool.main
94+
sign
95+
--key ${MCUBOOT_SIGNING_KEY_ABSPATH} # this specifies the file containing the keys used to sign/verify the application
96+
--align 4 # this lets mcuboot know the intrinsic alignment of the flash (32-bits = 4 byte alignment)
97+
--version ${PROJECT_VERSION} # this sets the version number of the application
98+
--header-size ${HEADER_SIZE_HEX} # this must be the same as the value specified in mcuboot.header-size configuration
99+
--pad-header # this tells imgtool to insert the entire header, including any necessary padding bytes.
100+
--slot-size ${SLOT_SIZE_HEX} # this specifies the maximum size of the application ("slot size"). It must be the same as the configured mcuboot.slot-size!
101+
${IMGTOOL_EXTRA_ARGS}
102+
${TARGET_HEX_FILE} ${IMAGE_BASE_PATH}.hex
103+
104+
COMMAND
105+
${CMAKE_COMMAND} -E echo "-- built: ${IMAGE_BASE_PATH}.hex"
106+
107+
# Also generate bin file
108+
COMMAND
109+
${objcopy} -I ihex -O binary ${IMAGE_BASE_PATH}.hex ${IMAGE_BASE_PATH}.bin
110+
111+
COMMAND
112+
${CMAKE_COMMAND} -E echo "-- built: ${IMAGE_BASE_PATH}.bin"
113+
114+
COMMENT "Generating mcuboot ${IMAGE_TYPE} image for ${TARGET}..."
115+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
116+
VERBATIM
117+
)
118+
endfunction(_mcuboot_generate_image)
119+
120+
#
121+
# Generate an initial image hex file for the given executable target.
122+
# This initial image is what should be flashed to a blank device (along with the bootloader).
123+
# A flash target (ninja flash-${TARGET}-initial-image) will also be created.
124+
#
125+
# NOTE: This function must be called *after* mbed_set_post_build() for the target!
126+
#
127+
# If you wish to specify the base name of the initial image, pass that as the second argument to
128+
# this function. Otherwise, it will default to $<target name>-initial-image
129+
#
130+
function(mcuboot_generate_initial_image TARGET) # optional 2nd arg: initial image base filename
131+
# Figure out file path
132+
if("${ARGN}" STREQUAL "")
133+
set(INITIAL_IMAGE_BASE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_BASE_NAME:${TARGET}>-initial-image)
134+
else()
135+
set(INITIAL_IMAGE_BASE_PATH ${CMAKE_CURRENT_BINARY_DIR}/${ARGN})
136+
endif()
137+
138+
_mcuboot_generate_image(${TARGET} initial ${INITIAL_IMAGE_BASE_PATH})
139+
140+
# Create a flash target.
141+
# We need to be slightly creative here -- Mbed thinks that the application start address
142+
# is <primary slot address> + <header size>, but we actually want to upload to <primary slot address>.
143+
# So we need to temporarily override MBED_UPLOAD_BASE_ADDR with an offset value
144+
if(NOT "${MBED_CONFIG_DEFINITIONS}" MATCHES "MCUBOOT_HEADER_SIZE=(0x[0-9A-Fa-f]+)")
145+
message(FATAL_ERROR "Couldn't find MCUBOOT_HEADER_SIZE in Mbed configuration!")
146+
endif()
147+
set(HEADER_SIZE_HEX ${CMAKE_MATCH_1})
148+
math(EXPR MBED_UPLOAD_BASE_ADDR "${MBED_UPLOAD_BASE_ADDR} - ${HEADER_SIZE_HEX}" OUTPUT_FORMAT HEXADECIMAL)
149+
150+
gen_upload_target(${TARGET}-initial-image ${INITIAL_IMAGE_BASE_PATH}.bin)
151+
if(TARGET flash-${TARGET}-initial-image)
152+
add_dependencies(flash-${TARGET}-initial-image ${TARGET})
153+
endif()
154+
endfunction(mcuboot_generate_initial_image)
155+
156+
#
157+
# Generate an update image hex file for the given executable target.
158+
# This image is what should be flashed to the secondary block device and passed to
159+
# mcuboot as an update file.
160+
#
161+
# NOTE: This function must be called *after* mbed_set_post_build() for the target!
162+
#
163+
# NOTE 2: The hex file produced by this function will still "declare" its address as the primary slot
164+
# address. This can cause issues if you pass it to a tool that uses this offset to decide where to load it.
165+
# If this is a problem, we recommend the "arm-none-eabi-objcopy --change-addresses" command to change this address.
166+
#
167+
# If you wish to specify the base name of the update image, pass that as the second argument to
168+
# this function. Otherwise, it will default to $<target name>-update-image
169+
#
170+
function(mcuboot_generate_update_image TARGET) # optional 2nd arg: update image base filename
171+
# Figure out file path
172+
if("${ARGN}" STREQUAL "")
173+
set(UPDATE_IMAGE_BASE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_BASE_NAME:${TARGET}>-update-image)
174+
else()
175+
set(UPDATE_IMAGE_BASE_PATH${CMAKE_CURRENT_BINARY_DIR}/${ARGN})
176+
endif()
177+
178+
_mcuboot_generate_image(${TARGET} update ${UPDATE_IMAGE_BASE_PATH})
179+
endfunction(mcuboot_generate_update_image)
180+
181+
#
182+
# Generate a C source file with signing keys in it at the given location.
183+
# The file should be added as a source file to a library built in the same directory.
184+
#
185+
function(mcuboot_generate_signing_keys_file SIGNING_KEYS_C_PATH)
186+
add_custom_command(
187+
OUTPUT ${SIGNING_KEYS_C_PATH}
188+
COMMAND
189+
${Python3_EXECUTABLE} -m imgtool.main
190+
getpub
191+
--key ${MCUBOOT_SIGNING_KEY_ABSPATH}
192+
--output ${SIGNING_KEYS_C_PATH}
193+
194+
DEPENDS ${MCUBOOT_SIGNING_KEY_ABSPATH}
195+
COMMENT "Converting signing key to C source..."
196+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
197+
VERBATIM
198+
)
199+
endfunction(mcuboot_generate_signing_keys_file)
200+
201+
#
202+
# Generate a C source file with the encryption private key in it at the given location.
203+
# The file should be added as a source file to a library built in the same directory.
204+
#
205+
function(mcuboot_generate_encryption_key_file ENC_KEY_C_PATH)
206+
add_custom_command(
207+
OUTPUT ${ENC_KEY_C_PATH}
208+
COMMAND
209+
${Python3_EXECUTABLE} -m imgtool.main
210+
getpriv
211+
--key ${MCUBOOT_SIGNING_KEY_ABSPATH}
212+
> ${ENC_KEY_C_PATH}
213+
214+
DEPENDS ${MCUBOOT_SIGNING_KEY_ABSPATH}
215+
COMMENT "Converting encryption key to C source..."
216+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
217+
VERBATIM
218+
)
219+
endfunction(mcuboot_generate_encryption_key_file)

boot/mbed/mcuboot_main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#if MCUBOOT_BOOTLOADER_BUILD
2020

2121
#include <stdlib.h>
22+
#include <cinttypes>
2223
#include "bootutil/bootutil.h"
2324
#include "bootutil/image.h"
2425
#include "hal/serial_api.h"
@@ -83,7 +84,7 @@ int main()
8384
// Workaround: The extra \n ensures the last trace gets flushed
8485
// before mbed_start_application() destroys the stack and jumps
8586
// to the application
86-
tr_info("Booting firmware image at 0x%x\n", address);
87+
tr_info("Booting firmware image at 0x%" PRIx32 "\n", address);
8788

8889
// Run the application in the primary slot
8990
// Add header size offset to calculate the actual start address of application

0 commit comments

Comments
 (0)