1# Copyright (c) 2020-2023 Nordic Semiconductor ASA 2# SPDX-License-Identifier: Apache-2.0 3 4# This file includes extra build system logic that is enabled when 5# CONFIG_BOOTLOADER_MCUBOOT=y. 6# 7# It builds signed binaries using imgtool as a post-processing step 8# after zephyr/zephyr.elf is created in the build directory. 9# 10# Since this file is brought in via include(), we do the work in a 11# function to avoid polluting the top-level scope. 12 13function(zephyr_runner_file type path) 14 # Property magic which makes west flash choose the signed build 15 # output of a given type. 16 set_target_properties(runners_yaml_props_target PROPERTIES "${type}_file" "${path}") 17endfunction() 18 19function(zephyr_mcuboot_tasks) 20 set(keyfile "${CONFIG_MCUBOOT_SIGNATURE_KEY_FILE}") 21 set(keyfile_enc "${CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE}") 22 23 if(NOT "${CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE}") 24 # Check for misconfiguration. 25 if("${keyfile}" STREQUAL "") 26 # No signature key file, no signed binaries. No error, though: 27 # this is the documented behavior. 28 message(WARNING "Neither CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE or " 29 "CONFIG_MCUBOOT_SIGNATURE_KEY_FILE are set, the generated build will not be " 30 "bootable by MCUboot unless it is signed manually/externally.") 31 return() 32 endif() 33 endif() 34 35 if(NOT WEST) 36 # This feature requires west. 37 message(FATAL_ERROR "Can't sign images for MCUboot: west not found. To fix, install west and ensure it's on PATH.") 38 endif() 39 40 foreach(file keyfile keyfile_enc) 41 if(NOT "${${file}}" STREQUAL "") 42 if(NOT IS_ABSOLUTE "${${file}}") 43 # Relative paths are relative to 'west topdir'. 44 set(${file} "${WEST_TOPDIR}/${${file}}") 45 endif() 46 47 if(NOT EXISTS "${${file}}" AND NOT "${CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE}") 48 message(FATAL_ERROR "west sign can't find file ${${file}} (Note: Relative paths are relative to the west workspace topdir \"${WEST_TOPDIR}\")") 49 elseif(NOT (CONFIG_BUILD_OUTPUT_BIN OR CONFIG_BUILD_OUTPUT_HEX)) 50 message(FATAL_ERROR "Can't sign images for MCUboot: Neither CONFIG_BUILD_OUTPUT_BIN nor CONFIG_BUILD_OUTPUT_HEX is enabled, so there's nothing to sign.") 51 endif() 52 endif() 53 endforeach() 54 55 # Find imgtool. Even though west is installed, imgtool might not be. 56 # The user may also have a custom manifest which doesn't include 57 # MCUboot. 58 # 59 # Therefore, go with an explicitly installed imgtool first, falling 60 # back on mcuboot/scripts/imgtool.py. 61 if(IMGTOOL) 62 set(imgtool_path "${IMGTOOL}") 63 elseif(DEFINED ZEPHYR_MCUBOOT_MODULE_DIR) 64 set(IMGTOOL_PY "${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts/imgtool.py") 65 if(EXISTS "${IMGTOOL_PY}") 66 set(imgtool_path "${IMGTOOL_PY}") 67 endif() 68 endif() 69 70 # No imgtool, no signed binaries. 71 if(NOT DEFINED imgtool_path) 72 message(FATAL_ERROR "Can't sign images for MCUboot: can't find imgtool. To fix, install imgtool with pip3, or add the mcuboot repository to the west manifest and ensure it has a scripts/imgtool.py file.") 73 return() 74 endif() 75 76 # Basic 'west sign' command and output format independent arguments. 77 separate_arguments(west_sign_extra UNIX_COMMAND ${CONFIG_MCUBOOT_CMAKE_WEST_SIGN_PARAMS}) 78 set(west_sign ${WEST} sign ${west_sign_extra} 79 --tool imgtool 80 --tool-path "${imgtool_path}" 81 --build-dir "${APPLICATION_BINARY_DIR}") 82 83 # Arguments to imgtool. 84 if(NOT CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS STREQUAL "") 85 # Separate extra arguments into the proper format for adding to 86 # extra_post_build_commands. 87 # 88 # Use UNIX_COMMAND syntax for uniform results across host 89 # platforms. 90 separate_arguments(imgtool_extra UNIX_COMMAND ${CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS}) 91 else() 92 set(imgtool_extra) 93 endif() 94 95 if(NOT "${keyfile}" STREQUAL "") 96 set(imgtool_extra --key "${keyfile}" ${imgtool_extra}) 97 endif() 98 99 set(imgtool_args -- ${imgtool_extra}) 100 101 # Extensionless prefix of any output file. 102 set(output ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}) 103 104 # List of additional build byproducts. 105 set(byproducts) 106 107 # 'west sign' arguments for confirmed, unconfirmed and encrypted images. 108 set(unconfirmed_args) 109 set(confirmed_args) 110 set(encrypted_args) 111 112 # Set up .bin outputs. 113 if(CONFIG_BUILD_OUTPUT_BIN) 114 list(APPEND unconfirmed_args --bin --sbin ${output}.signed.bin) 115 list(APPEND byproducts ${output}.signed.bin) 116 zephyr_runner_file(bin ${output}.signed.bin) 117 118 if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE) 119 list(APPEND confirmed_args --bin --sbin ${output}.signed.confirmed.bin) 120 list(APPEND byproducts ${output}.signed.confirmed.bin) 121 endif() 122 123 if(NOT "${keyfile_enc}" STREQUAL "") 124 list(APPEND encrypted_args --bin --sbin ${output}.signed.encrypted.bin) 125 list(APPEND byproducts ${output}.signed.encrypted.bin) 126 endif() 127 endif() 128 129 # Set up .hex outputs. 130 if(CONFIG_BUILD_OUTPUT_HEX) 131 list(APPEND unconfirmed_args --hex --shex ${output}.signed.hex) 132 list(APPEND byproducts ${output}.signed.hex) 133 zephyr_runner_file(hex ${output}.signed.hex) 134 135 if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE) 136 list(APPEND confirmed_args --hex --shex ${output}.signed.confirmed.hex) 137 list(APPEND byproducts ${output}.signed.confirmed.hex) 138 endif() 139 140 if(NOT "${keyfile_enc}" STREQUAL "") 141 list(APPEND encrypted_args --hex --shex ${output}.signed.encrypted.hex) 142 list(APPEND byproducts ${output}.signed.encrypted.hex) 143 endif() 144 endif() 145 146 # Add the west sign calls and their byproducts to the post-processing 147 # steps for zephyr.elf. 148 # 149 # CMake guarantees that multiple COMMANDs given to 150 # add_custom_command() are run in order, so adding the 'west sign' 151 # calls to the "extra_post_build_commands" property ensures they run 152 # after the commands which generate the unsigned versions. 153 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND 154 ${west_sign} ${unconfirmed_args} ${imgtool_args}) 155 if(confirmed_args) 156 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND 157 ${west_sign} ${confirmed_args} ${imgtool_args} --pad --confirm) 158 endif() 159 if(encrypted_args) 160 set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND 161 ${west_sign} ${encrypted_args} ${imgtool_args} --encrypt "${keyfile_enc}") 162 endif() 163 set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts ${byproducts}) 164endfunction() 165 166zephyr_mcuboot_tasks() 167