Initial commit

Initial commit.
This commit is contained in:
kntran1
2026-03-23 14:40:39 -05:00
parent e84b2b4166
commit 4e2a5258a5
872 changed files with 165227 additions and 0 deletions

View File

@@ -0,0 +1,409 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13)
cmake_policy(SET CMP0109 NEW)
include(${CMAKE_CURRENT_LIST_DIR}/tools/utils.cmake)
if (NOT DEFINED MCUBOOT_TARGET)
message(FATAL_ERROR "MCUBOOT_TARGET not defined. Please pass -DMCUBOOT_TARGET flag.")
endif()
add_definitions(-DMCUBOOT_TARGET=${MCUBOOT_TARGET})
add_definitions(-D__ESPRESSIF__=1)
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()
if (NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if (DEFINED TOOLCHAIN_BIN_DIR)
message("CMAKE_TOOLCHAIN_FILE not defined, searching for toolchain compiler in TOOLCHAIN_BIN_DIR: ${TOOLCHAIN_BIN_DIR}")
set(CMAKE_SYSTEM_NAME Generic)
file(GLOB C_COMPILER_BIN "${TOOLCHAIN_BIN_DIR}/*${MCUBOOT_ARCH}*elf-gcc")
if (NOT C_COMPILER_BIN)
message(FATAL_ERROR "No C compiler found. Please ensure that TOOLCHAIN_BIN_DIR directory contains a set of C compiling tools compatible with the target")
endif()
set(CMAKE_C_COMPILER ${C_COMPILER_BIN})
set(CMAKE_ASM_COMPILER ${C_COMPILER_BIN})
message("C compiler found: ${CMAKE_C_COMPILER}")
file(GLOB CXX_COMPILER_BIN "${TOOLCHAIN_BIN_DIR}/*${MCUBOOT_ARCH}*elf-g++")
if (NOT CXX_COMPILER_BIN)
message(FATAL_ERROR "No C++ compiler found. Please ensure that TOOLCHAIN_BIN_DIR directory contains a set of C++ compiling tools compatible with the target")
endif()
set(CMAKE_CXX_COMPILER ${CXX_COMPILER_BIN})
message("CXX compiler found: ${CMAKE_CXX_COMPILER}")
else()
# Set toolchain file that expect the same toolchain as IDF sets on PATH
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/tools/toolchain-${MCUBOOT_TARGET}.cmake)
message("No user-defined toolchain, setting default toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
endif()
# This flag is needed when redefining a different compiler toolchain at this point
# on CMakeLists, the reason is that CMake does a compiler testing prior to building
# that may fail due to cross-compilation
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
else()
message("CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}")
endif()
project(mcuboot_${MCUBOOT_TARGET})
# 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()
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()
execute_process(
COMMAND git describe --tags
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE MCUBOOT_VER
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DMCUBOOT_VER=\"${MCUBOOT_VER}\")
if (NOT DEFINED MCUBOOT_CONFIG_FILE)
set(MCUBOOT_CONFIG_FILE "${CMAKE_CURRENT_LIST_DIR}/port/${MCUBOOT_TARGET}/bootloader.conf")
endif()
string(REPLACE " " ";" MCUBOOT_CONFIG_FILE_LIST "${MCUBOOT_CONFIG_FILE}")
foreach(CONFIG_FILE ${MCUBOOT_CONFIG_FILE_LIST})
if (NOT EXISTS "${CONFIG_FILE}")
message(FATAL_ERROR "MCUboot configuration file does not exist at ${CONFIG_FILE}")
endif()
parse_and_set_config_file(${CONFIG_FILE})
endforeach()
set(APP_NAME mcuboot_${MCUBOOT_TARGET})
set(APP_EXECUTABLE ${APP_NAME}.elf)
set(MCUBOOT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
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(ESPRESSIF_PORT_DIR ${CMAKE_CURRENT_LIST_DIR})
# 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()
# Find installed esptool, if not found falls to IDF's
find_program(ESPTOOL_COMMAND
NAMES esptool esptool.py
)
if ("${ESPTOOL_COMMAND}" MATCHES "ESPTOOL_COMMAND-NOTFOUND")
if (DEFINED ENV{IDF_PATH})
set(esptool_path "${IDF_PATH}/components/esptool_py/esptool/esptool.py")
else()
message(FATAL_ERROR "esptool.py not found. Please install it using \'pip install esptool\'.")
endif()
else()
set(esptool_path "${ESPTOOL_COMMAND}")
endif()
# Flash frequency parameter for esptool.py, for more information, check `esptool.py -h`
if (NOT DEFINED ESP_FLASH_FREQ)
if ("${MCUBOOT_TARGET}" STREQUAL "esp32" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32s2" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32s3" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32c3" OR
"${MCUBOOT_TARGET}" STREQUAL "esp32c6")
set(ESP_FLASH_FREQ "40m")
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c2")
set(ESP_FLASH_FREQ "60m")
elseif("${MCUBOOT_TARGET}" STREQUAL "esp32h2")
set(ESP_FLASH_FREQ "24m")
endif()
endif()
# Flash mode parameter for esptool.py, for more information, check `esptool.py -h`
if (NOT DEFINED ESP_FLASH_MODE)
set(ESP_FLASH_MODE "dio")
endif()
# Serial baud rate parameter for esptool.py flash use, for more information, check `esptool.py -h`
if (NOT DEFINED ESP_BAUD_RATE)
set(ESP_BAUD_RATE 115200)
endif()
if (DEFINED CONFIG_ESP_SIGN_RSA)
include(${CMAKE_CURRENT_LIST_DIR}/include/crypto_config/rsa.cmake)
elseif (DEFINED CONFIG_ESP_SIGN_EC256)
include(${CMAKE_CURRENT_LIST_DIR}/include/crypto_config/ec256.cmake)
elseif (DEFINED CONFIG_ESP_SIGN_ED25519)
include(${CMAKE_CURRENT_LIST_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()
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/tlv.c
)
set(bootutil_paths)
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"
"-Wl,--Map=${APP_NAME}.map"
"-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()
add_subdirectory(hal)
add_executable(
${APP_EXECUTABLE}
${CMAKE_CURRENT_LIST_DIR}/main.c
)
target_compile_options(
${APP_EXECUTABLE}
PUBLIC
${CFLAGS}
)
set(port_srcs
${CMAKE_CURRENT_LIST_DIR}/port/esp_mcuboot.c
${CMAKE_CURRENT_LIST_DIR}/port/esp_loader.c
${CMAKE_CURRENT_LIST_DIR}/os.c
)
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 bootutil_paths
${ZCBOR_DIR}/include
)
list(APPEND port_srcs
${CMAKE_CURRENT_LIST_DIR}/port/${MCUBOOT_TARGET}/serial_adapter.c
${MBEDTLS_DIR}/library/base64.c
)
list(APPEND CRYPTO_INC
${MBEDTLS_DIR}/include
)
endif()
target_sources(
${APP_EXECUTABLE}
PUBLIC
${bootutil_srcs}
${crypto_srcs}
${port_srcs}
)
target_include_directories(
${APP_EXECUTABLE}
PUBLIC
${BOOTUTIL_DIR}/include
${BOOTUTIL_DIR}/src
${BOOT_SERIAL_DIR}/include
${CRYPTO_INC}
${CMAKE_CURRENT_LIST_DIR}/include
${bootutil_paths}
)
set(ld_input ${CMAKE_CURRENT_LIST_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..."
)
target_link_libraries(
${APP_EXECUTABLE}
PUBLIC
-T${ld_output}
${LDFLAGS}
)
target_link_libraries(
${APP_EXECUTABLE}
PUBLIC
hal
)
# This step uses esptool.py for generating the final bootloader binary in
# Espressif compatible format.
# Note: Both binary generation and flash steps still have some default arguments
add_custom_command(TARGET ${APP_EXECUTABLE} POST_BUILD
COMMAND
${esptool_path}
--chip ${MCUBOOT_TARGET} elf2image --min-rev ${ESP_MIN_REVISION}
--flash_mode ${ESP_FLASH_MODE} --flash_freq ${ESP_FLASH_FREQ} --flash_size ${CONFIG_ESP_FLASH_SIZE}
-o ${APP_NAME}.bin ${APP_NAME}.elf
)
if (DEFINED MCUBOOT_FLASH_PORT)
set(FLASH_PORT ${MCUBOOT_FLASH_PORT})
else()
# Defaults to the first USB serial port
set(FLASH_PORT "/dev/ttyUSB0")
endif()
if (NOT EXISTS "${FLASH_PORT}")
message(WARNING "Could not open ${FLASH_PORT}, serial port does not exist")
endif()
add_custom_target(flash DEPENDS ${APP_NAME}.bin)
add_custom_command(TARGET flash
USES_TERMINAL
COMMAND
${esptool_path}
-p ${FLASH_PORT} -b ${ESP_BAUD_RATE} --before default_reset --after no_reset
--chip ${MCUBOOT_TARGET} write_flash
--flash_mode ${ESP_FLASH_MODE} --flash_size ${CONFIG_ESP_FLASH_SIZE}
--flash_freq ${ESP_FLASH_FREQ} ${CONFIG_ESP_BOOTLOADER_OFFSET}
${APP_NAME}.bin
)

View File

@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# ATTENTION:
# This configuration file targets the building for CI environment and contains
# a set of definitions to resemble a bootloader image for RELEASE environment.
CONFIG_ESP_IMAGE_NUMBER=2
CONFIG_ESP_MULTI_PROCESSOR_BOOT=y

View File

@@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# ATTENTION:
# This configuration file targets the building for CI environment and contains
# a set of definitions to resemble a bootloader image for RELEASE environment.
CONFIG_ESP_IMAGE_NUMBER=2

View File

@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# ATTENTION:
# This configuration file targets the building for CI environment and contains
# a set of definitions to resemble a bootloader image for RELEASE environment.
# Running the generated firmware image may result in irreversible operations
# to the chip!
CONFIG_SECURE_SIGNED_ON_BOOT=1
CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
CONFIG_SECURE_BOOT=1
CONFIG_SECURE_BOOT_V2_ENABLED=1
CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
CONFIG_SECURE_FLASH_ENC_ENABLED=1
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
CONFIG_ESP_USE_TINYCRYPT=1
CONFIG_ESP_SIGN_EC256=1
CONFIG_ESP_DOWNGRADE_PREVENTION=1
CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=1

View File

@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# ATTENTION:
# This configuration file targets the building for CI environment and contains
# a set of definitions to resemble a bootloader image for RELEASE environment.
# Running the generated firmware image may result in irreversible operations
# to the chip!
CONFIG_SECURE_SIGNED_ON_BOOT=1
CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
CONFIG_SECURE_BOOT=1
CONFIG_SECURE_BOOT_V2_ENABLED=1
CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
CONFIG_SECURE_FLASH_ENC_ENABLED=1
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
CONFIG_ESP_SIGN_KEY_FILE=root-ed25519.pem
CONFIG_ESP_USE_TINYCRYPT=1
CONFIG_ESP_SIGN_ED25519=1
CONFIG_ESP_DOWNGRADE_PREVENTION=1
CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=1

View File

@@ -0,0 +1,23 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# ATTENTION:
# This configuration file targets the building for CI environment and contains
# a set of definitions to resemble a bootloader image for RELEASE environment.
# Running the generated firmware image may result in irreversible operations
# to the chip!
CONFIG_SECURE_SIGNED_ON_BOOT=1
CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
CONFIG_SECURE_BOOT=1
CONFIG_SECURE_BOOT_V2_ENABLED=1
CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
CONFIG_SECURE_FLASH_ENC_ENABLED=1
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
CONFIG_ESP_SIGN_KEY_FILE=root-rsa-2048.pem
CONFIG_ESP_USE_MBEDTLS=1
CONFIG_ESP_SIGN_RSA=1
CONFIG_ESP_SIGN_RSA_LEN=2048
CONFIG_ESP_DOWNGRADE_PREVENTION=1
CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=1

View File

@@ -0,0 +1,23 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# ATTENTION:
# This configuration file targets the building for CI environment and contains
# a set of definitions to resemble a bootloader image for RELEASE environment.
# Running the generated firmware image may result in irreversible operations
# to the chip!
CONFIG_SECURE_SIGNED_ON_BOOT=1
CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
CONFIG_SECURE_BOOT=1
CONFIG_SECURE_BOOT_V2_ENABLED=1
CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
CONFIG_SECURE_FLASH_ENC_ENABLED=1
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
CONFIG_ESP_SIGN_KEY_FILE=root-rsa-3072.pem
CONFIG_ESP_USE_MBEDTLS=1
CONFIG_ESP_SIGN_RSA=1
CONFIG_ESP_SIGN_RSA_LEN=3072
CONFIG_ESP_DOWNGRADE_PREVENTION=1
CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=1

View File

@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# ATTENTION:
# This configuration file targets the building for CI environment and contains
# a set of definitions to resemble a bootloader image for RELEASE environment.
CONFIG_ESP_MCUBOOT_SERIAL=y
CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y

View File

@@ -0,0 +1,213 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13)
project(hal)
set(esp_hal_dir ${ESP_HAL_PATH})
set(src_dir ${CMAKE_CURRENT_LIST_DIR}/src)
set(include_dirs
${CMAKE_CURRENT_LIST_DIR}/include
${CMAKE_CURRENT_LIST_DIR}/include/${MCUBOOT_TARGET}
)
list(APPEND include_dirs
${esp_hal_dir}/components/bootloader_support/include
${esp_hal_dir}/components/bootloader_support/private_include
${esp_hal_dir}/components/bootloader_support/bootloader_flash/include
${esp_hal_dir}/components/spi_flash/include
${esp_hal_dir}/components/spi_flash/include/spi_flash
${esp_hal_dir}/components/esp_app_format/include
${esp_hal_dir}/components/newlib/platform_include
${esp_hal_dir}/components/esp_common/include
${esp_hal_dir}/components/${MCUBOOT_ARCH}/include
${esp_hal_dir}/components/esp_rom/include
${esp_hal_dir}/components/esp_rom/include/${MCUBOOT_TARGET}
${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}
${esp_hal_dir}/components/soc/include
${esp_hal_dir}/components/soc/${MCUBOOT_TARGET}
${esp_hal_dir}/components/soc/${MCUBOOT_TARGET}/include
${esp_hal_dir}/components/efuse/include
${esp_hal_dir}/components/efuse/${MCUBOOT_TARGET}/include
${esp_hal_dir}/components/efuse/private_include
${esp_hal_dir}/components/efuse/${MCUBOOT_TARGET}/private_include
${esp_hal_dir}/components/esp_hw_support/include
${esp_hal_dir}/components/esp_hw_support/include/soc
${esp_hal_dir}/components/esp_hw_support/include/soc/${MCUBOOT_TARGET}
${esp_hal_dir}/components/esp_hw_support/port/include
${esp_hal_dir}/components/esp_hw_support/include/esp_private
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}
${esp_hal_dir}/components/hal/${MCUBOOT_TARGET}/include
${esp_hal_dir}/components/hal/include
${esp_hal_dir}/components/hal/platform_port/include
${esp_hal_dir}/components/esp_system/include
${esp_hal_dir}/components/log/include
)
if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
list(APPEND include_dirs
${esp_hal_dir}/components/${MCUBOOT_ARCH}/${MCUBOOT_TARGET}/include
${esp_hal_dir}/components/${MCUBOOT_ARCH}/include
)
endif()
set(hal_srcs
${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/bootloader_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_init.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_common.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_common_loader.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_console.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_console_loader.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_clock_init.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_clock_loader.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_efuse.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_panic.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_mem.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_random.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_random_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_utility.c
${esp_hal_dir}/components/bootloader_support/src/esp_image_format.c
${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/bootloader_soc.c
${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/bootloader_sha.c
${esp_hal_dir}/components/hal/mpu_hal.c
${esp_hal_dir}/components/hal/efuse_hal.c
${esp_hal_dir}/components/hal/mmu_hal.c
${esp_hal_dir}/components/hal/wdt_hal_iram.c
${esp_hal_dir}/components/hal/${MCUBOOT_TARGET}/efuse_hal.c
${esp_hal_dir}/components/soc/${MCUBOOT_TARGET}/uart_periph.c
${esp_hal_dir}/components/soc/${MCUBOOT_TARGET}/gpio_periph.c
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_time.c
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_clk.c
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_clk_init.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_uart.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_sys.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_spiflash.c
${esp_hal_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_table.c
${esp_hal_dir}/components/efuse/src/esp_efuse_fields.c
${esp_hal_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_fields.c
${esp_hal_dir}/components/efuse/src/esp_efuse_api.c
${esp_hal_dir}/components/efuse/src/esp_efuse_utility.c
${esp_hal_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_utility.c
${esp_hal_dir}/components/log/log_noos.c
${src_dir}/bootloader_banner.c
${src_dir}/bootloader_wdt.c
)
if(DEFINED CONFIG_SECURE_BOOT_V2_ENABLED)
list(APPEND hal_srcs
${src_dir}/secure_boot.c
${esp_hal_dir}/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c
${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/secure_boot_secure_features.c
)
list(APPEND include_dirs
${esp_hal_dir}/components/bootloader_support/src/secure_boot_v2
)
endif()
if(DEFINED CONFIG_SECURE_FLASH_ENC_ENABLED)
list(APPEND hal_srcs
${src_dir}/flash_encrypt.c
${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/flash_encryption_secure_features.c
)
set_source_files_properties(
${src_dir}/flash_encrypt.c
PROPERTIES COMPILE_FLAGS
"-Wno-unused-variable"
)
endif()
if("${MCUBOOT_ARCH}" STREQUAL "xtensa")
list(APPEND hal_srcs
${esp_hal_dir}/components/esp_rom/patches/esp_rom_longjmp.S
)
endif()
set(CFLAGS
"-nostdlib"
"-Wno-frame-address"
"-Wall"
"-Wextra"
"-W"
"-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"
)
set(LDFLAGS
"-Wno-frame-address"
"-Wl,--cref"
"-Wl,--Map=${APP_NAME}.map"
"-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_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.ld
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.libgcc.ld
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.api.ld
-T${esp_hal_dir}/components/soc/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.peripherals.ld
)
include(${CMAKE_CURRENT_LIST_DIR}/include/${MCUBOOT_TARGET}/${MCUBOOT_TARGET}.cmake)
add_library(hal STATIC ${hal_srcs} ${include_dirs})
# Wrap for overriding the print banner function from bootloader_support
add_definitions(-DIDF_VER=0)
target_link_libraries(
hal
INTERFACE
"-Wl,--wrap=bootloader_print_banner")
target_include_directories(
hal
PUBLIC
${include_dirs}
)
target_compile_options(
hal
PUBLIC
${CFLAGS}
)
target_link_libraries(
hal
PUBLIC
${LDFLAGS}
${LINKER_SCRIPTS}
)

View File

@@ -0,0 +1,11 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
void appcpu_start(uint32_t entry_addr);

View File

@@ -0,0 +1,8 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
void bootloader_wdt_feed(void);

View File

@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
list(APPEND hal_srcs
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_init.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/without_key_purposes/three_key_blocks/esp_efuse_api_key.c
)
if (DEFINED CONFIG_ESP_MULTI_PROCESSOR_BOOT)
list(APPEND hal_srcs
${src_dir}/${MCUBOOT_TARGET}/app_cpu_start.c
${esp_hal_dir}/components/esp_hw_support/cpu.c
)
endif()
if (DEFINED CONFIG_ESP_CONSOLE_UART_CUSTOM)
list(APPEND hal_srcs
${src_dir}/${MCUBOOT_TARGET}/console_uart_custom.c
)
endif()
list(APPEND LINKER_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib-funcs.ld
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.eco3.ld
)
set_source_files_properties(
${esp_hal_dir}/components/bootloader_support/src/esp32/bootloader_esp32.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash.c
PROPERTIES COMPILE_FLAGS
"-Wno-unused-variable -Wno-unused-but-set-variable")

View File

@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BOOTLOADER_BUILD 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0000
#define CONFIG_IDF_TARGET_ESP32 1
#define CONFIG_ESP32_REV_MIN_3 1
#define CONFIG_ESP32_REV_MIN_FULL 300
#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32_REV_MIN_FULL
#define CONFIG_ESP32_REV_MIN 3
#define CONFIG_ESP32_REV_MAX_FULL 399
#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32_REV_MAX_FULL
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_MMU_PAGE_SIZE 0x10000
#define CONFIG_ESP32_XTAL_FREQ 40
#define CONFIG_XTAL_FREQ 40
#define CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 1
#define CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ 160
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x1000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
#define CONFIG_EFUSE_MAX_BLK_LEN 192
#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1

View File

@@ -0,0 +1,29 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
list(APPEND hal_srcs
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_init.c
${esp_hal_dir}/components/hal/cache_hal.c
${esp_hal_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_table.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/without_key_purposes/one_key_block/esp_efuse_api_key.c
)
if (DEFINED CONFIG_ESP_CONSOLE_UART_CUSTOM)
list(APPEND hal_srcs
${src_dir}/${MCUBOOT_TARGET}/console_uart_custom.c
)
endif()
list(APPEND LINKER_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
)
set_source_files_properties(
${esp_hal_dir}/components/bootloader_support/src/esp_image_format.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/hal/mmu_hal.c
${esp_hal_dir}/components/hal/cache_hal.c
PROPERTIES COMPILE_FLAGS
"-Wno-logical-op")

View File

@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BOOTLOADER_BUILD 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x000C
#define CONFIG_IDF_TARGET_ESP32C2 1
#define CONFIG_ESP32C2_REV_MIN_0 1
#define CONFIG_ESP32C2_REV_MIN_FULL 3
#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32C2_REV_MIN_FULL
#define CONFIG_ESP32C2_REV_MIN 3
#define CONFIG_ESP32C2_REV_MAX_FULL 99
#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32C2_REV_MAX_FULL
#define CONFIG_IDF_TARGET_ARCH_RISCV 1
#define CONFIG_MMU_PAGE_SIZE 0x10000
#define CONFIG_XTAL_FREQ_26 1
#define CONFIG_XTAL_FREQ 26
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
#define CONFIG_EFUSE_MAX_BLK_LEN 256
#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1

View File

@@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
list(APPEND hal_srcs
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_init.c
${esp_hal_dir}/components/hal/cache_hal.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
)
if (DEFINED CONFIG_ESP_CONSOLE_UART_CUSTOM)
list(APPEND hal_srcs
${src_dir}/${MCUBOOT_TARGET}/console_uart_custom.c
)
endif()
list(APPEND LINKER_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.eco3.ld
)

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BOOTLOADER_BUILD 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0005
#define CONFIG_IDF_TARGET_ESP32C3 1
#define CONFIG_ESP32C3_REV_MIN_3 1
#define CONFIG_ESP32C3_REV_MIN_FULL 3
#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32C3_REV_MIN_FULL
#define CONFIG_ESP32C3_REV_MIN 3
#define CONFIG_ESP32C3_REV_MAX_FULL 99
#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32C3_REV_MAX_FULL
#define CONFIG_IDF_TARGET_ARCH_RISCV 1
#define CONFIG_MMU_PAGE_SIZE 0x10000
#define CONFIG_XTAL_FREQ 40
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
#define CONFIG_EFUSE_MAX_BLK_LEN 256
#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1

View File

@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
list(APPEND include_dirs
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/private_include
)
list(APPEND hal_srcs
${esp_hal_dir}/components/hal/cache_hal.c
${esp_hal_dir}/components/hal/lp_timer_hal.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_hp_regi2c_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/pmu_param.c
)
if (DEFINED CONFIG_ESP_CONSOLE_UART_CUSTOM)
list(APPEND hal_srcs
${src_dir}/${MCUBOOT_TARGET}/console_uart_custom.c
)
endif()
list(APPEND LINKER_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
)
set_source_files_properties(
${esp_hal_dir}/components/bootloader_support/src/esp_image_format.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/hal/mmu_hal.c
${esp_hal_dir}/components/hal/cache_hal.c
PROPERTIES COMPILE_FLAGS
"-Wno-logical-op")

View File

@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BOOTLOADER_BUILD 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x000D
#define CONFIG_IDF_TARGET_ESP32C6 1
#define CONFIG_ESP32C6_REV_MIN_0 1
#define CONFIG_ESP32C6_REV_MIN_FULL 0
#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32C6_REV_MIN_FULL
#define CONFIG_ESP32C6_REV_MIN 0
#define CONFIG_ESP32C6_REV_MAX_FULL 99
#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32C6_REV_MAX_FULL
#define CONFIG_IDF_TARGET_ARCH_RISCV 1
#define CONFIG_MMU_PAGE_SIZE 0x10000
#define SOC_MMU_PAGE_SIZE CONFIG_MMU_PAGE_SIZE /* from soc/CMakeLists */
#define CONFIG_XTAL_FREQ 40
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
#define CONFIG_EFUSE_MAX_BLK_LEN 256
#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1

View File

@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
list(APPEND include_dirs
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/private_include
)
list(APPEND hal_srcs
${esp_hal_dir}/components/hal/cache_hal.c
${esp_hal_dir}/components/hal/lp_timer_hal.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_regi2c_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/pmu_param.c
)
if (DEFINED CONFIG_ESP_CONSOLE_UART_CUSTOM)
list(APPEND hal_srcs
${src_dir}/${MCUBOOT_TARGET}/console_uart_custom.c
)
endif()
list(APPEND LINKER_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
)
set_source_files_properties(
${esp_hal_dir}/components/bootloader_support/src/esp_image_format.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash.c
${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/hal/mmu_hal.c
${esp_hal_dir}/components/hal/cache_hal.c
PROPERTIES COMPILE_FLAGS
"-Wno-logical-op")

View File

@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BOOTLOADER_BUILD 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0010
#define CONFIG_IDF_TARGET_ESP32H2 1
#define CONFIG_ESP32H2_REV_MIN_0 1
#define CONFIG_ESP32H2_REV_MIN_FULL 0
#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32H2_REV_MIN_FULL
#define CONFIG_ESP32H2_REV_MIN 0
#define CONFIG_ESP32H2_REV_MAX_FULL 99
#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32H2_REV_MAX_FULL
#define CONFIG_IDF_TARGET_ARCH_RISCV 1
#define CONFIG_MMU_PAGE_SIZE 0x10000
#define SOC_MMU_PAGE_SIZE CONFIG_MMU_PAGE_SIZE /* from soc/CMakeLists */
#define CONFIG_XTAL_FREQ_32 1
#define CONFIG_XTAL_FREQ 32
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
#define CONFIG_EFUSE_MAX_BLK_LEN 256
#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1

View File

@@ -0,0 +1,22 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
list(APPEND hal_srcs
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_init.c
${esp_hal_dir}/components/hal/cache_hal.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_crc.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_regi2c_esp32s2.c
)
list(APPEND LINKER_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib-funcs.ld
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.spiflash.ld
)
set_source_files_properties(
${esp_hal_dir}/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c
PROPERTIES COMPILE_FLAGS
"-Wno-unused-but-set-variable")

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BOOTLOADER_BUILD 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0002
#define CONFIG_IDF_TARGET_ESP32S2 1
#define CONFIG_ESP32S2_REV_MIN_0 1
#define CONFIG_ESP32S2_REV_MIN_FULL 0
#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32S2_REV_MIN_FULL
#define CONFIG_ESP32S2_REV_MIN 0
#define CONFIG_ESP32S2_REV_MAX_FULL 99
#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32S2_REV_MAX_FULL
#define CONFIG_MMU_PAGE_SIZE 0x10000
#define CONFIG_XTAL_FREQ 40
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_ESP32S2_XTAL_FREQ 40
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x1000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
#define CONFIG_EFUSE_MAX_BLK_LEN 256
#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1

View File

@@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
list(APPEND hal_srcs
${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_init.c
${esp_hal_dir}/components/hal/cache_hal.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
)
if (DEFINED CONFIG_ESP_MULTI_PROCESSOR_BOOT)
list(APPEND hal_srcs
${src_dir}/${MCUBOOT_TARGET}/app_cpu_start.c
${esp_hal_dir}/components/esp_hw_support/cpu.c
)
endif()
list(APPEND LINKER_SCRIPTS
-T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld
)
set_source_files_properties(
${esp_hal_dir}/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c
PROPERTIES COMPILE_FLAGS
"-Wno-unused-variable -Wno-unused-but-set-variable")

View File

@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BOOTLOADER_BUILD 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0009
#define CONFIG_IDF_TARGET_ESP32S3 1
#define CONFIG_ESP32S3_REV_MIN_0 1
#define CONFIG_ESP32S3_REV_MIN_FULL 0
#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32S3_REV_MIN_FULL
#define CONFIG_ESP32S3_REV_MIN 0
#define CONFIG_ESP32S3_REV_MAX_FULL 99
#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32S3_REV_MAX_FULL
#define CONFIG_MMU_PAGE_SIZE 0x10000
#define CONFIG_XTAL_FREQ 40
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_MCUBOOT 1
#define NDEBUG 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000
#define CONFIG_PARTITION_TABLE_OFFSET 0x10000
#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000
#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000
#define CONFIG_EFUSE_MAX_BLK_LEN 256

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <inttypes.h>
#include <mcuboot_config/mcuboot_logging.h>
/* Log levels from IDF are similar to MCUboot's */
#ifndef CONFIG_BOOTLOADER_LOG_LEVEL
#define CONFIG_BOOTLOADER_LOG_LEVEL MCUBOOT_LOG_LEVEL
#endif
#define ESP_LOGE(tag, fmt, ...) MCUBOOT_LOG_ERR("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_LOGV(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGE(tag, fmt, ...) MCUBOOT_LOG_ERR("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
#define ESP_EARLY_LOGV(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)
uint32_t esp_log_early_timestamp(void);

View File

@@ -0,0 +1,26 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/* Magic is derived from sha256sum of the string "espmcuboot"
* The application header magic must match this number
*/
#define ESP_LOAD_HEADER_MAGIC 0xace637d3
/* Load header that should be a part of application image
* for MCUboot-Espressif port booting.
*/
typedef struct esp_image_load_header {
uint32_t header_magic; /* Magic for load header */
uint32_t entry_addr; /* Application entry address */
uint32_t iram_dest_addr; /* Destination address(VMA) for IRAM region */
uint32_t iram_flash_offset; /* Flash offset(LMA) for start of IRAM region */
uint32_t iram_size; /* Size of IRAM region */
uint32_t dram_dest_addr; /* Destination address(VMA) for DRAM region */
uint32_t dram_flash_offset; /* Flash offset(LMA) for start of DRAM region */
uint32_t dram_size; /* Size of DRAM region */
} esp_image_load_header_t;

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
extern void mcuboot_assert_handler(const char *file, int line, const char *func);
#ifdef assert
#undef assert
#endif
#define assert(arg) \
do { \
if (!(arg)) { \
mcuboot_assert_handler(__FILE__, __LINE__, __func__); \
} \
} while(0)

View File

@@ -0,0 +1,193 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __MCUBOOT_CONFIG_H__
#define __MCUBOOT_CONFIG_H__
/*
* Signature types
*
* You must choose exactly one signature type - check bootloader.conf
* configuration file
*/
/* Uncomment for RSA signature support */
#if defined(CONFIG_ESP_SIGN_RSA)
#define MCUBOOT_SIGN_RSA
# if (CONFIG_ESP_SIGN_RSA_LEN != 2048 && \
CONFIG_ESP_SIGN_RSA_LEN != 3072)
# error "Invalid RSA key size (must be 2048 or 3072)"
# else
# define MCUBOOT_SIGN_RSA_LEN CONFIG_ESP_SIGN_RSA_LEN
# endif
#elif defined(CONFIG_ESP_SIGN_EC256)
#define MCUBOOT_SIGN_EC256
#elif defined(CONFIG_ESP_SIGN_ED25519)
#define MCUBOOT_SIGN_ED25519
#endif
#if defined(CONFIG_SECURE_FLASH_ENC_ENABLED)
#define MCUBOOT_BOOT_MAX_ALIGN 32
#endif
/*
* Upgrade mode
*
* The default is to support A/B image swapping with rollback. Other modes
* with simpler code path, which only supports overwriting the existing image
* with the update image or running the newest image directly from its flash
* partition, are also available.
*
* You can enable only one mode at a time from the list below to override
* the default upgrade mode.
*/
/* Uncomment to enable the overwrite-only code path. */
/* #define MCUBOOT_OVERWRITE_ONLY */
#ifdef MCUBOOT_OVERWRITE_ONLY
/* Uncomment to only erase and overwrite those primary slot sectors needed
* to install the new image, rather than the entire image slot. */
/* #define MCUBOOT_OVERWRITE_ONLY_FAST */
#endif
/* Uncomment to enable the direct-xip code path. */
/* #define MCUBOOT_DIRECT_XIP */
/* Uncomment to enable the ram-load code path. */
/* #define MCUBOOT_RAM_LOAD */
/*
* Cryptographic settings
*
* You must choose between Mbed TLS and Tinycrypt as source of
* cryptographic primitives. Other cryptographic settings are also
* available.
*/
/* Uncomment to use Mbed TLS cryptographic primitives */
#if defined(CONFIG_ESP_USE_MBEDTLS)
#define MCUBOOT_USE_MBED_TLS
#else
/* MCUboot requires the definition of a crypto lib,
* using Tinycrypt as default */
#define MCUBOOT_USE_TINYCRYPT
#endif
/*
* Always check the signature of the image in the primary slot before booting,
* even if no upgrade was performed. This is recommended if the boot
* time penalty is acceptable.
*/
#define MCUBOOT_VALIDATE_PRIMARY_SLOT
#ifdef CONFIG_ESP_DOWNGRADE_PREVENTION
#define MCUBOOT_DOWNGRADE_PREVENTION 1
/* MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER is used later as bool value so it is
* always defined, (unlike MCUBOOT_DOWNGRADE_PREVENTION which is only used in
* preprocessor condition and my be not defined) */
# ifdef CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER
# define MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER 1
# else
# define MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER 0
# endif
#endif
/*
* Flash abstraction
*/
/* Uncomment if your flash map API supports flash_area_get_sectors().
* See the flash APIs for more details. */
#define MCUBOOT_USE_FLASH_AREA_GET_SECTORS
/* Default maximum number of flash sectors per image slot; change
* as desirable. */
#define MCUBOOT_MAX_IMG_SECTORS 512
/* Default number of separately updateable images; change in case of
* multiple images. */
#if defined(CONFIG_ESP_IMAGE_NUMBER)
#define MCUBOOT_IMAGE_NUMBER CONFIG_ESP_IMAGE_NUMBER
#else
#define MCUBOOT_IMAGE_NUMBER 1
#endif
/*
* Logging
*/
/*
* If logging is enabled the following functions must be defined by the
* platform:
*
* MCUBOOT_LOG_MODULE_REGISTER(domain)
* Register a new log module and add the current C file to it.
*
* MCUBOOT_LOG_MODULE_DECLARE(domain)
* Add the current C file to an existing log module.
*
* MCUBOOT_LOG_ERR(...)
* MCUBOOT_LOG_WRN(...)
* MCUBOOT_LOG_INF(...)
* MCUBOOT_LOG_DBG(...)
*
* The function priority is:
*
* MCUBOOT_LOG_ERR > MCUBOOT_LOG_WRN > MCUBOOT_LOG_INF > MCUBOOT_LOG_DBG
*/
#define MCUBOOT_HAVE_LOGGING 1
/* #define MCUBOOT_LOG_LEVEL MCUBOOT_LOG_LEVEL_INFO */
/*
* Assertions
*/
/* Uncomment if your platform has its own mcuboot_config/mcuboot_assert.h.
* If so, it must provide an ASSERT macro for use by bootutil. Otherwise,
* "assert" is used. */
#define MCUBOOT_HAVE_ASSERT_H 1
#ifdef CONFIG_ESP_MCUBOOT_SERIAL
#define CONFIG_MCUBOOT_SERIAL
#endif
/*
* When a serial recovery process is receiving the image data, this option
* enables it to erase flash progressively (by sectors) instead of the
* default behavior that is erasing whole image size of flash area after
* receiving first frame.
* Enabling this options prevents stalling the beginning of transfer
* for the time needed to erase large chunk of flash.
*/
#ifdef CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY
#define MCUBOOT_ERASE_PROGRESSIVELY
#endif
/* Serial extensions are not implemented
*/
#define MCUBOOT_PERUSER_MGMT_GROUP_ENABLED 0
/*
* Watchdog feeding
*/
/* This macro might be implemented if the OS / HW watchdog is enabled while
* doing a swap upgrade and the time it takes for a swapping is long enough
* to cause an unwanted reset. If implementing this, the OS main.c must also
* enable the watchdog (if required)!
*/
#include <bootloader_wdt.h>
#define MCUBOOT_WATCHDOG_FEED() \
do { \
bootloader_wdt_feed(); \
} while (0)
#define MCUBOOT_CPU_IDLE() \
do { \
} while (0)
#endif /* __MCUBOOT_CONFIG_H__ */

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "mcuboot_config.h"
extern int ets_printf(const char *fmt, ...);
#define MCUBOOT_LOG_LEVEL_OFF 0
#define MCUBOOT_LOG_LEVEL_ERROR 1
#define MCUBOOT_LOG_LEVEL_WARNING 2
#define MCUBOOT_LOG_LEVEL_INFO 3
#define MCUBOOT_LOG_LEVEL_DEBUG 4
#if CONFIG_IDF_TARGET_ESP32
#define TARGET "[esp32]"
#elif CONFIG_IDF_TARGET_ESP32S2
#define TARGET "[esp32s2]"
#elif CONFIG_IDF_TARGET_ESP32S3
#define TARGET "[esp32s3]"
#elif CONFIG_IDF_TARGET_ESP32C3
#define TARGET "[esp32c3]"
#elif CONFIG_IDF_TARGET_ESP32C6
#define TARGET "[esp32c6]"
#elif CONFIG_IDF_TARGET_ESP32C2
#define TARGET "[esp32c2]"
#elif CONFIG_IDF_TARGET_ESP32H2
#define TARGET "[esp32h2]"
#else
#error "Selected target not supported."
#endif
#ifndef MCUBOOT_LOG_LEVEL
#define MCUBOOT_LOG_LEVEL MCUBOOT_LOG_LEVEL_INFO
#endif
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_ERROR
#define MCUBOOT_LOG_ERR(_fmt, ...) \
do { \
ets_printf(TARGET " [ERR] " _fmt "\n\r", ##__VA_ARGS__); \
} while (0)
#else
#define MCUBOOT_LOG_ERR(_fmt, ...)
#endif
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_WARNING
#define MCUBOOT_LOG_WRN(_fmt, ...) \
do { \
ets_printf(TARGET " [WRN] " _fmt "\n\r", ##__VA_ARGS__); \
} while (0)
#else
#define MCUBOOT_LOG_WRN(_fmt, ...)
#endif
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_INFO
#define MCUBOOT_LOG_INF(_fmt, ...) \
do { \
ets_printf(TARGET " [INF] " _fmt "\n\r", ##__VA_ARGS__); \
} while (0)
#else
#define MCUBOOT_LOG_INF(_fmt, ...)
#endif
#if MCUBOOT_LOG_LEVEL >= MCUBOOT_LOG_LEVEL_DEBUG
#define MCUBOOT_LOG_DBG(_fmt, ...) \
do { \
ets_printf(TARGET " [DBG] " _fmt "\n\r", ##__VA_ARGS__); \
} while (0)
#else
#define MCUBOOT_LOG_DBG(_fmt, ...)
#endif
#define MCUBOOT_LOG_MODULE_DECLARE(...)
#define MCUBOOT_LOG_MODULE_REGISTER(...)

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <mcuboot_config/mcuboot_logging.h>
#include <esp_rom_sys.h>
#define SOC_LOGE(tag, fmt, ...) MCUBOOT_LOG_ERR("[%s] " fmt, tag, ##__VA_ARGS__)
#define SOC_LOGW(tag, fmt, ...) MCUBOOT_LOG_WRN("[%s] " fmt, tag, ##__VA_ARGS__)
#define SOC_LOGI(tag, fmt, ...) MCUBOOT_LOG_INF("[%s] " fmt, tag, ##__VA_ARGS__)
#define SOC_LOGD(tag, fmt, ...) MCUBOOT_LOG_DBG("[%s] " fmt, tag, ##__VA_ARGS__)

View File

@@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <mcuboot_config/mcuboot_logging.h>
/**
* Override the bootloader's print banner function from IDF.
*/
void __wrap_bootloader_print_banner(void)
{
MCUBOOT_LOG_INF("*** Booting MCUboot build %s ***", MCUBOOT_VER);
}

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootloader_wdt.h>
#include <hal/wdt_hal.h>
#include "soc/rtc.h"
void bootloader_wdt_feed(void)
{
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
wdt_hal_feed(&rtc_wdt_ctx);
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
}

View File

@@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "app_cpu_start.h"
#include "soc/dport_reg.h"
#include "soc/gpio_periph.h"
#include "soc/rtc_periph.h"
#include "soc/rtc_cntl_reg.h"
#include "esp32/rom/cache.h"
#include "esp32/rom/uart.h"
#include "esp_cpu.h"
#include "esp_log.h"
static const char *TAG = "app_cpu_start";
void appcpu_start(uint32_t entry_addr)
{
ESP_LOGI(TAG, "Starting APPCPU");
Cache_Flush(1);
Cache_Read_Enable(1);
esp_cpu_unstall(1);
DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL);
DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
ets_set_appcpu_boot_addr(entry_addr);
ets_delay_us(10000);
uart_tx_wait_idle(0);
ESP_LOGI(TAG, "APPCPU start sequence complete");
}

View File

@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_rom_uart.h>
#include <hal/uart_ll.h>
#include <soc/uart_periph.h>
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
static uart_dev_t *alt_console_uart_dev = (CONFIG_ESP_CONSOLE_UART_NUM == 0) ?
&UART0 :
(CONFIG_ESP_CONSOLE_UART_NUM == 1) ?
&UART1 :
&UART2;
void IRAM_ATTR esp_rom_uart_putc(char c)
{
while (uart_ll_get_txfifo_len(alt_console_uart_dev) == 0);
uart_ll_write_txfifo(alt_console_uart_dev, (const uint8_t *) &c, 1);
}
#endif

View File

@@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_rom_uart.h>
#include <hal/uart_ll.h>
#include <soc/uart_periph.h>
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
static uart_dev_t *alt_console_uart_dev = (CONFIG_ESP_CONSOLE_UART_NUM == 0) ?
&UART0 :
&UART1;
void IRAM_ATTR esp_rom_uart_putc(char c)
{
while (uart_ll_get_txfifo_len(alt_console_uart_dev) == 0);
uart_ll_write_txfifo(alt_console_uart_dev, (const uint8_t *) &c, 1);
}
#endif

View File

@@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_rom_uart.h>
#include <hal/uart_ll.h>
#include <soc/uart_periph.h>
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
static uart_dev_t *alt_console_uart_dev = (CONFIG_ESP_CONSOLE_UART_NUM == 0) ?
&UART0 :
&UART1;
void IRAM_ATTR esp_rom_uart_putc(char c)
{
while (uart_ll_get_txfifo_len(alt_console_uart_dev) == 0);
uart_ll_write_txfifo(alt_console_uart_dev, (const uint8_t *) &c, 1);
}
#endif

View File

@@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_rom_uart.h>
#include <hal/uart_ll.h>
#include <soc/uart_periph.h>
#include <esp_attr.h>
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
static uart_dev_t *alt_console_uart_dev = (CONFIG_ESP_CONSOLE_UART_NUM == 0) ?
&UART0 :
&UART1;
void IRAM_ATTR esp_rom_uart_putc(char c)
{
while (uart_ll_get_txfifo_len(alt_console_uart_dev) == 0);
uart_ll_write_txfifo(alt_console_uart_dev, (const uint8_t *) &c, 1);
}
#endif

View File

@@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_rom_uart.h>
#include <hal/uart_ll.h>
#include <soc/uart_periph.h>
#include <esp_attr.h>
#if CONFIG_ESP_CONSOLE_UART_CUSTOM
static uart_dev_t *alt_console_uart_dev = (CONFIG_ESP_CONSOLE_UART_NUM == 0) ?
&UART0 :
&UART1;
void IRAM_ATTR esp_rom_uart_putc(char c)
{
while (uart_ll_get_txfifo_len(alt_console_uart_dev) == 0);
uart_ll_write_txfifo(alt_console_uart_dev, (const uint8_t *) &c, 1);
}
#endif

View File

@@ -0,0 +1,42 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "app_cpu_start.h"
#include "esp_rom_sys.h"
#include "soc/dport_reg.h"
#include "soc/gpio_periph.h"
#include "soc/rtc_periph.h"
#include "soc/rtc_cntl_reg.h"
#include "esp32s3/rom/cache.h"
#include "esp32s3/rom/uart.h"
#include "esp_cpu.h"
#include "esp_log.h"
static const char *TAG = "app_cpu_start";
void appcpu_start(uint32_t entry_addr)
{
ESP_LOGI(TAG, "Starting APPCPU");
esp_cpu_unstall(1);
// Enable clock and reset APP CPU. Note that OpenOCD may have already
// enabled clock and taken APP CPU out of reset. In this case don't reset
// APP CPU again, as that will clear the breakpoints which may have already
// been set.
if (!REG_GET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN)) {
REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN);
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RUNSTALL);
REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETING);
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETING);
}
ets_set_appcpu_boot_addr(entry_addr);
esp_rom_delay_us(10000);
uart_tx_wait_idle(0);
ESP_LOGI(TAG, "APPCPU start sequence complete");
}

View File

@@ -0,0 +1,482 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <strings.h>
#include "bootloader_flash_priv.h"
#include "bootloader_random.h"
#include "esp_image_format.h"
#include "esp_flash_encrypt.h"
#include "esp_flash_partitions.h"
#include "esp_secure_boot.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_log.h"
#include "hal/wdt_hal.h"
#include "hal/efuse_hal.h"
#include "soc/soc_caps.h"
#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
#include "soc/sensitive_reg.h"
#endif
#include "esp_mcuboot_image.h"
#if CONFIG_IDF_TARGET_ESP32
#define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT
#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT
#else
#define CRYPT_CNT ESP_EFUSE_SPI_BOOT_CRYPT_CNT
#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT
#endif
#define FLASH_ENC_CNT_MAX (CRYPT_CNT[0]->bit_count)
/* This file implements FLASH ENCRYPTION related APIs to perform
* various operations such as programming necessary flash encryption
* eFuses, detect whether flash encryption is enabled (by reading eFuse)
* and if required encrypt the partitions in flash memory
*/
static const char *TAG = "flash_encrypt";
/* Static functions for stages of flash encryption */
static esp_err_t encrypt_bootloader(void);
static esp_err_t encrypt_primary_slot(void);
static size_t get_flash_encrypt_cnt_value(void);
/**
* This former inlined function must not be defined in the header file anymore.
* As it depends on efuse component, any use of it outside of `bootloader_support`,
* would require the caller component to include `efuse` as part of its `REQUIRES` or
* `PRIV_REQUIRES` entries.
* Attribute IRAM_ATTR must be specified for the app build.
*/
bool IRAM_ATTR esp_flash_encryption_enabled(void)
{
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
return efuse_hal_flash_encryption_enabled();
#else
uint32_t flash_crypt_cnt = 0;
#if CONFIG_IDF_TARGET_ESP32
esp_efuse_read_field_blob(ESP_EFUSE_FLASH_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count);
#else
esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_SPI_BOOT_CRYPT_CNT[0]->bit_count);
#endif
/* __builtin_parity is in flash, so we calculate parity inline */
bool enabled = false;
while (flash_crypt_cnt) {
if (flash_crypt_cnt & 1) {
enabled = !enabled;
}
flash_crypt_cnt >>= 1;
}
return enabled;
#endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
}
static size_t get_flash_encrypt_cnt_value(void)
{
size_t flash_crypt_cnt = 0;
esp_efuse_read_field_cnt(CRYPT_CNT, &flash_crypt_cnt);
return flash_crypt_cnt;
}
bool esp_flash_encrypt_initialized_once(void)
{
return get_flash_encrypt_cnt_value() != 0;
}
bool esp_flash_encrypt_is_write_protected(bool print_error)
{
if (esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT)) {
if (print_error) {
ESP_LOGE(TAG, "Flash Encryption cannot be enabled (CRYPT_CNT (%d) is write protected)", get_flash_encrypt_cnt_value());
}
return true;
}
return false;
}
bool esp_flash_encrypt_state(void)
{
size_t flash_crypt_cnt = get_flash_encrypt_cnt_value();
bool flash_crypt_wr_dis = esp_flash_encrypt_is_write_protected(false);
ESP_LOGV(TAG, "CRYPT_CNT %d, write protection %d", flash_crypt_cnt, flash_crypt_wr_dis);
if (flash_crypt_cnt % 2 == 1) {
/* Flash is already encrypted */
int left = (FLASH_ENC_CNT_MAX - flash_crypt_cnt) / 2;
if (flash_crypt_wr_dis) {
left = 0; /* can't update FLASH_CRYPT_CNT, no more flashes */
}
ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
return true;
}
return false;
}
esp_err_t esp_flash_encrypt_check_and_update(void)
{
bool flash_encryption_enabled = esp_flash_encrypt_state();
if (!flash_encryption_enabled) {
#ifndef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
if (esp_flash_encrypt_is_write_protected(true)) {
return ESP_FAIL;
}
esp_err_t err = esp_flash_encrypt_init();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Initialization of Flash encryption key failed (%d)", err);
return err;
}
err = esp_flash_encrypt_contents();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Encryption flash contents failed (%d)", err);
return err;
}
err = esp_flash_encrypt_enable();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Enabling of Flash encryption failed (%d)", err);
return err;
}
#else
ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED "
"is set, refusing to boot.");
return ESP_ERR_INVALID_STATE;
#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
}
return ESP_OK;
}
static esp_err_t check_and_generate_encryption_keys(void)
{
size_t key_size = 32;
#ifdef CONFIG_IDF_TARGET_ESP32
enum { BLOCKS_NEEDED = 1 };
esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
ESP_EFUSE_KEY_PURPOSE_FLASH_ENCRYPTION,
};
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_ENCRYPT_FLASH);
if (coding_scheme != EFUSE_CODING_SCHEME_NONE && coding_scheme != EFUSE_CODING_SCHEME_3_4) {
ESP_LOGE(TAG, "Unknown/unsupported CODING_SCHEME value 0x%x", coding_scheme);
return ESP_ERR_NOT_SUPPORTED;
}
if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
key_size = 24;
}
#else
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_AES256
enum { BLOCKS_NEEDED = 2 };
esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1,
ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2,
};
if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY, NULL)) {
ESP_LOGE(TAG, "XTS_AES_128_KEY is already in use, XTS_AES_256_KEY_1/2 can not be used");
return ESP_ERR_INVALID_STATE;
}
#else
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_AES128_DERIVED
enum { BLOCKS_NEEDED = 1 };
esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS,
};
key_size = 16;
#else
enum { BLOCKS_NEEDED = 1 };
esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
};
#endif // CONFIG_SECURE_FLASH_ENCRYPTION_AES128_DERIVED
#endif // CONFIG_SECURE_FLASH_ENCRYPTION_AES256
#endif // CONFIG_IDF_TARGET_ESP32
/* Initialize all efuse block entries to invalid (max) value */
esp_efuse_block_t blocks[BLOCKS_NEEDED] = {[0 ... BLOCKS_NEEDED-1] = EFUSE_BLK_KEY_MAX};
bool has_key = true;
for (unsigned i = 0; i < BLOCKS_NEEDED; i++) {
bool tmp_has_key = esp_efuse_find_purpose(purposes[i], &blocks[i]);
if (tmp_has_key) { // For ESP32: esp_efuse_find_purpose() always returns True, need to check whether the key block is used or not.
tmp_has_key &= !esp_efuse_key_block_unused(blocks[i]);
}
if (i == 1 && tmp_has_key != has_key) {
ESP_LOGE(TAG, "Invalid efuse key blocks: Both AES-256 key blocks must be set.");
return ESP_ERR_INVALID_STATE;
}
has_key &= tmp_has_key;
}
if (!has_key) {
/* Generate key */
uint8_t keys[BLOCKS_NEEDED][32] = { 0 };
ESP_LOGI(TAG, "Generating new flash encryption key...");
for (unsigned i = 0; i < BLOCKS_NEEDED; ++i) {
bootloader_fill_random(keys[i], key_size);
}
ESP_LOGD(TAG, "Key generation complete");
esp_err_t err = esp_efuse_write_keys(purposes, keys, BLOCKS_NEEDED);
if (err != ESP_OK) {
if (err == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
ESP_LOGE(TAG, "Not enough free efuse key blocks (need %d) to continue", BLOCKS_NEEDED);
} else {
ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", err);
}
return err;
}
} else {
for (unsigned i = 0; i < BLOCKS_NEEDED; i++) {
if (!esp_efuse_get_key_dis_write(blocks[i])
|| !esp_efuse_get_key_dis_read(blocks[i])
|| !esp_efuse_get_keypurpose_dis_write(blocks[i])) { // For ESP32: no keypurpose, it returns always True.
ESP_LOGE(TAG, "Invalid key state, check read&write protection for key and keypurpose(if exists)");
return ESP_ERR_INVALID_STATE;
}
}
ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse");
}
return ESP_OK;
}
esp_err_t esp_flash_encrypt_init(void)
{
if (esp_flash_encryption_enabled() || esp_flash_encrypt_initialized_once()) {
return ESP_OK;
}
/* Very first flash encryption pass: generate keys, etc. */
esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
/* Before first flash encryption pass, need to initialise key & crypto config */
esp_err_t err = check_and_generate_encryption_keys();
if (err != ESP_OK) {
esp_efuse_batch_write_cancel();
return err;
}
err = esp_flash_encryption_enable_secure_features();
if (err != ESP_OK) {
esp_efuse_batch_write_cancel();
return err;
}
err = esp_efuse_batch_write_commit();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
return err;
}
return ESP_OK;
}
/* Encrypt all flash data that should be encrypted */
esp_err_t esp_flash_encrypt_contents(void)
{
esp_err_t err;
#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
REG_WRITE(SENSITIVE_XTS_AES_KEY_UPDATE_REG, 1);
#endif
err = encrypt_bootloader();
if (err != ESP_OK) {
return err;
}
/* If the primary slot executable application is not encrypted,
* then encrypt it
*/
err = encrypt_primary_slot();
if (err != ESP_OK) {
return err;
}
/* Unconditionally encrypts remaining regions
* This will need changes when implementing multi-slot support
*/
ESP_LOGI(TAG, "Encrypting remaining flash...");
uint32_t region_addr = CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS;
size_t region_size = CONFIG_ESP_APPLICATION_SIZE;
err = esp_flash_encrypt_region(region_addr, region_size);
if (err != ESP_OK) {
return err;
}
region_addr = CONFIG_ESP_SCRATCH_OFFSET;
region_size = CONFIG_ESP_SCRATCH_SIZE;
err = esp_flash_encrypt_region(region_addr, region_size);
if (err != ESP_OK) {
return err;
}
#if defined(CONFIG_ESP_IMAGE_NUMBER) && (CONFIG_ESP_IMAGE_NUMBER == 2)
region_addr = CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS;
region_size = CONFIG_ESP_APPLICATION_SIZE;
err = esp_flash_encrypt_region(region_addr, region_size);
if (err != ESP_OK) {
return err;
}
region_addr = CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS;
region_size = CONFIG_ESP_APPLICATION_SIZE;
err = esp_flash_encrypt_region(region_addr, region_size);
if (err != ESP_OK) {
return err;
}
#endif
ESP_LOGI(TAG, "Flash encryption completed");
return ESP_OK;
}
esp_err_t esp_flash_encrypt_enable(void)
{
esp_err_t err = ESP_OK;
if (!esp_flash_encryption_enabled()) {
if (esp_flash_encrypt_is_write_protected(true)) {
return ESP_FAIL;
}
size_t flash_crypt_cnt = get_flash_encrypt_cnt_value();
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
// Go straight to max, permanently enabled
ESP_LOGI(TAG, "Setting CRYPT_CNT for permanent encryption");
size_t new_flash_crypt_cnt = FLASH_ENC_CNT_MAX - flash_crypt_cnt;
#else
/* Set least significant 0-bit in flash_crypt_cnt */
size_t new_flash_crypt_cnt = 1;
#endif
ESP_LOGD(TAG, "CRYPT_CNT %d -> %d", flash_crypt_cnt, new_flash_crypt_cnt);
err = esp_efuse_write_field_cnt(CRYPT_CNT, new_flash_crypt_cnt);
#if defined(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE) && defined(CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED)
// For AES128_DERIVED, FE key is 16 bytes and XTS_KEY_LENGTH_256 is 0.
// It is important to protect XTS_KEY_LENGTH_256 from further changing it to 1. Set write protection for this bit.
// Burning WR_DIS_CRYPT_CNT, blocks further changing of eFuses: DOWNLOAD_DIS_MANUAL_ENCRYPT, SPI_BOOT_CRYPT_CNT, [XTS_KEY_LENGTH_256], SECURE_BOOT_EN.
esp_efuse_write_field_bit(WR_DIS_CRYPT_CNT);
#endif
}
ESP_LOGI(TAG, "Flash encryption completed");
#ifdef CONFIG_EFUSE_VIRTUAL
ESP_LOGW(TAG, "Flash encryption not really completed. Must disable virtual efuses");
#endif
return err;
}
static esp_err_t encrypt_bootloader(void)
{
esp_err_t err;
uint32_t image_length;
/* Check for plaintext bootloader (verification will fail if it's already encrypted) */
if (esp_image_verify_bootloader(&image_length) == ESP_OK) {
ESP_LOGI(TAG, "Encrypting bootloader...");
err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, CONFIG_ESP_BOOTLOADER_SIZE);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
return err;
}
ESP_LOGI(TAG, "Bootloader encrypted successfully");
} else {
ESP_LOGW(TAG, "No valid bootloader was found");
return ESP_ERR_NOT_FOUND;
}
return ESP_OK;
}
static esp_err_t verify_img_header(uint32_t addr, const esp_image_load_header_t *image, bool silent)
{
esp_err_t err = ESP_OK;
if (image->header_magic != ESP_LOAD_HEADER_MAGIC) {
if (!silent) {
ESP_LOGE(TAG, "image at 0x%x has invalid magic byte",
addr);
}
err = ESP_ERR_IMAGE_INVALID;
}
return err;
}
static esp_err_t encrypt_primary_slot(void)
{
esp_err_t err;
esp_image_load_header_t img_header;
/* Check if the slot is plaintext or encrypted, 0x20 offset is for skipping
* MCUboot header
*/
err = bootloader_flash_read(CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS + 0x20,
&img_header, sizeof(esp_image_load_header_t), true);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to read slot img header");
return err;
} else {
err = verify_img_header(CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS,
&img_header, true);
}
if (err == ESP_OK) {
ESP_LOGI(TAG, "Encrypting primary slot...");
err = esp_flash_encrypt_region(CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS,
CONFIG_ESP_APPLICATION_SIZE);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to encrypt slot in place: 0x%x", err);
return err;
}
} else {
ESP_LOGW(TAG, "Slot already encrypted or no valid image was found");
}
return ESP_OK;
}
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
{
esp_err_t err;
uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
if (src_addr % FLASH_SECTOR_SIZE != 0) {
ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x", src_addr);
return ESP_FAIL;
}
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
wdt_hal_feed(&rtc_wdt_ctx);
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
uint32_t sec_start = i + src_addr;
err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, true);
if (err != ESP_OK) {
goto flash_failed;
}
err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
if (err != ESP_OK) {
goto flash_failed;
}
err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
if (err != ESP_OK) {
goto flash_failed;
}
}
return ESP_OK;
flash_failed:
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
return err;
}

