You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/09/28 01:22:00 UTC

[incubator-nuttx] branch master updated (e72680b -> a5f9e29)

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

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from e72680b  sched/signal: Correct kill with cancellation
     new 800678c  xtensa/esp32s2: Enable booting from MCUboot bootloader
     new 75dd460  boards/esp32s2-saola-1: Add example defconfig for booting from MCUboot
     new a5f9e29  xtensa/esp32s2: Enable support for "make bootloader" target

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/xtensa/Kconfig                                |   1 +
 arch/xtensa/src/esp32s2/.gitignore                 |   1 +
 arch/xtensa/src/{esp32 => esp32s2}/Bootloader.mk   |  88 +++----
 arch/xtensa/src/esp32s2/Kconfig                    | 156 +++++++++++-
 arch/xtensa/src/esp32s2/Make.defs                  |   2 +
 arch/xtensa/src/esp32s2/esp32s2_start.c            | 265 ++++++++++++++++++---
 .../src/esp32s2/hardware/esp32s2_cache_memory.h    | 153 ++++++++++++
 arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h  |  69 ++++++
 .../configs/{gpio => mcuboot_nsh}/defconfig        |   6 +-
 .../esp32s2/esp32s2-saola-1/scripts/Make.defs      |  10 +-
 .../esp32s2-saola-1/scripts/esp32s2.template.ld    |  73 +++++-
 .../esp32s2-saola-1/scripts/esp32s2_flash.ld       |   2 +-
 .../esp32s2-saola-1/scripts/esp32s2_mcuboot.ld}    | 110 +++++----
 .../esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld |   8 +-
 tools/esp32s2/Config.mk                            | 108 +++++++--
 15 files changed, 878 insertions(+), 174 deletions(-)
 create mode 100644 arch/xtensa/src/esp32s2/.gitignore
 copy arch/xtensa/src/{esp32 => esp32s2}/Bootloader.mk (50%)
 create mode 100644 arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h
 create mode 100644 arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h
 copy boards/xtensa/esp32s2/esp32s2-saola-1/configs/{gpio => mcuboot_nsh}/defconfig (93%)
 copy boards/xtensa/{esp32/common/scripts/esp32_mcuboot.ld => esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld} (81%)

[incubator-nuttx] 01/03: xtensa/esp32s2: Enable booting from MCUboot bootloader

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 800678ca789eb96b1fe07f06e44130cbeda4dca2
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Mon Sep 13 13:56:55 2021 -0300

    xtensa/esp32s2: Enable booting from MCUboot bootloader
    
    Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
 arch/xtensa/src/esp32s2/Kconfig                    | 132 +++++++++-
 arch/xtensa/src/esp32s2/esp32s2_start.c            | 265 ++++++++++++++++++---
 .../src/esp32s2/hardware/esp32s2_cache_memory.h    | 153 ++++++++++++
 arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h  |  69 ++++++
 .../esp32s2/esp32s2-saola-1/scripts/Make.defs      |  10 +-
 .../esp32s2-saola-1/scripts/esp32s2.template.ld    |  73 +++++-
 .../esp32s2-saola-1/scripts/esp32s2_flash.ld       |   2 +-
 .../{esp32s2_flash.ld => esp32s2_mcuboot.ld}       | 241 +++++++++++++------
 .../esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld |   8 +-
 tools/esp32s2/Config.mk                            | 108 +++++++--
 10 files changed, 911 insertions(+), 150 deletions(-)

diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig
index c529b52..09bc35e 100644
--- a/arch/xtensa/src/esp32s2/Kconfig
+++ b/arch/xtensa/src/esp32s2/Kconfig
@@ -176,14 +176,6 @@ config ESP32S2_RT_TIMER
 	select ESP32S2_TIMER
 	default n
 
-config ESP32S2_PARTITION
-	bool "ESP32S2 Partition"
-	default n
-	select ESP32S2_SPIFLASH
-	---help---
-		Decode esp-idf's partition file and initialize
-		partition by nuttx MTD.
-
 config ESP32S2_RUN_IRAM
 	bool "Run from IRAM"
 	default n
@@ -620,9 +612,50 @@ endmenu # ESP32S2_SPI
 menu "SPI Flash configuration"
 	depends on ESP32S2_SPIFLASH
 
+if ESP32S2_HAVE_OTA_PARTITION
+
+comment "Application Image OTA Update support"
+
+config ESP32S2_OTA_PRIMARY_SLOT_OFFSET
+	hex "Application image primary slot offset"
+	default "0x10000"
+
+config ESP32S2_OTA_PRIMARY_SLOT_DEVPATH
+	string "Application image primary slot device path"
+	default "/dev/ota0"
+
+config ESP32S2_OTA_SECONDARY_SLOT_OFFSET
+	hex "Application image secondary slot offset"
+	default "0x110000"
+
+config ESP32S2_OTA_SECONDARY_SLOT_DEVPATH
+	string "Application image secondary slot device path"
+	default "/dev/ota1"
+
+config ESP32S2_OTA_SLOT_SIZE
+	hex "Application image slot size (in bytes)"
+	default "0x100000"
+
+config ESP32S2_OTA_SCRATCH_OFFSET
+	hex "Scratch partition offset"
+	default "0x210000"
+
+config ESP32S2_OTA_SCRATCH_SIZE
+	hex "Scratch partition size"
+	default "0x40000"
+
+config ESP32S2_OTA_SCRATCH_DEVPATH
+	string "Scratch partition device path"
+	default "/dev/otascratch"
+
+endif
+
+comment "General MTD configuration"
+
 config ESP32S2_MTD_OFFSET
 	hex "MTD base address in SPI Flash"
-	default 0x180000
+	default 0x180000 if !ESP32S2_HAVE_OTA_PARTITION
+	default 0x250000 if ESP32S2_HAVE_OTA_PARTITION
 	---help---
 		MTD base address in SPI Flash.
 
@@ -640,7 +673,7 @@ config ESP32S2_SPIFLASH_DEBUG
 		Enable this option, read and write of SPI Flash
 		will show input arguments and result.
 
-endmenu # ESP32S2_SPIFLASH
+endmenu # SPI Flash configuration
 
 menu "SPI RAM Config"
 	depends on ESP32S2_SPIRAM
@@ -866,6 +899,81 @@ config ESP32S2_FREERUN
 endmenu # Timer/counter Configuration
 endif # ESP32S2_TIMER
 
+config ESP32S2_HAVE_OTA_PARTITION
+	bool
+	default n
+
+menu "Application Image Configuration"
+
+choice
+	prompt "Application Image Format"
+	default ESP32S2_APP_FORMAT_LEGACY
+	---help---
+		Depending on the chosen 2nd stage bootloader, the application may
+		be required to be perform a specific startup routine. Furthermore,
+		the image binary must be formatted according to the definition from
+		the 2nd stage bootloader.
+
+config ESP32S2_APP_FORMAT_LEGACY
+	bool "Legacy format"
+	---help---
+		This is the legacy application image format, as supported by the ESP-IDF
+		2nd stage bootloader.
+
+config ESP32S2_APP_FORMAT_MCUBOOT
+	bool "MCUboot-bootable format"
+	select ESP32S2_HAVE_OTA_PARTITION
+	depends on EXPERIMENTAL
+	---help---
+		The Espressif port of MCUboot supports the loading of unsegmented firmware
+		images.
+
+comment "MCUboot support depends on CONFIG_EXPERIMENTAL"
+	depends on !EXPERIMENTAL
+
+endchoice # Application Image Format
+
+choice
+	prompt "Target slot for image flashing"
+	default ESP32S2_ESPTOOL_TARGET_PRIMARY
+	depends on ESP32S2_HAVE_OTA_PARTITION
+	---help---
+		Slot to which ESPTOOL will flash the generated binary image.
+
+config ESP32S2_ESPTOOL_TARGET_PRIMARY
+	bool "Application image primary slot"
+	---help---
+		This assumes that the generated image is already pre-validated.
+		This is the recommended option for the initial stages of the
+		application firmware image development.
+
+config ESP32S2_ESPTOOL_TARGET_SECONDARY
+	bool "Application image secondary slot"
+	---help---
+		The application needs to confirm the generated image as valid,
+		otherwise the bootloader may consider it invalid and perform the
+		rollback of the update after a reset.
+		This is the choice most suitable for the development and verification
+		of a secure firmware update workflow.
+
+endchoice
+
+config ESP32S2_APP_MCUBOOT_HEADER_SIZE
+	int "Application image header size (in bytes)"
+	default 32
+	depends on ESP32S2_APP_FORMAT_MCUBOOT
+
+endmenu # Application Image Configuration
+
+if ESP32S2_APP_FORMAT_LEGACY
+
+config ESP32S2_PARTITION
+	bool "ESP32-S2 Partition"
+	default n
+	select ESP32S2_SPIFLASH
+	---help---
+		Decode partition file and initialize partition as MTD.
+
 menu "Partition Configuration"
 	depends on ESP32S2_PARTITION
 
