From 18bfcecd6b4de667a7acd36fc654b6f1f0c988ba Mon Sep 17 00:00:00 2001 From: Lealem Amedie Date: Wed, 7 Dec 2022 09:33:22 -0800 Subject: [PATCH] wolfBoot cmake support --- .gitignore | 7 +- CMakeLists.txt | 743 +++++++++++++++++++++++++ Makefile | 31 +- README.md | 152 +++++ cmake/functions.cmake | 57 ++ cmake/toolchain_aarch64-none-elf.cmake | 114 ++++ cmake/toolchain_arm-none-eabi.cmake | 123 ++++ cmake/utils.cmake | 74 +++ cmake/wolfboot.cmake | 121 ++++ config/examples/sim.config | 2 +- hal/cc26x2.ld | 4 +- hal/hifive1.ld | 2 +- hal/imx_rt.ld | 4 +- hal/kinetis.ld | 4 +- hal/lpc.ld | 4 +- hal/nrf52.ld | 4 +- hal/psoc6.ld | 2 +- hal/samr21.ld | 4 +- hal/stm32f4.ld | 7 +- hal/stm32f7.ld | 4 +- hal/stm32g0.ld | 2 +- hal/stm32h7.c | 7 +- hal/stm32h7.ld | 7 +- hal/stm32l0.ld | 7 +- hal/stm32l0_chacha_ram.ld | 2 +- hal/stm32l4.ld | 2 +- hal/stm32l5.ld | 4 +- hal/stm32u5.ld | 4 +- hal/stm32wb.ld | 2 +- hal/t2080.ld | 2 +- hal/ti_hercules.ld | 2 +- include/hal.h | 13 + include/image.h | 9 + include/loader.h | 11 +- include/target.h.in | 41 +- include/wolfboot/wolfboot.h | 8 + lib/CMakeLists.txt | 198 +++++++ test-app/ARM-psoc6.ld | 2 +- test-app/ARM-r5be.ld | 2 +- test-app/ARM-stm32f7.ld | 2 +- test-app/ARM-stm32h7.ld | 7 +- test-app/ARM-stm32l5-ns.ld | 2 +- test-app/ARM-stm32l5.ld | 2 +- test-app/ARM-stm32u5-ns.ld | 2 +- test-app/ARM-stm32u5.ld | 2 +- test-app/ARM.ld | 7 +- test-app/CMakeLists.txt | 125 +++++ test-app/Makefile | 8 +- test-app/PPC.ld | 2 +- test-app/RISCV.ld | 2 +- test-app/imx_rt.ld | 2 +- tools/keytools/Makefile | 18 +- tools/keytools/keygen.c | 15 +- tools/keytools/keygen.py | 12 +- 54 files changed, 1907 insertions(+), 89 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 cmake/functions.cmake create mode 100644 cmake/toolchain_aarch64-none-elf.cmake create mode 100644 cmake/toolchain_arm-none-eabi.cmake create mode 100644 cmake/utils.cmake create mode 100644 cmake/wolfboot.cmake create mode 100644 lib/CMakeLists.txt create mode 100644 test-app/CMakeLists.txt diff --git a/.gitignore b/.gitignore index a8a2eba8..7758f82f 100644 --- a/.gitignore +++ b/.gitignore @@ -113,4 +113,9 @@ IDE/IAR/Debug IDE/IAR/Release # Simulated Flash files -*.dd \ No newline at end of file +*.dd + +# CMake +build/ +CMakeFiles/ +CMakeCache.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..fcf8f78d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,743 @@ +# CMakeLists.txt +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA +# +# Usage: +# When building with CMake, you'll have to specify build parameters normally +# located in the .config file +# +# $ mkdir build +# $ cd build +# $ cmake -DWOLFBOOT_TARGET= -DWOLFBOOT_PARTITION_BOOT_ADDRESS= +# -DWOLFBOOT_PARTITION_SIZE= -DWOLFBOOT_PARTITION_UPDATE_ADDRESS= +# -DWOLFBOOT_PARTITION_SWAP_ADDRESS= -DBUILD_TEST_APPS=yes .. +# $ cmake --build . + +cmake_minimum_required(VERSION 3.16) + +if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + message(FATAL_ERROR "In-source builds are not allowed.\ + Run cmake from a separate directory from where CMakeLists.txt lives.\ + NOTE: cmake will now create CMakeCache.txt and CMakeFiles/*.\ + You must delete them, or cmake will refuse to work.") +endif() + + +project(wolfBoot) + +include(cmake/utils.cmake) +include(cmake/functions.cmake) + + +if(NOT DEFINED WOLFBOOT_TARGET) + message(FATAL_ERROR "WOLFBOOT_TARGET must be defined") +else() + message(STATUS "Building for ${WOLFBOOT_TARGET}") +endif() + +if(NOT DEFINED WOLFBOOT_PARTITION_SIZE) + message(FATAL_ERROR "WOLFBOOT_PARTITION_SIZE must be defined") +endif() + +if(NOT DEFINED WOLFBOOT_SECTOR_SIZE) + message(FATAL_ERROR "WOLFBOOT_SECTOR_SIZE must be defined") +endif() + +if(NOT DEFINED WOLFBOOT_PARTITION_BOOT_ADDRESS) + message(FATAL_ERROR "WOLFBOOT_PARTITION_BOOT_ADDRESS must be defined") +endif() + +if(NOT DEFINED WOLFBOOT_PARTITION_UPDATE_ADDRESS) + message(FATAL_ERROR "WOLFBOOT_PARTITION_UPDATE_ADDRESS must be defined") +endif() + +if(NOT DEFINED WOLFBOOT_PARTITION_SWAP_ADDRESS) + message(FATAL_ERROR "WOLFBOOT_PARTITION_SWAP_ADDRESS must be defined") +endif() + + +if(NOT DEFINED ARM_TARGETS) + list(APPEND ARM_TARGETS stm32h7 stm32l0 stm32f4 stm32u5) + set(ARM_TARGETS + "${ARM_TARGETS}" + CACHE INTERNAL "") +endif() + +# check if WOLFBOOT_TARGET is a cache variable +if(NOT DEFINED CACHE{WOLFBOOT_TARGET}) + set(WOLFBOOT_TARGET + "${WOLFBOOT_TARGET}" + CACHE INTERNAL "Target platform") +endif() + +if(${WOLFBOOT_TARGET} IN_LIST ARM_TARGETS) + set(ARCH ARM) +elseif(WOLFBOOT_TARGET STREQUAL "x86_64_efi") + set(ARCH x86_64) +elseif(WOLFBOOT_TARGET STREQUAL "sim") + set(ARCH sim) +else() + message(FATAL_ERROR "Unable to configure ARCH for target ${WOLFBOOT_TARGET}") +endif() + +add_option("ALLOW_DOWNGRADE" "Allow downgrading firmware (default: disabled)" "no" "yes;no") +add_option("DELTA_UPDATES" "Allow incremental updates (default: disabled)" "no" "yes;no") +add_option( + "DISABLE_BACKUP" + "Disable backup copy of running firmware upon update installation (default: disabled)" "no" + "yes;no") +add_option("ENCRYPT" "Encrypt external flash (default: disabled)" "no" "yes;no") +add_option("ENCRYPT_WITH_AES128" "Encrypt external flash with AES128 (default: disabled)" "no" + "yes;no") +add_option("ENCRYPT_WITH_AES256" "Encrypt external flash with AES256 (default: disabled)" "no" + "yes;no") +add_option("ENCRYPT_WITH_CHACHA" "Encrypt external flash with CHACHA (default: disabled)" "no" + "yes;no") +add_option("EXT_FLASH" "Enable optional support for external flash memory (default: disabled)" "no" + "yes;no") +add_option( + "FLAGS_HOME" + "Store UPDATE partition flags in a sector in the BOOT partition (default: disabled)" "no" + "yes;no") +add_option("HASH" "Set the hash algorithm (default: SHA256)" "SHA256" "SHA3;SHA256;SHA384") +add_option("NO_ASM" "Don't use algorithms implemented in assembly code (default: disabled)" "no" + "yes;no") +add_option("NO_MPU" "Disable MPU code (default: disabled)" "no" "yes;no") +add_option("NO_XIP" "Disable execute-in-place (default: disabled)" "no" "yes;no") +add_option( + "NVM_FLASH_WRITEONCE" + "Enable the workaround for 'write once' internal flash (default: disabled)" "no" "yes;no") +add_option( + "RAM_CODE" + "Move all code accessing internal flash for writing into a section in RAM (default: disabled)" + "no" "yes;no") +add_option("SIGN" "Configure Digital Signatures Algorithm (default: ECC256)" "ECC256" + "ECC256;ECC384;ECC521;ED25519;ED448;NONE;RSA2048;RSA4096") +add_option("SPI_FLASH" "Use external SPI flash drivers (default: disabled)" "no" "yes;no") +add_option("SPMATH" "Use SP Math (default: disabled)" "no" "yes;no") +add_option("WOLFBOOT_TARGET" "Target platform to build for (default: stm32h7)" "stm32h7" + "stm32f4;stm32h7;stm32l0;stm32u5;x86_64_efi;sim") +add_option("UART_FLASH" "Use external UART flash drivers (default: disabled)" "no" "yes;no") +add_option( + "WOLFBOOT_SMALL_STACK" + "Use a fixed-size memory pool created at compile time for cryptography implementation (default: disabled)" + "no" + "yes;no") +add_option("BUILD_TEST_APPS" "Build the wolfBoot test apps (default: disabled)" "no" "yes;no") +add_option("PYTHON_KEYTOOLS" "Use wolfCrypt-py for key generation and signing (default: disabled)" "no" "yes;no") + +# unset cache variables Variables that need to be accessed by the gen_wolfboot_platform_target cmake +# function called from the parent cmake project are added to the cache so that they can be accessed +# anywhere in the project +unset(WOLFBOOT_DEFS CACHE) +unset(WOLFBOOT_SOURCES CACHE) +unset(WOLFBOOT_INCLUDE_DIRS CACHE) +unset(WOLFBOOT_COMPILE_OPTIONS CACHE) +unset(WOLFBOOT_LINK_OPTIONS CACHE) +unset(WOLFBOOT_PLATFORM_LD_SCRIPT CACHE) +unset(WOLFBOOT_SIGNING_PRIVATE_KEY CACHE) +unset(SIM_COMPILE_OPTIONS CACHE) +unset(SIGN_TOOL CACHE) +unset(SIGN_OPTIONS CACHE) +unset(KEYTOOL_OPTIONS CACHE) +unset(BINASSEMBLE CACHE) +unset(ARCH_FLASH_OFFSET CACHE) +unset(WOLFBOOT_VERSION CACHE) + +set(WOLFBOOT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) +list(APPEND WOLFBOOT_DEFS __WOLFBOOT) + +set(WOLFBOOT_SOURCES include/loader.h include/image.h src/string.c src/image.c) + +list(APPEND WOLFBOOT_SOURCES src/loader.c) + +# build bin-assemble tool +set(BINASSEMBLE ${CMAKE_CURRENT_BINARY_DIR}/bin-assemble) +add_custom_command( + OUTPUT ${BINASSEMBLE} + COMMAND gcc tools/bin-assemble/bin-assemble.c -o ${BINASSEMBLE} + WORKING_DIRECTORY ${WOLFBOOT_ROOT} + COMMENT "Generating bin-assemble tool") + +add_custom_target(binAssemble DEPENDS ${BINASSEMBLE}) + +# ----------------------------------------------------------------------------- +# Toolchain Specifications +# ----------------------------------------------------------------------------- + +if(ARCH STREQUAL "ARM") + include(cmake/toolchain_arm-none-eabi.cmake) +elseif(ARCH STREQUAL "AARCH64") + include(cmake/toolchain_aarch64-none-elf.cmake) +endif() + +# ----------------------------------------------------------------------------- +# Architecture/CPU configuration +# ----------------------------------------------------------------------------- +set(UPDATE_SOURCES src/update_flash.c) + +# Default flash offset +if(NOT DEFINED ARCH_FLASH_OFFSET) + set(ARCH_FLASH_OFFSET 0x0) +endif() + +if(ARCH STREQUAL "x86_64") + list(APPEND WOLFBOOT_SOURCES src/boot_x86_64.c) + if(DEBUG) + add_compile_definitions(WOLFBOOT_DEBUG_EFI=1) + endif() +endif() + +if(ARCH STREQUAL "ARM") + list(APPEND WOLFBOOT_SOURCES src/boot_arm.c) + list(APPEND WOLFBOOT_DEFS ARCH_ARM) + list(APPEND WOLFBOOT_COMPILE_OPTIONS -ffreestanding -nostartfiles -fomit-frame-pointer) + list(APPEND WOLFBOOT_LINK_OPTIONS -ffreestanding -nostartfiles -fomit-frame-pointer) + + if(${WOLFBOOT_TARGET} STREQUAL "stm32l0") + set(FLAGS_INVERT ON) + endif() + + if(${WOLFBOOT_TARGET} STREQUAL "stm32f4") + set(ARCH_FLASH_OFFSET 0x08000000) + set(WOLFBOOT_ORIGIN ${ARCH_FLASH_OFFSET}) + endif() + + if(${WOLFBOOT_TARGET} STREQUAL "stm32u5") + set(ARCH_FLASH_OFFSET 0x08000000) + set(WOLFBOOT_ORIGIN ${ARCH_FLASH_OFFSET}) + endif() + + if(${WOLFBOOT_TARGET} STREQUAL "stm32h7") + set(ARCH_FLASH_OFFSET 0x08000000) + set(WOLFBOOT_ORIGIN ${ARCH_FLASH_OFFSET}) + endif() +endif() + +if(ARCH STREQUAL "AARCH64") + list(APPEND WOLFBOOT_SOURCES src/boot_aarch64.c src/boot_aarch64_start.c src/update_ram.c) + list(APPEND WOLFBOOT_DEFS ARCH_AARCH64 NO_QNX WOLFBOOT_DUALBOOT MMU) + + if(SPMATH) + list(APPEND WOLFBOOT_SOURCES lib/wolfssl/wolfcrypt/src/sp_c32.c) + endif() + +endif() + + +list(APPEND WOLFBOOT_DEFS ARCH_FLASH_OFFSET=${ARCH_FLASH_OFFSET}) + +if(${WOLFBOOT_TARGET} STREQUAL "x86_64_efi") + if(NOT DEFINED GNU_EFI_LIB_PATH) + set(GNU_EFI_LIB_PATH /usr/lib) + endif() + + set(GNU_EFI_CRT0 "${GNU_EFI_LIB_PATH}/crt0-efi-x86_64.c") + set(GNU_EFI_LSCRIPT "${GNU_EFI_LIB_PATH}/elf_x86_64_efi.lds") + include_directories("/usr/include/efi" "/usr/include/efi/x86_64") + add_compile_definitions("PLATFORM_X86_64_EFI") + set(CMAKE_EXE_LINKER_FLAGS "-shared -Bsymbolic -L/usr/lib -T${GNU_EFI_LSCRIPT}") + set(LD_START_GROUP ${GNU_EFI_CRT0}) + set(LD_END_GROUP "-lgnuefi -lefi") + set(UPDATE_SOURCES src/update_ram.c) +endif() + +# ----------------------------------------------------------------------------- +# DSA Settings +# ----------------------------------------------------------------------------- +if(SIGN STREQUAL "NONE") + list(APPEND KEYTOOL_OPTIONS --no-sign) + message(STATUS "Image signing disabled") + set(WOLFBOOT_SIGNING_PRIVATE_KEY + "" + CACHE INTERNAL "") + set(STACK_USAGE 1216) + list(APPEND SIGN_OPTIONS WOLFBOOT_NO_SIGN) +else() + set(WOLFBOOT_SIGNING_PRIVATE_KEY ${CMAKE_CURRENT_BINARY_DIR}/wolfboot_signing_private_key.der) +endif() + +if(NOT DEFINED IMAGE_HEADER_SIZE) + set(IMAGE_HEADER_SIZE 256) +endif() + +if(WOLFBOOT_SMALL_STACK) + list(APPEND USER_SETTINGS WOLFBOOT_SMALL_STACK) + list(APPEND WOLFBOOT_DEFS XMALLOC_USER) + set(STACK_USAGE 4096) + list(APPEND WOLFBOOT_SOURCES src/xmalloc.c) +endif() + +if(SIGN STREQUAL "ECC256") + message(STATUS "Signing image using ${SIGN}") + set(DSA ecc256) + list(APPEND KEYTOOL_OPTIONS --ecc256) + + list(APPEND SIGN_OPTIONS WOLFBOOT_SIGN_ECC256) + + if(WOLFBOOT_SMALL_STACK) + set(STACK_USAGE 4096) + elseif(NOT SPMATH) + set(STACK_USAGE 5008) + else() + set(STACK_USAGE 3952) + endif() + + if(${IMAGE_HEADER_SIZE} LESS 256) + set(IMAGE_HEADER_SIZE 256) + endif() +endif() + +if(SIGN STREQUAL "ECC384") + message(STATUS "Signing image using ${SIGN}") + set(DSA ecc384) + list(APPEND KEYTOOL_OPTIONS --ecc384) + list(APPEND SIGN_OPTIONS WOLFBOOT_SIGN_ECC384) + + if(WOLFBOOT_SMALL_STACK) + set(STACK_USAGE 5880) + elseif(NOT SPMATH) + set(STACK_USAGE 11248) + else() + set(STACK_USAGE 5880) + endif() + + if(${IMAGE_HEADER_SIZE} LESS 512) + set(IMAGE_HEADER_SIZE 512) + endif() +endif() + +if(SIGN STREQUAL "ECC521") + message(STATUS "Signing image using ${SIGN}") + set(DSA ecc521) + list(APPEND KEYTOOL_OPTIONS --ecc521) + list(APPEND SIGN_OPTIONS WOLFBOOT_SIGN_ECC521) + + if(WOLFBOOT_SMALL_STACK) + set(STACK_USAGE 4096) + elseif(NOT SPMATH) + set(STACK_USAGE 7352) + else() + set(STACK_USAGE 3896) + endif() + + if(${IMAGE_HEADER_SIZE} LESS 512) + set(IMAGE_HEADER_SIZE 512) + endif() +endif() + +if(SIGN STREQUAL "ED25519") + message(STATUS "Signing image using ${SIGN}") + set(DSA ed25519) + list(APPEND KEYTOOL_OPTIONS --ed25519) + list(APPEND SIGN_OPTIONS WOLFBOOT_SIGN_ED25519) + + if(NOT DEFINED STACK_USAGE) + set(STACK_USAGE 1180) + endif() + + if(${IMAGE_HEADER_SIZE} LESS 256) + set(IMAGE_HEADER_SIZE 256) + endif() +endif() + +if(SIGN STREQUAL "ED448") + message(STATUS "Signing image using ${SIGN}") + set(DSA ed448) + list(APPEND KEYTOOL_OPTIONS --ed448) + + if(WOLFBOOT_SMALL_STACK) + if(NOT DEFINED STACK_USAGE) + set(STACK_USAGE 1024) + endif() + else() + if(NOT DEFINED STACK_USAGE) + set(STACK_USAGE 4376) + endif() + endif() + + list(APPEND SIGN_OPTIONS WOLFBOOT_SIGN_ED448) + + if(${IMAGE_HEADER_SIZE} LESS 512) + set(IMAGE_HEADER_SIZE 512) + endif() +endif() + +if(SIGN STREQUAL "RSA2048") + message(STATUS "Signing image using ${SIGN}") + set(DSA rsa2048) + list(APPEND KEYTOOL_OPTIONS --rsa2048) + list(APPEND SIGN_OPTIONS WOLFBOOT_SIGN_RSA2048 ${RSA_EXTRA_CFLAGS}) + + if(WOLFBOOT_SMALL_STACK) + if(NOT SPMATH) + set(STACK_USAGE 5008) + else() + set(STACK_USAGE 4096) + endif() + elseif(NOT SPMATH) + set(STACK_USAGE 35952) + else() + set(STACK_USAGE 12288) + endif() + + if(${IMAGE_HEADER_SIZE} LESS 512) + set(IMAGE_HEADER_SIZE 512) + endif() +endif() + +if(SIGN STREQUAL "RSA4096") + message(STATUS "Signing image using ${SIGN}") + set(DSA rsa4096) + list(APPEND KEYTOOL_OPTIONS --rsa4096) + list(APPEND SIGN_OPTIONS WOLFBOOT_SIGN_RSA4096 ${RSA_EXTRA_CFLAGS}) + + if(WOLFBOOT_SMALL_STACK) + if(NOT SPMATH) + set(STACK_USAGE 5888) + else() + set(STACK_USAGE 4096) + endif() + elseif(NOT SPMATH) + set(STACK_USAGE 69232) + else() + set(STACK_USAGE 18064) + endif() + + if(${IMAGE_HEADER_SIZE} LESS 1024) + set(IMAGE_HEADER_SIZE 1024) + endif() +endif() + +list(APPEND WOLFBOOT_DEFS IMAGE_HEADER_SIZE=${IMAGE_HEADER_SIZE}) + +# Append sign options to compile definitions +list(APPEND WOLFBOOT_DEFS ${SIGN_OPTIONS}) + +list(APPEND WOLFBOOT_COMPILE_OPTIONS -Wstack-usage=${STACK_USAGE} -Wno-unused) + +if(RAM_CODE) + list(APPEND WOLFBOOT_DEFS RAM_CODE) +endif() + +if(FLAGS_HOME) + list(APPEND WOLFBOOT_DEFS FLAGS_HOME=1) +endif() + +if(FLAGS_INVERT) + list(APPEND WOLFBOOT_DEFS WOLFBOOT_FLAGS_INVERT=1) +endif() + +if(SPI_FLASH) + set(EXT_FLASH ON) +endif() + +if(UART_FLASH) + set(EXT_FLASH ON) +endif() + +if(ENCRYPT) + list(APPEND USER_SETTINGS EXT_ENCRYPTED=1) + if(ENCRYPT_WITH_AES128) + list(APPEND WOLFBOOT_DEFS ENCRYPT_WITH_AES128) + elseif(ENCRYPT_WITH_AES256) + list(APPEND WOLFBOOT_DEFS ENCRYPT_WITH_AES256) + else() + set(ENCRYPT_WITH_CHACHA ON) + list(APPEND WOLFBOOT_DEFS ENCRYPT_WITH_CHACHA HAVE_CHACHA) + endif() +endif() + +if(EXT_FLASH) + list(APPEND WOLFBOOT_DEFS EXT_FLASH=1 PART_UPDATE_EXT=1 PART_SWAP_EXT=1) + if(NO_XIP) + list(APPEND WOLFBOOT_DEFS PART_BOOT_EXT=1) + endif() +endif() + +if(ALLOW_DOWNGRADE) + list(APPEND WOLFBOOT_DEFS ALLOW_DOWNGRADE) +endif() + +if(NVM_FLASH_WRITEONCE) + list(APPEND WOLFBOOT_DEFS NVM_FLASH_WRITEONCE) +endif() + +if(DISABLE_BACKUP) + list(APPEND WOLFBOOT_DEFS DISABLE_BACKUP) +endif() + +if(NO_MPU) + list(APPEND WOLFBOOT_DEFS WOLFBOOT_NO_MPU) +endif() + +if(NOT DEFINED WOLFBOOT_VERSION) + set(WOLFBOOT_VERSION 1) +endif() + list(APPEND WOLFBOOT_DEFS WOLFBOOT_VERSION=${WOLFBOOT_VERSION}) + +if(DELTA_UPDATES) + list(APPEND WOLFBOOT_SOURCES src/delta.c) + list(APPEND WOLFBOOT_DEFS DELTA_UPDATES) + if(NOT DEFINED DELTA_BLOCK_SIZE) + list(APPEND WOLFBOOT_DEFS DELTA_BLOCK_SIZE=${DELTA_BLOCK_SIZE}) + endif() +endif() + +if(ARMORED) + list(APPEND WOLFBOOT_DEFS WOLFBOOT_ARMORED) +endif() + +list(APPEND WOLFBOOT_SOURCES ${UPDATE_SOURCES}) + +list(TRANSFORM WOLFBOOT_SOURCES PREPEND ${WOLFBOOT_ROOT}/) + +# ----------------------------------------------------------------------------- +# Hash settings +# ----------------------------------------------------------------------------- +if(HASH STREQUAL "SHA256") + list(APPEND WOLFBOOT_DEFS WOLFBOOT_HASH_SHA256) + message(STATUS "Using SHA256 hash") +endif() + +if(HASH STREQUAL "SHA384") + list(APPEND WOLFBOOT_DEFS WOLFBOOT_HASH_SHA384) + list(APPEND KEYTOOL_OPTIONS --sha384) +endif() + +if(HASH STREQUAL "SHA3") + list(APPEND WOLFBOOT_DEFS WOLFBOOT_HASH_SHA3_384) + list(APPEND KEYTOOL_OPTIONS --sha3) +endif() + +# ----------------------------------------------------------------------------- +# wolfboot HAL +# ----------------------------------------------------------------------------- + +# Default SPI driver name +set(SPI_TARGET ${WOLFBOOT_TARGET}) + +# Default UART driver name +set(UART_TARGET ${WOLFBOOT_TARGET}) + +if(${WOLFBOOT_TARGET} STREQUAL "stm32l0") + set(SPI_TARGET stm32) +endif() + +if(${WOLFBOOT_TARGET} STREQUAL "stm32h7") + set(SPI_TARGET stm32) +endif() + +if(${WOLFBOOT_TARGET} STREQUAL "stm32u5") + set(SPI_TARGET stm32) +endif() + +if(${WOLFBOOT_TARGET} STREQUAL "stm32f4") + set(SPI_TARGET stm32) +endif() + +if(SPI_FLASH) + list(APPEND WOLFBOOT_DEFS SPI_FLASH) + list(APPEND WOLFBOOT_FLASH_SOURCES hal/spi/spi_drv_${SPI_TARGET}.c src/spi_flash.c) +endif() + +if(UART_FLASH) + list(APPEND WOLFBOOT_DEFS UART_FLASH) + list(APPEND WOLFBOOT_FLASH_SOURCES hal/uart/uart_drv_${UART_TARGET}.c src/uart_flash.c) +endif() + +if(FLAGS_HOME) + list(APPEND WOLFBOOT_DEFS FLAGS_HOME=1) +endif() + +list(APPEND WOLFBOOT_DEFS PLATFORM_${WOLFBOOT_TARGET}) + +if(NOT SPMATH) + list(APPEND USER_SETTINGS USE_FAST_MATH) +endif() + +add_library(user_settings INTERFACE) +target_compile_definitions(user_settings INTERFACE ${USER_SETTINGS} ${SIGN_OPTIONS}) + +add_library(wolfboothal) +target_sources(wolfboothal PRIVATE include/hal.h hal/${WOLFBOOT_TARGET}.c ${WOLFBOOT_FLASH_SOURCES} + ${PARTITION_SOURCE}) +target_link_libraries(wolfboothal target user_settings) +target_compile_definitions(wolfboothal PRIVATE ${WOLFBOOT_DEFS}) +target_include_directories(wolfboothal PRIVATE include) +target_compile_options(wolfboothal PRIVATE ${WOLFBOOT_COMPILE_OPTIONS} ${EXTRA_COMPILE_OPTIONS}) + +if(PYTHON_KEYTOOLS) + message(STATUS "Using Python Keytools") + set(SIGN_TOOL python3 ${WOLFBOOT_ROOT}/tools/keytools/sign.py) + set(KEYGEN_TOOL python3 ${WOLFBOOT_ROOT}/tools/keytools/keygen.py) +else() + message(STATUS "Using C Keytools") + set(SIGN_TOOL ${CMAKE_CURRENT_BINARY_DIR}/sign) + set(KEYGEN_TOOL ${CMAKE_CURRENT_BINARY_DIR}/keygen) +endif() + +list(APPEND WOLFBOOT_INCLUDE_DIRS ${WOLFBOOT_ROOT} ${WOLFBOOT_ROOT}/include) + +# set default linker script +set(WOLFBOOT_LSCRIPT_TEMPLATE hal/${WOLFBOOT_TARGET}.ld) + +# wolfcrypt +add_subdirectory(lib) + +if(BUILD_TEST_APPS) + # test applications + message(STATUS "Building wolfboot test apps") + add_subdirectory(test-app) +endif() + +set(WOLFBOOT_PLATFORM_LD_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/wolfboot_platform_${WOLFBOOT_TARGET}.ld) + +# add variables to cache so they have global scope +set(WOLFBOOT_DEFS + ${WOLFBOOT_DEFS} + CACHE INTERNAL "") +set(WOLFBOOT_SOURCES + ${WOLFBOOT_SOURCES} + CACHE INTERNAL "") +set(WOLFBOOT_COMPILE_OPTIONS + ${WOLFBOOT_COMPILE_OPTIONS} + CACHE INTERNAL "") +set(WOLFBOOT_LINK_OPTIONS + ${WOLFBOOT_LINK_OPTIONS} + CACHE INTERNAL "") +set(WOLFBOOT_INCLUDE_DIRS + ${WOLFBOOT_INCLUDE_DIRS} + CACHE INTERNAL "") +set(WOLFBOOT_COMPILE_OPTIONS + ${WOLFBOOT_COMPILE_OPTIONS} + CACHE INTERNAL "") +set(WOLFBOOT_PLATFORM_LD_SCRIPT + ${WOLFBOOT_PLATFORM_LD_SCRIPT} + CACHE INTERNAL "") +set(WOLFBOOT_SIGNING_PRIVATE_KEY + ${WOLFBOOT_SIGNING_PRIVATE_KEY} + CACHE INTERNAL "") +set(SIGN_TOOL + ${SIGN_TOOL} + CACHE INTERNAL "") +set(SIGN_OPTIONS + ${SIGN_OPTIONS} + CACHE INTERNAL "") +set(KEYTOOL_OPTIONS + ${KEYTOOL_OPTIONS} + CACHE INTERNAL "") +set(BINASSEMBLE + ${BINASSEMBLE} + CACHE INTERNAL "") +set(ARCH_FLASH_OFFSET + ${ARCH_FLASH_OFFSET} + CACHE INTERNAL "") +set(WOLFBOOT_VERSION + ${WOLFBOOT_VERSION} + CACHE INTERNAL "") + +# generate target.h +configure_file(include/target.h.in ${CMAKE_CURRENT_BINARY_DIR}/target.h @ONLY) + +add_library(target INTERFACE) +target_include_directories(target BEFORE INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) + + +set(KEYSTORE ${CMAKE_CURRENT_BINARY_DIR}/keystore.c) + +if(NOT SIGN STREQUAL "NONE") + if(NOT EXISTS ${KEYSTORE}) + + if(NOT PYTHON_KEYTOOLS) + list(APPEND KEYTOOL_SOURCES src/delta.c + lib/wolfssl/wolfcrypt/src/asn.c + lib/wolfssl/wolfcrypt/src/aes.c + lib/wolfssl/wolfcrypt/src/ecc.c + lib/wolfssl/wolfcrypt/src/coding.c + lib/wolfssl/wolfcrypt/src/chacha.c + lib/wolfssl/wolfcrypt/src/ed25519.c + lib/wolfssl/wolfcrypt/src/ed448.c + lib/wolfssl/wolfcrypt/src/fe_operations.c + lib/wolfssl/wolfcrypt/src/ge_operations.c + lib/wolfssl/wolfcrypt/src/fe_448.c + lib/wolfssl/wolfcrypt/src/ge_448.c + lib/wolfssl/wolfcrypt/src/hash.c + lib/wolfssl/wolfcrypt/src/logging.c + lib/wolfssl/wolfcrypt/src/memory.c + lib/wolfssl/wolfcrypt/src/random.c + lib/wolfssl/wolfcrypt/src/rsa.c + lib/wolfssl/wolfcrypt/src/sp_int.c + lib/wolfssl/wolfcrypt/src/sp_c32.c + lib/wolfssl/wolfcrypt/src/sp_c64.c + lib/wolfssl/wolfcrypt/src/sha3.c + lib/wolfssl/wolfcrypt/src/sha256.c + lib/wolfssl/wolfcrypt/src/sha512.c + lib/wolfssl/wolfcrypt/src/tfm.c + lib/wolfssl/wolfcrypt/src/wc_port.c + lib/wolfssl/wolfcrypt/src/wolfmath.c) + + list(APPEND KEYTOOL_FLAGS -Wall -Wextra -Werror -Itools/keytools -DWOLFSSL_USER_SETTINGS + -Ilib/wolfssl/ -Iinclude -I${CMAKE_CURRENT_BINARY_DIR} -DWOLFBOOT_KEYTOOLS -O2 -DIMAGE_HEADER_SIZE=256 -DDELTA_UPDATES) + + add_custom_command( + OUTPUT ${SIGN_TOOL} + COMMAND gcc -o ${CMAKE_CURRENT_BINARY_DIR}/sign tools/keytools/sign.c ${KEYTOOL_SOURCES} ${KEYTOOL_FLAGS} + WORKING_DIRECTORY ${WOLFBOOT_ROOT} + COMMENT "Building signing tool") + + add_custom_command( + OUTPUT ${KEYGEN_TOOL} + COMMAND gcc -o ${CMAKE_CURRENT_BINARY_DIR}/keygen tools/keytools/keygen.c ${KEYTOOL_SOURCES} ${KEYTOOL_FLAGS} + WORKING_DIRECTORY ${WOLFBOOT_ROOT} + COMMENT "Building keygen tool") + endif() + + add_custom_command( + OUTPUT ${KEYSTORE} + COMMAND ${KEYGEN_TOOL} ${KEYTOOL_OPTIONS} -g ${WOLFBOOT_SIGNING_PRIVATE_KEY} -keystoreDir ${CMAKE_CURRENT_BINARY_DIR} + WORKING_DIRECTORY ${WOLFBOOT_ROOT} + COMMENT "Generating keystore.c and signing private key") + + if(PYTHON_KEYTOOLS) + add_custom_target(keystore DEPENDS ${KEYSTORE}) + else() + add_custom_target(keystore ALL DEPENDS ${SIGN_TOOL} ${KEYGEN_TOOL} ${KEYSTORE}) + endif() + + endif() + + add_library(public_key) + target_sources(public_key PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/keystore.c) + target_compile_definitions(public_key PRIVATE ${WOLFBOOT_DEFS}) + target_include_directories(public_key PRIVATE include) + target_link_libraries(public_key target) +endif() + +# generate libwolfboot +add_library(wolfboot) +target_sources(wolfboot PRIVATE src/libwolfboot.c ${WOLFBOOT_FLASH_SOURCES}) +target_compile_definitions(wolfboot PUBLIC ${WOLFBOOT_DEFS}) +target_compile_options(wolfboot PUBLIC ${EXTRA_COMPILE_OPTIONS}) +target_include_directories(wolfboot PUBLIC ${WOLFBOOT_INCLUDE_DIRS}) +target_link_libraries(wolfboot wolfboothal target wolfcrypt) + +# dont warn on unused code +target_compile_options(wolfboot PRIVATE -Wno-unused ${SIM_COMPILE_OPTIONS}) + diff --git a/Makefile b/Makefile index b76c8368..bddba2d4 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,7 @@ ifeq ($(USE_GCC_HEADLESS),1) endif MAIN_TARGET=factory.bin +TARGET_H_TEMPLATE:=include/target.h.in ifeq ($(TARGET),stm32l5) # Don't build a contiguous image @@ -185,8 +186,12 @@ $(LSCRIPT): FORCE "custom linker script (i.e. $(TARGET)_chacha_ram.ld). Please read " \ "docs/encrypted_partitions.md for more information" && false) @cat $(LSCRIPT_IN) | \ - sed -e "s/##WOLFBOOT_PARTITION_BOOT_ADDRESS##/$(BOOTLOADER_PARTITION_SIZE)/g" | \ - sed -e "s/##WOLFBOOT_ORIGIN##/$(WOLFBOOT_ORIGIN)/g" \ + sed -e "s/@BOOTLOADER_PARTITION_SIZE@/$(BOOTLOADER_PARTITION_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_ORIGIN@/$(WOLFBOOT_ORIGIN)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_BOOT_ADDRESS@/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_SIZE@/$(WOLFBOOT_PARTITION_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_UPDATE_ADDRESS@/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_SWAP_ADDRESS@/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" \ > $@ hex: wolfboot.hex @@ -223,17 +228,17 @@ keysclean: clean distclean: clean keysclean utilsclean -include/target.h: include/target.h.in FORCE - @cat include/target.h.in | \ - sed -e "s/##WOLFBOOT_PARTITION_SIZE##/$(WOLFBOOT_PARTITION_SIZE)/g" | \ - sed -e "s/##WOLFBOOT_SECTOR_SIZE##/$(WOLFBOOT_SECTOR_SIZE)/g" | \ - sed -e "s/##WOLFBOOT_PARTITION_BOOT_ADDRESS##/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_PARTITION_UPDATE_ADDRESS##/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_PARTITION_SWAP_ADDRESS##/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_DTS_BOOT_ADDRESS##/$(WOLFBOOT_DTS_BOOT_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_DTS_UPDATE_ADDRESS##/$(WOLFBOOT_DTS_UPDATE_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_LOAD_ADDRESS##/$(WOLFBOOT_LOAD_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_LOAD_DTS_ADDRESS##/$(WOLFBOOT_LOAD_DTS_ADDRESS)/g" \ +include/target.h: $(TARGET_H_TEMPLATE) FORCE + @cat $(TARGET_H_TEMPLATE) | \ + sed -e "s/@WOLFBOOT_PARTITION_SIZE@/$(WOLFBOOT_PARTITION_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_SECTOR_SIZE@/$(WOLFBOOT_SECTOR_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_BOOT_ADDRESS@/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_UPDATE_ADDRESS@/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_SWAP_ADDRESS@/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_DTS_BOOT_ADDRESS@/$(WOLFBOOT_DTS_BOOT_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_DTS_UPDATE_ADDRESS@/$(WOLFBOOT_DTS_UPDATE_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_LOAD_ADDRESS@/$(WOLFBOOT_LOAD_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_LOAD_DTS_ADDRESS@/$(WOLFBOOT_LOAD_DTS_ADDRESS)/g" \ > $@ delta: tools/delta/bmdiff diff --git a/README.md b/README.md index 53eb843f..ea9c99b8 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,158 @@ For more detailed information about firmware update implementation, see [Firmwar - [Remote external flash interface](docs/remote_flash.md) - [External encrypted partitions](docs/encrypted_partitions.md) +## Building + +### Makefile + +To build using the Makefile, create a `.config` file with your build specifications in the wolfBoot root directory. You can find a +number of examples that you can use inside [config/examples](config/examples). Then run `make keytools` to generate the signing +and key generation tools. If you have wolfCrypt-py installed and would like to use it, you can skip this step. + +For example, to build using our provided `stm32h7.config`: +``` +cp config/examples/stm32h7.config .config +make keytools +make +``` + +### CMake + +To build using CMake, create a `build` directory and run `cmake` with the target platform as well as values for the partition +size and address variables. To build the test-apps, run with `-DBUILD_TEST_APPS=yes`. To use the wolfCrypt-py keytools, run +with `-DPYTHON_KEYTOOLS=yes`. + +For example, to build for the stm32h7 platform: +``` +$ mkdir build +$ cd build +$ cmake -DWOLFBOOT_TARGET=stm32h7 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 .. +$ make +``` + +The output should look something like: +``` +Scanning dependencies of target keystore +[ 2%] Building signing tool +[ 4%] Building keygen tool +[ 7%] Generating keystore.c and signing private key +Keytype: ECC256 +Gen /home/user/wolfBoot/build/wolfboot_signing_private_key.der +Generating key (type: ECC256) +Associated key file: /home/user/wolfBoot/build/wolfboot_signing_private_key.der +Key type : ECC256 +Public key slot: 0 +Done. +[ 7%] Built target keystore +Scanning dependencies of target public_key +[ 9%] Building C object CMakeFiles/public_key.dir/keystore.c.o +[ 11%] Linking C static library libpublic_key.a +[ 14%] Built target public_key +Scanning dependencies of target wolfboothal +[ 16%] Building C object CMakeFiles/wolfboothal.dir/hal/stm32h7.c.o +[ 19%] Linking C static library libwolfboothal.a +[ 19%] Built target wolfboothal +Scanning dependencies of target wolfcrypt +[ 21%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/integer.c.o +[ 23%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/tfm.c.o +[ 26%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/ecc.c.o +[ 28%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/memory.c.o +[ 30%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/wc_port.c.o +[ 33%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/wolfmath.c.o +[ 35%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/hash.c.o +[ 38%] Building C object lib/CMakeFiles/wolfcrypt.dir/wolfssl/wolfcrypt/src/sha256.c.o +[ 40%] Linking C static library libwolfcrypt.a +[ 40%] Built target wolfcrypt +Scanning dependencies of target wolfboot +[ 42%] Building C object CMakeFiles/wolfboot.dir/src/libwolfboot.c.o +[ 45%] Linking C static library libwolfboot.a +[ 45%] Built target wolfboot +Scanning dependencies of target image +[ 47%] Building C object test-app/CMakeFiles/image.dir/app_stm32h7.c.o +[ 50%] Building C object test-app/CMakeFiles/image.dir/led.c.o +[ 52%] Building C object test-app/CMakeFiles/image.dir/system.c.o +[ 54%] Building C object test-app/CMakeFiles/image.dir/timer.c.o +[ 57%] Building C object test-app/CMakeFiles/image.dir/startup_arm.c.o +[ 59%] Linking C executable image +[ 59%] Built target image +Scanning dependencies of target image_signed +[ 61%] Generating image.bin +[ 64%] Signing image +wolfBoot KeyTools (Compiled C version) +wolfBoot version 10C0000 +Update type: Firmware +Input image: /home/user/wolfBoot/build/test-app/image.bin +Selected cipher: ECC256 +Selected hash : SHA256 +Public key: /home/user/wolfBoot/build/wolfboot_signing_private_key.der +Output image: /home/user/wolfBoot/build/test-app/image_v1_signed.bin +Target partition id : 1 +Calculating SHA256 digest... +Signing the digest... +Output image(s) successfully created. +[ 64%] Built target image_signed +Scanning dependencies of target image_outputs +[ 66%] Generating image.size + text data bss dec hex filename + 5284 108 44 5436 153c /home/user/wolfBoot/build/test-app/image +[ 69%] Built target image_outputs +Scanning dependencies of target wolfboot_stm32h7 +[ 71%] Building C object test-app/CMakeFiles/wolfboot_stm32h7.dir/__/src/string.c.o +[ 73%] Building C object test-app/CMakeFiles/wolfboot_stm32h7.dir/__/src/image.c.o +[ 76%] Building C object test-app/CMakeFiles/wolfboot_stm32h7.dir/__/src/loader.c.o +[ 78%] Building C object test-app/CMakeFiles/wolfboot_stm32h7.dir/__/src/boot_arm.c.o +[ 80%] Building C object test-app/CMakeFiles/wolfboot_stm32h7.dir/__/src/update_flash.c.o +[ 83%] Linking C executable wolfboot_stm32h7 +[ 83%] Built target wolfboot_stm32h7 +Scanning dependencies of target binAssemble +[ 85%] Generating bin-assemble tool +[ 85%] Built target binAssemble +Scanning dependencies of target image_boot +[ 88%] Generating wolfboot_stm32h7.bin +[ 90%] Signing image +wolfBoot KeyTools (Compiled C version) +wolfBoot version 10C0000 +Update type: Firmware +Input image: /home/user/wolfBoot/build/test-app/image.bin +Selected cipher: ECC256 +Selected hash : SHA256 +Public key: /home/user/wolfBoot/build/wolfboot_signing_private_key.der +Output image: /home/user/wolfBoot/build/test-app/image_v1_signed.bin +Target partition id : 1 +Calculating SHA256 digest... +Signing the digest... +Output image(s) successfully created. +[ 92%] Assembling image factory image +[ 95%] Built target image_boot +Scanning dependencies of target wolfboot_stm32h7_outputs +[ 97%] Generating wolfboot_stm32h7.size + text data bss dec hex filename + 42172 0 76 42248 a508 /home/user/wolfBoot/build/test-app/wolfboot_stm32h7 +[100%] Built target wolfboot_stm32h7_outputs +``` + +Signing and hashing algorithms can be specified with `-DSIGN=` and `-DHASH=`. To view additional +options to configuring wolfBoot, add `-LAH` to your cmake command, along with the partition specifications. +``` +$ cmake -DWOLFBOOT_TARGET=stm32h7 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8020000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_SIZE=0xD0000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80F0000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81C0000 -LAH .. +``` + +##### stm32f4 +``` +$ cmake -DWOLFBOOT_TARGET=stm32f4 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_SECTOR_SIZE=0x20000 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08020000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08040000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x08060000 .. +``` + +##### stm32u5 +``` +$ cmake -DWOLFBOOT_TARGET=stm32u5 -DBUILD_TEST_APPS=yes -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x08100000 -DWOLFBOOT_SECTOR_SIZE=0x2000 -DWOLFBOOT_PARTITION_SIZE=0x20000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x817F000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x81FE000 -DNO_MPU=yes .. +``` + +##### stm32l0 +``` +$ cmake -DWOLFBOOT_TARGET=stm32l0 -DWOLFBOOT_PARTITION_BOOT_ADDRESS=0x8000 -DWOLFBOOT_SECTOR_SIZE=0x1000 -DWOLFBOOT_PARTITION_SIZE=0x10000 -DWOLFBOOT_PARTITION_UPDATE_ADDRESS=0x18000 -DWOLFBOOT_PARTITION_SWAP_ADDRESS=0x28000 -DNVM_FLASH_WRITEONCE=yes .. +``` + + ## Troubleshooting 1. Python errors when signing a key: diff --git a/cmake/functions.cmake b/cmake/functions.cmake new file mode 100644 index 00000000..ce470749 --- /dev/null +++ b/cmake/functions.cmake @@ -0,0 +1,57 @@ +# functions.cmake +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +function(override_cache VAR VAL) + get_property(VAR_STRINGS CACHE ${VAR} PROPERTY STRINGS) + LIST(FIND VAR_STRINGS ${VAL} CK) + if(-1 EQUAL ${CK}) + message(SEND_ERROR + "\"${VAL}\" is not valid override value for \"${VAR}\"." + " Please select value from \"${VAR_STRINGS}\"\n") + endif() + set_property(CACHE ${VAR} PROPERTY VALUE ${VAL}) +endfunction() + +function(add_option NAME HELP_STRING DEFAULT VALUES) + # Set the default value for the option. + set(${NAME} ${DEFAULT} CACHE STRING ${HELP_STRING}) + # Set the list of allowed values for the option. + set_property(CACHE ${NAME} PROPERTY STRINGS ${VALUES}) + + if(DEFINED ${NAME}) + list(FIND VALUES ${${NAME}} IDX) + # + # If the given value isn't in the list of allowed values for the option, + # reduce it to yes/no according to CMake's "if" logic: + # https://cmake.org/cmake/help/latest/command/if.html#basic-expressions + # + # This has no functional impact; it just makes the settings in + # CMakeCache.txt and cmake-gui easier to read. + # + if (${IDX} EQUAL -1) + if(${${NAME}}) + override_cache(${NAME} "yes") + else() + override_cache(${NAME} "no") + endif() + endif() + endif() +endfunction() + diff --git a/cmake/toolchain_aarch64-none-elf.cmake b/cmake/toolchain_aarch64-none-elf.cmake new file mode 100644 index 00000000..3257c8a9 --- /dev/null +++ b/cmake/toolchain_aarch64-none-elf.cmake @@ -0,0 +1,114 @@ +# toolchain_aarch64-none-elf.cmake +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + + +set(CMAKE_SYSTEM_NAME Generic) + +# There needs to be a default platform or the `project()` command will fail. +if(NOT DEFINED WOLFBOOT_TARGET) + set(WOLFBOOT_TARGET "stm32h7") +endif() + +# MARCH flag +set(MARCH_FLAGS "-march=armv8-a") + +# ----------------------------------------------------------------------------- +# Set toolchain paths +# ----------------------------------------------------------------------------- +set(TOOLCHAIN aarch64-none-elf) +set(CMAKE_CXX_STANDARD 20) + +execute_process( + COMMAND which ${TOOLCHAIN}-gcc + OUTPUT_VARIABLE TOOLCHAIN_GCC_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + +# get toolchain version. CMAKE_C_COMPILER_VERSION cannot be used here since its not defined until +# `project()` is run in the top-level cmake. The toolchain has to be setup before the `project` call +execute_process( + COMMAND ${TOOLCHAIN}-gcc -dumpversion + OUTPUT_VARIABLE TOOLCHAIN_GCC_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + +get_filename_component(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_GCC_PATH} DIRECTORY) +get_filename_component(TOOLCHAIN_ROOT_DIR "${TOOLCHAIN_BIN_DIR}/../" DIRECTORY ABSOLUTE) +set(CMAKE_SYSROOT ${TOOLCHAIN_ROOT_DIR}/${TOOLCHAIN}) + + +# ----------------------------------------------------------------------------- +# Set compiler/linker flags +#----------------------------------------------------------------------------- +set(OBJECT_GEN_FLAGS + "${MARCH_FLAGS} -Wall -Wextra -Wno-main -ffreestanding -Wno-unused -ffunction-sections -fdata-sections" +) + +# NOTE: Use CMAKE_*_STANDARD instead of -std= +set(CMAKE_C_FLAGS "${OBJECT_GEN_FLAGS}" CACHE INTERNAL "C Compiler options") +set(CMAKE_ASM_FLAGS "${OBJECT_GEN_FLAGS}" CACHE INTERNAL "ASM Compiler options") +set(CMAKE_EXE_LINKER_FLAGS "${MCPU_FLAGS} ${LD_FLAGS} -Wl,--gc-sections --specs=nano.specs --specs=nosys.specs" CACHE INTERNAL "Linker options") + +#--------------------------------------------------------------------------------------- +# Set compilers and toolchain utilities +#--------------------------------------------------------------------------------------- +set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler") +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler") +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler") +set(TOOLCHAIN_LD ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-ld CACHE INTERNAL "Toolchain linker") +set(TOOLCHAIN_AR ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc-ar CACHE INTERNAL "Toolchain archive tool") +set(TOOLCHAIN_OBJCOPY ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-objcopy CACHE INTERNAL "Toolchain objcopy tool") +set(TOOLCHAIN_OBJDUMP ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-objdump CACHE INTERNAL "Toolchain objdump tool") +set(TOOLCHAIN_SIZE ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-size CACHE INTERNAL "Toolchain object size tool") + +set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_PREFIX}/${${TOOLCHAIN}} ${CMAKE_PREFIX_PATH}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +message(STATUS "Cross-compiling using GNU aarch64-none-elf toolchain") + +# Options for DEBUG build +# -Og Enables optimizations that do not interfere with debugging. +# -g Produce debugging information in the operating system’s native format. +set(CMAKE_C_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C Compiler options for debug build type") +set(CMAKE_CXX_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C++ Compiler options for debug build type") +set(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "ASM Compiler options for debug build type") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "Linker options for debug build type") + +# Options for RELEASE build +# -Os Optimize for size. -Os enables all -O2 optimizations. +# -DNDEBUG ensure assertions are disabled +set(CMAKE_C_FLAGS_RELEASE "-Os -g -DNDEBUG" CACHE INTERNAL "C Compiler options for release build type") +set(CMAKE_CXX_FLAGS_RELEASE "-Os -g -DNDEBUG" CACHE INTERNAL "C++ Compiler options for release build type") +set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "ASM Compiler options for release build type") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Linker options for release build type") + +# Options for RELWITHDEBINFO build +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g -DNDEBUG" CACHE INTERNAL "C Compiler options for release with debug symbols build type") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -g -DNDEBUG" CACHE INTERNAL "C++ Compiler options for release with debug symbols build type") +set(CMAKE_ASM_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "ASM Compiler options for release with debug symbols build type") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "Linker options for release with debug symbols build type") + +# Options for MINSIZEREL build +# -flto, -Wl,-flto Link Time Optimization. Allows size optimizations to occur across compilation units at link time +set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL "C Compiler options for minimum size release build type") +set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL "C++ Compiler options for minimum size release build type") +set(CMAKE_ASM_FLAGS_MINSIZEREL "" CACHE INTERNAL "ASM Compiler options for minimum size release build type") +set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-flto -Wl,-flto" CACHE INTERNAL "Linker options for minimum size release build type") diff --git a/cmake/toolchain_arm-none-eabi.cmake b/cmake/toolchain_arm-none-eabi.cmake new file mode 100644 index 00000000..10776545 --- /dev/null +++ b/cmake/toolchain_arm-none-eabi.cmake @@ -0,0 +1,123 @@ +# toolchain_arm-none-eabi.cmake +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + + +set(CMAKE_SYSTEM_NAME Generic) + +# There needs to be a default platform or the `project()` command will fail. +if(NOT DEFINED WOLFBOOT_TARGET) + set(WOLFBOOT_TARGET "stm32h7") +endif() + +# Cortex-M CPU +if(${WOLFBOOT_TARGET} STREQUAL "stm32l0") + set(CMAKE_SYSTEM_PROCESSOR cortex-m0) + set(MCPU_FLAGS "-mcpu=cortex-m0 -mthumb -mlittle-endian -mthumb-interwork ") +elseif(${WOLFBOOT_TARGET} STREQUAL "stm32u5") + set(CMAKE_SYSTEM_PROCESSOR cortex-m33) + set(MCPU_FLAGS "-mcpu=cortex-m33 -mthumb -mlittle-endian -mthumb-interwork -Ihal -DCORTEX_M33") +else() + set(CMAKE_SYSTEM_PROCESSOR cortex-m3) + set(MCPU_FLAGS "-mcpu=cortex-m3 -mthumb -mlittle-endian -mthumb-interwork ") +endif() + +# ----------------------------------------------------------------------------- +# Set toolchain paths +# ----------------------------------------------------------------------------- +set(TOOLCHAIN arm-none-eabi) +set(CMAKE_CXX_STANDARD 20) + +execute_process( + COMMAND which ${TOOLCHAIN}-gcc + OUTPUT_VARIABLE TOOLCHAIN_GCC_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + +# get toolchain version. CMAKE_C_COMPILER_VERSION cannot be used here since its not defined until +# `project()` is run in the top-level cmake. The toolchain has to be setup before the `project` call +execute_process( + COMMAND ${TOOLCHAIN}-gcc -dumpversion + OUTPUT_VARIABLE TOOLCHAIN_GCC_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + +get_filename_component(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_GCC_PATH} DIRECTORY) +get_filename_component(TOOLCHAIN_ROOT_DIR "${TOOLCHAIN_BIN_DIR}/../" DIRECTORY ABSOLUTE) +set(CMAKE_SYSROOT ${TOOLCHAIN_ROOT_DIR}/${TOOLCHAIN}) + + +# ----------------------------------------------------------------------------- +# Set compiler/linker flags +#----------------------------------------------------------------------------- +set(OBJECT_GEN_FLAGS + "${MCPU_FLAGS} -Wall -Wextra -Wno-main -ffreestanding -Wno-unused -ffunction-sections -fdata-sections" +) + +# NOTE: Use CMAKE_*_STANDARD instead of -std= +set(CMAKE_C_FLAGS "${OBJECT_GEN_FLAGS}" CACHE INTERNAL "C Compiler options") +set(CMAKE_ASM_FLAGS "${OBJECT_GEN_FLAGS}" CACHE INTERNAL "ASM Compiler options") +set(CMAKE_EXE_LINKER_FLAGS "${MCPU_FLAGS} ${LD_FLAGS} -Wl,--gc-sections --specs=nano.specs --specs=nosys.specs" CACHE INTERNAL "Linker options") + +#--------------------------------------------------------------------------------------- +# Set compilers and toolchain utilities +#--------------------------------------------------------------------------------------- +set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler") +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler") +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler") +set(TOOLCHAIN_LD ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-ld CACHE INTERNAL "Toolchain linker") +set(TOOLCHAIN_AR ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc-ar CACHE INTERNAL "Toolchain archive tool") +set(TOOLCHAIN_OBJCOPY ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-objcopy CACHE INTERNAL "Toolchain objcopy tool") +set(TOOLCHAIN_OBJDUMP ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-objdump CACHE INTERNAL "Toolchain objdump tool") +set(TOOLCHAIN_SIZE ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-size CACHE INTERNAL "Toolchain object size tool") + +set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_PREFIX}/${${TOOLCHAIN}} ${CMAKE_PREFIX_PATH}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +message(STATUS "Cross-compiling using GNU arm-none-eabi toolchain") + +# Options for DEBUG build +# -Og Enables optimizations that do not interfere with debugging. +# -g Produce debugging information in the operating system’s native format. +set(CMAKE_C_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C Compiler options for debug build type") +set(CMAKE_CXX_FLAGS_DEBUG "-Og -g" CACHE INTERNAL "C++ Compiler options for debug build type") +set(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "ASM Compiler options for debug build type") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "Linker options for debug build type") + +# Options for RELEASE build +# -Os Optimize for size. -Os enables all -O2 optimizations. +# -DNDEBUG ensure assertions are disabled +set(CMAKE_C_FLAGS_RELEASE "-Os -g -DNDEBUG" CACHE INTERNAL "C Compiler options for release build type") +set(CMAKE_CXX_FLAGS_RELEASE "-Os -g -DNDEBUG" CACHE INTERNAL "C++ Compiler options for release build type") +set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "ASM Compiler options for release build type") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Linker options for release build type") + +# Options for RELWITHDEBINFO build +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g -DNDEBUG" CACHE INTERNAL "C Compiler options for release with debug symbols build type") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -g -DNDEBUG" CACHE INTERNAL "C++ Compiler options for release with debug symbols build type") +set(CMAKE_ASM_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "ASM Compiler options for release with debug symbols build type") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "Linker options for release with debug symbols build type") + +# Options for MINSIZEREL build +# -flto, -Wl,-flto Link Time Optimization. Allows size optimizations to occur across compilation units at link time +set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL "C Compiler options for minimum size release build type") +set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -flto -Wl,-flto" CACHE INTERNAL "C++ Compiler options for minimum size release build type") +set(CMAKE_ASM_FLAGS_MINSIZEREL "" CACHE INTERNAL "ASM Compiler options for minimum size release build type") +set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-flto -Wl,-flto" CACHE INTERNAL "Linker options for minimum size release build type") diff --git a/cmake/utils.cmake b/cmake/utils.cmake new file mode 100644 index 00000000..614a67e1 --- /dev/null +++ b/cmake/utils.cmake @@ -0,0 +1,74 @@ +# utils.cmake +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +# -------------------------------------------------------------------------------------------------- +# Utility for properly installing a file output regardless of if the current configuration is multi +# config or not +# -------------------------------------------------------------------------------------------------- + +macro(multiConfigFileInstall FILE_OUT DESTINATION) + # check for multi-config + get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(isMultiConfig) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/${FILE_OUT} + CONFIGURATIONS Debug + DESTINATION ${DESTINATION}) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/${FILE_OUT} + CONFIGURATIONS RelWithDebInfo + DESTINATION ${DESTINATION}) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/Release/${FILE_OUT} + CONFIGURATIONS Release + DESTINATION ${DESTINATION}) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/MinSizeRel/${FILE_OUT} + CONFIGURATIONS MinSizeRel + DESTINATION ${DESTINATION}) + else() + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${FILE_OUT} DESTINATION ${DESTINATION}) + endif() +endmacro() + +# -------------------------------------------------------------------------------------------------- +# Utility for creating MCU binary outputs +# -------------------------------------------------------------------------------------------------- +macro(gen_bin_target_outputs TARGET) + get_filename_component(FILENAME ${TARGET} NAME_WE) + + # Create bin from elf target + add_custom_command( + OUTPUT ${FILENAME}.bin + DEPENDS ${TARGET} + COMMAND ${TOOLCHAIN_OBJCOPY} -O binary $ + $.bin) + list(APPEND TARGET_OUTPUTS ${FILENAME}.bin) + + # Print size of bin target + add_custom_command( + OUTPUT ${FILENAME}.size + DEPENDS ${TARGET} + COMMAND ${TOOLCHAIN_SIZE} $ | tee $.size) + list(APPEND TARGET_OUTPUTS ${FILENAME}.size) + + # Add top level target for all MCU standard outputs + add_custom_target(${FILENAME}_outputs ALL DEPENDS ${TARGET_OUTPUTS}) +endmacro() diff --git a/cmake/wolfboot.cmake b/cmake/wolfboot.cmake new file mode 100644 index 00000000..60cb6ea6 --- /dev/null +++ b/cmake/wolfboot.cmake @@ -0,0 +1,121 @@ +# wolfboot.cmake +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +include(${CMAKE_CURRENT_LIST_DIR}/utils.cmake) + +set(VERSION ${WOLFBOOT_VERSION}) + +# gen_wolfboot_platform_target is a function instead of a macro because it uses configure_file to +# generate linker scripts based on CMake variables, and the arguments to a macro are not true CMake +# variables. See https://cmake.org/cmake/help/latest/command/macro.html#macro-vs-function. + +# generate a wolfboot executable with the flash partition addresses for the given target +function(gen_wolfboot_platform_target PLATFORM_NAME LINKER_SCRIPT_TARGET) + + # generate target for bootloader + add_executable(wolfboot_${PLATFORM_NAME}) + target_sources(wolfboot_${PLATFORM_NAME} PRIVATE ${WOLFBOOT_SOURCES}) + + # set include directories and compile definitions for bootloader + target_compile_definitions(wolfboot_${PLATFORM_NAME} PRIVATE ${WOLFBOOT_DEFS}) + target_include_directories(wolfboot_${PLATFORM_NAME} PRIVATE ${WOLFBOOT_INCLUDE_DIRS}) + + # link with cryptography library, set linker options + target_link_libraries(wolfboot_${PLATFORM_NAME} wolfcrypt target wolfboot + ${LINKER_SCRIPT_TARGET}) + + # link with public key if signing is enabled + if(NOT SIGN STREQUAL "NONE") + target_link_libraries(wolfboot_${PLATFORM_NAME} public_key) + endif() + + # set compiler options + target_compile_options(wolfboot_${PLATFORM_NAME} PRIVATE ${WOLFBOOT_COMPILE_OPTIONS} + ${EXTRA_COMPILE_OPTIONS}) + target_link_options(wolfboot_${PLATFORM_NAME} PRIVATE ${WOLFBOOT_LINK_OPTIONS}) + + if(WOLFBOOT_TARGET IN_LIST ARM_TARGETS) + # generate .bin file for bootloader + gen_bin_target_outputs(wolfboot_${PLATFORM_NAME}) + endif() + + install(TARGETS wolfboot_${PLATFORM_NAME} RUNTIME DESTINATION bin) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/wolfboot_${PLATFORM_NAME}.bin DESTINATION bin) +endfunction() + +function(gen_wolfboot_signed_image TARGET) + if(NOT DEFINED SIGN_TOOL) + message(FATAL_ERROR "SIGN_TOOL is not defined") + endif() + + # for arm targets, sign the .bin produced by objcopy. For x86 targets, sign the executable + # produced by the compiler + if(WOLFBOOT_TARGET IN_LIST ARM_TARGETS) + set(INPUT_IMAGE $.bin) + else() + set(INPUT_IMAGE $) + endif() + + # generate signed image + add_custom_command( + OUTPUT ${TARGET}_signed.bin + DEPENDS ${INPUT_IMAGE} ${WOLFBOOT_SIGNING_PRIVATE_KEY} + COMMAND ${SIGN_TOOL} ${KEYTOOL_OPTIONS} ${INPUT_IMAGE} ${WOLFBOOT_SIGNING_PRIVATE_KEY} ${VERSION} + COMMENT "Signing ${TARGET}" + ) + + add_custom_target(${TARGET}_signed ALL DEPENDS ${TARGET}_signed.bin) + + multiconfigfileinstall(${TARGET}_signed.bin bin) +endfunction() + +function(gen_wolfboot_factory_image PLATFORM_NAME TARGET) + get_filename_component(FILENAME ${TARGET} NAME) + + if(NOT DEFINED ${PLATFORM_NAME}_BOOT_ADDRESS) + message(FATAL_ERROR "${PLATFORM_NAME}_BOOT_ADDRESS is not defined") + endif() + + if(NOT DEFINED BINASSEMBLE) + message(FATAL_ERROR "BINASSEMBLE is not defined") + endif() + + if(NOT DEFINED ARCH_FLASH_OFFSET) + message(FATAL_ERROR "ARCH_FLASH_OFFSET is not defined") + endif() + + gen_wolfboot_signed_image(${TARGET}) + + set(BOOT_ADDRESS ${${PLATFORM_NAME}_BOOT_ADDRESS}) + + # merge images + add_custom_command( + OUTPUT ${FILENAME}_factory.bin + DEPENDS $.bin ${FILENAME}_signed.bin + ${WOLFBOOT_SIGNING_PRIVATE_KEY} binAssemble + COMMAND ${BINASSEMBLE} ${FILENAME}_factory.bin ${ARCH_FLASH_OFFSET} + $.bin ${BOOT_ADDRESS} ${TARGET}_v${VERSION}_signed.bin + COMMENT "Assembling ${FILENAME} factory image") + list(APPEND BOOTLOADER_OUTPUTS ${FILENAME}_factory.bin) + + add_custom_target(${FILENAME}_boot ALL DEPENDS ${BOOTLOADER_OUTPUTS} ${TARGET}_signed) + + multiconfigfileinstall(${BOOTLOADER_OUTPUTS} bin) +endfunction() diff --git a/config/examples/sim.config b/config/examples/sim.config index e27945a8..455e76c9 100644 --- a/config/examples/sim.config +++ b/config/examples/sim.config @@ -13,4 +13,4 @@ WOLFBOOT_PARTITION_BOOT_ADDRESS=0x10000 WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x3a000 WOLFBOOT_PARTITION_SWAP_ADDRESS=0x64000 # required for keytools -WOLFBOOT_FIXED_PARTITIONS=1 \ No newline at end of file +WOLFBOOT_FIXED_PARTITIONS=1 diff --git a/hal/cc26x2.ld b/hal/cc26x2.ld index 9f31418e..ea2cea63 100644 --- a/hal/cc26x2.ld +++ b/hal/cc26x2.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0xD800 } @@ -34,7 +34,7 @@ SECTIONS _end_data = .; } > RAM - .bss (NOLOAD) : + .bss (NOLOAD) : { _start_bss = .; __bss_start__ = .; diff --git a/hal/hifive1.ld b/hal/hifive1.ld index b1f2e88d..64c5fbb6 100644 --- a/hal/hifive1.ld +++ b/hal/hifive1.ld @@ -4,7 +4,7 @@ ENTRY( _reset ) MEMORY { - FLASH(rxai!w) : ORIGIN = 0x20010000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH(rxai!w) : ORIGIN = 0x20010000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM(wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K } diff --git a/hal/imx_rt.ld b/hal/imx_rt.ld index 338762e4..304bffdb 100644 --- a/hal/imx_rt.ld +++ b/hal/imx_rt.ld @@ -1,7 +1,7 @@ /* Specify the memory areas */ MEMORY { - FLASH(rx) : ORIGIN = 0x60000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH(rx) : ORIGIN = 0x60000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 0x0001FFF0 } @@ -49,7 +49,7 @@ SECTIONS _end_data = .; } > RAM - .bss (NOLOAD) : + .bss (NOLOAD) : { _start_bss = .; __bss_start__ = .; diff --git a/hal/kinetis.ld b/hal/kinetis.ld index e9a69bbc..583507ed 100644 --- a/hal/kinetis.ld +++ b/hal/kinetis.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 64K } @@ -40,7 +40,7 @@ SECTIONS _end_data = .; } > RAM - .bss (NOLOAD) : + .bss (NOLOAD) : { _start_bss = .; __bss_start__ = .; diff --git a/hal/lpc.ld b/hal/lpc.ld index d7c9f5ed..77dce199 100644 --- a/hal/lpc.ld +++ b/hal/lpc.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } @@ -36,7 +36,7 @@ SECTIONS _end_data = .; } > RAM - .bss (NOLOAD) : + .bss (NOLOAD) : { _start_bss = .; __bss_start__ = .; diff --git a/hal/nrf52.ld b/hal/nrf52.ld index e04276eb..e69f7d21 100644 --- a/hal/nrf52.ld +++ b/hal/nrf52.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } @@ -34,7 +34,7 @@ SECTIONS _end_data = .; } > RAM - .bss (NOLOAD) : + .bss (NOLOAD) : { _start_bss = .; __bss_start__ = .; diff --git a/hal/psoc6.ld b/hal/psoc6.ld index 03ef304b..2d349d03 100644 --- a/hal/psoc6.ld +++ b/hal/psoc6.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x10000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x08000000, LENGTH = 64K } diff --git a/hal/samr21.ld b/hal/samr21.ld index e9ad7883..66242fcb 100644 --- a/hal/samr21.ld +++ b/hal/samr21.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 } @@ -34,7 +34,7 @@ SECTIONS _end_data = .; } > RAM - .bss (NOLOAD) : + .bss (NOLOAD) : { _start_bss = .; __bss_start__ = .; diff --git a/hal/stm32f4.ld b/hal/stm32f4.ld index 517e20c4..611211ea 100644 --- a/hal/stm32f4.ld +++ b/hal/stm32f4.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0001C000 } @@ -53,4 +53,9 @@ SECTIONS . = ALIGN(4); } +_wolfboot_partition_boot_address = @WOLFBOOT_PARTITION_BOOT_ADDRESS@; +_wolfboot_partition_size = @WOLFBOOT_PARTITION_SIZE@; +_wolfboot_partition_update_address = @WOLFBOOT_PARTITION_UPDATE_ADDRESS@; +_wolfboot_partition_swap_address = @WOLFBOOT_PARTITION_SWAP_ADDRESS@; + END_STACK = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal/stm32f7.ld b/hal/stm32f7.ld index d4a408eb..ee4634d2 100644 --- a/hal/stm32f7.ld +++ b/hal/stm32f7.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* mapping TCM only */ } @@ -15,7 +15,7 @@ SECTIONS . = ALIGN(4); _end_text = .; } > FLASH - + .edidx : { . = ALIGN(4); diff --git a/hal/stm32g0.ld b/hal/stm32g0.ld index bf40f7d9..e4fc6ea0 100644 --- a/hal/stm32g0.ld +++ b/hal/stm32g0.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008FFF } diff --git a/hal/stm32h7.c b/hal/stm32h7.c index 457c4768..1f4d73c2 100644 --- a/hal/stm32h7.c +++ b/hal/stm32h7.c @@ -159,7 +159,8 @@ #define STM32H7_SECTOR_SIZE 0x20000 -#if (WOLFBOOT_PARTITION_SIZE < (2 * STM32H7_SECTOR_SIZE)) +#if defined(WOLFBOOT_PARTITION_SIZE) && \ + (WOLFBOOT_PARTITION_SIZE < (2 * STM32H7_SECTOR_SIZE)) # error "Please use a bigger WOLFBOOT_PARTITION_SIZE, since the last 128KB on each partition will be reserved for bootloader flags" #endif @@ -202,7 +203,7 @@ static void RAMFUNCTION flash_clear_errors(uint8_t bank) { if (bank==0) FLASH_SR1 |= (FLASH_SR_WRPERR | FLASH_SR_PGSERR | FLASH_SR_STRBERR | - FLASH_SR_INCERR | FLASH_SR_OPERR | FLASH_SR_RDPERR | + FLASH_SR_INCERR | FLASH_SR_OPERR | FLASH_SR_RDPERR | FLASH_SR_RDSERR | FLASH_SR_SNECCERR | FLASH_SR_DBECCERR); if (bank==1) FLASH_SR2 |= (FLASH_SR_WRPERR | FLASH_SR_PGSERR | FLASH_SR_STRBERR | @@ -351,7 +352,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len) { if (p < FLASH_BANK2_BASE_REL) { - uint32_t reg = FLASH_CR1 & + uint32_t reg = FLASH_CR1 & (~((FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT) | FLASH_CR_PSIZE)); FLASH_CR1 = reg | (((p >> 17) << FLASH_CR_SNB_SHIFT) | FLASH_CR_SER | 0x00); diff --git a/hal/stm32h7.ld b/hal/stm32h7.ld index 3c56efcf..7cf0d05e 100644 --- a/hal/stm32h7.ld +++ b/hal/stm32h7.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* mapping TCM only */ } @@ -47,4 +47,9 @@ SECTIONS . = ALIGN(4); } +_wolfboot_partition_boot_address = 0x8020000; +_wolfboot_partition_size = 0xD0000; +_wolfboot_partition_update_address = 0x80F0000; +_wolfboot_partition_swap_address = 0x81C0000; + END_STACK = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal/stm32l0.ld b/hal/stm32l0.ld index 72507e5c..82b95dbe 100644 --- a/hal/stm32l0.ld +++ b/hal/stm32l0.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K } @@ -45,4 +45,9 @@ SECTIONS . = ALIGN(4); } +_wolfboot_partition_boot_address = @WOLFBOOT_PARTITION_BOOT_ADDRESS@; +_wolfboot_partition_size = @WOLFBOOT_PARTITION_SIZE@; +_wolfboot_partition_update_address = @WOLFBOOT_PARTITION_UPDATE_ADDRESS@; +_wolfboot_partition_swap_address = @WOLFBOOT_PARTITION_SWAP_ADDRESS@; + END_STACK = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal/stm32l0_chacha_ram.ld b/hal/stm32l0_chacha_ram.ld index 9b8dccae..12c352cc 100644 --- a/hal/stm32l0_chacha_ram.ld +++ b/hal/stm32l0_chacha_ram.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K } diff --git a/hal/stm32l4.ld b/hal/stm32l4.ld index 4708c05d..822f0117 100644 --- a/hal/stm32l4.ld +++ b/hal/stm32l4.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x08000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00018000 } diff --git a/hal/stm32l5.ld b/hal/stm32l5.ld index 165dc18b..98b4e7dc 100644 --- a/hal/stm32l5.ld +++ b/hal/stm32l5.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_ORIGIN##, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00017FFF } @@ -14,7 +14,7 @@ SECTIONS *(.rodata*) . = ALIGN(8); _end_text = .; - } > FLASH + } > FLASH .edidx : { . = ALIGN(4); diff --git a/hal/stm32u5.ld b/hal/stm32u5.ld index 165dc18b..98b4e7dc 100644 --- a/hal/stm32u5.ld +++ b/hal/stm32u5.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_ORIGIN##, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00017FFF } @@ -14,7 +14,7 @@ SECTIONS *(.rodata*) . = ALIGN(8); _end_text = .; - } > FLASH + } > FLASH .edidx : { . = ALIGN(4); diff --git a/hal/stm32wb.ld b/hal/stm32wb.ld index 1e49e558..991b9f7a 100644 --- a/hal/stm32wb.ld +++ b/hal/stm32wb.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 } diff --git a/hal/t2080.ld b/hal/t2080.ld index 315de48b..35883caf 100644 --- a/hal/t2080.ld +++ b/hal/t2080.ld @@ -11,7 +11,7 @@ BOOTSTRAP_ENTRY = 0xEFFFFFFC; MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_ORIGIN##, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ /* Use L1 memory (DDR is not setup yet) */ RAM (rwx) : ORIGIN = 0xFDD00000, LENGTH = 0x4000 } diff --git a/hal/ti_hercules.ld b/hal/ti_hercules.ld index 95fdd97c..75956b7b 100644 --- a/hal/ti_hercules.ld +++ b/hal/ti_hercules.ld @@ -4,7 +4,7 @@ MEMORY { - FLASH (RX) : ORIGIN = 0x00000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS## + FLASH (RX) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ RAM (RWX) : ORIGIN = 0x08000000, LENGTH = 0x00080000 } diff --git a/include/hal.h b/include/hal.h index 3cfa06fe..648a9c7f 100644 --- a/include/hal.h +++ b/include/hal.h @@ -24,6 +24,9 @@ #ifndef H_HAL_ #define H_HAL_ +#ifdef __cplusplus +extern "C" { +#endif #include "target.h" @@ -35,6 +38,12 @@ extern void do_boot(const uint32_t *app_offset); #endif extern void arch_reboot(void); +/* Simulator-only calls */ +#ifdef PLATFORM_sim +void hal_set_internal_flash_file(const char* file); +void hal_set_external_flash_file(const char* file); +void hal_deinit(); +#endif void hal_init(void); int hal_flash_write(uint32_t address, const uint8_t *data, int len); @@ -80,4 +89,8 @@ void hal_prepare_boot(void); } #endif /* !SPI_FLASH */ +#ifdef __cplusplus +} +#endif + #endif /* H_HAL_FLASH_ */ diff --git a/include/image.h b/include/image.h index c7d88d13..573b9f5c 100644 --- a/include/image.h +++ b/include/image.h @@ -24,6 +24,11 @@ #ifndef IMAGE_H #define IMAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + #include #include "target.h" @@ -643,4 +648,8 @@ static inline int wb_flash_write_verify_word(struct wolfBoot_image *img, uint32_ #define WOLFBOOT_MAX_SPACE (WOLFBOOT_PARTITION_SIZE - ENCRYPT_TMP_SECRET_OFFSET) #endif +#ifdef __cplusplus +} +#endif + #endif /* !IMAGE_H */ diff --git a/include/loader.h b/include/loader.h index 1e57ee09..1f7f996d 100644 --- a/include/loader.h +++ b/include/loader.h @@ -25,6 +25,10 @@ #ifndef LOADER_H #define LOADER_H +#ifdef __cplusplus +extern "C" { +#endif + #if defined(WOLFBOOT_SIGN_ED25519) extern const unsigned char ed25519_pub_key[]; extern unsigned int ed25519_pub_key_len; @@ -74,7 +78,7 @@ void wolfBoot_start(void); asm volatile("b .-2"); \ asm volatile("b .-4"); \ asm volatile("b .-6"); \ - asm volatile("b .-8"); + asm volatile("b .-8"); #else static inline void wolfBoot_panic(void) @@ -83,4 +87,9 @@ static inline void wolfBoot_panic(void) ; } #endif + +#ifdef __cplusplus +} +#endif + #endif /* LOADER_H */ diff --git a/include/target.h.in b/include/target.h.in index 9b66c7d1..5e2cec13 100644 --- a/include/target.h.in +++ b/include/target.h.in @@ -27,26 +27,45 @@ #ifndef H_TARGETS_TARGET_ #define H_TARGETS_TARGET_ + #ifndef WOLFBOOT_NO_PARTITIONS # define WOLFBOOT_FIXED_PARTITIONS #endif -#define WOLFBOOT_SECTOR_SIZE ##WOLFBOOT_SECTOR_SIZE## +#define WOLFBOOT_SECTOR_SIZE @WOLFBOOT_SECTOR_SIZE@ #ifdef WOLFBOOT_FIXED_PARTITIONS - #define WOLFBOOT_PARTITION_BOOT_ADDRESS ##WOLFBOOT_PARTITION_BOOT_ADDRESS## - #define WOLFBOOT_PARTITION_SIZE ##WOLFBOOT_PARTITION_SIZE## - #define WOLFBOOT_PARTITION_UPDATE_ADDRESS ##WOLFBOOT_PARTITION_UPDATE_ADDRESS## - #define WOLFBOOT_PARTITION_SWAP_ADDRESS ##WOLFBOOT_PARTITION_SWAP_ADDRESS## - #define WOLFBOOT_DTS_BOOT_ADDRESS ##WOLFBOOT_DTS_BOOT_ADDRESS## - #define WOLFBOOT_DTS_UPDATE_ADDRESS ##WOLFBOOT_DTS_UPDATE_ADDRESS## + +#ifdef PULL_LINKER_DEFINES + #include + + /* linker script variables */ + extern const uint32_t _wolfboot_partition_boot_address[]; + extern const uint32_t _wolfboot_partition_size[]; + extern const uint32_t _wolfboot_partition_update_address[]; + extern const uint32_t _wolfboot_partition_swap_address[]; + + /* create plain integers from linker script variables */ + static const uint32_t WOLFBOOT_PARTITION_BOOT_ADDRESS = (uint32_t)_wolfboot_partition_boot_address; + static const uint32_t WOLFBOOT_PARTITION_SIZE = (uint32_t)_wolfboot_partition_size; + static const uint32_t WOLFBOOT_PARTITION_UPDATE_ADDRESS = (uint32_t)_wolfboot_partition_update_address; + static const uint32_t WOLFBOOT_PARTITION_SWAP_ADDRESS = (uint32_t)_wolfboot_partition_swap_address; +#else + /* use values provided on input template parsing */ + #define WOLFBOOT_PARTITION_BOOT_ADDRESS @WOLFBOOT_PARTITION_BOOT_ADDRESS@ + #define WOLFBOOT_PARTITION_SIZE @WOLFBOOT_PARTITION_SIZE@ + #define WOLFBOOT_PARTITION_UPDATE_ADDRESS @WOLFBOOT_PARTITION_UPDATE_ADDRESS@ + #define WOLFBOOT_PARTITION_SWAP_ADDRESS @WOLFBOOT_PARTITION_SWAP_ADDRESS@ #endif +#define WOLFBOOT_DTS_BOOT_ADDRESS @WOLFBOOT_DTS_BOOT_ADDRESS@ +#define WOLFBOOT_DTS_UPDATE_ADDRESS @WOLFBOOT_DTS_UPDATE_ADDRESS@ + +#endif /* WOLFBOOT_FIXED_PARTITIONS */ + /* Load address in RAM for staged OS (update_ram only) */ -#define WOLFBOOT_LOAD_ADDRESS ##WOLFBOOT_LOAD_ADDRESS## -#define WOLFBOOT_LOAD_DTS_ADDRESS ##WOLFBOOT_LOAD_DTS_ADDRESS## - - +#define WOLFBOOT_LOAD_ADDRESS @WOLFBOOT_LOAD_ADDRESS@ +#define WOLFBOOT_LOAD_DTS_ADDRESS @WOLFBOOT_LOAD_DTS_ADDRESS@ #endif /* !H_TARGETS_TARGET_ */ diff --git a/include/wolfboot/wolfboot.h b/include/wolfboot/wolfboot.h index 30cf1d19..48873911 100644 --- a/include/wolfboot/wolfboot.h +++ b/include/wolfboot/wolfboot.h @@ -25,6 +25,10 @@ #ifndef WOLFBOOT_H #define WOLFBOOT_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include "target.h" #include "wolfboot/version.h" @@ -267,4 +271,8 @@ int wolfBoot_set_encrypt_key(const uint8_t *key, const uint8_t *nonce); int wolfBoot_get_encrypt_key(uint8_t *key, uint8_t *nonce); int wolfBoot_erase_encrypt_key(void); +#ifdef __cplusplus +} +#endif + #endif /* !WOLFBOOT_H */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 00000000..2d53d779 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,198 @@ +# CMakeLists.txt +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +# check for FASTMATH or SP_MATH +if(SPMATH) + list(APPEND MATH_SOURCES wolfssl/wolfcrypt/src/sp_int.c) +else() + message(STATUS "Using fast math") + list(APPEND WOLFCRYPT_DEFS USE_FAST_MATH) + list(APPEND MATH_SOURCES wolfssl/wolfcrypt/src/integer.c wolfssl/wolfcrypt/src/tfm.c) +endif() + +if(ARCH STREQUAL "ARM") + # Cortex-M CPU + if(${WOLFBOOT_TARGET} STREQUAL "stm32l0") + if(SPMATH) + if(NO_ASM) + list(APPEND MATH_SOURCES wolfssl/wolfcrypt/src/sp_c32.c) + else() + list(APPEND WOLFCRYPT_DEFS WOLFSSL_SP_ASM WOLFSSL_SP_ARM_THUMB_ASM) + list(APPEND MATH_SOURCES wolfssl/wolfcrypt/src/sp_armthumb.c) + endif() + endif() + else() + if(NO_ASM) + if(SPMATH) + list(APPEND MATH_SOURCES wolfssl/wolfcrypt/src/sp_c32.c) + endif() + else() + if(SPMATH) + list(APPEND WOLFCRYPT_DEFS WOLFSSL_SP_ASM WOLFSSL_SP_ARM_CORTEX_M_ASM) + list(APPEND MATH_SOURCES wolfssl/wolfcrypt/src/sp_cortexm.c) + endif() + endif() + endif() +endif() + +if(SIGN STREQUAL "ECC256") + list( + APPEND + WOLFCRYPT_SOURCES + ${MATH_SOURCES} + wolfssl/wolfcrypt/src/ecc.c + wolfssl/wolfcrypt/src/memory.c + wolfssl/wolfcrypt/src/wc_port.c + wolfssl/wolfcrypt/src/wolfmath.c + wolfssl/wolfcrypt/src/hash.c) +endif() + +if(SIGN STREQUAL "ECC384") + list( + APPEND + WOLFCRYPT_SOURCES + ${MATH_SOURCES} + wolfssl/wolfcrypt/src/ecc.c + wolfssl/wolfcrypt/src/memory.c + wolfssl/wolfcrypt/src/wc_port.c + wolfssl/wolfcrypt/src/wolfmath.c + wolfssl/wolfcrypt/src/hash.c) +endif() + +if(SIGN STREQUAL "ECC521") + list( + APPEND + WOLFCRYPT_SOURCES + ${MATH_SOURCES} + wolfssl/wolfcrypt/src/ecc.c + wolfssl/wolfcrypt/src/memory.c + wolfssl/wolfcrypt/src/wc_port.c + wolfssl/wolfcrypt/src/wolfmath.c + wolfssl/wolfcrypt/src/hash.c) +endif() + +if(SIGN STREQUAL "ED25519") + list( + APPEND + WOLFCRYPT_SOURCES + wolfssl/wolfcrypt/src/sha512.c + wolfssl/wolfcrypt/src/ed25519.c + wolfssl/wolfcrypt/src/ge_low_mem.c + wolfssl/wolfcrypt/src/hash.c + wolfssl/wolfcrypt/src/wolfmath.c + wolfssl/wolfcrypt/src/wc_port.c + wolfssl/wolfcrypt/src/fe_low_mem.c) +endif() + +if(SIGN STREQUAL "ED448") + list( + APPEND + WOLFCRYPT_SOURCES + wolfssl/wolfcrypt/src/ed448.c + wolfssl/wolfcrypt/src/ge_low_mem.c + wolfssl/wolfcrypt/src/ge_448.c + wolfssl/wolfcrypt/src/fe_448.c + wolfssl/wolfcrypt/src/hash.c + wolfssl/wolfcrypt/src/wolfmath.c + wolfssl/wolfcrypt/src/wc_port.c + wolfssl/wolfcrypt/src/fe_low_mem.c) + + if(NOT HASH STREQUAL "SHA3") + list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/sha3.c) + endif() +endif() + +if(SIGN STREQUAL "RSA2048") + list( + APPEND + WOLFCRYPT_SOURCES + ${RSA_EXTRA_SOURCES} + ${MATH_SOURCES} + wolfssl/wolfcrypt/src/rsa.c + wolfssl/wolfcrypt/src/asn.c + wolfssl/wolfcrypt/src/hash.c + wolfssl/wolfcrypt/src/wc_port.c + wolfssl/wolfcrypt/src/wolfmath.c) +endif() + +if(SIGN STREQUAL "RSA4096") + list( + APPEND + WOLFCRYPT_SOURCES + ${RSA_EXTRA_SOURCES} + ${MATH_SOURCES} + wolfssl/wolfcrypt/src/rsa.c + wolfssl/wolfcrypt/src/asn.c + wolfssl/wolfcrypt/src/hash.c + wolfssl/wolfcrypt/src/wc_port.c + wolfssl/wolfcrypt/src/wolfmath.c) +endif() + +if(ENCRYPT) + if(ENCRYPT_WITH_AES128) + list(APPEND WOLFSSL_DEFS WOLFSSL_AES_COUNTER WOLFSSL_AES_DIRECT WOLFSSL_AES_128) + list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/aes.c) + elseif(ENCRYPT_WITH_AES256) + list(APPEND WOLFSSL_DEFS WOLFSSL_AES_COUNTER WOLFSSL_AES_DIRECT WOLFSSL_AES_256) + list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/aes.c) + else() + set(ENCRYPT_WITH_CHACHA ON) + list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/chacha.c) + list(APPEND WOLFSSL_DEFS HAVE_CHACHA) + endif() +endif() + +if(HASH STREQUAL "SHA384") + if(NOT SIGN STREQUAL "ED25519") + list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/sha512.c) + endif() +endif() + +if(HASH STREQUAL "SHA3") + list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/sha3.c) +endif() + +if(NOT WOLFBOOT_SMALL_STACK AND WOLFBOOT_TARGET STREQUAL "unit_test") + list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/memory.c) + list(REMOVE_DUPLICATES WOLFCRYPT_SOURCES) +endif() + +# Include SHA256 module because it's implicitly needed by RSA +list(APPEND WOLFCRYPT_SOURCES wolfssl/wolfcrypt/src/sha256.c) + +list(APPEND WOLFCRYPT_INCLUDE_DIRS PUBLIC ${CMAKE_CURRENT_LIST_DIR}/wolfssl + ${WOLFBOOT_ROOT}/include) + +# generate target for wolfcrypt +add_library(wolfcrypt) +target_sources(wolfcrypt PRIVATE ${WOLFCRYPT_SOURCES}) +target_include_directories(wolfcrypt PUBLIC ${WOLFCRYPT_INCLUDE_DIRS}) +target_link_libraries(wolfcrypt target user_settings) + +target_compile_definitions( + wolfcrypt + PUBLIC WOLFSSL_USER_SETTINGS + PRIVATE ${WOLFCRYPT_DEFS} ${SIGN_OPTIONS}) + +if(WOLFBOOT_SMALL_STACK) + target_compile_definitions(wolfcrypt PRIVATE WOLFBOOT_SMALL_STACK XMALLOC_USER) +endif() + +target_compile_options(wolfcrypt PRIVATE -Wno-unused -Wno-array-bounds) diff --git a/test-app/ARM-psoc6.ld b/test-app/ARM-psoc6.ld index c92ce8d8..58a791e1 100644 --- a/test-app/ARM-psoc6.ld +++ b/test-app/ARM-psoc6.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x08000000, LENGTH = 64K } diff --git a/test-app/ARM-r5be.ld b/test-app/ARM-r5be.ld index f315f9cd..f9734a26 100644 --- a/test-app/ARM-r5be.ld +++ b/test-app/ARM-r5be.ld @@ -6,7 +6,7 @@ MEMORY { - FLASH (RX) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (RX) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (RWX) : ORIGIN = 0x08000000, LENGTH = 0x00080000 } diff --git a/test-app/ARM-stm32f7.ld b/test-app/ARM-stm32f7.ld index ee9639a3..1e558155 100644 --- a/test-app/ARM-stm32f7.ld +++ b/test-app/ARM-stm32f7.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000 } diff --git a/test-app/ARM-stm32h7.ld b/test-app/ARM-stm32h7.ld index 244ec39c..9a230754 100644 --- a/test-app/ARM-stm32h7.ld +++ b/test-app/ARM-stm32h7.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* mapping TCM only */ } @@ -41,5 +41,10 @@ SECTIONS } > RAM } +_wolfboot_partition_boot_address = 0x8020000; +_wolfboot_partition_size = 0xD0000; +_wolfboot_partition_update_address = 0x80F0000; +_wolfboot_partition_swap_address = 0x81C0000; + PROVIDE(_start_heap = _end); PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM)); diff --git a/test-app/ARM-stm32l5-ns.ld b/test-app/ARM-stm32l5-ns.ld index b509fc7f..31d7da48 100644 --- a/test-app/ARM-stm32l5-ns.ld +++ b/test-app/ARM-stm32l5-ns.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x20018000, LENGTH = 16K /* Run in lowmem */ } diff --git a/test-app/ARM-stm32l5.ld b/test-app/ARM-stm32l5.ld index 23c89c3c..e68a7772 100644 --- a/test-app/ARM-stm32l5.ld +++ b/test-app/ARM-stm32l5.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 64K /* Run in lowmem */ } diff --git a/test-app/ARM-stm32u5-ns.ld b/test-app/ARM-stm32u5-ns.ld index 73194afa..d9193d9b 100644 --- a/test-app/ARM-stm32u5-ns.ld +++ b/test-app/ARM-stm32u5-ns.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x20040000, LENGTH = 64K /* Run in lowmem */ } diff --git a/test-app/ARM-stm32u5.ld b/test-app/ARM-stm32u5.ld index 23c89c3c..e68a7772 100644 --- a/test-app/ARM-stm32u5.ld +++ b/test-app/ARM-stm32u5.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 64K /* Run in lowmem */ } diff --git a/test-app/ARM.ld b/test-app/ARM.ld index 24318aed..3f86153e 100644 --- a/test-app/ARM.ld +++ b/test-app/ARM.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* Run in lowmem */ } @@ -41,5 +41,10 @@ SECTIONS } > RAM } +_wolfboot_partition_boot_address = @WOLFBOOT_PARTITION_BOOT_ADDRESS@; +_wolfboot_partition_size = @WOLFBOOT_PARTITION_SIZE@; +_wolfboot_partition_update_address = @WOLFBOOT_PARTITION_UPDATE_ADDRESS@; +_wolfboot_partition_swap_address = @WOLFBOOT_PARTITION_SWAP_ADDRESS@; + PROVIDE(_start_heap = _end); PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM)); diff --git a/test-app/CMakeLists.txt b/test-app/CMakeLists.txt new file mode 100644 index 00000000..8a3163b5 --- /dev/null +++ b/test-app/CMakeLists.txt @@ -0,0 +1,125 @@ +# CMakeLists.txt +# +# Copyright (C) 2022 wolfSSL Inc. +# +# This file is part of wolfBoot. +# +# wolfBoot is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfBoot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + +include(../cmake/wolfboot.cmake) + +set(PLATFORM_NAME ${WOLFBOOT_TARGET}) + +if(NOT DEFINED WOLFBOOT_TARGET) + set(WOLFBOOT_TARGET "none") +endif() + +if("${SIGN}" STREQUAL "RSA2048") + set(IMAGE_HEADER_SIZE "512") +endif() + +if("${SIGN}" STREQUAL "RSA4096") + set(IMAGE_HEADER_SIZE "1024") +endif() + +set(APP_SOURCES app_${WOLFBOOT_TARGET}.c led.c system.c timer.c) + +if(ARCH STREQUAL "ARM") + list(APPEND APP_SOURCES startup_arm.c) + list(APPEND TEST_APP_COMPILE_DEFINITIONS STM32) +endif() + +if(ENCRYPT) + list(APPEND TEST_APP_COMPILE_DEFINITIONS EXT_ENCRYPTED=1) +endif() + +if("${WOLFBOOT_TARGET}" STREQUAL "stm32h7") + set(APP_LSCRIPT_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/ARM-stm32h7.ld) +elseif("${WOLFBOOT_TARGET}" STREQUAL "stm32u5") + set(APP_LSCRIPT_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/ARM-stm32u5.ld) +else() + set(APP_LSCRIPT_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/${ARCH}.ld) +endif() + +if(SPI_FLASH) + list(APPEND TEST_APP_COMPILE_DEFINITIONS SPI_FLASH) +endif() + +math(EXPR WOLFBOOT_TEST_APP_ADDRESS "${WOLFBOOT_PARTITION_BOOT_ADDRESS} + ${IMAGE_HEADER_SIZE}" + OUTPUT_FORMAT HEXADECIMAL) +math(EXPR WOLFBOOT_TEST_APP_SIZE "${WOLFBOOT_PARTITION_SIZE} - ${IMAGE_HEADER_SIZE}" + OUTPUT_FORMAT HEXADECIMAL) + +# determine size of bootloader partition +if(NOT DEFINED BOOTLOADER_PARTITION_SIZE) + math(EXPR BOOTLOADER_PARTITION_SIZE "${WOLFBOOT_PARTITION_BOOT_ADDRESS} - ${ARCH_FLASH_OFFSET}" + OUTPUT_FORMAT HEXADECIMAL) +endif() + +get_filename_component(WOLFBOOT_LSCRIPT ${CMAKE_SOURCE_DIR}/${WOLFBOOT_LSCRIPT_TEMPLATE} NAME) +set(WOLFBOOT_LSCRIPT ${CMAKE_CURRENT_BINARY_DIR}/${WOLFBOOT_LSCRIPT}) + +get_filename_component(APP_LSCRIPT ${APP_LSCRIPT_TEMPLATE} NAME) +set(APP_LSCRIPT ${CMAKE_CURRENT_BINARY_DIR}/${APP_LSCRIPT}) + +# generate linker script for bootloader +configure_file(${CMAKE_SOURCE_DIR}/${WOLFBOOT_LSCRIPT_TEMPLATE} ${WOLFBOOT_LSCRIPT}) + +# generate linker script for app +configure_file(${APP_LSCRIPT_TEMPLATE} ${APP_LSCRIPT}) + +if(WOLFBOOT_TARGET STREQUAL "sim") + # create bootloader for platform + gen_wolfboot_platform_target(${PLATFORM_NAME} "") +else() + add_library(bootloader_linker_script INTERFACE) + target_link_options(bootloader_linker_script INTERFACE -T${WOLFBOOT_LSCRIPT} -Wl,-Map=wolfboot.map) + + # create bootloader for platform + gen_wolfboot_platform_target(${PLATFORM_NAME} bootloader_linker_script) +endif() + +add_executable(image) + +target_sources(image PRIVATE ${APP_SOURCES}) + +target_include_directories(image PRIVATE ../include ${CMAKE_CURRENT_BINARY_DIR}) + +target_link_libraries(image wolfboot target) + +target_compile_definitions(image PRIVATE PLATFORM_${WOLFBOOT_TARGET} + ${TEST_APP_COMPILE_DEFINITIONS} ${WOLFBOOT_DEFS}) + +target_compile_options(image PRIVATE -Wall -Wstack-usage=1024 -ffreestanding -Wno-unused + -nostartfiles) + +if(WOLFBOOT_TARGET STREQUAL "sim") + target_link_options(image PRIVATE -Wl,-gc-sections -Wl,-Map=image.map) +else() + target_link_options(image PRIVATE -T${APP_LSCRIPT} -Wl,-gc-sections -Wl,-Map=image.map) +endif() + +if(WOLFBOOT_TARGET IN_LIST ARM_TARGETS) + message(STATUS "Binary output products will be generated") + gen_bin_target_outputs(image) + + # add boot address to cache + unset(${PLATFORM_NAME}_BOOT_ADDRESS CACHE) + set(${PLATFORM_NAME}_BOOT_ADDRESS ${WOLFBOOT_PARTITION_BOOT_ADDRESS} CACHE INTERNAL "") + + gen_wolfboot_factory_image(${PLATFORM_NAME} image) +else() + gen_wolfboot_signed_image(image) +endif() diff --git a/test-app/Makefile b/test-app/Makefile index fc99e617..82c64540 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -280,8 +280,12 @@ $(LSCRIPT): $(LSCRIPT_TEMPLATE) FORCE $(Q)expr `cat .partition-size` - `cat .header-size` > .app-size $(Q)printf "0x%X" `cat .app-size` > .app-size $(Q)cat $(LSCRIPT_TEMPLATE) | \ - sed -e "s/##WOLFBOOT_TEST_APP_SIZE##/`cat .app-size`/g" | \ - sed -e "s/##WOLFBOOT_TEST_APP_ADDRESS##/`cat .entry-point`/g" \ + sed -e "s/@WOLFBOOT_TEST_APP_SIZE@/`cat .app-size`/g" | \ + sed -e "s/@WOLFBOOT_TEST_APP_ADDRESS@/`cat .entry-point`/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_BOOT_ADDRESS@/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_SIZE@/$(WOLFBOOT_PARTITION_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_UPDATE_ADDRESS@/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_SWAP_ADDRESS@/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" \ > $(@) $(Q)rm -f .app-size .entry-point .wolfboot-offset .partition-size .header-size diff --git a/test-app/PPC.ld b/test-app/PPC.ld index 7d4417f7..de87fcb4 100644 --- a/test-app/PPC.ld +++ b/test-app/PPC.ld @@ -10,7 +10,7 @@ PHDRS SECTIONS { - . = ##WOLFBOOT_TEST_APP_ADDRESS##; + . = @WOLFBOOT_TEST_APP_ADDRESS@; .text : { diff --git a/test-app/RISCV.ld b/test-app/RISCV.ld index 57947eec..34375c0e 100644 --- a/test-app/RISCV.ld +++ b/test-app/RISCV.ld @@ -4,7 +4,7 @@ ENTRY( _reset ) MEMORY { - FLASH(rxai!w) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH(rxai!w) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM(wxa!ri) : ORIGIN = 0x80001000, LENGTH = 12K } diff --git a/test-app/imx_rt.ld b/test-app/imx_rt.ld index 8ed1d28d..4733d7f0 100644 --- a/test-app/imx_rt.ld +++ b/test-app/imx_rt.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000 } diff --git a/tools/keytools/Makefile b/tools/keytools/Makefile index 9b28c27f..06b41fcb 100644 --- a/tools/keytools/Makefile +++ b/tools/keytools/Makefile @@ -67,15 +67,15 @@ debug: all # Target.h is required for key tools $(WOLFBOOTDIR)/include/target.h: $(WOLFBOOTDIR)/include/target.h.in @cat $(WOLFBOOTDIR)/include/target.h.in | \ - sed -e "s/##WOLFBOOT_PARTITION_SIZE##/$(WOLFBOOT_PARTITION_SIZE)/g" | \ - sed -e "s/##WOLFBOOT_SECTOR_SIZE##/$(WOLFBOOT_SECTOR_SIZE)/g" | \ - sed -e "s/##WOLFBOOT_PARTITION_BOOT_ADDRESS##/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_PARTITION_UPDATE_ADDRESS##/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_PARTITION_SWAP_ADDRESS##/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_DTS_BOOT_ADDRESS##/$(WOLFBOOT_DTS_BOOT_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_DTS_UPDATE_ADDRESS##/$(WOLFBOOT_DTS_UPDATE_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_LOAD_ADDRESS##/$(WOLFBOOT_LOAD_ADDRESS)/g" | \ - sed -e "s/##WOLFBOOT_LOAD_DTS_ADDRESS##/$(WOLFBOOT_LOAD_DTS_ADDRESS)/g" \ + sed -e "s/@WOLFBOOT_PARTITION_SIZE@/$(WOLFBOOT_PARTITION_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_SECTOR_SIZE@/$(WOLFBOOT_SECTOR_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_BOOT_ADDRESS@/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_UPDATE_ADDRESS@/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_PARTITION_SWAP_ADDRESS@/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_DTS_BOOT_ADDRESS@/$(WOLFBOOT_DTS_BOOT_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_DTS_UPDATE_ADDRESS@/$(WOLFBOOT_DTS_UPDATE_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_LOAD_ADDRESS@/$(WOLFBOOT_LOAD_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_LOAD_DTS_ADDRESS@/$(WOLFBOOT_LOAD_DTS_ADDRESS)/g" \ > $@ # build template diff --git a/tools/keytools/keygen.c b/tools/keytools/keygen.c index ddf6c117..7510b187 100644 --- a/tools/keytools/keygen.c +++ b/tools/keytools/keygen.c @@ -63,7 +63,7 @@ #include #endif -#if defined(_WIN32) && !defined(PATH_MAX) +#if !defined(PATH_MAX) #define PATH_MAX 256 #endif @@ -97,8 +97,8 @@ struct keystore_slot { uint8_t pubkey[KEYSLOT_MAX_PUBKEY_SIZE]; }; -const char pubkeyfile[]= "src/keystore.c"; -const char pubkeyimg[] = "keystore.der"; +char pubkeyfile[PATH_MAX]= "src/keystore.c"; +char pubkeyimg[PATH_MAX] = "keystore.der"; const char Cfile_Banner[]="/* Keystore file for wolfBoot, automatically generated. Do not edit. */\n" "/*\n" @@ -156,7 +156,7 @@ static void usage(const char *pname) /* implies exit */ { printf("Usage: %s [--ed25519 | --ed448 | --ecc256 | --ecc384 " "| --ecc521 | --rsa2048 | --rsa3072 " - "| --rsa4096 ] [-g privkey] [-i pubkey] \n", pname); + "| --rsa4096 ] [-g privkey] [-i pubkey] [-keystoreDir dir] \n", pname); exit(125); } @@ -553,6 +553,13 @@ int main(int argc, char** argv) n_pubkeys++; continue; } + else if (strcmp(argv[i], "-keystoreDir") == 0) { + i++; + sprintf(pubkeyfile,"%s%s", argv[i], "/keystore.c"); + sprintf(pubkeyimg, "%s%s", argv[i], "/keystore.der"); + i++; + continue; + } else { fprintf(stderr, "Invalid argument '%s'.", argv[i]); usage(argv[0]); diff --git a/tools/keytools/keygen.py b/tools/keytools/keygen.py index 8ff7384b..218fb621 100755 --- a/tools/keytools/keygen.py +++ b/tools/keytools/keygen.py @@ -38,7 +38,7 @@ sign="ed25519" def usage(): - print("Usage: %s [--ed25519 | --ed448 | --ecc256 | --ecc384 | --ecc521 | --rsa2048| --rsa3072 | --rsa4096] [ --force ] [-i pubkey0.der [-i pubkey1.der -i pubkey2.der ... -i pubkeyN.der]] [-i pubkey0.der [-i pubkey1.der -i pubkey2.der ... -i pubkeyN.der]]n" % sys.argv[0]) + print("Usage: %s [--ed25519 | --ed448 | --ecc256 | --ecc384 | --ecc521 | --rsa2048| --rsa3072 | --rsa4096] [ --force ] [-i pubkey0.der [-i pubkey1.der -i pubkey2.der ... -i pubkeyN.der]] [-i pubkey0.der [-i pubkey1.der -i pubkey2.der ... -i pubkeyN.der] [-keystoreDir dir]]n" % sys.argv[0]) parser.print_help() sys.exit(1) @@ -172,14 +172,20 @@ parser.add_argument('--rsa4096', dest='rsa4096', action='store_true') parser.add_argument('--force', dest='force', action='store_true') parser.add_argument('-i', dest='pubfile', nargs='+', action='extend') parser.add_argument('-g', dest='keyfile', nargs='+', action='extend') +parser.add_argument('-keystoreDir', dest='storeDir', nargs='+', action='extend') args=parser.parse_args() #sys.exit(0) #test -pubkey_cfile = "src/keystore.c" -keystore_imgfile = "keystore.der" +if (type(args.storeDir) == list): + pubkey_cfile = "".join(args.storeDir)+"/keystore.c" + keystore_imgfile = "".join(args.storeDir)+"/keystore.der" +else: + pubkey_cfile = "src/keystore.c" + keystore_imgfile = "keystore.der" + key_files = args.keyfile pubkey_files = args.pubfile