View File

@@ -0,0 +1,266 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_secure_boot.h"
#include "bootloader_flash_priv.h"
#include "bootloader_sha.h"
#include "bootloader_utility.h"
#include "esp_image_format.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "secure_boot_signature_priv.h"
/* The following API implementations are used only when called
* from the bootloader code.
*/
#ifdef CONFIG_SECURE_BOOT_V2_ENABLED
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
static const char *TAG = "secure_boot_v2";
/* A signature block is valid when it has correct magic byte, crc and image digest. */
static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *block, int block_num, const uint8_t *image_digest)
{
if (block->magic_byte != ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC) {
// All signature blocks have been parsed, no new signature block present.
ESP_LOGD(TAG, "Signature block(%d) invalid/absent.", block_num);
return ESP_FAIL;
}
if (block->block_crc != esp_rom_crc32_le(0, (uint8_t *)block, CRC_SIGN_BLOCK_LEN)) {
ESP_LOGE(TAG, "Magic byte correct but incorrect crc.");
return ESP_FAIL;
}
if (memcmp(image_digest, block->image_digest, ESP_SECURE_BOOT_DIGEST_LEN)) {
ESP_LOGE(TAG, "Magic byte & CRC correct but incorrect image digest.");
return ESP_FAIL;
} else {
ESP_LOGD(TAG, "valid signature block(%d) found", block_num);
return ESP_OK;
}
return ESP_FAIL;
}
/* Generates the public key digests of the valid public keys in an image's
signature block, verifies each signature, and stores the key digests in the
public_key_digests structure.
@param flash_offset Image offset in flash
@param flash_size Image size in flash (not including signature block)
@param[out] public_key_digests Pointer to structure to hold the key digests for valid sig blocks
Note that this function doesn't read any eFuses, so it doesn't know if the
keys are ultimately trusted by the hardware or not
@return - ESP_OK if no signatures failed to verify, or if no valid signature blocks are found at all.
- ESP_FAIL if there's a valid signature block that doesn't verify using the included public key (unexpected!)
*/
static esp_err_t s_calculate_image_public_key_digests(uint32_t flash_offset, uint32_t flash_size, esp_image_sig_public_key_digests_t *public_key_digests)
{
esp_err_t ret;
uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
size_t sig_block_addr = flash_offset + ALIGN_UP(flash_size, FLASH_SECTOR_SIZE);
ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%x (sig block offset 0x%x)", flash_offset, sig_block_addr);
bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
ret = bootloader_sha256_flash_contents(flash_offset, sig_block_addr - flash_offset, image_digest);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "error generating image digest, %d", ret);
return ret;
}
ESP_LOGD(TAG, "reading signature(s)");
const ets_secure_boot_signature_t *signatures = bootloader_mmap(sig_block_addr, sizeof(ets_secure_boot_signature_t));
if (signatures == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", sig_block_addr, sizeof(ets_secure_boot_signature_t));
return ESP_FAIL;
}
/* Validating Signature block */
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
const ets_secure_boot_sig_block_t *block = &signatures->block[i];
ret = validate_signature_block(block, i, image_digest);
if (ret != ESP_OK) {
ret = ESP_OK; // past the last valid signature block
break;
}
/* Generating the SHA of the public key components in the signature block */
bootloader_sha256_handle_t sig_block_sha;
sig_block_sha = bootloader_sha256_start();
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
bootloader_sha256_data(sig_block_sha, &block->key, sizeof(block->key));
#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
bootloader_sha256_data(sig_block_sha, &block->ecdsa.key, sizeof(block->ecdsa.key));
#endif
bootloader_sha256_finish(sig_block_sha, key_digest);
// Check we can verify the image using this signature and this key
uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
bool verified = ets_ecdsa_verify(&block->ecdsa.key.point[0], block->ecdsa.signature, block->ecdsa.key.curve_id, image_digest, temp_verified_digest);
#endif
if (!verified) {
/* We don't expect this: the signature blocks before we enable secure boot should all be verifiable or invalid,
so this is a fatal error
*/
ret = ESP_FAIL;
ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i);
break;
}
ESP_LOGD(TAG, "Signature block (%d) is verified", i);
/* Copy the key digest to the buffer provided by the caller */
memcpy((void *)public_key_digests->key_digests[i], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
public_key_digests->num_digests++;
}
if (ret == ESP_OK && public_key_digests->num_digests > 0) {
ESP_LOGI(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%x)",
public_key_digests->num_digests, flash_offset);
}
bootloader_munmap(signatures);
return ret;
}
esp_err_t check_and_generate_secure_boot_keys(void)
{
esp_err_t ret;
#ifdef CONFIG_IDF_TARGET_ESP32
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_SECURE_BOOT);
if (coding_scheme != EFUSE_CODING_SCHEME_NONE) {
ESP_LOGE(TAG, "No coding schemes are supported in secure boot v2.(Detected scheme: 0x%x)", coding_scheme);
return ESP_ERR_NOT_SUPPORTED;
}
#endif // CONFIG_IDF_TARGET_ESP32
esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
#if SECURE_BOOT_NUM_BLOCKS == 1
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
#else
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
#endif
};
/* Verify the bootloader */
esp_image_metadata_t bootloader_data = { 0 };
ret = esp_image_verify_bootloader_data(&bootloader_data);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "bootloader image appears invalid! error %d", ret);
return ret;
}
/* Initialize all efuse block entries to invalid (max) value */
esp_efuse_block_t blocks[SECURE_BOOT_NUM_BLOCKS] = {[0 ... SECURE_BOOT_NUM_BLOCKS-1] = EFUSE_BLK_KEY_MAX};
/* Check if secure boot digests are present */
bool has_secure_boot_digest = false;
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
bool tmp_has_key = esp_efuse_find_purpose(secure_boot_key_purpose[i], &blocks[i]);
if (tmp_has_key) { // For ESP32: esp_efuse_find_purpose() always returns True, need to check whether the key block is used or not.
tmp_has_key &= !esp_efuse_key_block_unused(blocks[i]);
}
has_secure_boot_digest |= tmp_has_key;
}
esp_image_sig_public_key_digests_t boot_key_digests = {0};
ESP_LOGI(TAG, "Secure boot digests %s", has_secure_boot_digest ? "already present":"absent, generating..");
if (!has_secure_boot_digest) {
/* Generate the bootloader public key digests */
ret = s_calculate_image_public_key_digests(bootloader_data.start_addr, bootloader_data.image_len - SIG_BLOCK_PADDING, &boot_key_digests);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Bootloader signature block is invalid");
return ret;
}
if (boot_key_digests.num_digests == 0) {
ESP_LOGE(TAG, "No valid bootloader signature blocks found.");
return ESP_FAIL;
}
ESP_LOGI(TAG, "%d signature block(s) found appended to the bootloader.", boot_key_digests.num_digests);
ESP_LOGI(TAG, "Burning public key hash to eFuse");
ret = esp_efuse_write_keys(secure_boot_key_purpose, boot_key_digests.key_digests, boot_key_digests.num_digests);
if (ret != ESP_OK) {
if (ret == ESP_ERR_NOT_ENOUGH_UNUSED_KEY_BLOCKS) {
ESP_LOGE(TAG, "Bootloader signatures(%d) more than available key slots.", boot_key_digests.num_digests);
} else {
ESP_LOGE(TAG, "Failed to write efuse block with purpose (err=0x%x). Can't continue.", ret);
}
return ret;
}
} else {
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
/* Check if corresponding digest slot is used or not */
if (blocks[i] == EFUSE_BLK_KEY_MAX) {
ESP_LOGD(TAG, "SECURE_BOOT_DIGEST%d slot is not used", i);
continue;
}
#if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
if (esp_efuse_get_digest_revoke(i)) {
continue;
}
#endif
#ifndef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
if (esp_efuse_get_key_dis_read(blocks[i])) {
ESP_LOGE(TAG, "Key digest (BLK%d) read protected, aborting...", blocks[i]);
return ESP_FAIL;
}
#endif
if (esp_efuse_block_is_empty(blocks[i])) {
ESP_LOGE(TAG, "%d eFuse block is empty, aborting...", blocks[i]);
return ESP_FAIL;
}
esp_efuse_set_key_dis_write(blocks[i]);
#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
size_t offset = 128;
#else
size_t offset = 0;
#endif
ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], offset,
ESP_SECURE_BOOT_KEY_DIGEST_LEN * 8);
if (ret) {
ESP_LOGE(TAG, "Error during reading %d eFuse block (err=0x%x)", blocks[i], ret);
return ret;
}
boot_key_digests.num_digests++;
}
if (boot_key_digests.num_digests == 0) {
ESP_LOGE(TAG, "No valid pre-loaded public key digest in eFuse");
return ESP_FAIL;
}
ESP_LOGW(TAG, "Using pre-loaded public key digest in eFuse");
}
#if SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
/* Revoke the empty signature blocks */
if (boot_key_digests.num_digests < SECURE_BOOT_NUM_BLOCKS) {
/* The revocation index can be 0, 1, 2. Bootloader count can be 1,2,3. */
for (unsigned i = boot_key_digests.num_digests; i < SECURE_BOOT_NUM_BLOCKS; i++) {
ESP_LOGI(TAG, "Revoking empty key digest slot (%d)...", i);
esp_efuse_set_digest_revoke(i);
}
}
#endif // SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
return ESP_OK;
}
#endif // CONFIG_SECURE_BOOT_V2_ENABLED

