Skip to content

boot: espressif: integrate Espressif Port with Zephyr sysbuild system #2233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
520 changes: 138 additions & 382 deletions boot/espressif/CMakeLists.txt

Large diffs are not rendered by default.

273 changes: 273 additions & 0 deletions boot/espressif/common.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0

add_definitions(-DMCUBOOT_TARGET=${MCUBOOT_TARGET})
add_definitions(-D__ESPRESSIF__=1)

# Set directories
set(BOOTUTIL_DIR ${MCUBOOT_ROOT_DIR}/boot/bootutil)
set(BOOT_SERIAL_DIR ${MCUBOOT_ROOT_DIR}/boot/boot_serial)
set(ZCBOR_DIR ${MCUBOOT_ROOT_DIR}/boot/zcbor)

# Set chip arch
if("${MCUBOOT_TARGET}" STREQUAL "esp32" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32s2" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32s3")
set(MCUBOOT_ARCH "xtensa")
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c3" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32c6" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32c2" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32h2")
set(MCUBOOT_ARCH "riscv")
endif()

# Set the minimum revision for each supported chip
if("${MCUBOOT_TARGET}" STREQUAL "esp32")
set(ESP_MIN_REVISION 3)
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32s2")
set(ESP_MIN_REVISION 0)
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32s3")
set(ESP_MIN_REVISION 0)
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c3")
set(ESP_MIN_REVISION 3)
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c6")
set(ESP_MIN_REVISION 0)
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c2")
set(ESP_MIN_REVISION 0)
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32h2")
set(ESP_MIN_REVISION 0)
else()
message(FATAL_ERROR "Unsupported target ${MCUBOOT_TARGET}")
endif()