@@ -877,7 +985,9 @@ config ESP32S2_PARTITION_MOUNT
 	string "Partition mount point"
 	default "/dev/esp/partition/"
 
-endmenu # ESP32S2_PARTITION
+endmenu # Partition Configuration
+
+endif
 
 menu "AES accelerate"
 	depends on ESP32S2_AES_ACCELERATOR
diff --git a/arch/xtensa/src/esp32s2/esp32s2_start.c b/arch/xtensa/src/esp32s2/esp32s2_start.c
index a6a883a..18dfe34 100644
--- a/arch/xtensa/src/esp32s2/esp32s2_start.c
+++ b/arch/xtensa/src/esp32s2/esp32s2_start.c
@@ -33,7 +33,8 @@
 #include "xtensa.h"
 #include "xtensa_attr.h"
 
-#include "hardware/esp32s2_rtccntl.h"
+#include "hardware/esp32s2_cache_memory.h"
+#include "hardware/esp32s2_extmem.h"
 #include "esp32s2_clockconfig.h"
 #include "esp32s2_region.h"
 #include "esp32s2_start.h"
@@ -50,6 +51,67 @@
 #  define showprogress(c)
 #endif
 
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+
+#define PRIMARY_SLOT_OFFSET   CONFIG_ESP32S2_OTA_PRIMARY_SLOT_OFFSET
+
+#define HDR_ATTR              __attribute__((section(".entry_addr"))) \
+                                __attribute__((used))
+
+/* Cache MMU block size */
+
+#define MMU_BLOCK_SIZE        0x00010000  /* 64 KB */
+
+/* Cache MMU address mask (MMU tables ignore bits which are zero) */
+
+#define MMU_FLASH_MASK        (~(MMU_BLOCK_SIZE - 1))
+
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+extern uint32_t _image_irom_vma;
+extern uint32_t _image_irom_lma;
+extern uint32_t _image_irom_size;
+
+extern uint32_t _image_drom_vma;
+extern uint32_t _image_drom_lma;
+extern uint32_t _image_drom_size;
+#endif
+
+/****************************************************************************
+ * ROM Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+extern int ets_printf(const char *fmt, ...);
+extern uint32_t cache_suspend_icache(void);
+extern void cache_resume_icache(uint32_t val);
+extern void cache_invalidate_icache_all(void);
+extern int cache_ibus_mmu_set(uint32_t ext_ram, uint32_t vaddr,
+                              uint32_t paddr, uint32_t psize, uint32_t num,
+                              uint32_t fixed);
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+noreturn_function void __start(void);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+HDR_ATTR static void (*_entry_point)(void) = &__start;
+#endif
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
@@ -60,29 +122,28 @@ uint32_t g_idlestack[IDLETHREAD_STACKWORDS]
   aligned_data(16) locate_data(".noinit");
 
 /****************************************************************************
- * Public Functions
+ * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: __start
+ * Name: __esp32s2_start
  *
  * Description:
- *   We arrive here after the bootloader finished loading the program from
- *   flash. The hardware is mostly uninitialized, and the app CPU is in
- *   reset. We do have a stack, so we can do the initialization in C.
+ *   Perform base configuration of the chip for code execution.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
  *
  ****************************************************************************/
 
-void IRAM_ATTR __start(void)
+void IRAM_ATTR __esp32s2_start(void)
 {
-  uint32_t *dest;
   uint32_t regval;
   uint32_t sp;
 
-  /* Disable any wdt enabled by bootloader */
-
-  esp32s2_wdt_early_deinit();
-
   regval  = getreg32(DR_REG_BB_BASE + 0x48); /* DR_REG_BB_BASE+48 */
   regval &= ~(1 << 14);
   putreg32(regval, DR_REG_BB_BASE + 0x48);
@@ -95,18 +156,6 @@ void IRAM_ATTR __start(void)
 
   up_irq_disable();
 
-  /* Set CPU frequency configured in board.h */
-
-  esp32s2_clockconfig();
-
-  esp32s2_lowsetup();
-
-#ifdef USE_EARLYSERIALINIT
-  /* Perform early serial initialization */
-
-  xtensa_earlyserialinit();
-#endif
-
   /* Move the stack to a known location.  Although we were given a stack
    * pointer at start-up, we don't know where that stack pointer is
    * positioned with respect to our memory map.  The only safe option is to
@@ -124,29 +173,187 @@ void IRAM_ATTR __start(void)
 
   __asm__ __volatile__ ("wsr %0, vecbase\n"::"r" (&_init_start));
 
-  showprogress('A');
-
   /* Set .bss to zero */
 
   /* Clear .bss.  We'll do this inline (vs. calling memset) just to be
    * certain that there are no issues with the state of global variables.
    */
 
-  for (dest = &_sbss; dest < &_ebss; dest++)
+  for (uint32_t *dest = &_sbss; dest < &_ebss; dest++)
     {
       *dest = 0;
     }
 
-  showprogress('B');
+  /* The 2nd stage bootloader enables RTC WDT to check on startup sequence
+   * related issues in application. Hence disable that as we are about to
+   * start the NuttX environment.
+   */
+
+  esp32s2_wdt_early_deinit();
+
+  /* Set CPU frequency configured in board.h */
+
+  esp32s2_clockconfig();
+
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+  /* Configure the UART so we can get debug output */
+
+  esp32s2_lowsetup();
+#endif
+
+#ifdef USE_EARLYSERIALINIT
+  /* Perform early serial initialization */
+
+  xtensa_earlyserialinit();
+#endif
+
+  showprogress('A');
 
   /* Initialize onboard resources */
 
   esp32s2_board_initialize();
 
-  showprogress('C');
+  showprogress('B');
 
   /* Bring up NuttX */
 
   nx_start();
   for (; ; ); /* Should not return */
 }