View File

@@ -0,0 +1,29 @@
# Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
#
# SPDX-License-Identifier: Apache-2.0
set(MBEDTLS_ASN1_DIR "${MCUBOOT_ROOT_DIR}/ext/mbedtls-asn1")
set(CRYPTO_INC
${MBEDTLS_ASN1_DIR}/include
)
set(crypto_srcs
# Additionally pull in just the ASN.1 parser from Mbed TLS.
${MBEDTLS_ASN1_DIR}/src/asn1parse.c
${MBEDTLS_ASN1_DIR}/src/platform_util.c
)
if (DEFINED CONFIG_ESP_USE_MBEDTLS)
message(FATAL_ERROR "EC256 signature verification using Mbed TLS lib is not supported")
elseif (DEFINED CONFIG_ESP_USE_TINYCRYPT)
set(TINYCRYPT_DIR ${MCUBOOT_ROOT_DIR}/ext/tinycrypt/lib)
list(APPEND CRYPTO_INC
${TINYCRYPT_DIR}/include
)
list(APPEND crypto_srcs
${ESPRESSIF_PORT_DIR}/keys.c
${TINYCRYPT_DIR}/source/utils.c
${TINYCRYPT_DIR}/source/sha256.c
${TINYCRYPT_DIR}/source/ecc.c
${TINYCRYPT_DIR}/source/ecc_dsa.c
)
endif()