# Get MCUboot revision to be added into bootloader image version
execute_process(
COMMAND git describe --tags
WORKING_DIRECTORY ${ESPRESSIF_PORT_DIR}
OUTPUT_VARIABLE MCUBOOT_VER
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DMCUBOOT_VER=\"${MCUBOOT_VER}\")

# Set Espressif HAL to use
if(NOT DEFINED ESP_HAL_PATH)
if(DEFINED ENV{ESP_HAL_PATH})
set(ESP_HAL_PATH $ENV{ESP_HAL_PATH})
else()
message(WARNING "ESP_HAL_PATH not defined, checking if IDF_PATH exists.")
if(DEFINED ENV{IDF_PATH})
set(ESP_HAL_PATH $ENV{IDF_PATH})
message("IDF installation found in the system, using IDF_PATH as ESP_HAL_PATH.")
else ()
message(FATAL_ERROR "Please set -DESP_HAL_PATH parameter or define ESP_HAL_PATH environment variable.")
endif()
endif()
endif()
message(STATUS "Defined ESP_HAL_PATH: ${ESP_HAL_PATH}")

# Verify from which IDF version the HAL is based on
set(IDF_VER_HEADER_FILE "${ESP_HAL_PATH}/components/esp_common/include/esp_idf_version.h")

get_version_from_header("ESP_IDF_VERSION_MAJOR" ${IDF_VER_HEADER_FILE} IDF_VERSION_MAJOR)
get_version_from_header("ESP_IDF_VERSION_MINOR" ${IDF_VER_HEADER_FILE} IDF_VERSION_MINOR)
get_version_from_header("ESP_IDF_VERSION_PATCH" ${IDF_VER_HEADER_FILE} IDF_VERSION_PATCH)

set(IDF_VERSION "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}")

if(NOT IDF_VERSION VERSION_EQUAL ${EXPECTED_IDF_HAL_VERSION})
message(
FATAL_ERROR "
Unsupported HAL version ${IDF_VERSION}, expected ${EXPECTED_IDF_HAL_VERSION}. \
Verify if the RTOS repository, where you are trying to build from, is up to date, \
or check the installation pointed on ESP_HAL_PATH."
)
else ()
message(STATUS "HAL based on ESP-IDF version: ${IDF_VERSION}")
endif()

# Find imgtool.
# Go with an explicitly installed imgtool first, falling
# back to mcuboot/scripts/imgtool.py.
find_program(IMGTOOL_COMMAND
NAMES imgtool imgtool.py
)
if("${IMGTOOL_COMMAND}" MATCHES "IMGTOOL_COMMAND-NOTFOUND")
set(imgtool_path "${MCUBOOT_ROOT_DIR}/scripts/imgtool.py")
else()
set(imgtool_path "${IMGTOOL_COMMAND}")
endif()

set(inc_directories
${BOOTUTIL_DIR}/include
${BOOTUTIL_DIR}/src
${ESPRESSIF_PORT_DIR}/include
)

set(main_src ${ESPRESSIF_PORT_DIR}/main.c)

set(port_srcs
${ESPRESSIF_PORT_DIR}/port/esp_mcuboot.c
${ESPRESSIF_PORT_DIR}/port/esp_loader.c
${ESPRESSIF_PORT_DIR}/os.c
)

set(bootutil_srcs
${BOOTUTIL_DIR}/src/boot_record.c
${BOOTUTIL_DIR}/src/bootutil_misc.c
${BOOTUTIL_DIR}/src/bootutil_public.c
${BOOTUTIL_DIR}/src/caps.c
${BOOTUTIL_DIR}/src/encrypted.c
${BOOTUTIL_DIR}/src/fault_injection_hardening.c
${BOOTUTIL_DIR}/src/fault_injection_hardening_delay_rng_mbedtls.c
${BOOTUTIL_DIR}/src/image_ecdsa.c
${BOOTUTIL_DIR}/src/image_ed25519.c
${BOOTUTIL_DIR}/src/image_rsa.c
${BOOTUTIL_DIR}/src/image_validate.c
${BOOTUTIL_DIR}/src/loader.c
${BOOTUTIL_DIR}/src/swap_misc.c
${BOOTUTIL_DIR}/src/swap_move.c
${BOOTUTIL_DIR}/src/swap_scratch.c
${BOOTUTIL_DIR}/src/swap_offset.c
${BOOTUTIL_DIR}/src/tlv.c
)

if(CONFIG_BOOT_RAM_LOAD)
list(APPEND bootutil_srcs ${BOOTUTIL_DIR}/src/ram_load.c)
endif()

if(DEFINED CONFIG_ESP_SIGN_RSA)
include(${ESPRESSIF_PORT_DIR}/include/crypto_config/rsa.cmake)
elseif(DEFINED CONFIG_ESP_SIGN_EC256)
include(${ESPRESSIF_PORT_DIR}/include/crypto_config/ec256.cmake)
elseif(DEFINED CONFIG_ESP_SIGN_ED25519)
include(${ESPRESSIF_PORT_DIR}/include/crypto_config/ed25519.cmake)
else()
# No signature verification
set(TINYCRYPT_DIR ${MCUBOOT_ROOT_DIR}/ext/tinycrypt/lib)
set(CRYPTO_INC
${TINYCRYPT_DIR}/include
)
set(crypto_srcs
${TINYCRYPT_DIR}/source/sha256.c
${TINYCRYPT_DIR}/source/utils.c
)
endif()

if(DEFINED CONFIG_ESP_SIGN_KEY_FILE)
if(IS_ABSOLUTE ${CONFIG_ESP_SIGN_KEY_FILE})
set(KEY_FILE ${CONFIG_ESP_SIGN_KEY_FILE})
else()
set(KEY_FILE ${MCUBOOT_ROOT_DIR}/${CONFIG_ESP_SIGN_KEY_FILE})
endif()
message("MCUBoot bootloader key file: ${KEY_FILE}")

set(GENERATED_PUBKEY ${CMAKE_CURRENT_BINARY_DIR}/autogen-pubkey.c)
add_custom_command(
OUTPUT ${GENERATED_PUBKEY}
COMMAND
${imgtool_path}
getpub
-k
${KEY_FILE}
> ${GENERATED_PUBKEY}
DEPENDS ${KEY_FILE}
)
list(APPEND crypto_srcs ${GENERATED_PUBKEY})
endif()

if(CONFIG_ESP_MCUBOOT_SERIAL)
set(MBEDTLS_DIR "${MCUBOOT_ROOT_DIR}/ext/mbedtls")

list(APPEND bootutil_srcs
${BOOT_SERIAL_DIR}/src/boot_serial.c
${BOOT_SERIAL_DIR}/src/zcbor_bulk.c
${ZCBOR_DIR}/src/zcbor_decode.c
${ZCBOR_DIR}/src/zcbor_encode.c
${ZCBOR_DIR}/src/zcbor_common.c
)
list(APPEND inc_directories
${BOOT_SERIAL_DIR}/include
${ZCBOR_DIR}/include
)
list(APPEND port_srcs
${ESPRESSIF_PORT_DIR}/port/${MCUBOOT_TARGET}/serial_adapter.c
${MBEDTLS_DIR}/library/base64.c
)
list(APPEND CRYPTO_INC
${MBEDTLS_DIR}/include
)
endif()

list(APPEND inc_directories
${CRYPTO_INC}
)

set(CFLAGS
"-Wno-frame-address"
"-Wall"
"-Wextra"
"-W"
"-Wdeclaration-after-statement"
"-Wwrite-strings"
"-Wlogical-op"
"-Wshadow"
"-ffunction-sections"
"-fdata-sections"
"-fstrict-volatile-bitfields"
"-Werror=all"
"-Wno-error=unused-function"
"-Wno-error=unused-but-set-variable"
"-Wno-error=unused-variable"
"-Wno-error=deprecated-declarations"
"-Wno-unused-parameter"
"-Wno-sign-compare"
"-ggdb"
"-Os"
"-D_GNU_SOURCE"
"-std=gnu17"
"-Wno-old-style-declaration"
"-Wno-implicit-int"
"-Wno-declaration-after-statement"
)

set(LDFLAGS
"-nostdlib"
"-Wno-frame-address"
"-Wl,--cref"
"-fno-rtti"
"-fno-lto"
"-Wl,--gc-sections"
"-Wl,--undefined=uxTopUsedPriority"
"-lm"
"-lgcc"
"-lgcov"
)

if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
list(APPEND CFLAGS
"-mlongcalls"
)
list(APPEND LDFLAGS
"-mlongcalls"
)
endif()

# Set linker script
set(ld_input ${ESPRESSIF_PORT_DIR}/port/${MCUBOOT_TARGET}/ld/bootloader.ld)
set(ld_output ${CMAKE_CURRENT_BINARY_DIR}/ld/bootloader.ld)

file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ld")

get_directory_property(configs COMPILE_DEFINITIONS)
foreach(c ${configs})
list(APPEND conf_defines "-D${c}")
endforeach()

# Preprocess linker script
add_custom_command(
TARGET ${APP_EXECUTABLE} PRE_LINK
COMMAND ${CMAKE_C_COMPILER} -x c -E -P -o ${ld_output} ${conf_defines} ${ld_input}
MAIN_DEPENDENCY ${ld_input}
COMMENT "Preprocessing bootloader.ld linker script..."
)
28 changes: 27 additions & 1 deletion boot/espressif/hal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

cmake_minimum_required(VERSION 3.13)

if(CONFIG_BUILD_FROM_ZEPHYR)
message(STATUS "Building HAL for MCUboot Espressif Port")

if(${CONFIG_ESP_CONSOLE_UART})
add_compile_definitions(CONFIG_ESP_CONSOLE_UART=${CONFIG_ESP_CONSOLE_UART})
add_compile_definitions(CONFIG_ESP_CONSOLE_UART_NUM=${CONFIG_ESP_CONSOLE_UART_NUM})
if(${CONFIG_ESP_CONSOLE_UART_CUSTOM})
add_compile_definitions(CONFIG_ESP_CONSOLE_UART_CUSTOM=${CONFIG_ESP_CONSOLE_UART_CUSTOM})
add_compile_definitions(CONFIG_ESP_CONSOLE_UART_TX_GPIO=${CONFIG_ESP_CONSOLE_UART_TX_GPIO})
add_compile_definitions(CONFIG_ESP_CONSOLE_UART_RX_GPIO=${CONFIG_ESP_CONSOLE_UART_RX_GPIO})
endif()
elseif(${CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG})
add_compile_definitions(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=${CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG})
endif()
add_compile_definitions(CONFIG_MCUBOOT_ESPRESSIF=1)
endif()

project(hal)

set(esp_hal_dir ${ESP_HAL_PATH})
Expand Down Expand Up @@ -156,7 +173,6 @@ set(CFLAGS
set(LDFLAGS
"-Wno-frame-address"
"-Wl,--cref"
"-Wl,--Map=${APP_NAME}.map"
"-fno-rtti"
"-fno-lto"
"-Wl,--gc-sections"
Expand All @@ -166,6 +182,16 @@ set(LDFLAGS
"-lgcov"
)

if(CONFIG_BUILD_FROM_ZEPHYR)
list(APPEND include_dirs
${ESPRESSIF_PORT_DIR}/zephyr/include
)
else()
list(APPEND LDFLAGS
"-Wl,--Map=${APP_NAME}.map"
)
endif()

if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
list(APPEND CFLAGS
"-mlongcalls"
Expand Down
2 changes: 1 addition & 1 deletion boot/espressif/hal/include/esp32c2/sdkconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 74880
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
Expand Down
2 changes: 2 additions & 0 deletions boot/espressif/hal/include/mcuboot_config/mcuboot_assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ extern void mcuboot_assert_handler(const char *file, int line, const char *func)
mcuboot_assert_handler(__FILE__, __LINE__, __func__); \
} \
} while(0)

#define ASSERT(arg) assert(arg)
51 changes: 51 additions & 0 deletions boot/espressif/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
cmake_policy(SET CMP0109 NEW)

include(${CMAKE_CURRENT_LIST_DIR}/../tools/utils.cmake)

message(STATUS "Building MCUboot for Zephyr OS -- ESPRESSIF PORT")

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

# Set Zephyr referenced variables
set(MCUBOOT_ROOT_DIR ${ZEPHYR_MCUBOOT_MODULE_DIR})
set(ESPRESSIF_PORT_DIR ${MCUBOOT_ROOT_DIR}/boot/espressif)
set(MCUBOOT_TARGET ${CONFIG_SOC})
set(ESP_HAL_PATH ${ZEPHYR_HAL_ESPRESSIF_MODULE_DIR})
set(APP_EXECUTABLE ${ZEPHYR_CURRENT_LIBRARY})
set(EXPECTED_IDF_HAL_VERSION "5.1.5")

project(NONE)

include(../common.cmake)

zephyr_library_include_directories(
${inc_directories}
)

zephyr_library_sources(
${main_src}
${bootutil_srcs}
${crypto_srcs}
${port_srcs}
)

zephyr_library_link_libraries(
gcc
-T${ld_output}
${LDFLAGS}
)

if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
zephyr_include_directories(
${ESP_HAL_PATH}/components/${MCUBOOT_ARCH}/${MCUBOOT_TARGET}/include
${ESP_HAL_PATH}/components/${MCUBOOT_ARCH}/include
)
endif()

add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../hal ${CMAKE_CURRENT_BINARY_DIR}/hal)
zephyr_library_link_libraries(hal)
Loading
Loading