+
+/****************************************************************************
+ * Name: calc_mmu_pages
+ *
+ * Description:
+ *   Calculate the number of cache pages to map.
+ *
+ * Input Parameters:
+ *   size  - Size of data to map
+ *   vaddr - Virtual address where data will be mapped
+ *
+ * Returned Value:
+ *   Number of cache MMU pages required to do the mapping.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+static inline uint32_t calc_mmu_pages(uint32_t size, uint32_t vaddr)
+{
+  return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_BLOCK_SIZE - 1) /
+    MMU_BLOCK_SIZE;
+}
+#endif
+
+/****************************************************************************
+ * Name: map_rom_segments
+ *
+ * Description:
+ *   Configure the MMU and Cache peripherals for accessing ROM code and data.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+static int map_rom_segments(void)
+{
+  uint32_t rc = 0;
+  uint32_t regval;
+  uint32_t drom_lma_aligned;
+  uint32_t drom_vma_aligned;
+  uint32_t drom_page_count;
+  uint32_t irom_lma_aligned;
+  uint32_t irom_vma_aligned;
+  uint32_t irom_page_count;
+
+  size_t partition_offset = PRIMARY_SLOT_OFFSET;
+  uint32_t app_irom_lma = partition_offset + (uint32_t)&_image_irom_lma;
+  uint32_t app_irom_size = (uint32_t)&_image_irom_size;
+  uint32_t app_irom_vma = (uint32_t)&_image_irom_vma;
+  uint32_t app_drom_lma = partition_offset + (uint32_t)&_image_drom_lma;
+  uint32_t app_drom_size = (uint32_t)&_image_drom_size;
+  uint32_t app_drom_vma = (uint32_t)&_image_drom_vma;
+
+  uint32_t autoload = cache_suspend_icache();
+  cache_invalidate_icache_all();
+
+  /* Clear the MMU entries that are already set up, so the new app only has
+   * the mappings it creates.
+   */
+
+  for (size_t i = 0; i < FLASH_MMU_TABLE_SIZE; i++)
+    {
+      FLASH_MMU_TABLE[i] = MMU_TABLE_INVALID_VAL;
+    }
+
+  drom_lma_aligned = app_drom_lma & MMU_FLASH_MASK;
+  drom_vma_aligned = app_drom_vma & MMU_FLASH_MASK;
+  drom_page_count = calc_mmu_pages(app_drom_size, app_drom_vma);
+  rc = cache_ibus_mmu_set(MMU_ACCESS_FLASH, drom_vma_aligned,
+                           drom_lma_aligned, 64, (int)drom_page_count, 0);
+
+  irom_lma_aligned = app_irom_lma & MMU_FLASH_MASK;
+  irom_vma_aligned = app_irom_vma & MMU_FLASH_MASK;
+  irom_page_count = calc_mmu_pages(app_irom_size, app_irom_vma);
+
+  if (app_irom_lma + app_irom_size > IRAM1_ADDRESS_LOW)
+    {
+      rc |= cache_ibus_mmu_set(MMU_ACCESS_FLASH, IRAM0_ADDRESS_LOW, 0, 64,
+                               64, 1);
+      rc |= cache_ibus_mmu_set(MMU_ACCESS_FLASH, IRAM1_ADDRESS_LOW, 0, 64,
+                               64, 1);
+
+      regval  = getreg32(EXTMEM_PRO_ICACHE_CTRL1_REG);
+      regval &= ~(EXTMEM_PRO_ICACHE_MASK_IRAM1);
+      putreg32(regval, EXTMEM_PRO_ICACHE_CTRL1_REG);
+    }
+
+  rc |= cache_ibus_mmu_set(MMU_ACCESS_FLASH, irom_vma_aligned,
+                           irom_lma_aligned, 64, (int)irom_page_count, 0);
+
+  regval  = getreg32(EXTMEM_PRO_ICACHE_CTRL1_REG);
+  regval &= ~(EXTMEM_PRO_ICACHE_MASK_IRAM0 |
+              EXTMEM_PRO_ICACHE_MASK_DROM0);
+  putreg32(regval, EXTMEM_PRO_ICACHE_CTRL1_REG);
+
+  cache_resume_icache(autoload);
+
+  return (int)rc;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: __start
+ *
+ * Description:
+ *   We arrive here after the bootloader finished loading the program from
+ *   flash. The hardware is mostly uninitialized, and the app CPU is in
+ *   reset. We do have a stack, so we can do the initialization in C.
+ *
+ *   The app CPU will remain in reset unless CONFIG_SMP is selected and
+ *   up_cpu_start() is called later in the bring-up sequence.
+ *
+ ****************************************************************************/
+
+void __start(void)
+{
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+  if (map_rom_segments() != 0)
+    {
+      ets_printf("Failed to setup XIP, aborting\n");
+      while (true);
+    }
+
+#endif
+  __esp32s2_start();
+
+  while (true); /* Should not return */
+}
diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h
new file mode 100644
index 0000000..2812646
--- /dev/null
+++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s2/hardware/esp32s2_cache_memory.h
+ *
+ * Licensed 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_CACHE_MEMORY_H_
+#define __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_CACHE_MEMORY_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+#include "esp32s2_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* IRAM0 is connected with Cache IBUS0 */
+
+#define IRAM0_ADDRESS_LOW               0x40000000
+#define IRAM0_ADDRESS_HIGH              0x40400000
+#define IRAM0_CACHE_ADDRESS_LOW         0x40080000
+#define IRAM0_CACHE_ADDRESS_HIGH        0x40400000
+
+/* IRAM1 is connected with Cache IBUS1 */
+
+#define IRAM1_ADDRESS_LOW               0x40400000
+#define IRAM1_ADDRESS_HIGH              0x40800000
+
+/* DROM0 is connected with Cache IBUS2 */
+
+#define DROM0_ADDRESS_LOW               0x3f000000
+#define DROM0_ADDRESS_HIGH              0x3f400000
+
+/* DRAM0 is connected with Cache DBUS0 */
+
+#define DRAM0_ADDRESS_LOW               0x3fc00000
+#define DRAM0_ADDRESS_HIGH              0x40000000
+#define DRAM0_CACHE_ADDRESS_LOW         0x3fc00000
+#define DRAM0_CACHE_ADDRESS_HIGH        0x3ff80000
+
+/* DRAM1 is connected with Cache DBUS1 */
+
+#define DRAM1_ADDRESS_LOW               0x3f800000
+#define DRAM1_ADDRESS_HIGH              0x3fc00000
+
+/* DPORT is connected with Cache DBUS2 */
+
+#define DPORT_ADDRESS_LOW               0x3f400000
+#define DPORT_ADDRESS_HIGH              0x3f800000
+#define DPORT_CACHE_ADDRESS_LOW         0x3f500000
+#define DPORT_CACHE_ADDRESS_HIGH        0x3f800000
+
+#define BUS_SIZE(bus_name)              (bus_name##_ADDRESS_HIGH - \
+                                            bus_name##_ADDRESS_LOW)
+#define ADDRESS_IN_BUS(bus_name, vaddr) ((vaddr) >= bus_name##_ADDRESS_LOW \
+                                            && (vaddr) < \
+                                                bus_name##_ADDRESS_HIGH)
+
+#define ADDRESS_IN_IRAM0(vaddr)         ADDRESS_IN_BUS(IRAM0, vaddr)
+#define ADDRESS_IN_IRAM0_CACHE(vaddr)   ADDRESS_IN_BUS(IRAM0_CACHE, vaddr)
+#define ADDRESS_IN_IRAM1(vaddr)         ADDRESS_IN_BUS(IRAM1, vaddr)
+#define ADDRESS_IN_DROM0(vaddr)         ADDRESS_IN_BUS(DROM0, vaddr)
+#define ADDRESS_IN_DRAM0(vaddr)         ADDRESS_IN_BUS(DRAM0, vaddr)
+#define ADDRESS_IN_DRAM0_CACHE(vaddr)   ADDRESS_IN_BUS(DRAM0_CACHE, vaddr)
+#define ADDRESS_IN_DRAM1(vaddr)         ADDRESS_IN_BUS(DRAM1, vaddr)
+#define ADDRESS_IN_DPORT(vaddr)         ADDRESS_IN_BUS(DPORT, vaddr)
+#define ADDRESS_IN_DPORT_CACHE(vaddr)   ADDRESS_IN_BUS(DPORT_CACHE, vaddr)
+
+#define BUS_IRAM0_CACHE_SIZE            BUS_SIZE(IRAM0_CACHE)
+#define BUS_IRAM1_CACHE_SIZE            BUS_SIZE(IRAM1)
+#define BUS_IROM0_CACHE_SIZE            BUS_SIZE(IROM0)
+#define BUS_DROM0_CACHE_SIZE            BUS_SIZE(DROM0)
+#define BUS_DRAM0_CACHE_SIZE            BUS_SIZE(DRAM0_CACHE)
+#define BUS_DRAM1_CACHE_SIZE            BUS_SIZE(DRAM1)
+#define BUS_DPORT_CACHE_SIZE            BUS_SIZE(DPORT)
+
+#define PRO_CACHE_IBUS0                 0
+#define PRO_CACHE_IBUS0_MMU_START       0
+#define PRO_CACHE_IBUS0_MMU_END         0x100
+
+#define PRO_CACHE_IBUS1                 1
+#define PRO_CACHE_IBUS1_MMU_START       0x100
+#define PRO_CACHE_IBUS1_MMU_END         0x200
+
+#define PRO_CACHE_IBUS2                 2
+#define PRO_CACHE_IBUS2_MMU_START       0x200
+#define PRO_CACHE_IBUS2_MMU_END         0x300
+
+#define PRO_CACHE_DBUS0                 3
+#define PRO_CACHE_DBUS0_MMU_START       0x300
+#define PRO_CACHE_DBUS0_MMU_END         0x400
+
+#define PRO_CACHE_DBUS1                 4
+#define PRO_CACHE_DBUS1_MMU_START       0x400
+#define PRO_CACHE_DBUS1_MMU_END         0x500
+
+#define PRO_CACHE_DBUS2                 5
+#define PRO_CACHE_DBUS2_MMU_START       0x500
+#define PRO_CACHE_DBUS2_MMU_END         0x600
+
+#define ICACHE_MMU_SIZE                 0x300
+#define DCACHE_MMU_SIZE                 0x300
+
+#define MMU_BUS_START(i)                ((i) * 0x100)
+#define MMU_BUS_SIZE                    0x100
+
+#define MMU_INVALID                     BIT(14)
+#define MMU_ACCESS_FLASH                BIT(15)
+#define MMU_ACCESS_SPIRAM               BIT(16)
+
+#define FLASH_MMU_TABLE             ((volatile uint32_t *)DR_REG_MMU_TABLE)
+#define FLASH_MMU_TABLE_SIZE        (ICACHE_MMU_SIZE / sizeof(uint32_t))
+
+#define MMU_TABLE_INVALID_VAL           0x4000
+#define FLASH_MMU_TABLE_INVALID_VAL     DPORT_MMU_TABLE_INVALID_VAL
+#define MMU_ADDRESS_MASK                0x3fff
+#define MMU_PAGE_SIZE                   0x10000
+
+#define BUS_ADDR_SIZE                   0x400000
+#define BUS_ADDR_MASK                   (BUS_ADDR_SIZE - 1)
+#define BUS_NUM_MASK                    0x3
+
+#define CACHE_MEMORY_BANK_SIZE          8192
+#define CACHE_MEMORY_BANK_NUM           4
+#define CACHE_MEMORY_BANK_NUM_MASK      0x3
+#define CACHE_MEMORY_LAYOUT_SHIFT       4
+#define CACHE_MEMORY_LAYOUT_SHIFT0      0
+#define CACHE_MEMORY_LAYOUT_SHIFT1      4
+#define CACHE_MEMORY_LAYOUT_SHIFT2      8
+#define CACHE_MEMORY_LAYOUT_SHIFT3      12
+#define CACHE_MEMORY_LAYOUT_MASK        0xf
+#define CACHE_MEMORY_BANK0_ADDR         0x3ffb0000
+#define CACHE_MEMORY_BANK1_ADDR         0x3ffb2000
+#define CACHE_MEMORY_BANK2_ADDR         0x3ffb4000
+#define CACHE_MEMORY_BANK3_ADDR         0x3ffb6000
+
+#endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_CACHE_MEMORY_H_ */
diff --git a/arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h b/arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h
new file mode 100644
index 0000000..5fdd8e2
--- /dev/null
+++ b/arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s2/hardware/esp32s2_extmem.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_EXTMEM_H_
+#define __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_EXTMEM_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32s2_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define EXTMEM_PRO_ICACHE_CTRL1_REG         (DR_REG_EXTMEM_BASE + 0x044)
+
+/* EXTMEM_PRO_ICACHE_MASK_BUS2 : R/W ;bitpos:[2] ;default: 1'b1 ;
+ * description: The bit is used to disable ibus2
+ * 0: enable  1: disable
+ */
+
+#define EXTMEM_PRO_ICACHE_MASK_BUS2         (BIT(2))
+#define EXTMEM_PRO_ICACHE_MASK_BUS2_M       (BIT(2))
+#define EXTMEM_PRO_ICACHE_MASK_BUS2_V       0x1
+#define EXTMEM_PRO_ICACHE_MASK_BUS2_S       2
+
+/* EXTMEM_PRO_ICACHE_MASK_BUS1 : R/W ;bitpos:[1] ;default: 1'b1 ;
+ * description: The bit is used to disable ibus1
+ * 0: enable  1: disable
+ */
+
+#define EXTMEM_PRO_ICACHE_MASK_BUS1         (BIT(1))
+#define EXTMEM_PRO_ICACHE_MASK_BUS1_M       (BIT(1))
+#define EXTMEM_PRO_ICACHE_MASK_BUS1_V       0x1
+#define EXTMEM_PRO_ICACHE_MASK_BUS1_S       1
+
+/* EXTMEM_PRO_ICACHE_MASK_BUS0 : R/W ;bitpos:[0] ;default: 1'b1 ;
+ * description: The bit is used to disable ibus0
+ * 0: enable  1: disable
+ */
+
+#define EXTMEM_PRO_ICACHE_MASK_BUS0         (BIT(0))
+#define EXTMEM_PRO_ICACHE_MASK_BUS0_M       (BIT(0))
+#define EXTMEM_PRO_ICACHE_MASK_BUS0_V       0x1
+#define EXTMEM_PRO_ICACHE_MASK_BUS0_S       0
+#define EXTMEM_PRO_ICACHE_MASK_IRAM0        EXTMEM_PRO_ICACHE_MASK_BUS0
+#define EXTMEM_PRO_ICACHE_MASK_IRAM1        EXTMEM_PRO_ICACHE_MASK_BUS1
+#define EXTMEM_PRO_ICACHE_MASK_DROM0        EXTMEM_PRO_ICACHE_MASK_BUS2
+
+#endif /* __ARCH_XTENSA_SRC_ESP32S2_HARDWARE_ESP32S2_EXTMEM_H_ */
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs
index addad88..b757289 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/Make.defs
@@ -27,10 +27,14 @@ LDSCRIPT1 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_out.ld
 LDSCRIPT3 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_rom.ld
 LDSCRIPT4 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_peripherals.ld
 
