From b1d1c24300e04394ef4640e1052c7c14e7ed5a11 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Thu, 18 Nov 2021 10:20:17 +0100 Subject: [PATCH 1/9] cmake: kconfig: allow build systems to decide defconfig Allow build system to define an alternative defconfig file. This allows reusing the existing kconfig.cmake file in other projects, such as multi image builds. Signed-off-by: Torsten Rasmussen --- cmake/modules/kconfig.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index e13ac293f3379..3e1a5f95f8ded 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -59,7 +59,7 @@ else() set(KCONFIG_ROOT ${ZEPHYR_BASE}/Kconfig) endif() -set(BOARD_DEFCONFIG ${BOARD_DIR}/${BOARD}_defconfig) +set_ifndef(BOARD_DEFCONFIG ${BOARD_DIR}/${BOARD}_defconfig) set(DOTCONFIG ${PROJECT_BINARY_DIR}/.config) set(PARSED_KCONFIG_SOURCES_TXT ${PROJECT_BINARY_DIR}/kconfig/sources.txt) From 32a28eff0b1ede48cbba48700b4843681896f69b Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Sat, 27 Nov 2021 11:50:37 +0100 Subject: [PATCH 2/9] cmake: kconfig: allow for Kconfig CONFIG namespace This commit allows for specifying a dedicated Kconfig namespace, for example: _CONFIG This namespace will then be used for handling loading of configuration files into CMake configure scope, as well as handling of CMake cache variables when set using `-D_CONFIG_=`. This allows greater flexibility when re-using the cmake/kconfig.cmake in other projects. Signed-off-by: Torsten Rasmussen --- cmake/modules/kconfig.cmake | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 3e1a5f95f8ded..2746c9b7016da 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -17,6 +17,8 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${AUTOCONF_H}) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/generated) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/config) +set_ifndef(KCONFIG_NAMESPACE "CONFIG") + # Support multiple SOC_ROOT, remove ZEPHYR_BASE as that is always sourced. set(kconfig_soc_root ${SOC_ROOT}) list(REMOVE_ITEM kconfig_soc_root ${ZEPHYR_BASE}) @@ -109,6 +111,7 @@ set(COMMON_KCONFIG_ENV_SETTINGS PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} srctree=${ZEPHYR_BASE} KERNELVERSION=${KERNELVERSION} + CONFIG_=${KCONFIG_NAMESPACE}_ KCONFIG_CONFIG=${DOTCONFIG} # Set environment variables so that Kconfig can prune Kconfig source # files for other architectures @@ -170,15 +173,15 @@ foreach(kconfig_target endforeach() # Support assigning Kconfig symbols on the command-line with CMake -# cache variables prefixed with 'CONFIG_'. This feature is -# experimental and undocumented until it has undergone more +# cache variables prefixed according to the Kconfig namespace. +# This feature is experimental and undocumented until it has undergone more # user-testing. unset(EXTRA_KCONFIG_OPTIONS) get_cmake_property(cache_variable_names CACHE_VARIABLES) foreach (name ${cache_variable_names}) - if("${name}" MATCHES "^CONFIG_") - # When a cache variable starts with 'CONFIG_', it is assumed to be - # a Kconfig symbol assignment from the CMake command line. + if("${name}" MATCHES "^${KCONFIG_NAMESPACE}_") + # When a cache variable starts with the 'KCONFIG_NAMESPACE' value, it is + # assumed to be a Kconfig symbol assignment from the CMake command line. set(EXTRA_KCONFIG_OPTIONS "${EXTRA_KCONFIG_OPTIONS}\n${name}=${${name}}" ) @@ -316,18 +319,18 @@ add_custom_target(config-twister DEPENDS ${DOTCONFIG}) # CMakeCache.txt. If the symbols end up in DOTCONFIG they will be # re-introduced to the namespace through 'import_kconfig'. foreach (name ${cache_variable_names}) - if("${name}" MATCHES "^CONFIG_") + if("${name}" MATCHES "^${KCONFIG_NAMESPACE}_") unset(${name}) unset(${name} CACHE) endif() endforeach() -# Parse the lines prefixed with CONFIG_ in the .config file from Kconfig -import_kconfig(CONFIG_ ${DOTCONFIG}) +# Import the .config file and make all settings available in CMake processing. +import_kconfig(${KCONFIG_NAMESPACE} ${DOTCONFIG}) # Re-introduce the CLI Kconfig symbols that survived foreach (name ${cache_variable_names}) - if("${name}" MATCHES "^CONFIG_") + if("${name}" MATCHES "^${KCONFIG_NAMESPACE}_") if(DEFINED ${name}) set(${name} ${${name}} CACHE STRING "") endif() From a0665bf5f375025ce9b7e5858e2898a560b38a5f Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Sat, 27 Nov 2021 11:58:00 +0100 Subject: [PATCH 3/9] cmake: kconfig: allow to set Kconfig targets externally This commit allows a project to specify a given set of Kconfig targets prior to sourcing kconfig.cmake. This allows for greater flexibility when re-using kconfig.cmake in other projects. Signed-off-by: Torsten Rasmussen --- cmake/modules/kconfig.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 2746c9b7016da..e72cb65a00ec9 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -149,10 +149,10 @@ set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_hardenconfig ${ZEPHYR_BASE}/scripts/kconfig/hardenconfig.py ) +set_ifndef(KCONFIG_TARGETS menuconfig guiconfig hardenconfig) + foreach(kconfig_target - menuconfig - guiconfig - hardenconfig + ${KCONFIG_TARGETS} ${EXTRA_KCONFIG_TARGETS} ) add_custom_target( From 1a71ce8b7f75234b2a3e2843b1510441a924bff5 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 22 Jun 2022 11:05:49 +0200 Subject: [PATCH 4/9] cmake: initial sysbuild / multi image support This is the initial commit with system build, sysbuild. Using CMake as infrastructure together with the Zephyr sysbuild allows us to support a convenient way of building a sample and allow for extra images to be built as part of a larger system. It uses Kconfig for configuration of image builds. This allows for future extension with additional build images. Signed-off-by: Torsten Rasmussen --- CODEOWNERS | 1 + share/sysbuild/CMakeLists.txt | 42 ++++ share/sysbuild/Kconfig | 34 ++++ .../cmake/modules/sysbuild_extensions.cmake | 187 ++++++++++++++++++ .../cmake/modules/sysbuild_kconfig.cmake | 60 ++++++ 5 files changed, 324 insertions(+) create mode 100644 share/sysbuild/CMakeLists.txt create mode 100644 share/sysbuild/Kconfig create mode 100644 share/sysbuild/cmake/modules/sysbuild_extensions.cmake create mode 100644 share/sysbuild/cmake/modules/sysbuild_kconfig.cmake diff --git a/CODEOWNERS b/CODEOWNERS index e8722d1e901ef..667a4a4573a20 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -725,6 +725,7 @@ scripts/build/gen_image_info.py @tejlmand /scripts/build/uf2conv.py @petejohanson /scripts/build/user_wordsize.py @cfriedt /scripts/valgrind.supp @aescolar @daor-oti +/share/sysbuild/ @tejlmand /share/zephyr-package/ @tejlmand /share/zephyrunittest-package/ @tejlmand /subsys/bluetooth/ @alwa-nordic @jhedberg @Vudentz diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt new file mode 100644 index 0000000000000..d30d629e1fe84 --- /dev/null +++ b/share/sysbuild/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20) + +if(NOT DEFINED APP_DIR) + message(FATAL_ERROR "No main application specified") +endif() + +# This will update the APP_DIR cache variable to PATH type and apply a comment. +# If APP_DIR is a relative path, then CMake will adjust to absolute path based +# on current working dir. +set(APP_DIR ${APP_DIR} CACHE PATH "Main Application Source Directory") + +# Add sysbuild/cmake/modules to CMAKE_MODULE_PATH which allows us to integrate +# sysbuild CMake modules with general Zephyr CMake modules. +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) +# List of Zephyr and sysbuild CMake modules we need for sysbuild. +# Note: sysbuild_kconfig will internally load kconfig CMake module. +set(zephyr_modules extensions sysbuild_extensions python west root zephyr_module boards shields sysbuild_kconfig) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS ${zephyr_modules}) + +project(sysbuild LANGUAGES) + +# Global list of images enabled in this multi image build system. +set(IMAGES) + +get_filename_component(APP_DIR ${APP_DIR} ABSOLUTE) +get_filename_component(app_name ${APP_DIR} NAME) + +# This adds the primary application to the build. +ExternalZephyrProject_Add( + APPLICATION ${app_name} + SOURCE_DIR ${APP_DIR} + MAIN_APP +) + +# This allows for board and app specific images to be included. +include(${BOARD_DIR}/sysbuild.cmake OPTIONAL) +include(${APP_DIR}/sysbuild.cmake OPTIONAL) diff --git a/share/sysbuild/Kconfig b/share/sysbuild/Kconfig new file mode 100644 index 0000000000000..ce49acff28681 --- /dev/null +++ b/share/sysbuild/Kconfig @@ -0,0 +1,34 @@ +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +comment "Sysbuild image configuration" + +osource "$(BOARD_DIR)/Kconfig.sysbuild" + +config EXPERIMENTAL + bool + help + Symbol that must be selected by a feature if it is considered to be + at an experimental implementation stage. + +config WARN_EXPERIMENTAL + bool + prompt "Warn on experimental usage" + help + Print a warning when the Kconfig tree is parsed if any experimental + features are enabled. + +config DEPRECATED + bool + help + Symbol that must be selected by a feature or module if it is + considered to be deprecated. + +config WARN_DEPRECATED + bool + default y + prompt "Warn on deprecated usage" + help + Print a warning when the Kconfig tree is parsed if any deprecated + features are enabled. diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake new file mode 100644 index 0000000000000..e9b841bf8c26b --- /dev/null +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -0,0 +1,187 @@ +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# Usage: +# ExternalZephyrProject_Add(APPLICATION +# SOURCE_DIR +# [BOARD ] +# [MAIN_APP] +# ) +# +# This function includes a Zephyr based build system into the multiimage +# build system +# +# APPLICATION: : Name of the application, name will also be used for build +# folder of the application +# SOURCE_DIR : Source directory of the application +# BOARD : Use for application build instead user defined BOARD. +# MAIN_APP: Flag indicating this application is the main application +# and where user defined settings should be passed on as-is +# except for multi image build flags. +# For example, -DCONF_FILES= will be passed on to the +# MAIN_APP unmodified. +# +function(ExternalZephyrProject_Add) + cmake_parse_arguments(ZBUILD "MAIN_APP" "APPLICATION;BOARD;SOURCE_DIR" "" ${ARGN}) + + if(ZBUILD_UNPARSED_ARGUMENTS) + message(FATAL_ERROR + "ExternalZephyrProject_Add(${ARGV0} ...) given unknown arguments:" + " ${ZBUILD_UNPARSED_ARGUMENTS}" + ) + endif() + + set(sysbuild_vars + "APP_DIR" + "SB_CONF_FILE" + ) + + # General variables that should be propagated to all Zephyr builds, for example: + # - ZEPHYR_MODULES / ZEPHYR_EXTRA_MODULES + # - ZEPHYR_TOOLCHAIN_VARIANT + # - *_TOOLCHAIN_PATH + # - *_ROOT + # etc. + # Note: setting vars on a single image can be done by using + # `_CONF_FILE`, like `mcuboot_CONF_FILE` + set( + shared_image_variables_list + CMAKE_BUILD_TYPE + CMAKE_VERBOSE_MAKEFILE + BOARD + ZEPHYR_MODULES + ZEPHYR_EXTRA_MODULES + ZEPHYR_TOOLCHAIN_VARIANT + EXTRA_KCONFIG_TARGETS + ) + + set(shared_image_variables_regex + "^[^_]*_TOOLCHAIN_PATH|^[^_]*_ROOT" + ) + + set(app_cache_file ${CMAKE_BINARY_DIR}/CMake${ZBUILD_APPLICATION}PreloadCache.txt) + + if(EXISTS ${app_cache_file}) + file(STRINGS ${app_cache_file} app_cache_strings) + set(app_cache_strings_current ${app_cache_strings}) + endif() + + get_cmake_property(variables_cached CACHE_VARIABLES) + foreach(var_name ${variables_cached}) + # Any var of the form `_` should be propagated. + # For example mcuboot_= ==> -D= for mcuboot build. + if("${var_name}" MATCHES "^${ZBUILD_APPLICATION}_.*") + list(APPEND application_vars ${var_name}) + continue() + endif() + + # This means there is a match to another image than current one, ignore. + if("${var_name}" MATCHES "^.*_CONFIG_.*") + continue() + endif() + + # sysbuild reserved namespace. + if(var_name IN_LIST sysbuild_vars OR "${var_name}" MATCHES "^SB_CONFIG_.*") + continue() + endif() + + if("${var_name}" MATCHES "^CONFIG_.*") + if(ZBUILD_MAIN_APP) + list(APPEND application_vars ${var_name}) + endif() + continue() + endif() + + if(var_name IN_LIST shared_image_variables_list) + list(APPEND application_vars ${var_name}) + continue() + endif() + + if("${var_name}" MATCHES "${shared_image_variables_regex}") + list(APPEND application_vars ${var_name}) + endif() + endforeach() + + foreach(app_var_name ${application_vars}) + string(REGEX REPLACE "^${ZBUILD_APPLICATION}_" "" var_name "${app_var_name}") + get_property(var_type CACHE ${app_var_name} PROPERTY TYPE) + set(new_cache_entry "${var_name}:${var_type}=${${app_var_name}}") + if(NOT new_cache_entry IN_LIST app_cache_strings) + # This entry does not exists, let's see if it has been updated. + foreach(entry ${app_cache_strings}) + if("${entry}" MATCHES "^${var_name}:.*") + list(REMOVE_ITEM app_cache_strings "${entry}") + break() + endif() + endforeach() + list(APPEND app_cache_strings "${var_name}:${var_type}=${${app_var_name}}") + list(APPEND app_cache_entries "-D${var_name}:${var_type}=${${app_var_name}}") + endif() + endforeach() + + if(NOT "${app_cache_strings_current}" STREQUAL "${app_cache_strings}") + string(REPLACE ";" "\n" app_cache_strings "${app_cache_strings}") + file(WRITE ${app_cache_file} ${app_cache_strings}) + endif() + + if(DEFINED ZBUILD_BOARD) + list(APPEND app_cache_entries "-DBOARD=${ZBUILD_BOARD}") + elseif(NOT ZBUILD_MAIN_APP) + list(APPEND app_cache_entries "-DBOARD=${BOARD}") + endif() + + set(image_banner "* Running CMake for ${ZBUILD_APPLICATION} *") + string(LENGTH "${image_banner}" image_banner_width) + string(REPEAT "*" ${image_banner_width} image_banner_header) + message(STATUS "\n ${image_banner_header}\n" + " ${image_banner}\n" + " ${image_banner_header}\n" + ) + + execute_process( + COMMAND ${CMAKE_COMMAND} + -G${CMAKE_GENERATOR} + ${app_cache_entries} + -B${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION} + -S${ZBUILD_SOURCE_DIR} + RESULT_VARIABLE return_val + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + + if(return_val) + message(FATAL_ERROR + "CMake configure failed for Zephyr project: ${ZBUILD_APPLICATION}\n" + "Location: ${ZBUILD_SOURCE_DIR}" + ) + endif() + + foreach(kconfig_target + menuconfig + hardenconfig + guiconfig + ${EXTRA_KCONFIG_TARGETS} + ) + + if(NOT ZBUILD_MAIN_APP) + set(image_prefix "${ZBUILD_APPLICATION}_") + endif() + + add_custom_target(${image_prefix}${kconfig_target} + ${CMAKE_MAKE_PROGRAM} ${kconfig_target} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION} + USES_TERMINAL + ) + endforeach() + include(ExternalProject) + ExternalProject_Add( + ${ZBUILD_APPLICATION} + SOURCE_DIR ${ZBUILD_SOURCE_DIR} + BINARY_DIR ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION} + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMAKE_COMMAND} --build . + INSTALL_COMMAND "" + BUILD_ALWAYS True + USES_TERMINAL_BUILD True + ) +endfunction() diff --git a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake new file mode 100644 index 0000000000000..add0bb8ac0447 --- /dev/null +++ b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake @@ -0,0 +1,60 @@ +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_sysbuild_menuconfig + ${ZEPHYR_BASE}/scripts/kconfig/menuconfig.py +) + +set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_sysbuild_guiconfig + ${ZEPHYR_BASE}/scripts/kconfig/guiconfig.py +) + +set(KCONFIG_TARGETS sysbuild_menuconfig sysbuild_guiconfig) +list(TRANSFORM EXTRA_KCONFIG_TARGETS PREPEND "sysbuild_") + +if(DEFINED SB_CONF_FILE) + # SB_CONF_FILE already set so nothing to do. +elseif(DEFINED ENV{SB_CONF_FILE}) + set(SB_CONF_FILE $ENV{SB_CONF_FILE}) +elseif(EXISTS ${APP_DIR}/sysbuild.conf) + set(SB_CONF_FILE ${APP_DIR}/sysbuild.conf) +else() + # Because SYSBuild is opt-in feature, then it is permitted to not have a + # SYSBuild dedicated configuration file. +endif() + +if(DEFINED SB_CONF_FILE AND NOT IS_ABSOLUTE SB_CONF_FILE) + cmake_path(ABSOLUTE_PATH SB_CONF_FILE BASE_DIRECTORY ${APP_DIR} OUTPUT_VARIABLE SB_CONF_FILE) +endif() + +if(DEFINED SB_CONF_FILE AND NOT DEFINED CACHE{SB_CONF_FILE}) + # We only want to set this in cache it has been defined and is not already there. + set(SB_CONF_FILE ${SB_CONF_FILE} CACHE STRING "If desired, you can build the application with \ + SYSbuild configuration settings specified in an alternate .conf file using this parameter. \ + These settings will override the settings in the application’s SYSBuild config file or its \ + default .conf file. Multiple files may be listed, e.g. SB_CONF_FILE=\"sys1.conf sys2.conf\"") +endif() + +if(NOT DEFINED SB_CONF_FILE) + # If there is no SB_CONF_FILE, then use empty.conf to make kconfiglib happy. + # Not adding it to CMake cache ensures that a later created sysbuild.conf + # will be automatically detected. + set(SB_CONF_FILE ${CMAKE_CURRENT_BINARY_DIR}/empty.conf) +endif() + +# Empty files to make kconfig.py happy. +file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/empty.conf) +set(APPLICATION_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(KCONFIG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) +set(AUTOCONF_H ${CMAKE_CURRENT_BINARY_DIR}/autoconf.h) +set(CONF_FILE ${SB_CONF_FILE}) +set(BOARD_DEFCONFIG "${CMAKE_CURRENT_BINARY_DIR}/empty.conf") +list(APPEND ZEPHYR_KCONFIG_MODULES_DIR BOARD=${BOARD}) +set(KCONFIG_NAMESPACE SB_CONFIG) + +if(EXISTS ${APP_DIR}/Kconfig.sysbuild) + set(KCONFIG_ROOT ${APP_DIR}/Kconfig.sysbuild) +endif() +include(${ZEPHYR_BASE}/cmake/modules/kconfig.cmake) +set(CONF_FILE) From f655493c4d68cfbb34db1730977ff9117cee3dda Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 22 Jun 2022 11:19:05 +0200 Subject: [PATCH 5/9] cmake: support MCUBoot bootloader natively with SYSBuild This commit adds CMake and Kconfig files needed to build MCUboot as an extra image using SYSBuild. Building an application with MCUBoot using SYSBuild allows users to build both images using a single build. Signed-off-by: Torsten Rasmussen --- share/sysbuild/CMakeLists.txt | 2 ++ share/sysbuild/Kconfig | 2 ++ share/sysbuild/bootloader/CMakeLists.txt | 11 +++++++++ share/sysbuild/bootloader/Kconfig | 29 ++++++++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 share/sysbuild/bootloader/CMakeLists.txt create mode 100644 share/sysbuild/bootloader/Kconfig diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index d30d629e1fe84..d50b5cd20d0a6 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -37,6 +37,8 @@ ExternalZephyrProject_Add( MAIN_APP ) +add_subdirectory(bootloader) + # This allows for board and app specific images to be included. include(${BOARD_DIR}/sysbuild.cmake OPTIONAL) include(${APP_DIR}/sysbuild.cmake OPTIONAL) diff --git a/share/sysbuild/Kconfig b/share/sysbuild/Kconfig index ce49acff28681..0ef8f8b802351 100644 --- a/share/sysbuild/Kconfig +++ b/share/sysbuild/Kconfig @@ -32,3 +32,5 @@ config WARN_DEPRECATED help Print a warning when the Kconfig tree is parsed if any deprecated features are enabled. + +rsource "bootloader/Kconfig" diff --git a/share/sysbuild/bootloader/CMakeLists.txt b/share/sysbuild/bootloader/CMakeLists.txt new file mode 100644 index 0000000000000..82943152522a1 --- /dev/null +++ b/share/sysbuild/bootloader/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# Include MCUboot if enabled. +if(SB_CONFIG_BOOTLOADER_MCUBOOT) + ExternalZephyrProject_Add( + APPLICATION mcuboot + SOURCE_DIR ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/zephyr/ + ) +endif() diff --git a/share/sysbuild/bootloader/Kconfig b/share/sysbuild/bootloader/Kconfig new file mode 100644 index 0000000000000..6c70a6e9594a0 --- /dev/null +++ b/share/sysbuild/bootloader/Kconfig @@ -0,0 +1,29 @@ +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +config SUPPORT_BOOTLOADER + bool + default y + +config SUPPORT_BOOTLOADER_MCUBOOT_ZEPHYR + bool + default y + +choice BOOTLOADER + prompt "Bootloader support" + default BOOTLOADER_NONE + depends on SUPPORT_BOOTLOADER + +config BOOTLOADER_NONE + bool "None" + help + Do not Include a bootloader in the build + +config BOOTLOADER_MCUBOOT + bool "MCUboot" + depends on SUPPORT_BOOTLOADER_MCUBOOT_ZEPHYR + help + Include MCUboot (Zephyr port) as the bootloader to use + +endchoice From 86dda4547d26fb08f6ed967b8360bf76892965f0 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 22 Nov 2021 13:55:57 +0100 Subject: [PATCH 6/9] cmake: create domains.yaml Support creation of domains.yaml to support `west --domain` when working with sysbuild multi image. Each Zephyr based image is added to list of domain that can be handled by the Zephyr west extension commands. Signed-off-by: Torsten Rasmussen --- share/sysbuild/CMakeLists.txt | 4 ++++ share/sysbuild/bootloader/CMakeLists.txt | 3 +++ share/sysbuild/cmake/domains.cmake | 12 ++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 share/sysbuild/cmake/domains.cmake diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index d50b5cd20d0a6..289fba0cade67 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -36,9 +36,13 @@ ExternalZephyrProject_Add( SOURCE_DIR ${APP_DIR} MAIN_APP ) +list(APPEND IMAGES "${app_name}") +set(DEFAULT_IMAGE "${app_name}") add_subdirectory(bootloader) # This allows for board and app specific images to be included. include(${BOARD_DIR}/sysbuild.cmake OPTIONAL) include(${APP_DIR}/sysbuild.cmake OPTIONAL) + +include(cmake/domains.cmake) diff --git a/share/sysbuild/bootloader/CMakeLists.txt b/share/sysbuild/bootloader/CMakeLists.txt index 82943152522a1..f9ba2ba2cb9f9 100644 --- a/share/sysbuild/bootloader/CMakeLists.txt +++ b/share/sysbuild/bootloader/CMakeLists.txt @@ -8,4 +8,7 @@ if(SB_CONFIG_BOOTLOADER_MCUBOOT) APPLICATION mcuboot SOURCE_DIR ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/zephyr/ ) + # MCUBoot default configuration is to perform a full chip erase. + # Placing MCUBoot first in list to ensure it is flashed before other images. + set(IMAGES "mcuboot" ${IMAGES} PARENT_SCOPE) endif() diff --git a/share/sysbuild/cmake/domains.cmake b/share/sysbuild/cmake/domains.cmake new file mode 100644 index 0000000000000..68cbd8c63df90 --- /dev/null +++ b/share/sysbuild/cmake/domains.cmake @@ -0,0 +1,12 @@ +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +set(domains_yaml "default: ${DEFAULT_IMAGE}") +set(domains_yaml "${domains_yaml}\nbuild_dir: ${CMAKE_BINARY_DIR}") +set(domains_yaml "${domains_yaml}\ndomains:") +foreach(image ${IMAGES}) + set(domains_yaml "${domains_yaml}\n - name: ${image}") + set(domains_yaml "${domains_yaml}\n build_dir: $") +endforeach() +file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/domains.yaml CONTENT "${domains_yaml}") From 4ec16a3acdbb656ae9c8c85b8ea5fb78b0d766c7 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 22 Nov 2021 13:35:06 +0100 Subject: [PATCH 7/9] scripts: extend west build command to support sysbuild CMake project west build now support the sysbuild CMake project which allows users to easily enable and build a bootloader together with any sample. This will allow for cleaning up samples and boards which already does custom multi image in a non-generic way, for example: - mps2_an521 which includes a build for remote board - samples/ipc/ which includes a samples for remote board - esp32 which includes custom bootloaders Signed-off-by: Torsten Rasmussen --- scripts/west_commands/build.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index 3e72bc9dea27d..b6da2a7aa23e1 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -19,10 +19,14 @@ _ARG_SEPARATOR = '--' +SYSBUILD_PROJ_DIR = pathlib.Path(__file__).resolve().parent.parent.parent \ + / pathlib.Path('share/sysbuild') + BUILD_USAGE = '''\ west build [-h] [-b BOARD[@REV]]] [-d BUILD_DIR] [-t TARGET] [-p {auto, always, never}] [-c] [--cmake-only] [-n] [-o BUILD_OPT] [-f] + [--sysbuild | --no-sysbuild] [source_dir] -- [cmake_opt [cmake_opt ...]] ''' @@ -124,6 +128,13 @@ def do_add_parser(self, parser_adder): dest='dry_run', action='store_true', help="just print build commands; don't run them") + group = parser.add_mutually_exclusive_group() + group.add_argument('--sysbuild', action='store_true', + help='''create multi domain build system''') + group.add_argument('--no-sysbuild', action='store_true', + help='''do not create multi domain build system + (default)''') + group = parser.add_argument_group('pristine builds', PRISTINE_DESCRIPTION) group.add_argument('-p', '--pristine', choices=['auto', 'always', @@ -357,9 +368,14 @@ def _sanity_check(self): # CMake configuration phase. self.run_cmake = True - cached_app = self.cmake_cache.get('APPLICATION_SOURCE_DIR') - log.dbg('APPLICATION_SOURCE_DIR:', cached_app, - level=log.VERBOSE_EXTREME) + cached_proj = self.cmake_cache.get('APPLICATION_SOURCE_DIR') + cached_app = self.cmake_cache.get('APP_DIR') + # if APP_DIR is None but APPLICATION_SOURCE_DIR is set, that indicates + # an older build folder, this still requires pristine. + if cached_app is None and cached_proj: + cached_app = cached_proj + + log.dbg('APP_DIR:', cached_app, level=log.VERBOSE_EXTREME) source_abs = (os.path.abspath(self.args.source_dir) if self.args.source_dir else None) cached_abs = os.path.abspath(cached_app) if cached_app else None @@ -445,6 +461,14 @@ def _run_cmake(self, board, origin, cmake_opts): if user_args: cmake_opts.extend(shlex.split(user_args)) + config_sysbuild = config_getboolean('sysbuild', False) + if self.args.sysbuild or (config_sysbuild and not self.args.no_sysbuild): + cmake_opts.extend(['-S{}'.format(SYSBUILD_PROJ_DIR), + '-DAPP_DIR={}'.format(self.source_dir)]) + else: + # self.args.no_sysbuild == True or config sysbuild False + cmake_opts.extend(['-S{}'.format(self.source_dir)]) + # Invoke CMake from the current working directory using the # -S and -B options (officially introduced in CMake 3.13.0). # This is important because users expect invocations like this @@ -453,7 +477,6 @@ def _run_cmake(self, board, origin, cmake_opts): # west build -- -DOVERLAY_CONFIG=relative-path.conf final_cmake_args = ['-DWEST_PYTHON={}'.format(sys.executable), '-B{}'.format(self.build_dir), - '-S{}'.format(self.source_dir), '-G{}'.format(config_get('generator', DEFAULT_CMAKE_GENERATOR))] if cmake_opts: From b719e1542f7e424a224b4ca4168c6b6ffe7eefd6 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 22 Nov 2021 10:29:56 +0100 Subject: [PATCH 8/9] scripts: west commands to support --domain This commit extends the west commands build, flash, and debug to support --domain when having multiple domains (images) defined in a domains.yaml build file. The domains.yaml uses the following yaml format to specify the build directory of each domain in the multi image build: > default: > domains: > : > build_dir: > : > build_dir: > ... `west ` has been extended to support `--domain `. `west build` calls CMake to create the build system, and if `--domain` is given, then the build tool will be invoked afterwards for the specified domain. `west flash` will default flash all domains, but `--domain ` argument can be used to select a specific domain to flash, for example: > west flash --domain mcuboot `west debug` only a single domain can be debugged at any given time. If `--domain` is not specified, then the default domain specified in the domains.yml file will be used. Users can still select a different domain, for example with: > west debug --domain mcuboot Signed-off-by: Torsten Rasmussen --- scripts/west_commands/build.py | 31 ++++-- scripts/west_commands/build_helpers.py | 17 +++ scripts/west_commands/domains.py | 139 +++++++++++++++++++++++++ scripts/west_commands/flash.py | 7 +- scripts/west_commands/run_common.py | 33 ++++-- 5 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 scripts/west_commands/domains.py diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index b6da2a7aa23e1..c4d0e09b851d5 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -12,7 +12,7 @@ from west import log from west.configuration import config from zcmake import DEFAULT_CMAKE_GENERATOR, run_cmake, run_build, CMakeCache -from build_helpers import is_zephyr_build, find_build_dir, \ +from build_helpers import is_zephyr_build, find_build_dir, load_domains, \ FIND_BUILD_DIR_DESCRIPTION from zephyr_ext_common import Forceable @@ -115,6 +115,9 @@ def do_add_parser(self, parser_adder): help='force a cmake run') group.add_argument('--cmake-only', action='store_true', help="just run cmake; don't build (implies -c)") + group.add_argument('--domain', action='append', + help='''execute build tool (make or ninja) only for + given domain''') group.add_argument('-t', '--target', help='''run build system target TARGET (try "-t usage")''') @@ -201,8 +204,9 @@ def do_run(self, args, remainder): self._sanity_check() self._update_cache() + self.domains = load_domains(self.build_dir) - self._run_build(args.target) + self._run_build(args.target, args.domain) def _find_board(self): board, origin = None, None @@ -464,7 +468,7 @@ def _run_cmake(self, board, origin, cmake_opts): config_sysbuild = config_getboolean('sysbuild', False) if self.args.sysbuild or (config_sysbuild and not self.args.no_sysbuild): cmake_opts.extend(['-S{}'.format(SYSBUILD_PROJ_DIR), - '-DAPP_DIR={}'.format(self.source_dir)]) + '-DAPP_DIR:PATH={}'.format(self.source_dir)]) else: # self.args.no_sysbuild == True or config sysbuild False cmake_opts.extend(['-S{}'.format(self.source_dir)]) @@ -499,7 +503,7 @@ def _run_pristine(self): '-P', cache['ZEPHYR_BASE'] + '/cmake/pristine.cmake'] run_cmake(cmake_args, cwd=self.build_dir, dry_run=self.args.dry_run) - def _run_build(self, target): + def _run_build(self, target, domain): if target: _banner('running target {}'.format(target)) elif self.run_cmake: @@ -511,8 +515,23 @@ def _run_build(self, target): if self.args.verbose: self._append_verbose_args(extra_args, not bool(self.args.build_opt)) - run_build(self.build_dir, extra_args=extra_args, - dry_run=self.args.dry_run) + + domains = load_domains(self.build_dir) + build_dir_list = [] + + if domain is None: + # If no domain is specified, we just build top build dir as that + # will build all domains. + build_dir_list = [domains.get_top_build_dir()] + else: + _banner('building domain(s): {}'.format(' '.join(domain))) + domain_list = domains.get_domains(domain) + for d in domain_list: + build_dir_list.append(d.build_dir) + + for b in build_dir_list: + run_build(b, extra_args=extra_args, + dry_run=self.args.dry_run) def _append_verbose_args(self, extra_args, add_dashes): # These hacks are only needed for CMake versions earlier than diff --git a/scripts/west_commands/build_helpers.py b/scripts/west_commands/build_helpers.py index a54978ffc315c..eca5bde6aeb9f 100644 --- a/scripts/west_commands/build_helpers.py +++ b/scripts/west_commands/build_helpers.py @@ -16,6 +16,7 @@ from west import log from west.configuration import config from west.util import escapes_directory +from domains import Domains DEFAULT_BUILD_DIR = 'build' '''Name of the default Zephyr build directory.''' @@ -133,3 +134,19 @@ def is_zephyr_build(path): log.dbg(f'{path} is NOT a valid zephyr build directory', level=log.VERBOSE_EXTREME) return False + + +def load_domains(path): + '''Load domains from a domains.yaml. + + If domains.yaml is not found, then a single 'app' domain referring to the + top-level build folder is created and returned. + ''' + domains_file = Path(path) / 'domains.yaml' + + if not domains_file.is_file(): + return Domains.from_data({'default': 'app', + 'build_dir': path, + 'domains': [{'name': 'app', 'build_dir': path}]}) + + return Domains.from_file(domains_file) diff --git a/scripts/west_commands/domains.py b/scripts/west_commands/domains.py new file mode 100644 index 0000000000000..9301c761f7210 --- /dev/null +++ b/scripts/west_commands/domains.py @@ -0,0 +1,139 @@ +# Copyright (c) 2022 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +'''Domain handling for west extension commands. + +This provides parsing of domains yaml file and creation of objects of the +Domain class. +''' + +import yaml +import pykwalify.core +from west import log + +DOMAINS_SCHEMA = ''' +## A pykwalify schema for basic validation of the structure of a +## domains YAML file. +## +# The domains.yaml file is a simple list of domains from a multi image build +# along with the default domain to use. +type: map +mapping: + default: + required: true + type: str + build_dir: + required: true + type: str + domains: + required: false + type: seq + sequence: + - type: map + mapping: + name: + required: true + type: str + build_dir: + required: true + type: str +''' + +schema = yaml.safe_load(DOMAINS_SCHEMA) + + +class Domains: + + def __init__(self, data): + self._domains = [] + self._domain_names = [] + self._domain_default = [] + + self._build_dir = data.get('build_dir') + domain_list = data.get('domains') + if not domain_list: + log.wrn("no domains defined; this probably won't work") + + for d in domain_list: + domain = Domain(d['name'], d['build_dir']) + self._domains.append(domain) + self._domain_names.append(domain.name) + if domain.name == data['default']: + self._default_domain = domain + + @staticmethod + def from_file(domains_file): + '''Load domains from domains.yaml. + + Exception raised: + - ``FileNotFoundError`` if the domains file is not found. + ''' + try: + with open(domains_file, 'r') as f: + domains = yaml.safe_load(f.read()) + except FileNotFoundError: + log.die(f'domains.yaml file not found: {domains_file}') + + try: + pykwalify.core.Core(source_data=domains, schema_data=schema)\ + .validate() + except pykwalify.errors.SchemaError: + log.die(f'ERROR: Malformed yaml in file: {domains_file}') + + return Domains(domains) + + @staticmethod + def from_data(domains_data): + '''Load domains from domains dictionary. + ''' + return Domains(domains_data) + + def get_domains(self, names=None): + ret = [] + + if not names: + return self._domains + + for n in names: + found = False + for d in self._domains: + if n == d.name: + ret.append(d) + found = True + break + # Getting here means the domain was not found. + # Todo: throw an error. + if not found: + log.die(f'domain {n} not found, ' + f'valid domains are:', *self._domain_names) + return ret + + def get_default_domain(self): + return self._default_domain + + def get_top_build_dir(self): + return self._build_dir + + +class Domain: + + def __init__(self, name, build_dir): + self.name = name + self.build_dir = build_dir + + @property + def name(self): + return self._name + + @name.setter + def name(self, value): + self._name = value + + @property + def build_dir(self): + return self._build_dir + + @build_dir.setter + def build_dir(self, value): + self._build_dir = value diff --git a/scripts/west_commands/flash.py b/scripts/west_commands/flash.py index 321ba24bacd8e..073a1ab2a2838 100644 --- a/scripts/west_commands/flash.py +++ b/scripts/west_commands/flash.py @@ -8,7 +8,8 @@ from west.commands import WestCommand -from run_common import add_parser_common, do_run_common +from run_common import add_parser_common, do_run_common, get_build_dir +from build_helpers import load_domains class Flash(WestCommand): @@ -26,4 +27,6 @@ def do_add_parser(self, parser_adder): return add_parser_common(self, parser_adder) def do_run(self, my_args, runner_args): - do_run_common(self, my_args, runner_args) + build_dir = get_build_dir(my_args) + domains = load_domains(build_dir).get_domains(my_args.domain) + do_run_common(self, my_args, runner_args, domains=domains) diff --git a/scripts/west_commands/run_common.py b/scripts/west_commands/run_common.py index 84d3f0a208f72..2cde9e4c31846 100644 --- a/scripts/west_commands/run_common.py +++ b/scripts/west_commands/run_common.py @@ -16,7 +16,7 @@ import traceback from west import log -from build_helpers import find_build_dir, is_zephyr_build, \ +from build_helpers import find_build_dir, is_zephyr_build, load_domains, \ FIND_BUILD_DIR_DESCRIPTION from west.commands import CommandError from west.configuration import config @@ -104,6 +104,8 @@ def add_parser_common(command, parser_adder=None, parser=None): help='override default runner from --build-dir') group.add_argument('--skip-rebuild', action='store_true', help='do not refresh cmake dependencies first') + group.add_argument('--domain', action='append', + help='execute runner only for given domain') group = parser.add_argument_group( 'runner configuration', @@ -145,7 +147,7 @@ def add_parser_common(command, parser_adder=None, parser=None): return parser -def do_run_common(command, user_args, user_runner_args): +def do_run_common(command, user_args, user_runner_args, domains=None): # This is the main routine for all the "west flash", "west debug", # etc. commands. @@ -153,13 +155,30 @@ def do_run_common(command, user_args, user_runner_args): dump_context(command, user_args, user_runner_args) return - command_name = command.name build_dir = get_build_dir(user_args) - cache = load_cmake_cache(build_dir, user_args) - board = cache['CACHED_BOARD'] if not user_args.skip_rebuild: rebuild(command, build_dir, user_args) + if domains is None: + if user_args.domain is None: + # No domains are passed down and no domains specified by the user. + # So default domain will be used. + domains = [load_domains(build_dir).get_default_domain()] + else: + # No domains are passed down, but user has specified domains to use. + # Get the user specified domains. + domains = load_domains(build_dir).get_domains(user_args.domain) + + for d in domains: + do_run_common_image(command, user_args, user_runner_args, d.build_dir) + +def do_run_common_image(command, user_args, user_runner_args, build_dir=None): + command_name = command.name + if build_dir is None: + build_dir = get_build_dir(user_args) + cache = load_cmake_cache(build_dir, user_args) + board = cache['CACHED_BOARD'] + # Load runners.yaml. yaml_path = runners_yaml_path(build_dir, board) runners_yaml = load_runners_yaml(yaml_path) @@ -173,7 +192,9 @@ def do_run_common(command, user_args, user_runner_args): # Set up runner logging to delegate to west.log commands. logger = logging.getLogger('runners') logger.setLevel(LOG_LEVEL) - logger.addHandler(WestLogHandler()) + if not logger.hasHandlers(): + # Only add a runners log handler if none has been added already. + logger.addHandler(WestLogHandler()) # If the user passed -- to force the parent argument parser to stop # parsing, it will show up here, and needs to be filtered out. From 70e05e2d2a379ba71d24430382a183706c865142 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 22 Nov 2021 13:52:15 +0100 Subject: [PATCH 9/9] cmake: sysbuild: signing support This commit introduces image signing by adding the possibility to specify algorithm and signing key for sysbuild images. It introduces Kconfig setting to specify signing algorithm and key file. It will default the signing key to the default key provided by MCUBoot if no key has been specified. When signing is enabling, the signature key will be passed to the application so the build system can sign the image as post build step. Signed-off-by: Torsten Rasmussen --- share/sysbuild/CMakeLists.txt | 25 ++++++++++++++++++++ share/sysbuild/bootloader/Kconfig | 38 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index 289fba0cade67..8b1042b48072f 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -30,6 +30,31 @@ set(IMAGES) get_filename_component(APP_DIR ${APP_DIR} ABSOLUTE) get_filename_component(app_name ${APP_DIR} NAME) +# Propagate bootloader and signing settings from this system to the MCUboot and +# application image build systems. +if(SB_CONFIG_BOOTLOADER_MCUBOOT) + set(${app_name}_CONFIG_BOOTLOADER_MCUBOOT y CACHE STRING + "MCUBOOT is enabled as bootloader" FORCE + ) + set(${app_name}_CONFIG_MCUBOOT_SIGNATURE_KEY_FILE + \"${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}\" CACHE STRING + "Signature key file for signing" FORCE + ) + + # Set corresponding values in mcuboot + set(mcuboot_CONFIG_BOOT_SIGNATURE_TYPE_${SB_CONFIG_SIGNATURE_TYPE} y CACHE STRING + "MCUBOOT signature type" FORCE + ) + set(mcuboot_CONFIG_BOOT_SIGNATURE_KEY_FILE + \"${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}\" CACHE STRING + "Signature key file for signing" FORCE + ) +else() + set(${app_name}_CONFIG_BOOTLOADER_MCUBOOT n CACHE STRING + "MCUBOOT is disabled as bootloader" FORCE + ) +endif() + # This adds the primary application to the build. ExternalZephyrProject_Add( APPLICATION ${app_name} diff --git a/share/sysbuild/bootloader/Kconfig b/share/sysbuild/bootloader/Kconfig index 6c70a6e9594a0..833e9e76469c4 100644 --- a/share/sysbuild/bootloader/Kconfig +++ b/share/sysbuild/bootloader/Kconfig @@ -27,3 +27,41 @@ config BOOTLOADER_MCUBOOT Include MCUboot (Zephyr port) as the bootloader to use endchoice + +if BOOTLOADER_MCUBOOT + +config SIGNATURE_TYPE + string + default NONE if BOOT_SIGNATURE_TYPE_NONE + default RSA if BOOT_SIGNATURE_TYPE_RSA + default ECDSA_P256 if BOOT_SIGNATURE_TYPE_ECDSA_P256 + default ED25519 if BOOT_SIGNATURE_TYPE_ED25519 + +choice + prompt "Signature type" + default BOOT_SIGNATURE_TYPE_RSA + +config BOOT_SIGNATURE_TYPE_NONE + bool "No signature; use only hash check" + +config BOOT_SIGNATURE_TYPE_RSA + bool "RSA signatures" + +config BOOT_SIGNATURE_TYPE_ECDSA_P256 + bool "Elliptic curve digital signatures with curve P-256" + +config BOOT_SIGNATURE_TYPE_ED25519 + bool "Edwards curve digital signatures using ed25519" + +endchoice + +config BOOT_SIGNATURE_KEY_FILE + string "PEM key file" + default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 + default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-ed25519.pem" if BOOT_SIGNATURE_TYPE_ED25519 + default "$(ZEPHYR_MCUBOOT_MODULE_DIR)/root-rsa-2048.pem" if BOOT_SIGNATURE_TYPE_RSA + default "" + help + Absolute path to key file to use with MCUBoot. + +endif