View File

@@ -0,0 +1,31 @@
# Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
#
# SPDX-License-Identifier: Apache-2.0
set(MBEDTLS_ASN1_DIR "${MCUBOOT_ROOT_DIR}/ext/mbedtls-asn1")
set(CRYPTO_INC
${MBEDTLS_ASN1_DIR}/include
)
set(crypto_srcs
# Additionally pull in just the ASN.1 parser from Mbed TLS.
${MBEDTLS_ASN1_DIR}/src/asn1parse.c
${MBEDTLS_ASN1_DIR}/src/platform_util.c
)
if (DEFINED CONFIG_ESP_USE_MBEDTLS)
message(FATAL_ERROR "ED25519 image signing using Mbed TLS lib is not supported")
elseif (DEFINED CONFIG_ESP_USE_TINYCRYPT)
set(TINYCRYPT_DIR ${MCUBOOT_ROOT_DIR}/ext/tinycrypt/lib)
set(TINYCRYPT512_DIR ${MCUBOOT_ROOT_DIR}/ext/tinycrypt-sha512/lib)
list(APPEND CRYPTO_INC
${TINYCRYPT_DIR}/include
${TINYCRYPT512_DIR}/include
)
list(APPEND crypto_srcs
${ESPRESSIF_PORT_DIR}/keys.c
${TINYCRYPT_DIR}/source/utils.c
${TINYCRYPT_DIR}/source/sha256.c
${TINYCRYPT512_DIR}/source/sha512.c
${MCUBOOT_ROOT_DIR}/ext/fiat/src/curve25519.c
)
endif()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
# Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
#
# SPDX-License-Identifier: Apache-2.0
if (DEFINED CONFIG_ESP_USE_MBEDTLS)
set(MBEDTLS_DIR ${MCUBOOT_ROOT_DIR}/ext/mbedtls)
set(CRYPTO_INC
${MBEDTLS_DIR}/include
)
set(crypto_srcs
${ESPRESSIF_PORT_DIR}/keys.c
${MBEDTLS_DIR}/library/platform.c
${MBEDTLS_DIR}/library/platform_util.c
${MBEDTLS_DIR}/library/sha256.c
${MBEDTLS_DIR}/library/rsa.c
${MBEDTLS_DIR}/library/bignum.c
${MBEDTLS_DIR}/library/asn1parse.c
${MBEDTLS_DIR}/library/md.c
${MBEDTLS_DIR}/library/memory_buffer_alloc.c
)
if (DEFINED MBEDTLS_CONFIG_FILE)
add_definitions(-DMBEDTLS_CONFIG_FILE=\"${MBEDTLS_CONFIG_FILE}\")
else()
add_definitions(-DMBEDTLS_CONFIG_FILE=\"${ESPRESSIF_PORT_DIR}/include/crypto_config/mbedtls_custom_config.h\")
endif()
elseif (DEFINED CONFIG_ESP_USE_TINYCRYPT)
message(FATAL_ERROR "RSA signature verification using Tinycrypt lib is not supported")
endif()

View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
void start_cpu0_image(int image_index, int slot, unsigned int hdr_offset);
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
void start_cpu1_image(int image_index, int slot, unsigned int hdr_offset);
#endif
void esp_app_image_load(int image_index, int slot, unsigned int hdr_offset, unsigned int *entry_addr);

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <inttypes.h>
struct flash_area {
uint8_t fa_id; /** The slot/scratch identification */
uint8_t fa_device_id; /** The device id (usually there's only one) */
uint16_t pad16;
uint32_t fa_off; /** The flash offset from the beginning */
uint32_t fa_size; /** The size of this sector */
};
//! Structure describing a sector within a flash area.
struct flash_sector {
//! Offset of this sector, from the start of its flash area (not device).
uint32_t fs_off;
//! Size of this sector, in bytes.
uint32_t fs_size;
};
static inline uint8_t flash_area_get_device_id(const struct flash_area *fa)
{
return (uint8_t)fa->fa_device_id;
}
static inline uint32_t flash_area_get_off(const struct flash_area *fa)
{
return (uint32_t)fa->fa_off;
}
static inline uint32_t flash_area_get_size(const struct flash_area *fa)
{
return (uint32_t)fa->fa_size;
}
static inline uint8_t flash_area_get_id(const struct flash_area *fa)
{
return fa->fa_id;
}
static inline uint32_t flash_sector_get_off(const struct flash_sector *fs)
{
return fs->fs_off;
}
static inline uint32_t flash_sector_get_size(const struct flash_sector *fs)
{
return fs->fs_size;
}
//! Opens the area for use. id is one of the `fa_id`s */
int flash_area_open(uint8_t id, const struct flash_area **area_outp);
void flash_area_close(const struct flash_area *fa);
//! Reads `len` bytes of flash memory at `off` to the buffer at `dst`
int flash_area_read(const struct flash_area *fa, uint32_t off,
void *dst, uint32_t len);
//! Writes `len` bytes of flash memory at `off` from the buffer at `src`
int flash_area_write(const struct flash_area *fa, uint32_t off,
const void *src, uint32_t len);
//! Erases `len` bytes of flash memory at `off`
int flash_area_erase(const struct flash_area *fa,
uint32_t off, uint32_t len);
//! Returns this `flash_area`s alignment
uint32_t flash_area_align(const struct flash_area *area);
//! Returns the value read from an erased flash area byte
uint8_t flash_area_erased_val(const struct flash_area *area);
//! Given flash area ID, return info about sectors within the area
int flash_area_get_sectors(int fa_id, uint32_t *count,
struct flash_sector *sectors);
//! Retrieve the flash sector a given offset belongs to.
int flash_area_sector_from_off(uint32_t off, struct flash_sector *sector);
//! Retrieve the flash sector a given offset belongs to.
int flash_area_get_sector(const struct flash_area *area, uint32_t off,
struct flash_sector *sector);
//! Returns the `fa_id` for slot, where slot is 0 (primary) or 1 (secondary).
//!
//! `image_index` (0 or 1) is the index of the image. Image index is
//! relevant only when multi-image support support is enabled
int flash_area_id_from_multi_image_slot(int image_index, int slot);
int flash_area_id_from_image_slot(int slot);
int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa);

View File

@@ -0,0 +1,11 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdlib.h>
void os_heap_init(void);

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* Serial write implementation used by MCUboot boot serial structure
* in boot_serial.h
*/
void console_write(const char *str, int cnt);
/**
* Serial read implementation used by MCUboot boot serial structure
* in boot_serial.h
*/
int console_read(char *str, int str_cnt, int *newline);
/**
* Initialize GPIOs used by console serial read/write
*/
void boot_console_init(void);
/**
* Check if serial recovery detection pin is active
*/
bool boot_serial_detect_pin(void);

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <mcuboot_config/mcuboot_config.h>
//! A user-defined identifier for different storage mediums
//! (i.e internal flash, external NOR flash, eMMC, etc)
#define FLASH_DEVICE_INTERNAL_FLASH 0
//! An arbitrarily high slot ID we will use to indicate that
//! there is not slot
#define FLASH_SLOT_DOES_NOT_EXIST 255
//! The slot we will use to track the bootloader allocation
#define FLASH_AREA_BOOTLOADER 0
#define FLASH_AREA_IMAGE_0_PRIMARY 1
#define FLASH_AREA_IMAGE_0_SECONDARY 2
#define FLASH_AREA_IMAGE_SCRATCH 3
#define FLASH_AREA_IMAGE_1_PRIMARY 4
#define FLASH_AREA_IMAGE_1_SECONDARY 5
#if (MCUBOOT_IMAGE_NUMBER == 1)
#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? \
FLASH_AREA_IMAGE_0_PRIMARY : \
FLASH_SLOT_DOES_NOT_EXIST)
#define FLASH_AREA_IMAGE_SECONDARY(x) (((x) == 0) ? \
FLASH_AREA_IMAGE_0_SECONDARY : \
FLASH_SLOT_DOES_NOT_EXIST)
#elif (MCUBOOT_IMAGE_NUMBER == 2)
#define FLASH_AREA_IMAGE_PRIMARY(x) (((x) == 0) ? \
FLASH_AREA_IMAGE_0_PRIMARY : \
((x) == 1) ? \
FLASH_AREA_IMAGE_1_PRIMARY : \
FLASH_SLOT_DOES_NOT_EXIST)
#define FLASH_AREA_IMAGE_SECONDARY(x) (((x) == 0) ? \
FLASH_AREA_IMAGE_0_SECONDARY : \
((x) == 1) ? \
FLASH_AREA_IMAGE_1_SECONDARY : \
FLASH_SLOT_DOES_NOT_EXIST)
#else
#warning "Image slot and flash area mapping is not defined"
#endif

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootutil/sign_key.h>
#include <mcuboot_config/mcuboot_config.h>
#if !defined(MCUBOOT_HW_KEY)
#if defined(MCUBOOT_SIGN_RSA)
#define HAVE_KEYS
extern const unsigned char rsa_pub_key[];
extern const unsigned int rsa_pub_key_len;
#elif defined(MCUBOOT_SIGN_EC256)
#define HAVE_KEYS
extern const unsigned char ecdsa_pub_key[];
extern const unsigned int ecdsa_pub_key_len;
#elif defined(MCUBOOT_SIGN_ED25519)
#define HAVE_KEYS
extern const unsigned char ed25519_pub_key[];
extern const unsigned int ed25519_pub_key_len;
#endif
/*
* NOTE: *_pub_key and *_pub_key_len are autogenerated based on the provided
* key file. If no key file was configured, the array and length must be
* provided and added to the build manually.
*/
#if defined(HAVE_KEYS)
const struct bootutil_key bootutil_keys[] = {
{
#if defined(MCUBOOT_SIGN_RSA)
.key = rsa_pub_key,
.len = &rsa_pub_key_len,
#elif defined(MCUBOOT_SIGN_EC256)
.key = ecdsa_pub_key,
.len = &ecdsa_pub_key_len,
#elif defined(MCUBOOT_SIGN_ED25519)
.key = ed25519_pub_key,
.len = &ed25519_pub_key_len,
#endif
},
};
const int bootutil_key_cnt = 1;
#endif /* HAVE_KEYS */
#else
unsigned int pub_key_len;
struct bootutil_key bootutil_keys[1] = {
{
.key = 0,
.len = &pub_key_len,
}
};
const int bootutil_key_cnt = 1;
#endif /* !MCUBOOT_HW_KEY */