-ifeq ($(CONFIG_ESP32S2_RUN_IRAM),y)
-  LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_iram.ld
+ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
+  LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_mcuboot.ld
 else
-  LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_flash.ld
+  ifeq ($(CONFIG_ESP32S2_RUN_IRAM),y)
+    LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_iram.ld
+  else
+    LDSCRIPT2 = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s2_flash.ld
+  endif
 endif
 
 ifeq ($(CONFIG_CYGWIN_WINTOOL),y)
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld
index 3617280..f4811bb 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2.template.ld
@@ -46,9 +46,34 @@
 
 #define I_D_RAM_SIZE   DATA_RAM_END - DRAM_ORG
 
+#ifdef CONFIG_ESP32S2_FLASH_2M
+#  define FLASH_SIZE        0x200000
+#elif defined (CONFIG_ESP32S2_FLASH_4M)
+#  define FLASH_SIZE        0x400000
+#elif defined (CONFIG_ESP32S2_FLASH_8M)
+#  define FLASH_SIZE        0x800000
+#elif defined (CONFIG_ESP32S2_FLASH_16M)
+#  define FLASH_SIZE        0x1000000
+#endif
+
 MEMORY
 {
-  /* All these values assume the flash cache is on, and have the blocks this
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+  /* The origin values for "metadata" and "ROM" memory regions are the actual
+   * load addresses.
+   *
+   * NOTE: The memory region starting from 0x0 with length represented by
+   * CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE is reserved for the MCUboot header,
+   * which will be prepended to the binary file by the "imgtool" during the
+   * signing of firmware image.
+   */
+
+  metadata (RX) :        org = CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE, len = 0x20
+  ROM (RX) :             org = CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20,
+                         len = FLASH_SIZE - (CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20)
+#endif
+
+  /* Below values assume the flash cache is on, and have the blocks this
    * uses subtracted from the length of the various regions. The 'data access
    * port' dram/drom regions map to the same iram/irom regions but are
    * connected to the data port of the CPU and eg allow bytewise access.
@@ -58,26 +83,57 @@ MEMORY
 
   iram0_0_seg (RX) :                 org = IRAM_ORG, len = I_D_RAM_SIZE
 
-  /* Even though the segment name is iram, it is actually mapped to flash */
+  /* Flash mapped instruction data. */
 
-  iram0_2_seg (RX) :                 org = 0x40080020, len = 0x780000-0x20
-
-  /* (0x20 offset above is a convenience for the app binary image generation.
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+  irom0_0_seg (RX) :                 org = 0x40080020, len = FLASH_SIZE
+#else
+  /* The 0x20 offset is a convenience for the app binary image generation.
    * Flash cache has 64KB pages. The .bin file which is flashed to the chip
    * has a 0x18 byte file header, and each segment has a 0x08 byte segment
    * header. Setting this offset makes it simple to meet the flash cache MMU's
-   * constraint that (paddr % 64KB == vaddr % 64KB).)
+   * constraint that (paddr % 64KB == vaddr % 64KB).
    */
 
+  irom0_0_seg (RX) :                 org = 0x40080020, len = FLASH_SIZE - 0x20
+#endif
+
   /* Shared data RAM, excluding memory reserved for bootloader and ROM
    * bss/data/stack.
    */
 
   dram0_0_seg (RW) :                 org = DRAM_ORG, len = I_D_RAM_SIZE
 
+
+
   /* Flash mapped constant data */
 
-  drom0_0_seg (R) :                  org = 0x3f000020, len = 0x3f0000-0x20
+#ifdef CONFIG_ESP32S2_APP_FORMAT_MCUBOOT
+  /* The DROM segment origin is offset by 0x40 for mirroring the actual ROM
+   * image layout:
+   *    0x0  - 0x1F : MCUboot header
+   *    0x20 - 0x3F : Application image metadata section
+   *    0x40 onwards: ROM code and data
+   * This is required to meet the following constraint from the external
+   * flash MMU:
+   *    VMA % 64KB == LMA % 64KB
+   * i.e. the lower 16 bits of both the virtual address (address seen by the
+   * CPU) and the load address (physical address of the external flash) must
+   * be equal.
+   */
+
+  drom0_0_seg (R) :      org = 0x3f000000 + (CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20),
+                         len = FLASH_SIZE - (CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE + 0x20)
+#else
+  /* The 0x20 offset is a convenience for the app binary image generation.
+   * Flash cache has 64KB pages. The .bin file which is flashed to the chip
+   * has a 0x18 byte file header, and each segment has a 0x08 byte segment
+   * header. Setting this offset makes it simple to meet the flash cache MMU's
+   * constraint that (paddr % 64KB == vaddr % 64KB).
+   */
+
+  drom0_0_seg (R) :                  org = 0x3f000020, len = FLASH_SIZE - 0x20
+#endif
 
   /* RTC fast memory (executable). Persists over deep sleep. */
 
@@ -90,5 +146,8 @@ MEMORY
 
   rtc_slow_seg(RW)  :    org = 0x50000000 + CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM,
                          len = 0x2000 - CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM
+
+  /* RTC fast memory (same block as above), viewed from data bus */
+  rtc_data_seg(RW)  :                 org = 0x3ff9e000, len = 0x2000
 }
 
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld
index 74acf2f..fa4823e 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld
@@ -198,7 +198,7 @@ SECTIONS
     . += 16;
 
     _etext = .;
