This is an automated email from the ASF dual-hosted git repository.

michallenc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 68b87a9a9bb arch/xtensa/esp32s3: Build MCUboot with CMake.
68b87a9a9bb is described below

commit 68b87a9a9bb77d820bf79ed75ae2bd2f01d57524
Author: Max Kriegleder <[email protected]>
AuthorDate: Thu Oct 29 17:55:24 2026 +0100

    arch/xtensa/esp32s3: Build MCUboot with CMake.
    
    The CMake build of the ESP32-S3 stopped at configure time for
    ESP32S3_APP_FORMAT_MCUBOOT. Port Bootloader.mk:
    
    * Bootloader.cmake writes bootloader.conf as Bootloader.mk does, and adds
      a "bootloader" target (not in the default build, as "make bootloader")
      that clones MCUboot and its HAL, runs tools/espressif/build_mcuboot.sh
      and copies mcuboot-esp32s3.bin to the NuttX directory, where the flash
      and merge steps look for it (as on RISC-V).
    * On Xtensa the board options are named <CHIP>_ESPTOOL_TARGET_*,
      <CHIP>_APP_MCUBOOT_HEADER_SIZE and <CHIP>_OTA_*, as 
tools/esp32s3/Config.mk
      reads them; map them onto the ESPRESSIF_* names the shared image and flash
      scripts use. Without it the image was signed and flashed for the
      ESPRESSIF_OTA_* defaults, or stopped at "Missing MCUBoot slot target".
    * The bootloader binary is needed only for a merged or UF2 image, as in
      Config.mk; an app build no longer fails before the bootloader target has
      run.
    
    ESP32 and ESP32-S2 MCUboot and the legacy app format still stop at
    configure time: their Bootloader.mk differ (secure boot, 0x1000 offset).
    
    Assisted-by: Claude:claude-opus-5-5
    Signed-off-by: Max Kriegleder <[email protected]>
---
 arch/xtensa/src/common/espressif/CMakeLists.txt |  15 ++-
 arch/xtensa/src/esp32s3/Bootloader.cmake        | 157 ++++++++++++++++++++++++
 tools/espressif/espressif_esptool_common.cmake  |  14 +++
 tools/espressif/espressif_mkimage.cmake         |   9 +-
 4 files changed, 189 insertions(+), 6 deletions(-)

diff --git a/arch/xtensa/src/common/espressif/CMakeLists.txt 
b/arch/xtensa/src/common/espressif/CMakeLists.txt
index dd423a7c1ae..30bded41fe8 100644
--- a/arch/xtensa/src/common/espressif/CMakeLists.txt
+++ b/arch/xtensa/src/common/espressif/CMakeLists.txt
@@ -4,13 +4,13 @@
 # SPDX-License-Identifier: Apache-2.0
 # 
##############################################################################
 
-# The CMake build makes simple boot images only; MCUboot and the legacy app
-# format (the bootloader build of the chips' Bootloader.mk) need Make for now.
+# The CMake build makes simple boot images, and MCUboot images on the ESP32-S3;
+# the other bootloader builds of the chips' Bootloader.mk need Make for now.
 
-if(NOT CONFIG_ESPRESSIF_SIMPLE_BOOT)
+if(NOT CONFIG_ESPRESSIF_SIMPLE_BOOT AND NOT CONFIG_ESP32S3_APP_FORMAT_MCUBOOT)
   message(
     FATAL_ERROR
-      "CMake builds of ${CONFIG_ARCH_CHIP} support ESPRESSIF_SIMPLE_BOOT only, 
use Make for MCUboot or the legacy app format"
+      "CMake builds of ${CONFIG_ARCH_CHIP} support ESPRESSIF_SIMPLE_BOOT (and 
MCUboot on the ESP32-S3) only, use Make for this app format"
   )
 endif()
 
@@ -334,6 +334,13 @@ add_custom_command(
   COMMENT "Generating ESP-compatible binary"
   VERBATIM)
 