View File

@@ -0,0 +1,298 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootutil/bootutil.h>
#include <bootutil/bootutil_log.h>
#include <bootutil/fault_injection_hardening.h>
#include <bootutil/image.h>
#include "bootloader_init.h"
#include "bootloader_utility.h"
#include "bootloader_random.h"
#include "bootloader_soc.h"
#include "esp_assert.h"
#ifdef CONFIG_MCUBOOT_SERIAL
#include "boot_serial/boot_serial.h"
#include "serial_adapter/serial_adapter.h"
const struct boot_uart_funcs boot_funcs = {
.read = console_read,
.write = console_write
};
#endif
#if defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH) || defined(CONFIG_SECURE_BOOT)
#include "esp_efuse.h"
#endif
#ifdef CONFIG_SECURE_BOOT
#include "esp_secure_boot.h"
#endif
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
#include "esp_flash_encrypt.h"
#endif
#include "esp_loader.h"
#include "os/os_malloc.h"
#define IMAGE_INDEX_0 0
#define IMAGE_INDEX_1 1
#define PRIMARY_SLOT 0
#define SECONDARY_SLOT 1
#ifdef CONFIG_SECURE_BOOT
extern esp_err_t check_and_generate_secure_boot_keys(void);
#endif
void do_boot(struct boot_rsp *rsp)
{
BOOT_LOG_INF("br_image_off = 0x%x", rsp->br_image_off);
BOOT_LOG_INF("ih_hdr_size = 0x%x", rsp->br_hdr->ih_hdr_size);
int slot = (rsp->br_image_off == CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS) ? PRIMARY_SLOT : SECONDARY_SLOT;
start_cpu0_image(IMAGE_INDEX_0, slot, rsp->br_hdr->ih_hdr_size);
}
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
int read_image_header(uint32_t img_index, uint32_t slot, struct image_header *img_header)
{
const struct flash_area *fap;
int area_id;
int rc = 0;
area_id = flash_area_id_from_multi_image_slot(img_index, slot);
rc = flash_area_open(area_id, &fap);
if (rc != 0) {
rc = BOOT_EFLASH;
goto done;
}
if (flash_area_read(fap, 0, img_header, sizeof(struct image_header))) {
rc = BOOT_EFLASH;
goto done;
}
BOOT_LOG_INF("Image offset = 0x%x", fap->fa_off);
BOOT_LOG_INF("Image header size = 0x%x", img_header->ih_hdr_size);
done:
flash_area_close(fap);
return rc;
}
void do_boot_appcpu(uint32_t img_index, uint32_t slot)
{
struct image_header img_header;
if (read_image_header(img_index, slot, &img_header) != 0) {
FIH_PANIC;
}
start_cpu1_image(img_index, slot, img_header.ih_hdr_size);
}
#endif
int main()
{
if (bootloader_init() != ESP_OK) {
FIH_PANIC;
}
/* Rough steps for a first boot when Secure Boot and/or Flash Encryption are still disabled on device:
* Secure Boot:
* 1) Calculate the SHA-256 hash digest of the public key and write to EFUSE.
* 2) Validate the application images and prepare the booting process.
* 3) Burn EFUSE to enable Secure Boot V2 (ABS_DONE_0).
* Flash Encryption:
* 4) Generate Flash Encryption key and write to EFUSE.
* 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
* 6) Burn EFUSE to enable Flash Encryption.
* 7) Reset system to ensure Flash Encryption cache resets properly.
*/
#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
BOOT_LOG_WRN("eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
#endif
#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_FLASH_ENC_ENABLED)
esp_err_t err;
#endif
#ifdef CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
if (esp_secure_boot_enabled() ^ esp_flash_encrypt_initialized_once()) {
BOOT_LOG_ERR("Secure Boot and Flash Encryption cannot be enabled separately, only together (their keys go into one eFuse key block)");
FIH_PANIC;
}
if (!esp_secure_boot_enabled() || !esp_flash_encryption_enabled()) {
esp_efuse_batch_write_begin();
}
#endif // CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
#ifdef CONFIG_SECURE_BOOT
/* Steps 1 (see above for full description):
* 1) Compute digest of the public key.
*/
BOOT_LOG_INF("enabling secure boot v2...");
bool sb_hw_enabled = esp_secure_boot_enabled();
if (sb_hw_enabled) {
BOOT_LOG_INF("secure boot v2 is already enabled, continuing..");
} else {
esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
err = check_and_generate_secure_boot_keys();
if (err != ESP_OK) {
esp_efuse_batch_write_cancel();
FIH_PANIC;
}
}
#endif
os_heap_init();
struct boot_rsp rsp;
FIH_DECLARE(fih_rc, FIH_FAILURE);
#ifdef CONFIG_MCUBOOT_SERIAL
boot_console_init();
if (boot_serial_detect_pin()) {
BOOT_LOG_INF("Enter the serial recovery mode");
boot_serial_start(&boot_funcs);
}
#endif
/* Step 2 (see above for full description):
* 2) MCUboot validates the application images and prepares the booting process.
*/
/* MCUboot's boot_go validates and checks all images for update and returns
* the load information for booting the main image
*/
FIH_CALL(boot_go, fih_rc, &rsp);
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
BOOT_LOG_ERR("Unable to find bootable image");
#ifdef CONFIG_SECURE_BOOT
esp_efuse_batch_write_cancel();
#endif
FIH_PANIC;
}
#ifdef CONFIG_SECURE_BOOT
/* Step 3 (see above for full description):
* 3) Burn EFUSE to enable Secure Boot V2.
*/
if (!sb_hw_enabled) {
BOOT_LOG_INF("blowing secure boot efuse...");
err = esp_secure_boot_enable_secure_features();
if (err != ESP_OK) {
esp_efuse_batch_write_cancel();
FIH_PANIC;
}
err = esp_efuse_batch_write_commit();
if (err != ESP_OK) {
BOOT_LOG_ERR("Error programming security eFuses (err=0x%x).", err);
FIH_PANIC;
}
#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
#endif
#ifndef CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
assert(esp_secure_boot_enabled());
BOOT_LOG_INF("Secure boot permanently enabled");
#endif
}
#endif
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
/* Step 4, 5 & 6 (see above for full description):
* 4) Generate Flash Encryption key and write to EFUSE.
* 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
* 6) Burn EFUSE to enable flash encryption
*/
BOOT_LOG_INF("Checking flash encryption...");
bool flash_encryption_enabled = esp_flash_encrypt_state();
if (!flash_encryption_enabled) {
#ifdef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
BOOT_LOG_ERR("flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED is set, refusing to boot.");
FIH_PANIC;
#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
if (esp_flash_encrypt_is_write_protected(true)) {
FIH_PANIC;
}
err = esp_flash_encrypt_init();
if (err != ESP_OK) {
BOOT_LOG_ERR("Initialization of Flash Encryption key failed (%d)", err);
FIH_PANIC;
}
}
if (!flash_encryption_enabled) {
err = esp_flash_encrypt_contents();
if (err != ESP_OK) {
BOOT_LOG_ERR("Encryption flash contents failed (%d)", err);
FIH_PANIC;
}
err = esp_flash_encrypt_enable();
if (err != ESP_OK) {
BOOT_LOG_ERR("Enabling of Flash encryption failed (%d)", err);
FIH_PANIC;
}
}
#ifdef CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
if (!esp_secure_boot_enabled() || !flash_encryption_enabled) {
err = esp_efuse_batch_write_commit();
if (err != ESP_OK) {
BOOT_LOG_ERR("Error programming eFuses (err=0x%x).", err);
FIH_PANIC;
}
assert(esp_secure_boot_enabled());
BOOT_LOG_INF("Secure boot permanently enabled");
}
#endif // CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
/* Step 7 (see above for full description):
* 7) Reset system to ensure flash encryption cache resets properly.
*/
if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
BOOT_LOG_INF("Resetting with flash encryption enabled...");
bootloader_reset();
}
#endif
BOOT_LOG_INF("Disabling RNG early entropy source...");
bootloader_random_disable();
/* Disable glitch reset after all the security checks are completed.
* Glitch detection can be falsely triggered by EMI interference (high RF TX power, etc)
* and to avoid such false alarms, disable it.
*/
bootloader_ana_clock_glitch_reset_config(false);
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
/* Multi image independent boot
* Boot on the second processor happens before the image0 boot
*/
do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
#endif
do_boot(&rsp);
while(1);
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef CONFIG_ESP_USE_MBEDTLS
#include <mbedtls/platform.h>
#include <mbedtls/memory_buffer_alloc.h>
#define CRYPTO_HEAP_SIZE 8192
static unsigned char memory_buf[CRYPTO_HEAP_SIZE];
/*
* Initialize Mbed TLS to be able to use the local heap.
*/
void os_heap_init(void)
{
mbedtls_memory_buffer_alloc_init(memory_buf, sizeof(memory_buf));
}
#else
void os_heap_init(void)
{
}
#endif

View File

@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x1000
# Example of values to be used when multi image is enabled
# Notice that the OS layer and update agent must be aware
# of these regions
CONFIG_ESP_APPLICATION_SIZE=0x80000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x90000
CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0x110000
CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x190000
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=26
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=25
# Enables multi image, if it is not defined, it is assumed
# only one updatable image
# CONFIG_ESP_IMAGE_NUMBER=2
# Enables multi image boot on independent processors
# (main host OS is not responsible for booting the second image)
# Use only with CONFIG_ESP_IMAGE_NUMBER=2
# CONFIG_ESP_MULTI_PROCESSOR_BOOT=y

View File

@@ -0,0 +1,101 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x1000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_APPLICATION_SIZE=0x100000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# When enabled, prevents updating image to an older version
# CONFIG_ESP_DOWNGRADE_PREVENTION=y
# This option makes downgrade prevention rely also on security
# counter (defined using imgtool) instead of only image version
# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
# Enables the MCUboot Serial Recovery, that allows the use of
# MCUMGR to upload a firmware through the serial port
# CONFIG_ESP_MCUBOOT_SERIAL=y
# Use sector erasing instead of entire image size erasing
# when uploading through Serial Recovery
# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
# GPIO used to boot on Serial Recovery
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=32
# GPIO input type (0 for Pull-down, 1 for Pull-up)
# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
# GPIO signal value
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
# Delay time for identify the GPIO signal
# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
# UART port used for serial communication
# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
# GPIO for Serial RX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=25
# GPIO for Serial TX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=26
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=26
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=25
# Enables multi image, if it is not defined, it is assumed
# only one updatable image
# CONFIG_ESP_IMAGE_NUMBER=2
# Enables multi image boot on independent processors
# (main host OS is not responsible for booting the second image)
# Use only with CONFIG_ESP_IMAGE_NUMBER=2
# CONFIG_ESP_MULTI_PROCESSOR_BOOT=y
# Example of values to be used when multi image is enabled
# Notice that the OS layer and update agent must be aware
# of these regions
# CONFIG_ESP_APPLICATION_SIZE=0x80000
# CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
# CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x90000
# CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0x110000
# CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x190000
# CONFIG_ESP_SCRATCH_OFFSET=0x210000
# CONFIG_ESP_SCRATCH_SIZE=0x40000
# CONFIG_ESP_SIGN_EC256=y
# CONFIG_ESP_SIGN_ED25519=n
# CONFIG_ESP_SIGN_RSA=n
# CONFIG_ESP_SIGN_RSA_LEN=2048
# Use Tinycrypt lib for EC256 or ED25519 signing
# CONFIG_ESP_USE_TINYCRYPT=y
# Use Mbed TLS lib for RSA image signing
# CONFIG_ESP_USE_MBEDTLS=n
# It is strongly recommended to generate a new signing key
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
# Hardware Secure Boot related options
# CONFIG_SECURE_SIGNED_ON_BOOT=1
# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
# CONFIG_SECURE_BOOT=1
# CONFIG_SECURE_BOOT_V2_ENABLED=1
# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1

View File

@@ -0,0 +1,144 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Simplified memory map for the bootloader.
*
* The main purpose is to make sure the bootloader can load into main memory
* without overwriting itself.
*/
MEMORY
{
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
iram_loader_seg (RWX) : org = 0x400AB900, len = 0x6500
#else
/* iram_loader_seg is currently placed on APP_CPU cache IRAM address range */
iram_loader_seg (RWX) : org = 0x40078000, len = 0x6500
#endif
iram_seg (RWX) : org = 0x40090000, len = 0x9000
dram_seg (RW) : org = 0x3FFF4700, len = 0xB900
}
/* Default entry point: */
ENTRY(main);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libhal.a:*.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*main.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -0,0 +1,179 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootutil/bootutil_log.h>
#include <esp_rom_uart.h>
#include <esp_rom_gpio.h>
#include <esp_rom_sys.h>
#include <soc/uart_periph.h>
#include <soc/gpio_struct.h>
#include <soc/io_mux_reg.h>
#include <soc/rtc.h>
#include <hal/gpio_types.h>
#include <hal/gpio_ll.h>
#include <hal/uart_ll.h>
#include <hal/clk_gate_ll.h>
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#else
#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#else
#define SERIAL_BOOT_GPIO_DETECT_VAL 1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#else
#define SERIAL_BOOT_DETECT_DELAY_S 5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#else
// pull-down
#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
#else
#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#else
#define SERIAL_BOOT_GPIO_RX GPIO_NUM_8
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#else
#define SERIAL_BOOT_GPIO_TX GPIO_NUM_9
#endif
static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
&UART0 :
&UART1;
void console_write(const char *str, int cnt)
{
uint32_t tx_len;
do {
tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
} while (tx_len < cnt);
uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, cnt);
}
int console_read(char *str, int cnt, int *newline)
{
volatile uint32_t len = 0;
volatile uint32_t read_len = 0;
volatile bool stop = false;
do {
len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
if (len) {
for (uint32_t i = 0; i < len; i++) {
/* Read the character from the RX FIFO */
uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
read_len++;
if (read_len == cnt || str[read_len - 1] == '\n') {
stop = true;
break;
}
}
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!stop);
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
}
int boot_console_init(void)
{
BOOT_LOG_INF("Initializing serial boot pins");
/* Enable GPIO for UART RX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
0);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
/* Enable GPIO for UART TX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
0, 0);
gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_APB);
uart_ll_set_mode_normal(serial_boot_uart_dev);
uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_APB);
uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
uart_ll_txfifo_rst(serial_boot_uart_dev);
uart_ll_rxfifo_rst(serial_boot_uart_dev);
esp_rom_delay_us(50000);
return 0;
}
bool boot_serial_detect_pin(void)
{
bool detected = false;
int pin_value = 0;
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
// Pull-down
case 0:
gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
// Pull-up
case 1:
gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
}
esp_rom_delay_us(50000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
esp_rom_delay_us(50000);
if (detected) {
if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
/* The delay time is an approximation */
for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
esp_rom_delay_us(10000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
if (!detected) {
break;
}
}
}
}
return detected;
}

View File

@@ -0,0 +1,87 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x0000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_APPLICATION_SIZE=0x100000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# When enabled, prevents updating image to an older version
# CONFIG_ESP_DOWNGRADE_PREVENTION=y
# This option makes downgrade prevention rely also on security
# counter (defined using imgtool) instead of only image version
# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
# Enables the MCUboot Serial Recovery, that allows the use of
# MCUMGR to upload a firmware through the serial port
# CONFIG_ESP_MCUBOOT_SERIAL=y
# Use sector erasing (recommended) instead of entire image size
# erasing when uploading through Serial Recovery
# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
# GPIO used to boot on Serial Recovery
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=18
# GPIO input type (0 for Pull-down, 1 for Pull-up)
# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
# GPIO signal value
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
# Delay time for identify the GPIO signal
# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
# UART port used for serial communication (not needed when using USB)
# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
# GPIO for Serial RX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=2
# GPIO for Serial TX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=3
# Use UART0 for console printing (use either UART or USB alone)
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# (UART_NUM=0 must not be changed)
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=3
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=2
# CONFIG_ESP_SIGN_EC256=y
# CONFIG_ESP_SIGN_ED25519=n
# CONFIG_ESP_SIGN_RSA=n
# CONFIG_ESP_SIGN_RSA_LEN=2048
# Use Tinycrypt lib for EC256 or ED25519 signing
# CONFIG_ESP_USE_TINYCRYPT=y
# Use Mbed TLS lib for RSA image signing
# CONFIG_ESP_USE_MBEDTLS=n
# It is strongly recommended to generate a new signing key
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
# Hardware Secure Boot related options
# CONFIG_SECURE_SIGNED_ON_BOOT=1
# CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME=1
# CONFIG_SECURE_BOOT=1
# CONFIG_SECURE_BOOT_V2_ENABLED=1
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
# This option must be also enabled when enabling both Secure Boot
# and Flash Encryption at same time
# CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER=1
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1