-  } >iram0_2_seg
+  } >irom0_0_seg
 
   .rtc.text :
   {
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld
similarity index 50%
copy from boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld
copy to boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld
index 74acf2f..a459692 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld
@@ -1,5 +1,21 @@
 /****************************************************************************
- * boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_flash.ld
+ * boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_mcuboot.ld
+ *
+ * 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.
+ *
  ****************************************************************************/
 
 /* Default entry point: */
@@ -8,6 +24,95 @@ ENTRY(__start);
 
 SECTIONS
 {
+  .metadata :
+  {
+    /* Magic for load header */
+
+    LONG(0xace637d3)
+
+    /* Application entry point address */
+
+    KEEP(*(.entry_addr))
+
+    /* IRAM metadata:
+     * - Destination address (VMA) for IRAM region
+     * - Flash offset (LMA) for start of IRAM region
+     * - Size of IRAM region
+     */
+
+    LONG(ADDR(.iram0.vectors))
+    LONG(LOADADDR(.iram0.vectors))
+    LONG(LOADADDR(.iram0.text) + SIZEOF(.iram0.text) - LOADADDR(.iram0.vectors))
+
+    /* DRAM metadata:
+     * - Destination address (VMA) for DRAM region
+     * - Flash offset (LMA) for start of DRAM region
+     * - Size of DRAM region
+     */
+
+    LONG(ADDR(.dram0.data))
+    LONG(LOADADDR(.dram0.data))
+    LONG(SIZEOF(.dram0.data))
+  } >metadata
+
+  _image_drom_vma = ADDR(.flash.rodata);
+  _image_drom_lma = LOADADDR(.flash.rodata);
+  _image_drom_size = LOADADDR(.flash.rodata) + SIZEOF(.flash.rodata) - _image_drom_lma;
+
+  .flash.rodata :
+  {
+    _srodata = ABSOLUTE(.);
+    *(EXCLUDE_FILE (esp32s2_start.*) .rodata)
+    *(EXCLUDE_FILE (esp32s2_start.*) .rodata.*)
+
+    *(.srodata.*)
+
+    *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
+    *(.gnu.linkonce.r.*)
+    *(.rodata1)
+    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
+    *(.xt_except_table)
+    *(.gcc_except_table .gcc_except_table.*)
+    *(.gnu.linkonce.e.*)
+    *(.gnu.version_r)
+    KEEP(*(.eh_frame))
+    . = (. + 3) & ~ 3;
+
+    /* C++ constructor and destructor tables, properly ordered: */
+
+    _sinit = ABSOLUTE(.);
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    _einit = ABSOLUTE(.);
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .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)
+    . = ALIGN(4);               /* This table MUST be 4-byte aligned */
+    _erodata = ABSOLUTE(.);
+
+    /* Literals are also RO data. */
+
+    _lit4_start = ABSOLUTE(.);
+    *(*.lit4)
+    *(.lit4.*)
+    *(.gnu.linkonce.lit4.*)
+    _lit4_end = ABSOLUTE(.);
+    . = ALIGN(4);
+  } >drom0_0_seg AT>ROM
+
   /* Send .iram0 code to iram */
 
   .iram0.vectors :
@@ -47,24 +152,30 @@ SECTIONS
     *(.entry.text)
     *(.init.literal)
     *(.init)
-  } > iram0_0_seg
+    _init_end = ABSOLUTE(.);
+  } >iram0_0_seg AT>ROM
 
   .iram0.text :
   {
     /* Code marked as running out of IRAM */
 
     *(.iram1 .iram1.*)
+    esp32s2_start.*(.literal .text .literal.* .text.*)
 
     /* align + add 16B for CPU dummy speculative instr. fetch */
 
     . = ALIGN(4) + 16;
     _iram_text = ABSOLUTE(.);
-  } > iram0_0_seg
+  } >iram0_0_seg AT>ROM
 
-  .dram0_reserved_for_iram (NOLOAD):
+  .dram0.dummy (NOLOAD):
   {
-    . = ORIGIN(dram0_0_seg) + _iram_text - _iram_start;
-  } > dram0_0_seg
+    /* This section is required to skip .iram0.text area because iram0_0_seg
+     * and dram0_0_seg reflect the same address space on different buses.
+     */
+
+    . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
+  } >dram0_0_seg
 
   /* Shared RAM */
 
@@ -100,6 +211,7 @@ SECTIONS
 
     . = ALIGN(4);
     *(.noinit)
+    *(.noinit.*)
     . = ALIGN(4);
   } >dram0_0_seg
 
@@ -120,95 +232,86 @@ SECTIONS
     KEEP (*(.gnu.linkonce.s2.*))
     KEEP (*(.jcr))
     *(.dram1 .dram1.*)
-    . = ALIGN(4);
+    esp32s2_start.*(.rodata .rodata.*)
     _edata = ABSOLUTE(.);
+    . = ALIGN(4);
 
     /* Heap starts at the end of .data */
 
     _sheap = ABSOLUTE(.);
-  } >dram0_0_seg
-
-  .flash.rodata :
-  {
-    _srodata = ABSOLUTE(.);
-    *(.rodata)
-    *(.rodata.*)
-    *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
-    *(.gnu.linkonce.r.*)
-    *(.rodata1)
-    __XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
-    *(.xt_except_table)
-    *(.gcc_except_table)
-    *(.gcc_except_table.*)
-    *(.gnu.linkonce.e.*)
-    *(.gnu.version_r)
-    *(.eh_frame)
+  } >dram0_0_seg AT>ROM
 
-    . = (. + 3) & ~ 3;
+  /* Marks the end of IRAM code segment */
 