+if(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT)
+  include(${NUTTX_CHIP_ABS_DIR}/Bootloader.cmake)
+else()
+  add_custom_target(bootloader COMMAND ${CMAKE_COMMAND} -E echo
+                                       "Using direct bootloader to boot 
NuttX.")
+endif()
+
 # Usage: ESPTOOL_PORT=/dev/ttyUSBx cmake --build <build_dir> --target flash
 
 add_custom_target(
diff --git a/arch/xtensa/src/esp32s3/Bootloader.cmake 
b/arch/xtensa/src/esp32s3/Bootloader.cmake
new file mode 100644
index 00000000000..ffd162c69c9
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/Bootloader.cmake
@@ -0,0 +1,157 @@
+# 
##############################################################################
+# arch/xtensa/src/esp32s3/Bootloader.cmake
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more 
contributor
+# license agreements.  See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership.  The ASF licenses this
+# file to you under the Apache License, Version 2.0 (the "License"); you may 
not
+# use this file except in compliance with the License.  You may obtain a copy 
of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+# 
##############################################################################
+
+# MCUboot for the ESP32-S3, as Bootloader.mk: "cmake --build <dir> -t
+# bootloader" writes mcuboot-esp32s3.bin to the NuttX directory, where the 
flash
+# and merge steps look for it.
+
+set(BOOTLOADER_DIR ${NUTTX_BINARY_DIR}/bootloader)
+set(BOOTLOADER_CONFIG ${BOOTLOADER_DIR}/bootloader.conf)
+set(BOOTLOADER_BIN ${NUTTX_DIR}/mcuboot-esp32s3.bin)
+set(MCUBOOT_SRCDIR ${BOOTLOADER_DIR}/mcuboot)
+set(MCUBOOT_TOOLCHAIN
+    ${NUTTX_DIR}/tools/esp32s3/mcuboot_toolchain_esp32s3.cmake)
+set(HALDIR ${BOOTLOADER_DIR}/esp-hal-3rdparty-mcuboot)
+
+if(DEFINED ENV{MCUBOOT_VERSION})
+  set(MCUBOOT_VERSION $ENV{MCUBOOT_VERSION})
+else()
+  string(REPLACE "\"" "" MCUBOOT_VERSION "${CONFIG_ESP32S3_MCUBOOT_VERSION}")
+endif()
+
+if(DEFINED ENV{MCUBOOT_URL})
+  set(MCUBOOT_URL $ENV{MCUBOOT_URL})
+else()
+  set(MCUBOOT_URL https://github.com/mcu-tools/mcuboot)
+endif()
+
+if(DEFINED ENV{ESP_HAL_3RDPARTY_VERSION_FOR_MCUBOOT})
+  set(ESP_HAL_3RDPARTY_VERSION_FOR_MCUBOOT
+      $ENV{ESP_HAL_3RDPARTY_VERSION_FOR_MCUBOOT})
+else()
+  set(ESP_HAL_3RDPARTY_VERSION_FOR_MCUBOOT
+      911dbec8e4a92e70056b58a3d2b0d965b8b7bcc9)
+endif()
+
+# bootloader.conf, line for line as Bootloader.mk writes it
+
+set(CONF "")
+
+macro(conf_en name)
+  string(APPEND CONF "${name}=1\n")
+endmacro()
+
+macro(conf_val name value)
+  string(APPEND CONF "${name}=${value}\n")
+endmacro()
+
+string(REPLACE "\"" "" FLASH_FREQ "${CONFIG_ESPRESSIF_FLASH_FREQ}")
+
+conf_en(NON_OS_BUILD)
+foreach(size 4M 8M 16M 32M)
+  if(CONFIG_ESP32S3_FLASH_${size})
+    conf_en(CONFIG_ESPTOOLPY_FLASHSIZE_${size}B)
+  endif()
+endforeach()
+foreach(mode DIO DOUT QIO QOUT)
+  if(CONFIG_ESP32S3_FLASH_MODE_${mode})
+    conf_en(CONFIG_ESPTOOLPY_FLASHMODE_${mode})
+  endif()
+endforeach()
+foreach(freq 120M 80M 40M 20M)
+  if(CONFIG_ESP32S3_FLASH_FREQ_${freq})
+    conf_en(CONFIG_ESPTOOLPY_FLASHFREQ_${freq})
+  endif()
+endforeach()
+conf_val(CONFIG_ESPTOOLPY_FLASHFREQ "${FLASH_FREQ}")
+
+conf_en(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT)
+conf_val(CONFIG_ESP_BOOTLOADER_OFFSET 0x0000)
+conf_val(CONFIG_ESP_BOOTLOADER_SIZE 0xF000)
+conf_val(CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS
+         "${CONFIG_ESP32S3_OTA_PRIMARY_SLOT_OFFSET}")
+conf_val(CONFIG_ESP_APPLICATION_SIZE "${CONFIG_ESP32S3_OTA_SLOT_SIZE}")
+conf_val(CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS
+         "${CONFIG_ESP32S3_OTA_SECONDARY_SLOT_OFFSET}")
+conf_en(CONFIG_ESP_MCUBOOT_WDT_ENABLE)
+conf_en(CONFIG_LIBC_NEWLIB)
+conf_val(CONFIG_ESP_SCRATCH_OFFSET "${CONFIG_ESP32S3_OTA_SCRATCH_OFFSET}")
+conf_val(CONFIG_ESP_SCRATCH_SIZE "${CONFIG_ESP32S3_OTA_SCRATCH_SIZE}")
+conf_en(CONFIG_ESP_CONSOLE_UART)
+if(CONFIG_UART0_SERIAL_CONSOLE)
+  conf_val(CONFIG_ESP_CONSOLE_UART_NUM 0)
+endif()
+if(CONFIG_UART1_SERIAL_CONSOLE)
+  conf_val(CONFIG_ESP_CONSOLE_UART_NUM 1)
+endif()
+if(CONFIG_UART0_SERIAL_CONSOLE)
+  conf_val(CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM 0)
+endif()
+if(CONFIG_UART1_SERIAL_CONSOLE)
+  conf_val(CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM 1)
+endif()
+conf_en(CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT)
+conf_en(CONFIG_IDF_TARGET_ARCH_XTENSA)
+conf_val(CONFIG_BOOTLOADER_LOG_LEVEL 3)
+foreach(
+  opt
+  SECURE_FLASH_ENC_ENABLED SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+  SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC
+  SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE EFUSE_VIRTUAL)
+  if(CONFIG_ESPRESSIF_${opt})
+    conf_en(CONFIG_${opt})
+  endif()
+endforeach()
+if(CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH)
+  conf_en(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH)
+  conf_val(CONFIG_EFUSE_VIRTUAL_OFFSET
+           "${CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH_OFFSET}")
+  conf_val(CONFIG_EFUSE_VIRTUAL_SIZE
+           "${CONFIG_ESPRESSIF_EFUSE_VIRTUAL_KEEP_IN_FLASH_SIZE}")
+endif()
+
+file(MAKE_DIRECTORY ${BOOTLOADER_DIR})
+file(
+  GENERATE
+  OUTPUT ${BOOTLOADER_CONFIG}
+  CONTENT "${CONF}")
+
+# Clone MCUboot and its HAL on first use and build with build_mcuboot.sh, as
+# Bootloader.mk does; not part of the default build.
+
+add_custom_target(
+  bootloader
+  COMMAND
+    sh -c
+    "[ -d '${MCUBOOT_SRCDIR}' ] || { echo 'Cloning MCUboot' && git clone 
--quiet '${MCUBOOT_URL}' '${MCUBOOT_SRCDIR}' && git -C '${MCUBOOT_SRCDIR}' 
checkout --quiet '${MCUBOOT_VERSION}' && git -C '${MCUBOOT_SRCDIR}' submodule 
--quiet update --init --recursive ext/mbedtls; }"
+  COMMAND
+    sh -c
+    "[ -d '${HALDIR}' ] || { echo 'Cloning Espressif HAL for 3rd Party 
Platforms (MCUBoot build)' && git clone --quiet '${ESP_HAL_3RDPARTY_URL}' 
'${HALDIR}' && git -C '${HALDIR}' checkout --quiet 
'${ESP_HAL_3RDPARTY_VERSION_FOR_MCUBOOT}'; }"
+  COMMAND
+    ${NUTTX_DIR}/tools/espressif/build_mcuboot.sh -c esp32s3 -f
+    ${BOOTLOADER_CONFIG} -p ${BOOTLOADER_DIR} -e ${HALDIR} -d
+    ${MCUBOOT_TOOLCHAIN}
+  COMMAND ${CMAKE_COMMAND} -E copy ${BOOTLOADER_DIR}/out/mcuboot-esp32s3.bin
+          ${BOOTLOADER_BIN}
+  BYPRODUCTS ${BOOTLOADER_BIN}
+  COMMENT "Building Bootloader"
+  VERBATIM)
diff --git a/tools/espressif/espressif_esptool_common.cmake 
b/tools/espressif/espressif_esptool_common.cmake
index 914f2d23398..800225444a3 100644
--- a/tools/espressif/espressif_esptool_common.cmake
+++ b/tools/espressif/espressif_esptool_common.cmake
@@ -73,6 +73,20 @@ endif()
 set(EFUSE_OFFSET ${EFUSE_FLASH_OFFSET})
 
 # MCUboot application slot (Config.mk APP_OFFSET); default when not MCUboot 
boot
+# The Xtensa chips name their MCUboot options per chip (tools/<chip>/Config.mk)
+
+if(CONFIG_ARCH_XTENSA AND CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT)
+  string(TOUPPER "${CHIP_SERIES}" _chip)
+  foreach(
+    _opt
+    ESPTOOL_TARGET_PRIMARY ESPTOOL_TARGET_SECONDARY APP_MCUBOOT_HEADER_SIZE
+    OTA_PRIMARY_SLOT_OFFSET OTA_SECONDARY_SLOT_OFFSET OTA_SLOT_SIZE)
+    if(DEFINED CONFIG_${_chip}_${_opt})
+      set(CONFIG_ESPRESSIF_${_opt} "${CONFIG_${_chip}_${_opt}}")
+    endif()
+  endforeach()
+endif()
+
 if(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT)
   if(CONFIG_ESPRESSIF_ESPTOOL_TARGET_PRIMARY)
     set(MCUBOOT_APP_OFFSET ${CONFIG_ESPRESSIF_OTA_PRIMARY_SLOT_OFFSET})
diff --git a/tools/espressif/espressif_mkimage.cmake 
b/tools/espressif/espressif_mkimage.cmake
index 7405836bca6..7233bbca358 100644
--- a/tools/espressif/espressif_mkimage.cmake
+++ b/tools/espressif/espressif_mkimage.cmake
@@ -304,14 +304,19 @@ set(ESPTOOL_BINS "")
 if(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT)
   # MCUboot configuration
 
+  # Only a merged image needs the bootloader, as in Config.mk; it is built by
+  # the bootloader target.
   if(EXISTS "${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
     message(
       STATUS
         "Merge bin: ${BL_OFFSET} -> ${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
     list(APPEND ESPTOOL_BINS ${BL_OFFSET}
          "${SOURCE_DIR}/mcuboot-${CHIP_SERIES}.bin")
-  else()
-    message(FATAL_ERROR "mcuboot-${CHIP_SERIES}.bin not found in 
${SOURCE_DIR}")
+  elseif(CONFIG_ESPRESSIF_MERGE_BINS OR UF2_ENABLED)
+    message(
+      FATAL_ERROR
+        "mcuboot-${CHIP_SERIES}.bin not found in ${SOURCE_DIR}, build it with 
the bootloader target first"
+    )
   endif()
 
   # Create empty vefuse.bin if it doesn't exist

Reply via email to