View File

@@ -0,0 +1,181 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** Simplified memory map for the bootloader.
* Make sure the bootloader can load into main memory without overwriting itself.
*
* ESP32-C2 ROM static data usage is as follows:
* - 0x3fccb264 - 0x3fcdcb70: Shared buffers, used in UART/USB/SPI download mode only
* - 0x3fcdcb70 - 0x3fcdeb70: PRO CPU stack, can be reclaimed as heap after RTOS startup
* - 0x3fcdeb70 - 0x3fce0000: ROM .bss and .data (not easily reclaimable)
*
* The 2nd stage bootloader can take space up to the end of ROM shared
* buffers area (0x3fcdcb70).
*/
/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */
iram_dram_offset = 0x6e0000;
/* We consider 0x3fcdcb70 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
* and work out iram_seg and iram_loader_seg addresses from there, backwards.
*/
/* These lengths can be adjusted, if necessary: */
bootloader_usable_dram_end = 0x3fcdcb70;
bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
bootloader_dram_seg_len = 0xA000;
bootloader_iram_loader_seg_len = 0x7000;
bootloader_iram_seg_len = 0x8800;
/* Start of the lower region is determined by region size and the end of the higher region */
bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead;
bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len;
bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset;
bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len;
MEMORY
{
iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
}
/* The app may use RAM for static allocations up to the start of iram_loader_seg.
* If you have changed something above and this assert fails:
* 1. Check what the new value of bootloader_iram_loader_seg start is.
* 2. Update the value in this assert.
* 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c2/memory.ld.in to the same value.
*/
ASSERT(bootloader_iram_loader_seg_start == 0x403a9b70, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
/* Default entry point: */
ENTRY(main);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libhal.a:*.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*main.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -0,0 +1,190 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootutil/bootutil_log.h>
#include <esp_rom_uart.h>
#include <esp_rom_gpio.h>
#include <esp_rom_sys.h>
#include <esp_rom_caps.h>
#include <soc/uart_periph.h>
#include <soc/gpio_struct.h>
#include <soc/io_mux_reg.h>
#include <soc/rtc.h>
#include <hal/gpio_types.h>
#include <hal/gpio_ll.h>
#include <hal/uart_ll.h>
#include <hal/clk_gate_ll.h>
#include <hal/gpio_hal.h>
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#else
#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_18
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#else
#define SERIAL_BOOT_GPIO_DETECT_VAL 1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#else
#define SERIAL_BOOT_DETECT_DELAY_S 5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#else
// pull-down
#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
#else
#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#else
#define SERIAL_BOOT_GPIO_RX GPIO_NUM_2
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#else
#define SERIAL_BOOT_GPIO_TX GPIO_NUM_3
#endif
static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
&UART0 :
&UART1;
void console_write(const char *str, int cnt)
{
uint32_t tx_len;
uint32_t write_len;
do {
tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
if (tx_len > 0) {
write_len = tx_len < cnt ? tx_len : cnt;
uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len);
cnt -= write_len;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (cnt > 0);
}
int console_read(char *str, int cnt, int *newline)
{
uint32_t len = 0;
uint32_t read_len = 0;
bool stop = false;
do {
len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
if (len > 0) {
for (uint32_t i = 0; i < len; i++) {
/* Read the character from the RX FIFO */
uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
read_len++;
if (read_len == cnt - 1|| str[read_len - 1] == '\n') {
stop = true;
break;
}
}
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!stop);
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
}
int boot_console_init(void)
{
BOOT_LOG_INF("Initializing serial boot pins");
/* Enable GPIO for UART RX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
0);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX);
/* Enable GPIO for UART TX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
0, 0);
gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_DEFAULT);
uart_ll_set_mode_normal(serial_boot_uart_dev);
uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_DEFAULT);
uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
uart_ll_txfifo_rst(serial_boot_uart_dev);
uart_ll_rxfifo_rst(serial_boot_uart_dev);
esp_rom_delay_us(50000);
return 0;
}
bool boot_serial_detect_pin(void)
{
bool detected = false;
int pin_value = 0;
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
// Pull-down
case 0:
gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
// Pull-up
case 1:
gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
}
esp_rom_delay_us(50000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
esp_rom_delay_us(50000);
if (detected) {
if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
/* The delay time is an approximation */
for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
esp_rom_delay_us(10000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
if (!detected) {
break;
}
}
}
}
return detected;
}

View File

@@ -0,0 +1,88 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x0000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_APPLICATION_SIZE=0x100000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# When enabled, prevents updating image to an older version
# CONFIG_ESP_DOWNGRADE_PREVENTION=y
# This option makes downgrade prevention rely also on security
# counter (defined using imgtool) instead of only image version
# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
# Enables the MCUboot Serial Recovery, that allows the use of
# MCUMGR to upload a firmware through the serial port
# CONFIG_ESP_MCUBOOT_SERIAL=y
# Use Serial through USB JTAG Serial port for Serial Recovery
# CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
# Use sector erasing (recommended) instead of entire image size
# erasing when uploading through Serial Recovery
# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
# GPIO used to boot on Serial Recovery
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
# GPIO input type (0 for Pull-down, 1 for Pull-up)
# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
# GPIO signal value
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
# Delay time for identify the GPIO signal
# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
# UART port used for serial communication (not needed when using USB)
# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
# GPIO for Serial RX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=8
# GPIO for Serial TX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=9
# Use UART0 for console printing (use either UART or USB alone)
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# (UART_NUM=0 must not be changed)
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=9
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=8
# Use USB JTAG Serial for console printing
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
# CONFIG_ESP_SIGN_EC256=y
# CONFIG_ESP_SIGN_ED25519=n
# CONFIG_ESP_SIGN_RSA=n
# CONFIG_ESP_SIGN_RSA_LEN=2048
# Use Tinycrypt lib for EC256 or ED25519 signing
# CONFIG_ESP_USE_TINYCRYPT=y
# Use Mbed TLS lib for RSA image signing
# CONFIG_ESP_USE_MBEDTLS=n
# It is strongly recommended to generate a new signing key
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
# Hardware Secure Boot related options
# CONFIG_SECURE_SIGNED_ON_BOOT=1
# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
# CONFIG_SECURE_BOOT=1
# CONFIG_SECURE_BOOT_V2_ENABLED=1
# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1

View File

@@ -0,0 +1,147 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Simplified memory map for the bootloader.
*
* The main purpose is to make sure the bootloader can load into main memory
* without overwriting itself.
*/
MEMORY
{
iram_seg (RWX) : org = 0x403C7000, len = 0x9000
iram_loader_seg (RWX) : org = 0x403D0000, len = 0x5400
dram_seg (RW) : org = 0x3FCD5400, len = 0xA000
}
/* Default entry point: */
ENTRY(main);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libhal.a:*.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*main.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -0,0 +1,226 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootutil/bootutil_log.h>
#include <esp_rom_uart.h>
#include <esp_rom_gpio.h>
#include <esp_rom_sys.h>
#include <esp_rom_caps.h>
#include <soc/uart_periph.h>
#include <soc/gpio_struct.h>
#include <soc/io_mux_reg.h>
#include <soc/rtc.h>
#include <hal/gpio_types.h>
#include <hal/gpio_ll.h>
#include <hal/uart_ll.h>
#include <hal/clk_gate_ll.h>
#include <hal/usb_serial_jtag_ll.h>
#include <hal/gpio_hal.h>
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#else
#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#else
#define SERIAL_BOOT_GPIO_DETECT_VAL 1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#else
#define SERIAL_BOOT_DETECT_DELAY_S 5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#else
// pull-down
#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
#endif
#ifndef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
#else
#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#else
#define SERIAL_BOOT_GPIO_RX GPIO_NUM_8
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#else
#define SERIAL_BOOT_GPIO_TX GPIO_NUM_9
#endif
static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
&UART0 :
&UART1;
#endif
void console_write(const char *str, int cnt)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
while (!usb_serial_jtag_ll_txfifo_writable()) {
MCUBOOT_WATCHDOG_FEED();
}
usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, cnt);
usb_serial_jtag_ll_txfifo_flush();
#else
uint32_t tx_len;
uint32_t write_len;
do {
tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
if (tx_len > 0) {
write_len = tx_len < cnt ? tx_len : cnt;
uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len);
cnt -= write_len;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (cnt > 0);
#endif
}
int console_read(char *str, int cnt, int *newline)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
uint32_t read_len = 0;
esp_rom_delay_us(1000);
do {
if (usb_serial_jtag_ll_rxfifo_data_available()) {
usb_serial_jtag_ll_read_rxfifo((uint8_t *)&str[read_len], 1);
read_len++;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!(read_len == cnt || str[read_len - 1] == '\n'));
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#else
uint32_t len = 0;
uint32_t read_len = 0;
bool stop = false;
do {
len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
if (len > 0) {
for (uint32_t i = 0; i < len; i++) {
/* Read the character from the RX FIFO */
uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
read_len++;
if (read_len == cnt - 1|| str[read_len - 1] == '\n') {
stop = true;
break;
}
}
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!stop);
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#endif
}
int boot_console_init(void)
{
BOOT_LOG_INF("Initializing serial boot pins");
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
esp_rom_uart_tx_wait_idle(0);
#else
/* Enable GPIO for UART RX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
0);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX);
/* Enable GPIO for UART TX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
0, 0);
gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_APB);
uart_ll_set_mode_normal(serial_boot_uart_dev);
uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_APB);
uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
uart_ll_txfifo_rst(serial_boot_uart_dev);
uart_ll_rxfifo_rst(serial_boot_uart_dev);
esp_rom_delay_us(50000);
#endif
return 0;
}
bool boot_serial_detect_pin(void)
{
bool detected = false;
int pin_value = 0;
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
// Pull-down
case 0:
gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
// Pull-up
case 1:
gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
}
esp_rom_delay_us(50000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
esp_rom_delay_us(50000);
if (detected) {
if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
/* The delay time is an approximation */
for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
esp_rom_delay_us(10000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
if (!detected) {
break;
}
}
}
}
return detected;
}

View File

@@ -0,0 +1,88 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x0000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_APPLICATION_SIZE=0x100000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# When enabled, prevents updating image to an older version
# CONFIG_ESP_DOWNGRADE_PREVENTION=y
# This option makes downgrade prevention rely also on security
# counter (defined using imgtool) instead of only image version
# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
# Enables the MCUboot Serial Recovery, that allows the use of
# MCUMGR to upload a firmware through the serial port
# CONFIG_ESP_MCUBOOT_SERIAL=y
# Use Serial through USB JTAG Serial port for Serial Recovery
# CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
# Use sector erasing (recommended) instead of entire image size
# erasing when uploading through Serial Recovery
# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
# GPIO used to boot on Serial Recovery
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
# GPIO input type (0 for Pull-down, 1 for Pull-up)
# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
# GPIO signal value
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
# Delay time for identify the GPIO signal
# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
# UART port used for serial communication (not needed when using USB)
# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
# GPIO for Serial RX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=8
# GPIO for Serial TX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=9
# Use UART0 for console printing (use either UART or USB alone)
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# (UART_NUM=0 must not be changed)
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=9
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=8
# Use USB JTAG Serial for console printing
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
# CONFIG_ESP_SIGN_EC256=y
# CONFIG_ESP_SIGN_ED25519=n
# CONFIG_ESP_SIGN_RSA=n
# CONFIG_ESP_SIGN_RSA_LEN=2048
# Use Tinycrypt lib for EC256 or ED25519 signing
# CONFIG_ESP_USE_TINYCRYPT=y
# Use Mbed TLS lib for RSA image signing
# CONFIG_ESP_USE_MBEDTLS=n
# It is strongly recommended to generate a new signing key
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
# Hardware Secure Boot related options
# CONFIG_SECURE_SIGNED_ON_BOOT=1
# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
# CONFIG_SECURE_BOOT=1
# CONFIG_SECURE_BOOT_V2_ENABLED=1
# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1

View File

@@ -0,0 +1,177 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** Simplified memory map for the bootloader.
* Make sure the bootloader can load into main memory without overwriting itself.
*
* ESP32-C6 ROM static data usage is as follows:
* - 0x4086ad08 - 0x4087c610: Shared buffers, used in UART/USB/SPI download mode only
* - 0x4087c610 - 0x4087e610: PRO CPU stack, can be reclaimed as heap after RTOS startup
* - 0x4087e610 - 0x40880000: ROM .bss and .data (not easily reclaimable)
*
* The 2nd stage bootloader can take space up to the end of ROM shared
* buffers area (0x4087c610).
*/
/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
* and work out iram_seg and iram_loader_seg addresses from there, backwards.
*/
/* These lengths can be adjusted, if necessary: */
bootloader_usable_dram_end = 0x4087c610;
bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
bootloader_dram_seg_len = 0xA000;
bootloader_iram_loader_seg_len = 0x7000;
bootloader_iram_seg_len = 0x9000;
/* Start of the lower region is determined by region size and the end of the higher region */
bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; /* 0x4087c610 - 0x2000 = 0x4087a610 */
bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; /* 0x4087a610 - 0x5000 = 0x40875610 */
bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; /* 0x40875610 - 0x7000 = 0x4086e610 */
bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; /* 0x4086e610 - 0x3000 = 0x4086b610 */
MEMORY
{
iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
}
/* The app may use RAM for static allocations up to the start of iram_loader_seg.
* If you have changed something above and this assert fails:
* 1. Check what the new value of bootloader_iram_loader_seg start is.
* 2. Update the value in this assert.
* 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c6/memory.ld.in to the same value.
*/
ASSERT(bootloader_iram_loader_seg_start == 0x40869610, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
/* Default entry point: */
ENTRY(main);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libhal.a:*.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*main.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -0,0 +1,226 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootutil/bootutil_log.h>
#include <esp_rom_uart.h>
#include <esp_rom_gpio.h>
#include <esp_rom_sys.h>
#include <esp_rom_caps.h>
#include <soc/uart_periph.h>
#include <soc/gpio_struct.h>
#include <soc/io_mux_reg.h>
#include <soc/rtc.h>
#include <hal/gpio_types.h>
#include <hal/gpio_ll.h>
#include <hal/uart_ll.h>
#include <hal/clk_gate_ll.h>
#include <hal/usb_serial_jtag_ll.h>
#include <hal/gpio_hal.h>
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#else
#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_3
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#else
#define SERIAL_BOOT_GPIO_DETECT_VAL 1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#else
#define SERIAL_BOOT_DETECT_DELAY_S 5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#else
// pull-down
#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
#endif
#ifndef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
#else
#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#else
#define SERIAL_BOOT_GPIO_RX GPIO_NUM_10
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#else
#define SERIAL_BOOT_GPIO_TX GPIO_NUM_11
#endif
static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
&UART0 :
&UART1;
#endif
void console_write(const char *str, int cnt)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
while (!usb_serial_jtag_ll_txfifo_writable()) {
MCUBOOT_WATCHDOG_FEED();
}
usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, cnt);
usb_serial_jtag_ll_txfifo_flush();
#else
uint32_t tx_len;
uint32_t write_len;
do {
tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
if (tx_len > 0) {
write_len = tx_len < cnt ? tx_len : cnt;
uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len);
cnt -= write_len;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (cnt > 0);
#endif
}
int console_read(char *str, int cnt, int *newline)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
uint32_t read_len = 0;
esp_rom_delay_us(1000);
do {
if (usb_serial_jtag_ll_rxfifo_data_available()) {
usb_serial_jtag_ll_read_rxfifo((uint8_t *)&str[read_len], 1);
read_len++;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!(read_len == cnt || str[read_len - 1] == '\n'));
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#else
uint32_t len = 0;
uint32_t read_len = 0;
bool stop = false;
do {
len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
if (len > 0) {
for (uint32_t i = 0; i < len; i++) {
/* Read the character from the RX FIFO */
uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
read_len++;
if (read_len == cnt - 1|| str[read_len - 1] == '\n') {
stop = true;
break;
}
}
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!stop);
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#endif
}
int boot_console_init(void)
{
BOOT_LOG_INF("Initializing serial boot pins");
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
esp_rom_uart_tx_wait_idle(0);
#else
/* Enable GPIO for UART RX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
0);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX);
/* Enable GPIO for UART TX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
0, 0);
gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_DEFAULT);
uart_ll_set_mode_normal(serial_boot_uart_dev);
uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_DEFAULT);
uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
uart_ll_txfifo_rst(serial_boot_uart_dev);
uart_ll_rxfifo_rst(serial_boot_uart_dev);
esp_rom_delay_us(50000);
#endif
return 0;
}
bool boot_serial_detect_pin(void)
{
bool detected = false;
int pin_value = 0;
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
// Pull-down
case 0:
gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
// Pull-up
case 1:
gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
}
esp_rom_delay_us(50000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
esp_rom_delay_us(50000);
if (detected) {
if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
/* The delay time is an approximation */
for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
esp_rom_delay_us(10000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
if (!detected) {
break;
}
}
}
}
return detected;
}

View File

@@ -0,0 +1,88 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x0000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_APPLICATION_SIZE=0x100000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# When enabled, prevents updating image to an older version
# CONFIG_ESP_DOWNGRADE_PREVENTION=y
# This option makes downgrade prevention rely also on security
# counter (defined using imgtool) instead of only image version
# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
# Enables the MCUboot Serial Recovery, that allows the use of
# MCUMGR to upload a firmware through the serial port
# CONFIG_ESP_MCUBOOT_SERIAL=y
# Use Serial through USB JTAG Serial port for Serial Recovery
# CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
# Use sector erasing (recommended) instead of entire image size
# erasing when uploading through Serial Recovery
# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
# GPIO used to boot on Serial Recovery
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
# GPIO input type (0 for Pull-down, 1 for Pull-up)
# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
# GPIO signal value
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
# Delay time for identify the GPIO signal
# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
# UART port used for serial communication (not needed when using USB)
# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
# GPIO for Serial RX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=8
# GPIO for Serial TX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=9
# Use UART0 for console printing (use either UART or USB alone)
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# (UART_NUM=0 must not be changed)
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=9
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=8
# Use USB JTAG Serial for console printing
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
# CONFIG_ESP_SIGN_EC256=y
# CONFIG_ESP_SIGN_ED25519=n
# CONFIG_ESP_SIGN_RSA=n
# CONFIG_ESP_SIGN_RSA_LEN=2048
# Use Tinycrypt lib for EC256 or ED25519 signing
# CONFIG_ESP_USE_TINYCRYPT=y
# Use Mbed TLS lib for RSA image signing
# CONFIG_ESP_USE_MBEDTLS=n
# It is strongly recommended to generate a new signing key
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
# Hardware Secure Boot related options
# CONFIG_SECURE_SIGNED_ON_BOOT=1
# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
# CONFIG_SECURE_BOOT=1
# CONFIG_SECURE_BOOT_V2_ENABLED=1
# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1

View File