-    /* C++ constructor and destructor tables, properly ordered: */
-
-    _sinit = ABSOLUTE(.);
-    KEEP (*crtbegin.o(.ctors))
-    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
-    KEEP (*(SORT(.ctors.*)))
-    KEEP (*(.ctors))
-    _einit = ABSOLUTE(.);
-    KEEP (*crtbegin.o(.dtors))
-    KEEP (*(EXCLUDE_FILE (*crtend.o) .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)
-    _erodata = ABSOLUTE(.);
-
-    /* Literals are also RO data. */
+  .iram0.text_end (NOLOAD) :
+  {
+    . = ALIGN (4);
+    _iram_end = ABSOLUTE(.);
+  } >iram0_0_seg
+
+  _image_irom_vma = ADDR(.flash.text);
+  _image_irom_lma = LOADADDR(.flash.text);
+  _image_irom_size = LOADADDR(.flash.text) + SIZEOF(.flash.text) - _image_irom_lma;
+
+  /* The alignment of the ".flash.text" output section is forced to
+   * 0x0000FFFF (64KB) to ensure that it will be allocated at the beginning
+   * of the next available Flash block.
+   * This is required to meet the following constraint from the external
+   * flash MMU:
+   *    VMA % 64KB == LMA % 64KB
+   * i.e. the lower 16 bits of both the virtual address (address seen by the
+   * CPU) and the load address (physical address of the external flash) must
+   * be equal.
+   */
+
+  .flash_text_dummy (NOLOAD) : ALIGN(0x0000FFFF)
+  {
+    /* This section is required to skip .flash.rodata area because irom0_0_seg
+     * and drom0_0_seg reflect the same address space on different buses.
+     */
 
-    _lit4_start = ABSOLUTE(.);
-    *(*.lit4)
-    *(.lit4.*)
-    *(.gnu.linkonce.lit4.*)
-    _lit4_end = ABSOLUTE(.);
-    . = ALIGN(4);
-  } >drom0_0_seg
+    . = SIZEOF(.flash.rodata);
+  } >irom0_0_seg
 
-  .flash.text :
+  .flash.text : ALIGN(0x0000FFFF)
   {
     _stext = .;
+
     *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
     *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
     *(.fini.literal)
     *(.fini)
     *(.gnu.version)
-
-    /* CPU will try to prefetch up to 16 bytes of instructions.
-     * This means that any configuration (e.g. MMU, PMS) must allow
-     * safe access to up to 16 bytes after the last real instruction, add
-     * dummy bytes to ensure this
-     */
-
-    . += 16;
+    . = ALIGN(4);
 
     _etext = .;
-  } >iram0_2_seg
+  } >irom0_0_seg AT>ROM
 
   .rtc.text :
   {
     . = ALIGN(4);
     *(.rtc.literal .rtc.text)
-  } >rtc_iram_seg
+  } >rtc_iram_seg AT>ROM
+
+  .rtc.dummy (NOLOAD) :
+  {
+    /* This section is required to skip .rtc.text area because the text and
+     * data segments reflect the same address space on different buses.
+     */
+
+    . = SIZEOF(.rtc.text);
+  } >rtc_data_seg
+
+  /* RTC BSS section. */
+
+  .rtc.bss (NOLOAD) :
+  {
+    *(.rtc.bss)
+  } >rtc_data_seg
 
   .rtc.data :
   {
     *(.rtc.data)
     *(.rtc.rodata)
-  } > rtc_slow_seg
+  } >rtc_data_seg AT>ROM
 }
diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld
index d6d6e1b..61d252a 100644
--- a/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/scripts/esp32s2_rom.ld
@@ -43,12 +43,12 @@ PROVIDE ( Cache_Get_Memory_BaseAddr = 0x40019244 );
 PROVIDE ( Cache_Get_Memory_value = 0x400192d8 );
 PROVIDE ( Cache_Get_Mode = 0x40017ff0 );
 PROVIDE ( Cache_Get_Virtual_Addr = 0x40019210 );
-PROVIDE ( Cache_Ibus_MMU_Set = 0x40018df4 );
+PROVIDE ( cache_ibus_mmu_set = 0x40018df4 );
 PROVIDE ( Cache_ICache_Preload_Done = 0x4001859c );
 PROVIDE ( Cache_Invalidate_Addr = 0x400182e4 );
 PROVIDE ( Cache_Invalidate_DCache_All = 0x4001842c );
 PROVIDE ( Cache_Invalidate_DCache_Items = 0x40018208 );
-PROVIDE ( Cache_Invalidate_ICache_All = 0x40018420 );
+PROVIDE ( cache_invalidate_icache_all = 0x40018420 );
 PROVIDE ( Cache_Invalidate_ICache_Items = 0x400181b8 );
 PROVIDE ( Cache_Lock_Addr = 0x40018b10 );
 PROVIDE ( Cache_Lock_DCache_Items = 0x40018a80 );
@@ -58,7 +58,7 @@ PROVIDE ( cache_memory_baseaddrs = 0x3ffaf020 );
 PROVIDE ( Cache_MMU_Init = 0x40018dd8 );
 PROVIDE ( Cache_Resume_DCache = 0x40018d3c );
 PROVIDE ( Cache_Resume_DCache_Autoload = 0x4001850c );
-PROVIDE ( Cache_Resume_ICache = 0x40018cdc );
+PROVIDE ( cache_resume_icache = 0x40018cdc );
 PROVIDE ( Cache_Resume_ICache_Autoload = 0x400184c4 );
 PROVIDE ( Cache_Set_DCache_Mode = 0x40018074 );
 PROVIDE ( Cache_Set_Default_Mode = 0x4001810c );
@@ -67,7 +67,7 @@ PROVIDE ( Cache_Start_DCache_Preload = 0x400185c4 );
 PROVIDE ( Cache_Start_ICache_Preload = 0x40018530 );
 PROVIDE ( Cache_Suspend_DCache = 0x40018d04 );
 PROVIDE ( Cache_Suspend_DCache_Autoload = 0x400184e0 );
-PROVIDE ( Cache_Suspend_ICache = 0x40018ca4 );
+PROVIDE ( cache_suspend_icache = 0x40018ca4 );
 PROVIDE ( Cache_Suspend_ICache_Autoload = 0x40018498 );
 PROVIDE ( Cache_Travel_Tag_Memory = 0x4001908c );
 PROVIDE ( Cache_Unlock_Addr = 0x40018b9c );
diff --git a/tools/esp32s2/Config.mk b/tools/esp32s2/Config.mk
index 51d38f2..9e39b88 100644
--- a/tools/esp32s2/Config.mk
+++ b/tools/esp32s2/Config.mk
@@ -60,36 +60,43 @@ endif
 
 ESPTOOL_FLASH_OPTS := -fs $(FLASH_SIZE) -fm $(FLASH_MODE) -ff $(FLASH_FREQ)
 
+# Configure the variables according to build environment
+
 ifdef ESPTOOL_BINDIR
-	BL_OFFSET       := 0x1000
-	PT_OFFSET       := 0x8000
-	BOOTLOADER      := $(ESPTOOL_BINDIR)/bootloader-esp32s2.bin
-	PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32s2.bin
-	FLASH_BL        := $(BL_OFFSET) $(BOOTLOADER)
-	FLASH_PT        := $(PT_OFFSET) $(PARTITION_TABLE)
-	ESPTOOL_BINS    := $(FLASH_BL) $(FLASH_PT)
+	ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y)
+		BL_OFFSET       := 0x1000
+		PT_OFFSET       := 0x8000
+		BOOTLOADER      := $(ESPTOOL_BINDIR)/bootloader-esp32s2.bin
+		PARTITION_TABLE := $(ESPTOOL_BINDIR)/partition-table-esp32s2.bin
+		FLASH_BL        := $(BL_OFFSET) $(BOOTLOADER)
+		FLASH_PT        := $(PT_OFFSET) $(PARTITION_TABLE)
+		ESPTOOL_BINS    := $(FLASH_BL) $(FLASH_PT)
+	else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
+		BL_OFFSET       := 0x1000
+		BOOTLOADER      := $(ESPTOOL_BINDIR)/mcuboot-esp32s2.bin
+		FLASH_BL        := $(BL_OFFSET) $(BOOTLOADER)
+		ESPTOOL_BINS    := $(FLASH_BL)
+	endif
 endif
 
-ESPTOOL_BINS += 0x10000 nuttx.bin
+ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y)
+	APP_OFFSET     := 0x10000
+	APP_IMAGE      := nuttx.bin
+	FLASH_APP      := $(APP_OFFSET) $(APP_IMAGE)
+else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
+	ifeq ($(CONFIG_ESP32S2_ESPTOOL_TARGET_PRIMARY),y)
+		VERIFIED   := --confirm
+		APP_OFFSET := $(CONFIG_ESP32S2_OTA_PRIMARY_SLOT_OFFSET)
+	else ifeq ($(CONFIG_ESP32S2_ESPTOOL_TARGET_SECONDARY),y)
+		VERIFIED   :=
+		APP_OFFSET := $(CONFIG_ESP32S2_OTA_SECONDARY_SLOT_OFFSET)
+	endif
+
+	APP_IMAGE      := nuttx.signed.bin
+	FLASH_APP      := $(APP_OFFSET) $(APP_IMAGE)
+endif
 
-# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application image format
-
-define ELF2IMAGE
-	$(Q) echo "MKIMAGE: ESP32-S2 binary"
-	$(Q) if ! esptool.py version 1>/dev/null 2>&1; then \
-		echo ""; \
-		echo "esptool.py not found.  Please run: \"pip install esptool\""; \
-		echo ""; \
-		echo "Run make again to create the nuttx.bin image."; \
-		exit 1; \
-	fi
-	$(Q) if [ -z $(FLASH_SIZE) ]; then \
-		echo "Missing Flash memory size configuration for the ESP32-S2 chip."; \
-		exit 1; \
-	fi
-	esptool.py -c esp32s2 elf2image $(ESPTOOL_FLASH_OPTS) -o nuttx.bin nuttx
-	$(Q) echo "Generated: nuttx.bin (ESP32-S2 compatible)"
-endef
+ESPTOOL_BINS += $(FLASH_APP)
 
 # MERGEBIN -- Merge raw binary files into a single file
 
@@ -114,12 +121,61 @@ define MERGEBIN
 endef
 endif
 
+# SIGNBIN -- Sign the binary image file
+
+ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
+define SIGNBIN
+	$(Q) echo "MKIMAGE: ESP32-S2 binary"
+	$(Q) if ! imgtool version 1>/dev/null 2>&1; then \
+		echo ""; \
+		echo "imgtool not found.  Please run: \"pip install imgtool\""; \
+		echo ""; \
+		echo "Run make again to create the nuttx.signed.bin image."; \
+		exit 1; \
+	fi
+	imgtool sign --pad --pad-sig $(VERIFIED) --align 4 -v 0 \
+		-H $(CONFIG_ESP32S2_APP_MCUBOOT_HEADER_SIZE) --pad-header \
+		-S $(CONFIG_ESP32S2_OTA_SLOT_SIZE) \
+		nuttx.bin nuttx.signed.bin
+	$(Q) echo nuttx.signed.bin >> nuttx.manifest
+	$(Q) echo "Generated: nuttx.signed.bin (MCUboot compatible)"
+endef
+endif
+
+# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application image format
+
+ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y)
+define ELF2IMAGE
+	$(Q) echo "MKIMAGE: ESP32-S2 binary"
+	$(Q) if ! esptool.py version 1>/dev/null 2>&1; then \
+		echo ""; \
+		echo "esptool.py not found.  Please run: \"pip install esptool\""; \
+		echo ""; \
+		echo "Run make again to create the nuttx.bin image."; \
+		exit 1; \
+	fi
+	$(Q) if [ -z $(FLASH_SIZE) ]; then \
+		echo "Missing Flash memory size configuration for the ESP32-S2 chip."; \
+		exit 1; \
+	fi
+	esptool.py -c esp32s2 elf2image $(ESPTOOL_FLASH_OPTS) -o nuttx.bin nuttx
+	$(Q) echo "Generated: nuttx.bin (ESP32-S2 compatible)"
+endef
+endif
+
 # POSTBUILD -- Perform post build operations
 
+ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
+define POSTBUILD
+	$(call SIGNBIN)
+	$(call MERGEBIN)
+endef
+else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y)
 define POSTBUILD
 	$(call ELF2IMAGE)
 	$(call MERGEBIN)
 endef
+endif
 
 # ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via esptool.py
 

[incubator-nuttx] 03/03: xtensa/esp32s2: Enable support for "make bootloader" target

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a5f9e29d7831fe136b8cd2452ba7a78310768ac4
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Fri Sep 24 09:28:34 2021 -0300

    xtensa/esp32s2: Enable support for "make bootloader" target
    
    This enables the provisioning of the bootloader binaries through the
    build system.
    
    Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
 arch/xtensa/Kconfig                   |   1 +
 arch/xtensa/src/esp32s2/.gitignore    |   1 +
 arch/xtensa/src/esp32s2/Bootloader.mk | 123 ++++++++++++++++++++++++++++++++++
 arch/xtensa/src/esp32s2/Kconfig       |  24 +++++++
 arch/xtensa/src/esp32s2/Make.defs     |   2 +
 5 files changed, 151 insertions(+)

diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 43b405b..6e383c5 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -44,6 +44,7 @@ config ARCH_CHIP_ESP32S2
 	select ARCH_HAVE_TEXT_HEAP
 	select ARCH_HAVE_SDRAM
 	select ARCH_HAVE_RESET
+	select ARCH_HAVE_BOOTLOADER
 	select ARCH_VECNOTIRQ
 	select LIBC_ARCH_MEMCPY
 	select LIBC_ARCH_MEMCHR