@@ -0,0 +1,179 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** Simplified memory map for the bootloader.
* Make sure the bootloader can load into main memory without overwriting itself.
*
* ESP32-H2 ROM static data usage is as follows:
* - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only
* - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup
* - 0x4084f380 - 0x4084fee0: ROM .bss and .data used in startup code or nonos/early boot (can be freed when IDF runs)
* - 0x4084fee0 - 0x40850000: ROM .bss and .data used in startup code and when IDF runs (cannot be freed)
*
* The 2nd stage bootloader can take space up to the end of ROM shared
* buffers area (0x4084d380).
*/
/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
* and work out iram_seg and iram_loader_seg addresses from there, backwards.
*/
/* These lengths can be adjusted, if necessary: */
bootloader_usable_dram_end = 0x4084cfd0;
bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
bootloader_dram_seg_len = 0xA000;
bootloader_iram_loader_seg_len = 0x7000;
bootloader_iram_seg_len = 0x8800;
/* Start of the lower region is determined by region size and the end of the higher region */
bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead;
bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len;
bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len;
bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len;
MEMORY
{
iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
}
/* The app may use RAM for static allocations up to the start of iram_loader_seg.
* If you have changed something above and this assert fails:
* 1. Check what the new value of bootloader_iram_loader_seg start is.
* 2. Update the value in this assert.
* 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32h2/memory.ld.in to the same value.
*/
ASSERT(bootloader_iram_loader_seg_start == 0x40839FD0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END");
/* Default entry point: */
ENTRY(main);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libhal.a:*.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*main.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -0,0 +1,226 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <bootutil/bootutil_log.h>
#include <esp_rom_uart.h>
#include <esp_rom_gpio.h>
#include <esp_rom_sys.h>
#include <esp_rom_caps.h>
#include <soc/uart_periph.h>
#include <soc/gpio_struct.h>
#include <soc/io_mux_reg.h>
#include <soc/rtc.h>
#include <hal/gpio_types.h>
#include <hal/gpio_ll.h>
#include <hal/uart_ll.h>
#include <hal/clk_gate_ll.h>
#include <hal/usb_serial_jtag_ll.h>
#include <hal/gpio_hal.h>
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#else
#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_12
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#else
#define SERIAL_BOOT_GPIO_DETECT_VAL 1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#else
#define SERIAL_BOOT_DETECT_DELAY_S 5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#else
// pull-down
#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
#endif
#ifndef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
#else
#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#else
#define SERIAL_BOOT_GPIO_RX GPIO_NUM_10
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#else
#define SERIAL_BOOT_GPIO_TX GPIO_NUM_11
#endif
static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
&UART0 :
&UART1;
#endif
void console_write(const char *str, int cnt)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
while (!usb_serial_jtag_ll_txfifo_writable()) {
MCUBOOT_WATCHDOG_FEED();
}
usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, cnt);
usb_serial_jtag_ll_txfifo_flush();
#else
uint32_t tx_len;
uint32_t write_len;
do {
tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
if (tx_len > 0) {
write_len = tx_len < cnt ? tx_len : cnt;
uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len);
cnt -= write_len;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (cnt > 0);
#endif
}
int console_read(char *str, int cnt, int *newline)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
uint32_t read_len = 0;
esp_rom_delay_us(1000);
do {
if (usb_serial_jtag_ll_rxfifo_data_available()) {
usb_serial_jtag_ll_read_rxfifo((uint8_t *)&str[read_len], 1);
read_len++;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!(read_len == cnt || str[read_len - 1] == '\n'));
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#else
uint32_t len = 0;
uint32_t read_len = 0;
bool stop = false;
do {
len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
if (len > 0) {
for (uint32_t i = 0; i < len; i++) {
/* Read the character from the RX FIFO */
uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
read_len++;
if (read_len == cnt - 1|| str[read_len - 1] == '\n') {
stop = true;
break;
}
}
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!stop);
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#endif
}
int boot_console_init(void)
{
BOOT_LOG_INF("Initializing serial boot pins");
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
esp_rom_uart_tx_wait_idle(0);
#else
/* Enable GPIO for UART RX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
0);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX);
/* Enable GPIO for UART TX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
0, 0);
gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_DEFAULT);
uart_ll_set_mode_normal(serial_boot_uart_dev);
uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_DEFAULT);
uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
uart_ll_txfifo_rst(serial_boot_uart_dev);
uart_ll_rxfifo_rst(serial_boot_uart_dev);
esp_rom_delay_us(50000);
#endif
return 0;
}
bool boot_serial_detect_pin(void)
{
bool detected = false;
int pin_value = 0;
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
// Pull-down
case 0:
gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
// Pull-up
case 1:
gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
}
esp_rom_delay_us(50000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
esp_rom_delay_us(50000);
if (detected) {
if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
/* The delay time is an approximation */
for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
esp_rom_delay_us(10000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
if (!detected) {
break;
}
}
}
}
return detected;
}

View File

@@ -0,0 +1,84 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x1000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_APPLICATION_SIZE=0x100000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# When enabled, prevents updating image to an older version
# CONFIG_ESP_DOWNGRADE_PREVENTION=y
# This option makes downgrade prevention rely also on security
# counter (defined using imgtool) instead of only image version
# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
# Enables the MCUboot Serial Recovery, that allows the use of
# MCUMGR to upload a firmware through the serial port
# CONFIG_ESP_MCUBOOT_SERIAL=y
# Use sector erasing (recommended) instead of entire image size
# erasing when uploading through Serial Recovery
# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
# GPIO used to boot on Serial Recovery
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
# GPIO input type (0 for Pull-down, 1 for Pull-up)
# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
# GPIO signal value
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
# Delay time for identify the GPIO signal
# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
# UART port used for serial communication (not needed when using USB)
# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
# GPIO for Serial RX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=18
# GPIO for Serial TX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=17
# Use UART0 for console printing (use either UART or USB alone)
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# (UART_NUM=0 must not be changed)
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=17
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=18
# CONFIG_ESP_SIGN_EC256=y
# CONFIG_ESP_SIGN_ED25519=n
# CONFIG_ESP_SIGN_RSA=n
# CONFIG_ESP_SIGN_RSA_LEN=2048
# Use Tinycrypt lib for EC256 or ED25519 signing
# CONFIG_ESP_USE_TINYCRYPT=y
# Use Mbed TLS lib for RSA image signing
# CONFIG_ESP_USE_MBEDTLS=n
# It is strongly recommended to generate a new signing key
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
# Hardware Secure Boot related options
# CONFIG_SECURE_SIGNED_ON_BOOT=1
# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
# CONFIG_SECURE_BOOT=1
# CONFIG_SECURE_BOOT_V2_ENABLED=1
# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1

View File

@@ -0,0 +1,147 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Simplified memory map for the bootloader.
*
* The main purpose is to make sure the bootloader can load into main memory
* without overwriting itself.
*/
MEMORY
{
iram_seg (RWX) : org = 0x40047000, len = 0x9000
iram_loader_seg (RWX) : org = 0x40050000, len = 0x6000
dram_seg (RW) : org = 0x3FFE6000, len = 0x9000
}
/* Default entry point: */
ENTRY(main);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libhal.a:*.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*main.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -0,0 +1,191 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include <bootutil/bootutil_log.h>
#include <esp_rom_uart.h>
#include <esp_rom_gpio.h>
#include <esp_rom_sys.h>
#include <esp_rom_caps.h>
#include <soc/uart_periph.h>
#include <soc/gpio_struct.h>
#include <soc/io_mux_reg.h>
#include <soc/rtc.h>
#include <hal/gpio_types.h>
#include <hal/gpio_ll.h>
#include <hal/uart_ll.h>
#include <hal/clk_gate_ll.h>
#include <hal/gpio_hal.h>
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#else
#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#else
#define SERIAL_BOOT_GPIO_DETECT_VAL 1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#else
#define SERIAL_BOOT_DETECT_DELAY_S 5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#else
// pull-down
#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
#else
#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#else
#define SERIAL_BOOT_GPIO_RX GPIO_NUM_18
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#else
#define SERIAL_BOOT_GPIO_TX GPIO_NUM_17
#endif
static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
&UART0 :
&UART1;
void console_write(const char *str, int cnt)
{
uint32_t tx_len;
uint32_t write_len;
do {
tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
if (tx_len > 0) {
write_len = tx_len < cnt ? tx_len : cnt;
uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len);
cnt -= write_len;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (cnt > 0);
}
int console_read(char *str, int cnt, int *newline)
{
uint32_t len = 0;
uint32_t read_len = 0;
bool stop = false;
do {
len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
if (len > 0) {
for (uint32_t i = 0; i < len; i++) {
/* Read the character from the RX FIFO */
uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
read_len++;
if (read_len == cnt - 1|| str[read_len - 1] == '\n') {
stop = true;
break;
}
}
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!stop);
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
}
int boot_console_init(void)
{
BOOT_LOG_INF("Initializing serial boot pins");
/* Enable GPIO for UART RX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
0);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX);
/* Enable GPIO for UART TX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
0, 0);
gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_APB);
uart_ll_set_mode_normal(serial_boot_uart_dev);
uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_APB);
uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
uart_ll_txfifo_rst(serial_boot_uart_dev);
uart_ll_rxfifo_rst(serial_boot_uart_dev);
esp_rom_delay_us(50000);
return 0;
}
bool boot_serial_detect_pin(void)
{
bool detected = false;
int pin_value = 0;
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
// Pull-down
case 0:
gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
// Pull-up
case 1:
gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
}
esp_rom_delay_us(50000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
esp_rom_delay_us(50000);
if (detected) {
if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
/* The delay time is an approximation */
for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
esp_rom_delay_us(10000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
if (!detected) {
break;
}
}
}
}
return detected;
}

View File

@@ -0,0 +1,38 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x0000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
# Example of values to be used when multi image is enabled
# Notice that the OS layer and update agent must be aware
# of these regions
CONFIG_ESP_APPLICATION_SIZE=0x80000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x90000
CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0x110000
CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x190000
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# Use UART0 for console printing (use either UART or USB alone)
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# (UART_NUM=0 must not be changed)
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=17
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=18
# Use USB JTAG Serial for console printing
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
# Enables multi image, if it is not defined, it is assumed
# only one updatable image
# CONFIG_ESP_IMAGE_NUMBER=2
# Enables multi image boot on independent processors
# (main host OS is not responsible for booting the second image)
# Use only with CONFIG_ESP_IMAGE_NUMBER=2
# CONFIG_ESP_MULTI_PROCESSOR_BOOT=y

View File

@@ -0,0 +1,108 @@
# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
CONFIG_ESP_FLASH_SIZE=4MB
CONFIG_ESP_BOOTLOADER_SIZE=0xF000
CONFIG_ESP_BOOTLOADER_OFFSET=0x0000
CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
CONFIG_ESP_APPLICATION_SIZE=0x100000
CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000
CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
CONFIG_ESP_SCRATCH_OFFSET=0x210000
CONFIG_ESP_SCRATCH_SIZE=0x40000
# When enabled, prevents updating image to an older version
# CONFIG_ESP_DOWNGRADE_PREVENTION=y
# This option makes downgrade prevention rely also on security
# counter (defined using imgtool) instead of only image version
# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
# Enables multi image, if it is not defined, it is assumed
# only one updatable image
# CONFIG_ESP_IMAGE_NUMBER=2
# Enables multi image boot on independent processors
# (main host OS is not responsible for booting the second image)
# Use only with CONFIG_ESP_IMAGE_NUMBER=2
# CONFIG_ESP_MULTI_PROCESSOR_BOOT=y
# Example of values to be used when multi image is enabled
# Notice that the OS layer and update agent must be aware
# of these regions
# CONFIG_ESP_APPLICATION_SIZE=0x80000
# CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
# CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x90000
# CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0x110000
# CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x190000
# CONFIG_ESP_SCRATCH_OFFSET=0x210000
# CONFIG_ESP_SCRATCH_SIZE=0x40000
# Enables the MCUboot Serial Recovery, that allows the use of
# MCUMGR to upload a firmware through the serial port
# CONFIG_ESP_MCUBOOT_SERIAL=y
# Use Serial through USB JTAG Serial port for Serial Recovery
# CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
# Use sector erasing (recommended) instead of entire image size
# erasing when uploading through Serial Recovery
# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
# GPIO used to boot on Serial Recovery
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
# GPIO input type (0 for Pull-down, 1 for Pull-up)
# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
# GPIO signal value
# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
# Delay time for identify the GPIO signal
# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
# UART port used for serial communication (not needed when using USB)
# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
# GPIO for Serial RX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=18
# GPIO for Serial TX signal
# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=17
# Use UART0 for console printing (use either UART or USB alone)
CONFIG_ESP_CONSOLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=0
# Configures alternative UART port for console printing
# (UART_NUM=0 must not be changed)
# CONFIG_ESP_CONSOLE_UART_CUSTOM=y
# CONFIG_ESP_CONSOLE_UART_TX_GPIO=17
# CONFIG_ESP_CONSOLE_UART_RX_GPIO=18
# Use USB JTAG Serial for console printing
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
# CONFIG_ESP_SIGN_EC256=y
# CONFIG_ESP_SIGN_ED25519=n
# CONFIG_ESP_SIGN_RSA=n
# CONFIG_ESP_SIGN_RSA_LEN=2048
# Use Tinycrypt lib for EC256 or ED25519 signing
# CONFIG_ESP_USE_TINYCRYPT=y
# Use Mbed TLS lib for RSA image signing
# CONFIG_ESP_USE_MBEDTLS=n
# It is strongly recommended to generate a new signing key
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
# Hardware Secure Boot related options
# CONFIG_SECURE_SIGNED_ON_BOOT=1
# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
# CONFIG_SECURE_BOOT=1
# CONFIG_SECURE_BOOT_V2_ENABLED=1
# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1

View File

@@ -0,0 +1,147 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Simplified memory map for the bootloader.
*
* The main purpose is to make sure the bootloader can load into main memory
* without overwriting itself.
*/
MEMORY
{
iram_seg (RWX) : org = 0x403B0000, len = 0xA000
iram_loader_seg (RWX) : org = 0x403BA000, len = 0x6000
dram_seg (RW) : org = 0x3FCD0000, len = 0x9A00
}
/* Default entry point: */
ENTRY(main);
SECTIONS
{
.iram_loader.text :
{
. = ALIGN (16);
_loader_text_start = ABSOLUTE(.);
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
*libhal.a:*.*(.literal .text .literal.* .text.*)
*esp_mcuboot.*(.literal .text .literal.* .text.*)
*esp_loader.*(.literal .text .literal.* .text.*)
*main.*(.literal .text .literal.* .text.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
_loader_text_end = ABSOLUTE(.);
} > iram_loader_seg
.iram.text :
{
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
} > iram_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_dram_start = ABSOLUTE(.);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
} >dram_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
_data_end = ABSOLUTE(.);
} >dram_seg
.dram0.rodata :
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
*(.eh_frame)
. = (. + 3) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */
__init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
_dram_end = ABSOLUTE(.);
} >dram_seg
.iram.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.iram .iram.*) /* catch stray IRAM_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} > iram_seg
}

View File

@@ -0,0 +1,228 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include <bootutil/bootutil_log.h>
#include <esp_rom_uart.h>
#include <esp_rom_gpio.h>
#include <esp_rom_sys.h>
#include <esp_rom_caps.h>
#include <soc/uart_periph.h>
#include <soc/gpio_struct.h>
#include <soc/io_mux_reg.h>
#include <soc/rtc.h>
#include <hal/gpio_types.h>
#include <hal/gpio_ll.h>
#include <hal/uart_ll.h>
#include <hal/clk_gate_ll.h>
#include <hal/gpio_hal.h>
#include <hal/usb_serial_jtag_ll.h>
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT
#else
#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL
#else
#define SERIAL_BOOT_GPIO_DETECT_VAL 1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S
#else
#define SERIAL_BOOT_DETECT_DELAY_S 5
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE
#else
// pull-down
#define SERIAL_BOOT_GPIO_INPUT_TYPE 0
#endif
#ifndef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM
#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM
#else
#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX
#else
#define SERIAL_BOOT_GPIO_RX GPIO_NUM_18
#endif
#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX
#else
#define SERIAL_BOOT_GPIO_TX GPIO_NUM_17
#endif
static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ?
&UART0 :
&UART1;
#endif
void console_write(const char *str, int cnt)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
while (!usb_serial_jtag_ll_txfifo_writable()) {
MCUBOOT_WATCHDOG_FEED();
}
usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, cnt);
usb_serial_jtag_ll_txfifo_flush();
#else
uint32_t tx_len;
uint32_t write_len;
do {
tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev);
if (tx_len > 0) {
write_len = tx_len < cnt ? tx_len : cnt;
uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len);
cnt -= write_len;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (cnt > 0);
#endif
}
int console_read(char *str, int cnt, int *newline)
{
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
uint32_t read_len = 0;
esp_rom_delay_us(1000);
do {
if (usb_serial_jtag_ll_rxfifo_data_available()) {
usb_serial_jtag_ll_read_rxfifo((uint8_t *)&str[read_len], 1);
read_len++;
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!(read_len == cnt || str[read_len - 1] == '\n'));
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#else
uint32_t len = 0;
uint32_t read_len = 0;
bool stop = false;
do {
len = uart_ll_get_rxfifo_len(serial_boot_uart_dev);
if (len > 0) {
for (uint32_t i = 0; i < len; i++) {
/* Read the character from the RX FIFO */
uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1);
read_len++;
if (read_len == cnt - 1|| str[read_len - 1] == '\n') {
stop = true;
break;
}
}
}
MCUBOOT_WATCHDOG_FEED();
esp_rom_delay_us(1000);
} while (!stop);
*newline = (str[read_len - 1] == '\n') ? 1 : 0;
return read_len;
#endif
}
int boot_console_init(void)
{
BOOT_LOG_INF("Initializing serial boot pins");
#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG
usb_serial_jtag_ll_txfifo_flush();
esp_rom_uart_tx_wait_idle(0);
#else
/* Enable GPIO for UART RX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX),
0);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX);
esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX);
/* Enable GPIO for UART TX */
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX);
esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX,
UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX),
0, 0);
gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX);
uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_APB);
uart_ll_set_mode_normal(serial_boot_uart_dev);
uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_APB);
uart_ll_set_stop_bits(serial_boot_uart_dev, 1u);
uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE);
uart_ll_set_rx_tout(serial_boot_uart_dev, 16);
uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS);
uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0);
uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100);
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM);
uart_ll_txfifo_rst(serial_boot_uart_dev);
uart_ll_rxfifo_rst(serial_boot_uart_dev);
esp_rom_delay_us(50000);
#endif
return 0;
}
bool boot_serial_detect_pin(void)
{
bool detected = false;
int pin_value = 0;
esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT);
gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT);
switch (SERIAL_BOOT_GPIO_INPUT_TYPE) {
// Pull-down
case 0:
gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
// Pull-up
case 1:
gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT);
break;
}
esp_rom_delay_us(50000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
esp_rom_delay_us(50000);
if (detected) {
if (SERIAL_BOOT_DETECT_DELAY_S > 0) {
/* The delay time is an approximation */
for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) {
esp_rom_delay_us(10000);
pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT);
detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL);
if (!detected) {
break;
}
}
}
}
return detected;
}

View File