diff --git a/arch/xtensa/src/esp32s2/.gitignore b/arch/xtensa/src/esp32s2/.gitignore
new file mode 100644
index 0000000..c0bce18
--- /dev/null
+++ b/arch/xtensa/src/esp32s2/.gitignore
@@ -0,0 +1 @@
+/esp-nuttx-bootloader
\ No newline at end of file
diff --git a/arch/xtensa/src/esp32s2/Bootloader.mk b/arch/xtensa/src/esp32s2/Bootloader.mk
new file mode 100644
index 0000000..1c5d9a9
--- /dev/null
+++ b/arch/xtensa/src/esp32s2/Bootloader.mk
@@ -0,0 +1,123 @@
+############################################################################
+# arch/xtensa/src/esp32s2/Bootloader.mk
+#
+# 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.
+#
+############################################################################
+
+ifeq ($(CONFIG_ESP32S2_BOOTLOADER_BUILD_FROM_SOURCE),y)
+
+CHIPDIR            = $(TOPDIR)/arch/xtensa/src/chip
+
+BOOTLOADER_SRCDIR  = $(CHIPDIR)/esp-nuttx-bootloader
+BOOTLOADER_VERSION = main
+BOOTLOADER_URL     = https://github.com/espressif/esp-nuttx-bootloader
+BOOTLOADER_OUTDIR  = out
+
+$(BOOTLOADER_SRCDIR):
+	$(Q) git clone $(BOOTLOADER_URL) $(BOOTLOADER_SRCDIR) -b $(BOOTLOADER_VERSION)
+
+ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
+
+BOOTLOADER_CONFIG = $(CHIPDIR)/mcuboot.conf
+
+$(BOOTLOADER_CONFIG): $(TOPDIR)/.config
+	$(Q) echo "Creating Bootloader configuration"
+	$(Q) {                                                                                                \
+		echo "CONFIG_ESP_BOOTLOADER_SIZE=0xF000";                                                         \
+		echo "CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS=$(CONFIG_ESP32S2_OTA_PRIMARY_SLOT_OFFSET)";    \
+		echo "CONFIG_ESP_APPLICATION_SIZE=$(CONFIG_ESP32S2_OTA_SLOT_SIZE)";                               \
+		echo "CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS=$(CONFIG_ESP32S2_OTA_SECONDARY_SLOT_OFFSET)";\
+		echo "CONFIG_ESP_MCUBOOT_WDT_ENABLE=y";                                                           \
+		echo "CONFIG_ESP_SCRATCH_OFFSET=$(CONFIG_ESP32S2_OTA_SCRATCH_OFFSET)";                            \
+		echo "CONFIG_ESP_SCRATCH_SIZE=$(CONFIG_ESP32S2_OTA_SCRATCH_SIZE)";                                \
+	} > $(BOOTLOADER_CONFIG)
+
+bootloader: $(BOOTLOADER_SRCDIR) $(BOOTLOADER_CONFIG)
+	$(Q) echo "Building Bootloader binaries"
+	$(Q) $(BOOTLOADER_SRCDIR)/build_mcuboot.sh -c esp32s2 -s -f $(BOOTLOADER_CONFIG)
+	$(call COPYFILE, $(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/mcuboot-esp32s2.bin, $(TOPDIR))
+
+clean_bootloader:
+	$(call DELDIR, $(BOOTLOADER_SRCDIR))
+	$(call DELFILE, $(BOOTLOADER_CONFIG))
+	$(call DELFILE, $(TOPDIR)/mcuboot-esp32s2.bin)
+
+else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y)
+
+BOOTLOADER_CONFIG = $(CHIPDIR)/sdkconfig
+
+$(BOOTLOADER_CONFIG): $(TOPDIR)/.config
+	$(Q) echo "Creating Bootloader configuration"
+	$(Q) {                                                                                         \
+		[ "$(CONFIG_ESP32S2_FLASH_2M)"        = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_4M)"        = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_8M)"        = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_16M)"       = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y"; \
+		[ "$(CONFIG_ESP32S2_FLASH_MODE_DIO)"  = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHMODE_DIO=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_MODE_DOUT)" = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHMODE_DOUT=y"; \
+		[ "$(CONFIG_ESP32S2_FLASH_MODE_QIO)"  = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHMODE_QIO=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_MODE_QOUT)" = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHMODE_QOUT=y"; \
+		[ "$(CONFIG_ESP32S2_FLASH_FREQ_80M)"  = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHFREQ_80M=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_FREQ_40M)"  = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHFREQ_40M=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_FREQ_26M)"  = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHFREQ_26M=y";  \
+		[ "$(CONFIG_ESP32S2_FLASH_FREQ_20M)"  = "y" ] && echo "CONFIG_ESPTOOLPY_FLASHFREQ_20M=y";  \
+		echo "CONFIG_PARTITION_TABLE_CUSTOM=y";                                                    \
+		echo "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions.csv\"";                          \
+	} > $(BOOTLOADER_CONFIG)
+
+bootloader: $(BOOTLOADER_SRCDIR) $(BOOTLOADER_CONFIG)
+	$(Q) echo "Building Bootloader binaries"
+	$(Q) $(BOOTLOADER_SRCDIR)/build_idfboot.sh -c esp32s2 -s -f $(BOOTLOADER_CONFIG)
+	$(call COPYFILE, $(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/bootloader-esp32s2.bin, $(TOPDIR))
+	$(call COPYFILE, $(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/partition-table-esp32s2.bin, $(TOPDIR))
+
+clean_bootloader:
+	$(call DELDIR, $(BOOTLOADER_SRCDIR))
+	$(call DELFILE, $(BOOTLOADER_CONFIG))
+	$(call DELFILE, $(TOPDIR)/bootloader-esp32s2.bin)
+	$(call DELFILE, $(TOPDIR)/partition-table-esp32s2.bin)
+
+endif
+
+else ifeq ($(CONFIG_ESP32S2_BOOTLOADER_DOWNLOAD_PREBUILT),y)
+
+BOOTLOADER_VERSION = latest
+BOOTLOADER_URL     = https://github.com/espressif/esp-nuttx-bootloader/releases/download/$(BOOTLOADER_VERSION)
+
+ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
+
+bootloader:
+	$(Q) echo "Downloading Bootloader binaries"
+	$(Q) curl -L $(BOOTLOADER_URL)/mcuboot-esp32s2.bin -o $(TOPDIR)/mcuboot-esp32s2.bin
+
+clean_bootloader:
+	$(call DELFILE, $(TOPDIR)/mcuboot-esp32s2.bin)
+
+else ifeq ($(CONFIG_ESP32S2_APP_FORMAT_LEGACY),y)
+
+bootloader:
+	$(Q) echo "Downloading Bootloader binaries"
+	$(Q) curl -L $(BOOTLOADER_URL)/bootloader-esp32s2.bin -o $(TOPDIR)/bootloader-esp32s2.bin
+	$(Q) curl -L $(BOOTLOADER_URL)/partition-table-esp32s2.bin -o $(TOPDIR)/partition-table-esp32s2.bin
+
+clean_bootloader:
+	$(call DELFILE, $(TOPDIR)/bootloader-esp32s2.bin)
+	$(call DELFILE, $(TOPDIR)/partition-table-esp32s2.bin)
+
+endif
+
+endif
diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig
index 09bc35e..79ce46f 100644
--- a/arch/xtensa/src/esp32s2/Kconfig
+++ b/arch/xtensa/src/esp32s2/Kconfig
@@ -934,6 +934,30 @@ comment "MCUboot support depends on CONFIG_EXPERIMENTAL"
 endchoice # Application Image Format
 
 choice
+	prompt "Source for bootloader binaries"
+	default ESP32S2_BOOTLOADER_DOWNLOAD_PREBUILT
+	---help---
+		Select the action to be taken by the build system for the
+		"make bootloader" target.
+
+config ESP32S2_BOOTLOADER_DOWNLOAD_PREBUILT
+	bool "Download prebuilt binaries"
+	---help---
+		The build system will download the prebuilt binaries from
+		https://github.com/espressif/esp-nuttx-bootloader according to the chosen
+		Application Image Format (ESP32S2_APP_FORMAT_LEGACY or ESP32S2_APP_FORMAT_MCUBOOT)
+
+config ESP32S2_BOOTLOADER_BUILD_FROM_SOURCE
+	bool "Build binaries from source"
+	---help---
+		The build system will build all the required binaries from source. It will clone
+		the https://github.com/espressif/esp-nuttx-bootloader repository and build a
+		custom bootloader according to the chosen Application Image Format
+		(ESP32S2_APP_FORMAT_LEGACY or ESP32S2_APP_FORMAT_MCUBOOT) and partition information.
+
+endchoice
+
+choice
 	prompt "Target slot for image flashing"
 	default ESP32S2_ESPTOOL_TARGET_PRIMARY
 	depends on ESP32S2_HAVE_OTA_PARTITION
diff --git a/arch/xtensa/src/esp32s2/Make.defs b/arch/xtensa/src/esp32s2/Make.defs
index b375737..84e2d78 100644
--- a/arch/xtensa/src/esp32s2/Make.defs
+++ b/arch/xtensa/src/esp32s2/Make.defs
@@ -18,6 +18,8 @@
 #
 ############################################################################
 
+include chip/Bootloader.mk
+
 # The start-up, "head", file.  May be either a .S or a .c file.
 
 HEAD_ASRC  = xtensa_vectors.S xtensa_window_vector.S xtensa_windowspill.S

[incubator-nuttx] 02/03: boards/esp32s2-saola-1: Add example defconfig for booting from MCUboot

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 75dd460f79674b2736703e89c6eb2f181a828653
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Mon Sep 13 14:09:50 2021 -0300

    boards/esp32s2-saola-1: Add example defconfig for booting from MCUboot
    
    Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
 .../esp32s2-saola-1/configs/mcuboot_nsh/defconfig  | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/configs/mcuboot_nsh/defconfig b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/mcuboot_nsh/defconfig
new file mode 100644
index 0000000..3e8d9e4
--- /dev/null
+++ b/boards/xtensa/esp32s2/esp32s2-saola-1/configs/mcuboot_nsh/defconfig
@@ -0,0 +1,49 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32s2-saola-1"
+CONFIG_ARCH_BOARD_ESP32S2_SAOLA_1=y
+CONFIG_ARCH_CHIP="esp32s2"
+CONFIG_ARCH_CHIP_ESP32S2=y
+CONFIG_ARCH_CHIP_ESP32S2WROVER=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_ESP32S2_APP_FORMAT_MCUBOOT=y
+CONFIG_ESP32S2_DATA_CACHE_0KB=y
+CONFIG_ESP32S2_SPIFLASH=y
+CONFIG_ESP32S2_UART0=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INTELHEX_BINARY=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_USER_ENTRYPOINT="nsh_main"