@@ -0,0 +1,105 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <bootutil/bootutil_log.h>
#include <bootutil/fault_injection_hardening.h>
#include "bootloader_memory_utils.h"
#include "bootloader_flash_priv.h"
#include "esp_flash_encrypt.h"
#include "rom/uart.h"
#include "esp_mcuboot_image.h"
#include "esp_loader.h"
#include "flash_map_backend/flash_map_backend.h"
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
#include "app_cpu_start.h"
#endif
static int load_segment(const struct flash_area *fap, uint32_t data_addr, uint32_t data_len, uint32_t load_addr)
{
const uint32_t *data = (const uint32_t *)bootloader_mmap((fap->fa_off + data_addr), data_len);
if (!data) {
BOOT_LOG_ERR("%s: Bootloader mmap failed", __func__);
return -1;
}
memcpy((void *)load_addr, data, data_len);
bootloader_munmap(data);
return 0;
}
void esp_app_image_load(int image_index, int slot, unsigned int hdr_offset, unsigned int *entry_addr)
{
const struct flash_area *fap;
int area_id;
int rc;
area_id = flash_area_id_from_multi_image_slot(image_index, slot);
rc = flash_area_open(area_id, &fap);
if (rc != 0) {
BOOT_LOG_ERR("%s: flash_area_open failed with %d", __func__, rc);
}
BOOT_LOG_INF("Loading image %d - slot %d from flash, area id: %d", image_index, slot, area_id);
const uint32_t *data = (const uint32_t *)bootloader_mmap((fap->fa_off + hdr_offset), sizeof(esp_image_load_header_t));
esp_image_load_header_t load_header = {0};
memcpy((void *)&load_header, data, sizeof(esp_image_load_header_t));
bootloader_munmap(data);
if (load_header.header_magic != ESP_LOAD_HEADER_MAGIC) {
BOOT_LOG_ERR("Load header magic verification failed. Aborting");
FIH_PANIC;
}
if (!esp_ptr_in_iram((void *)load_header.iram_dest_addr) || !esp_ptr_in_iram((void *)(load_header.iram_dest_addr + load_header.iram_size))) {
BOOT_LOG_ERR("IRAM region in load header is not valid. Aborting");
FIH_PANIC;
}
if (!esp_ptr_in_dram((void *)load_header.dram_dest_addr) || !esp_ptr_in_dram((void *)(load_header.dram_dest_addr + load_header.dram_size))) {
BOOT_LOG_ERR("DRAM region in load header is not valid. Aborting");
FIH_PANIC;
}
if (!esp_ptr_in_iram((void *)load_header.entry_addr)) {
BOOT_LOG_ERR("Application entry point (0x%x) is not in IRAM. Aborting", load_header.entry_addr);
FIH_PANIC;
}
BOOT_LOG_INF("DRAM segment: start=0x%x, size=0x%x, vaddr=0x%x", fap->fa_off + load_header.dram_flash_offset, load_header.dram_size, load_header.dram_dest_addr);
load_segment(fap, load_header.dram_flash_offset, load_header.dram_size, load_header.dram_dest_addr);
BOOT_LOG_INF("IRAM segment: start=0x%x, size=0x%x, vaddr=0x%x", fap->fa_off + load_header.iram_flash_offset, load_header.iram_size, load_header.iram_dest_addr);
load_segment(fap, load_header.iram_flash_offset, load_header.iram_size, load_header.iram_dest_addr);
BOOT_LOG_INF("start=0x%x", load_header.entry_addr);
uart_tx_wait_idle(0);
assert(entry_addr != NULL);
*entry_addr = load_header.entry_addr;
}
void start_cpu0_image(int image_index, int slot, unsigned int hdr_offset)
{
unsigned int entry_addr;
esp_app_image_load(image_index, slot, hdr_offset, &entry_addr);
((void (*)(void))entry_addr)(); /* Call to application entry address should not return */
FIH_PANIC; /* It should not get here */
}
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
void start_cpu1_image(int image_index, int slot, unsigned int hdr_offset)
{
unsigned int entry_addr;
esp_app_image_load(image_index, slot, hdr_offset, &entry_addr);
appcpu_start(entry_addr);
}
#endif

View File

@@ -0,0 +1,420 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <bootutil/bootutil.h>
#include <bootutil/bootutil_log.h>
#include "sdkconfig.h"
#include "esp_err.h"
#include "bootloader_flash_priv.h"
#include "esp_flash_encrypt.h"
#include "flash_map_backend/flash_map_backend.h"
#include "sysflash/sysflash.h"
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#ifndef MIN
# define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef ALIGN_UP
# define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
#endif
#ifndef ALIGN_DOWN
# define ALIGN_DOWN(num, align) ((num) & ~((align) - 1))
#endif
#ifndef ALIGN_OFFSET
# define ALIGN_OFFSET(num, align) ((num) & ((align) - 1))
#endif
#ifndef IS_ALIGNED
# define IS_ALIGNED(num, align) (ALIGN_OFFSET((num), (align)) == 0)
#endif
#define FLASH_BUFFER_SIZE 256 /* SPI Flash block size */
_Static_assert(IS_ALIGNED(FLASH_BUFFER_SIZE, 4), "Buffer size for SPI Flash operations must be 4-byte aligned.");
#define BOOTLOADER_START_ADDRESS CONFIG_BOOTLOADER_OFFSET_IN_FLASH
#define BOOTLOADER_SIZE CONFIG_ESP_BOOTLOADER_SIZE
#define IMAGE0_PRIMARY_START_ADDRESS CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS
#define IMAGE0_SECONDARY_START_ADDRESS CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS
#define SCRATCH_OFFSET CONFIG_ESP_SCRATCH_OFFSET
#if (MCUBOOT_IMAGE_NUMBER == 2)
#define IMAGE1_PRIMARY_START_ADDRESS CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS
#define IMAGE1_SECONDARY_START_ADDRESS CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS
#endif
#define APPLICATION_SIZE CONFIG_ESP_APPLICATION_SIZE
#define SCRATCH_SIZE CONFIG_ESP_SCRATCH_SIZE
extern int ets_printf(const char *fmt, ...);
static const struct flash_area bootloader = {
.fa_id = FLASH_AREA_BOOTLOADER,
.fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
.fa_off = BOOTLOADER_START_ADDRESS,
.fa_size = BOOTLOADER_SIZE,
};
static const struct flash_area primary_img0 = {
.fa_id = FLASH_AREA_IMAGE_PRIMARY(0),
.fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
.fa_off = IMAGE0_PRIMARY_START_ADDRESS,
.fa_size = APPLICATION_SIZE,
};
static const struct flash_area secondary_img0 = {
.fa_id = FLASH_AREA_IMAGE_SECONDARY(0),
.fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
.fa_off = IMAGE0_SECONDARY_START_ADDRESS,
.fa_size = APPLICATION_SIZE,
};
#if (MCUBOOT_IMAGE_NUMBER == 2)
static const struct flash_area primary_img1 = {
.fa_id = FLASH_AREA_IMAGE_PRIMARY(1),
.fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
.fa_off = IMAGE1_PRIMARY_START_ADDRESS,
.fa_size = APPLICATION_SIZE,
};
static const struct flash_area secondary_img1 = {
.fa_id = FLASH_AREA_IMAGE_SECONDARY(1),
.fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
.fa_off = IMAGE1_SECONDARY_START_ADDRESS,
.fa_size = APPLICATION_SIZE,
};
#endif
static const struct flash_area scratch_img0 = {
.fa_id = FLASH_AREA_IMAGE_SCRATCH,
.fa_device_id = FLASH_DEVICE_INTERNAL_FLASH,
.fa_off = SCRATCH_OFFSET,
.fa_size = SCRATCH_SIZE,
};
static const struct flash_area *s_flash_areas[] = {
&bootloader,
&primary_img0,
&secondary_img0,
#if (MCUBOOT_IMAGE_NUMBER == 2)
&primary_img1,
&secondary_img1,
#endif
&scratch_img0,
};
static const struct flash_area *prv_lookup_flash_area(uint8_t id) {
for (size_t i = 0; i < ARRAY_SIZE(s_flash_areas); i++) {
const struct flash_area *area = s_flash_areas[i];
if (id == area->fa_id) {
return area;
}
}
return NULL;
}
int flash_area_open(uint8_t id, const struct flash_area **area_outp)
{
BOOT_LOG_DBG("%s: ID=%d", __func__, (int)id);
const struct flash_area *area = prv_lookup_flash_area(id);
*area_outp = area;
return area != NULL ? 0 : -1;
}
void flash_area_close(const struct flash_area *area)
{
}
static bool aligned_flash_read(uintptr_t addr, void *dest, size_t size)
{
if (IS_ALIGNED(addr, 4) && IS_ALIGNED((uintptr_t)dest, 4) && IS_ALIGNED(size, 4)) {
/* A single read operation is enough when when all parameters are aligned */
return bootloader_flash_read(addr, dest, size, true) == ESP_OK;
}
const uint32_t aligned_addr = ALIGN_DOWN(addr, 4);
const uint32_t addr_offset = ALIGN_OFFSET(addr, 4);
uint32_t bytes_remaining = size;
uint8_t read_data[FLASH_BUFFER_SIZE] = {0};
/* Align the read address to 4-byte boundary and ensure read size is a multiple of 4 bytes */
uint32_t bytes = MIN(bytes_remaining + addr_offset, sizeof(read_data));
if (bootloader_flash_read(aligned_addr, read_data, ALIGN_UP(bytes, 4), true) != ESP_OK) {
return false;
}
/* Skip non-useful data which may have been read for adjusting the alignment */
uint32_t bytes_read = bytes - addr_offset;
memcpy(dest, &read_data[addr_offset], bytes_read);
bytes_remaining -= bytes_read;
/* Read remaining data from Flash in case requested size is greater than buffer size */
uint32_t offset = bytes;
while (bytes_remaining != 0) {
bytes = MIN(bytes_remaining, sizeof(read_data));
if (bootloader_flash_read(aligned_addr + offset, read_data, ALIGN_UP(bytes, 4), true) != ESP_OK) {
return false;
}
memcpy(&((uint8_t *)dest)[bytes_read], read_data, bytes);
offset += bytes;
bytes_read += bytes;
bytes_remaining -= bytes;
}
return true;
}
int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
uint32_t len)
{
if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
return -1;
}
const uint32_t end_offset = off + len;
if (end_offset > fa->fa_size) {
BOOT_LOG_ERR("%s: Out of Bounds (0x%x vs 0x%x)", __func__, end_offset, fa->fa_size);
return -1;
}
bool success = aligned_flash_read(fa->fa_off + off, dst, len);
if (!success) {
BOOT_LOG_ERR("%s: Flash read failed", __func__);
return -1;
}
return 0;
}
static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
{
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
bool flash_encryption_enabled = esp_flash_encryption_enabled();
#else
bool flash_encryption_enabled = false;
#endif
if (IS_ALIGNED(dest_addr, 4) && IS_ALIGNED((uintptr_t)src, 4) && IS_ALIGNED(size, 4)) {
/* A single write operation is enough when all parameters are aligned */
return bootloader_flash_write(dest_addr, (void *)src, size, flash_encryption_enabled) == ESP_OK;
}
const uint32_t aligned_addr = ALIGN_DOWN(dest_addr, 4);
const uint32_t addr_offset = ALIGN_OFFSET(dest_addr, 4);
uint32_t bytes_remaining = size;
uint8_t write_data[FLASH_BUFFER_SIZE] = {0};
/* Perform a read operation considering an offset not aligned to 4-byte boundary */
uint32_t bytes = MIN(bytes_remaining + addr_offset, sizeof(write_data));
if (bootloader_flash_read(aligned_addr, write_data, ALIGN_UP(bytes, 4), true) != ESP_OK) {
return false;
}
uint32_t bytes_written = bytes - addr_offset;
memcpy(&write_data[addr_offset], src, bytes_written);
if (bootloader_flash_write(aligned_addr, write_data, ALIGN_UP(bytes, 4), flash_encryption_enabled) != ESP_OK) {
return false;
}
bytes_remaining -= bytes_written;
/* Write remaining data to Flash if any */
uint32_t offset = bytes;
while (bytes_remaining != 0) {
bytes = MIN(bytes_remaining, sizeof(write_data));
if (bootloader_flash_read(aligned_addr + offset, write_data, ALIGN_UP(bytes, 4), true) != ESP_OK) {
return false;
}
memcpy(write_data, &((uint8_t *)src)[bytes_written], bytes);
if (bootloader_flash_write(aligned_addr + offset, write_data, ALIGN_UP(bytes, 4), flash_encryption_enabled) != ESP_OK) {
return false;
}
offset += bytes;
bytes_written += bytes;
bytes_remaining -= bytes;
}
return true;
}
int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src,
uint32_t len)
{
if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
return -1;
}
const uint32_t end_offset = off + len;
if (end_offset > fa->fa_size) {
BOOT_LOG_ERR("%s: Out of Bounds (0x%x vs 0x%x)", __func__, end_offset, fa->fa_size);
return -1;
}
const uint32_t start_addr = fa->fa_off + off;
BOOT_LOG_DBG("%s: Addr: 0x%08x Length: %d", __func__, (int)start_addr, (int)len);
bool success = aligned_flash_write(start_addr, src, len);
if (!success) {
BOOT_LOG_ERR("%s: Flash write failed", __func__);
return -1;
}
return 0;
}
int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
{
if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
return -1;
}
if ((len % FLASH_SECTOR_SIZE) != 0 || (off % FLASH_SECTOR_SIZE) != 0) {
BOOT_LOG_ERR("%s: Not aligned on sector Offset: 0x%x Length: 0x%x",
__func__, (int)off, (int)len);
return -1;
}
const uint32_t start_addr = fa->fa_off + off;
BOOT_LOG_DBG("%s: Addr: 0x%08x Length: %d", __func__, (int)start_addr, (int)len);
if (bootloader_flash_erase_range(start_addr, len) != ESP_OK) {
BOOT_LOG_ERR("%s: Flash erase failed", __func__);
return -1;
}
#if VALIDATE_PROGRAM_OP
for (size_t i = 0; i < len; i++) {
uint8_t *val = (void *)(start_addr + i);
if (*val != 0xff) {
BOOT_LOG_ERR("%s: Erase at 0x%x Failed", __func__, (int)val);
assert(0);
}
}
#endif
return 0;
}
uint32_t flash_area_align(const struct flash_area *area)
{
static size_t align = 0;
if (align == 0) {
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
bool flash_encryption_enabled = esp_flash_encryption_enabled();
#else
bool flash_encryption_enabled = false;
#endif
if (flash_encryption_enabled) {
align = 32;
} else {
align = 4;
}
}
return align;
}
uint8_t flash_area_erased_val(const struct flash_area *area)
{
return 0xff;
}
int flash_area_get_sectors(int fa_id, uint32_t *count,
struct flash_sector *sectors)
{
const struct flash_area *fa = prv_lookup_flash_area(fa_id);
if (fa->fa_device_id != FLASH_DEVICE_INTERNAL_FLASH) {
return -1;
}
const size_t sector_size = FLASH_SECTOR_SIZE;
uint32_t total_count = 0;
for (size_t off = 0; off < fa->fa_size; off += sector_size) {
// Note: Offset here is relative to flash area, not device
sectors[total_count].fs_off = off;
sectors[total_count].fs_size = sector_size;
total_count++;
}
*count = total_count;
return 0;
}
int flash_area_sector_from_off(uint32_t off, struct flash_sector *sector)
{
sector->fs_off = (off / FLASH_SECTOR_SIZE) * FLASH_SECTOR_SIZE;
sector->fs_size = FLASH_SECTOR_SIZE;
return 0;
}
int flash_area_get_sector(const struct flash_area *fa, uint32_t off,
struct flash_sector *sector)
{
sector->fs_off = (off / FLASH_SECTOR_SIZE) * FLASH_SECTOR_SIZE;
sector->fs_size = FLASH_SECTOR_SIZE;
return 0;
}
int flash_area_id_from_multi_image_slot(int image_index, int slot)
{
BOOT_LOG_DBG("%s", __func__);
switch (slot) {
case 0:
return FLASH_AREA_IMAGE_PRIMARY(image_index);
case 1:
return FLASH_AREA_IMAGE_SECONDARY(image_index);
}
BOOT_LOG_ERR("Unexpected Request: image_index=%d, slot=%d", image_index, slot);
return -1; /* flash_area_open will fail on that */
}
int flash_area_id_from_image_slot(int slot)
{
return flash_area_id_from_multi_image_slot(0, slot);
}
int flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa)
{
return -1;
}
void mcuboot_assert_handler(const char *file, int line, const char *func)
{
ets_printf("assertion failed: file \"%s\", line %d, func: %s\n", file, line, func);
abort();
}

View File

@@ -0,0 +1,12 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER xtensa-esp32-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX xtensa-esp32-elf-)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "ASM Compiler Base Flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections" CACHE STRING "Linker Base Flags")

View File

@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_C_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -march=rv32imc_zicsr_zifencei --specs=nosys.specs" CACHE STRING "Linker Base Flags")

View File

@@ -0,0 +1,9 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_C_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -march=rv32imc_zicsr_zifencei --specs=nosys.specs" CACHE STRING "Linker Base Flags")

View File

@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_C_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -march=rv32imc_zicsr_zifencei --specs=nosys.specs" CACHE STRING "Linker Base Flags")

View File

@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_C_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -march=rv32imc_zicsr_zifencei --specs=nosys.specs" CACHE STRING "Linker Base Flags")

View File

@@ -0,0 +1,10 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER xtensa-esp32s2-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32s2-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32s2-elf-gcc)
set(CMAKE_C_FLAGS "-mlongcalls" CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-mlongcalls" CACHE STRING "C++ Compiler Base Flags")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections" CACHE STRING "Linker Base Flags")

View File

@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER xtensa-esp32s3-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32s3-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32s3-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX xtensa-esp32s3-elf-)
set(CMAKE_C_FLAGS "-mlongcalls" CACHE STRING "C Compiler Base Flags" FORCE)
set(CMAKE_CXX_FLAGS "-mlongcalls" CACHE STRING "C++ Compiler Base Flags" FORCE)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "ASM Compiler Base Flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections" CACHE STRING "Linker Base Flags")

View File

@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
#
# SPDX-License-Identifier: Apache-2.0
# Parse config files (.conf, format: <CONFIG_NAME>=<VALUE>) and set each as
# definitions and variables
function(parse_and_set_config_file CONFIG_FILE)
file(STRINGS ${CONFIG_FILE} BOOTLOADER_CONF)
foreach(config ${BOOTLOADER_CONF})
if (NOT (${config} MATCHES "#"))
string(REGEX REPLACE "^[ ]+" "" config ${config})
string(REGEX MATCH "^[^=]+" CONFIG_NAME ${config})
string(REPLACE "${CONFIG_NAME}=" "" CONFIG_VALUE ${config})
# Overrides if already defined (definitions from latter file prevails over the former)
if (DEFINED ${CONFIG_NAME})
set(CONFIG_OLD "${CONFIG_NAME}")
remove_definitions(-D${CONFIG_NAME}=${${CONFIG_OLD}})
endif()
if (NOT ("${CONFIG_VALUE}" STREQUAL "n"
OR "${CONFIG_VALUE}" STREQUAL "N"))
if (("${CONFIG_VALUE}" STREQUAL "y")
OR ("${CONFIG_VALUE}" STREQUAL "Y"))
set(CONFIG_VALUE 1)
endif()
add_compile_definitions(${CONFIG_NAME}=${CONFIG_VALUE})
set(${CONFIG_NAME} ${CONFIG_VALUE} PARENT_SCOPE)
endif()
endif()
endforeach()
endfunction()