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/nuttx.git

commit bfc40c74d077318794906aac7263ef570f64f6e7
Author: Gustavo Henrique Nihei <[email protected]>
AuthorDate: Mon Oct 31 11:47:33 2022 -0300

    xtensa/esp32s3: Add support for Protected Mode
    
    Signed-off-by: Gustavo Henrique Nihei <[email protected]>
---
 arch/xtensa/Kconfig                                |   1 +
 arch/xtensa/src/esp32s3/Kconfig                    |  10 +
 arch/xtensa/src/esp32s3/Make.defs                  |   4 +
 arch/xtensa/src/esp32s3/chip_macros.h              |  10 +
 arch/xtensa/src/esp32s3/esp32s3_allocateheap.c     |  84 ++++-
 arch/xtensa/src/esp32s3/esp32s3_start.c            |  14 +
 arch/xtensa/src/esp32s3/esp32s3_userspace.c        | 347 +++++++++++++++++++++
 arch/xtensa/src/esp32s3/esp32s3_userspace.h        |  49 +++
 boards/xtensa/esp32s3/common/kernel/Makefile       | 102 ++++++
 .../esp32s3/common/kernel/esp32s3_userspace.c      | 100 ++++++
 .../xtensa/esp32s3/common/scripts/esp32s3_rom.ld   |   4 +-
 .../scripts/{esp32s3_memory.ld => flat_memory.ld}  |   0
 .../xtensa/esp32s3/common/scripts/kernel-space.ld  | 322 +++++++++++++++++++
 .../{esp32s3_memory.ld => protected_memory.ld}     |  66 ++--
 boards/xtensa/esp32s3/common/scripts/user-space.ld | 231 ++++++++++++++
 .../esp32s3/esp32s3-devkit/configs/knsh/defconfig  |  55 ++++
 .../esp32s3-devkit/include/board_memorymap.h       | 116 +++++++
 .../esp32s3/esp32s3-devkit/scripts/Make.defs       |  12 +-
 .../xtensa/esp32s3/esp32s3-eye/scripts/Make.defs   |  12 +-
 tools/esp32s3/Config.mk                            |   4 +
 20 files changed, 1485 insertions(+), 58 deletions(-)

diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 16d12f639e..e288c01f8f 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -79,6 +79,7 @@ config ARCH_CHIP_ESP32S3
        select ARCH_FAMILY_LX7
        select XTENSA_HAVE_INTERRUPTS
        select ARCH_HAVE_FPU
+       select ARCH_HAVE_MPU
        select ARCH_HAVE_MULTICPU
        select ARCH_HAVE_TEXT_HEAP
        select ARCH_HAVE_SDRAM
diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig
index 9fd728d96a..b604ab9e56 100644
--- a/arch/xtensa/src/esp32s3/Kconfig
+++ b/arch/xtensa/src/esp32s3/Kconfig
@@ -906,6 +906,16 @@ config ESP32S3_PARTITION_TABLE_OFFSET
        default 0x8000
        depends on ESP32S3_APP_FORMAT_LEGACY
 
+if BUILD_PROTECTED
+
+config ESP32S3_USER_IMAGE_OFFSET
+       hex "User image offset"
+       default 0x90000
+       ---help---
+               Offset in SPI Flash for flashing the User application firmware 
image.
+
+endif
+
 endmenu # Application Image Configuration
 
 endif # ARCH_CHIP_ESP32S3
diff --git a/arch/xtensa/src/esp32s3/Make.defs 
b/arch/xtensa/src/esp32s3/Make.defs
index 14985252c3..e01aed9551 100644
--- a/arch/xtensa/src/esp32s3/Make.defs
+++ b/arch/xtensa/src/esp32s3/Make.defs
@@ -37,6 +37,10 @@ ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y)
 CHIP_CSRCS += esp32s3_idle.c
 endif
 
+ifeq ($(CONFIG_BUILD_PROTECTED),y)
+CHIP_CSRCS += esp32s3_userspace.c
+endif
+
 ifeq ($(CONFIG_SMP),y)
 CHIP_ASRCS  = esp32s3_cpuindex.S
 CHIP_CSRCS += esp32s3_cpuidlestack.c esp32s3_cpustart.c 
esp32s3_intercpu_interrupt.c
diff --git a/arch/xtensa/src/esp32s3/chip_macros.h 
b/arch/xtensa/src/esp32s3/chip_macros.h
index 95ebd91ea0..913f2e8476 100644
--- a/arch/xtensa/src/esp32s3/chip_macros.h
+++ b/arch/xtensa/src/esp32s3/chip_macros.h
@@ -43,6 +43,16 @@
 
 #define HANDLER_SECTION .iram1
 
+#if defined(CONFIG_BUILD_PROTECTED)
+
+#define xtensa_saveprivilege(regs,var)
+#define xtensa_restoreprivilege(regs,var)
+
+#define xtensa_lowerprivilege(regs)
+#define xtensa_raiseprivilege(regs)
+
+#endif
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
diff --git a/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c 
b/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c
index 2da70fea3e..1ccac0a905 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_allocateheap.c
@@ -24,16 +24,19 @@
 
 #include <nuttx/config.h>
 
-#include <sys/types.h>
 #include <debug.h>
+#include <sys/types.h>
 
-#include <nuttx/mm/mm.h>
 #include <nuttx/arch.h>
 #include <nuttx/board.h>
+#include <nuttx/mm/mm.h>
+#include <nuttx/userspace.h>
 #include <arch/board/board.h>
+#ifdef CONFIG_MM_KERNEL_HEAP
+#include <arch/board/board_memorymap.h>
+#endif
 
 #include "xtensa.h"
-
 #include "hardware/esp32s3_rom_layout.h"
 
 /****************************************************************************
@@ -50,23 +53,84 @@
  * Description:
  *   This function will be called to dynamically set aside the heap region.
  *
- *   For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and
- *   user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the
- *   size of the unprotected, user-space heap.
+ *   For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel and
+ *   userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the
+ *   size of the unprotected, userspace heap.
  *
- *   If a protected kernel-space heap is provided, the kernel heap must be
+ *   If a protected kernel space heap is provided, the kernel heap must be
  *   allocated (and protected) by an analogous up_allocate_kheap().
  *
  ****************************************************************************/
 
 void up_allocate_heap(void **heap_start, size_t *heap_size)
 {
+#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
+  uintptr_t ubase = USERSPACE->us_dataend;
+  uintptr_t utop  = ets_rom_layout_p->dram0_rtos_reserved_start;
+  size_t    usize = utop - ubase;
+
+  minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n",
+        ubase, utop, usize);
+
+  board_autoled_on(LED_HEAPALLOCATE);
+
+  /* Return the userspace heap settings */
+
+  *heap_start = (void *)ubase;
+  *heap_size  = usize;
+
+  /* Allow user-mode access to the user heap memory in PMP
+   * is already done in esp32s3_userspace().
+   */
+
+#else
+  /* These values come from the linker scripts (esp32s3_sections.ld and
+   * flat_memory.ld).
+   * Check boards/xtensa/esp32s3.
+   */
+
+  board_autoled_on(LED_HEAPALLOCATE);
+
+  *heap_start = _sheap;
+  *heap_size  = ets_rom_layout_p->dram0_rtos_reserved_start -
+                (uintptr_t)_sheap;
+#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */
+}
+
+/****************************************************************************
+ * Name: up_allocate_kheap
+ *
+ * Description:
+ *   This function will be called to dynamically set aside the heap region.
+ *
+ *   For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel and
+ *   userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
+ *   (and protects) the kernel space heap.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) && \
+    defined(__KERNEL__)
+void up_allocate_kheap(void **heap_start, size_t *heap_size)
+{
+  /* These values come from the linker scripts (kernel-space.ld and
+   * protected_memory.ld).
+   * Check boards/xtensa/esp32s3.
+   */
+
+  uintptr_t kbase = (uintptr_t)_sheap;
+  uintptr_t ktop  = KDRAM_END;
+  size_t    ksize = ktop - kbase;
+
+  minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n",
+        kbase, ktop, ksize);
+
   board_autoled_on(LED_HEAPALLOCATE);
 
-  *heap_start = (void *)_sheap;
-  *heap_size = (size_t)(ets_rom_layout_p->dram0_rtos_reserved_start -
-                (uintptr_t)_sheap);
+  *heap_start = (void *)kbase;
+  *heap_size  = ksize;
 }
+#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */
 
 /****************************************************************************
  * Name: xtensa_add_region
diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c 
b/arch/xtensa/src/esp32s3/esp32s3_start.c
index 910ab96171..fc6091c9ca 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_start.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_start.c
@@ -39,6 +39,9 @@
 #include "esp32s3_region.h"
 #include "esp32s3_spiram.h"
 #include "esp32s3_wdt.h"
+#ifdef CONFIG_BUILD_PROTECTED
+#  include "esp32s3_userspace.h"
+#endif
 #include "hardware/esp32s3_cache_memory.h"
 #include "hardware/esp32s3_system.h"
 
@@ -312,6 +315,17 @@ void noreturn_function IRAM_ATTR __esp32s3_start(void)
 
   showprogress('B');
 
+#ifdef CONFIG_BUILD_PROTECTED
+  /* For the case of the separate user-/kernel-space build, perform whatever
+   * platform specific initialization of the user memory is required.
+   * Normally this just means initializing the user space .data and .bss
+   * segments.
+   */
+
+  esp32s3_userspace();
+  showprogress('C');
+#endif
+
   /* Bring up NuttX */
 
   nx_start();
diff --git a/arch/xtensa/src/esp32s3/esp32s3_userspace.c 
b/arch/xtensa/src/esp32s3/esp32s3_userspace.c
new file mode 100644
index 0000000000..04786a5c6c
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/esp32s3_userspace.c
@@ -0,0 +1,347 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/esp32s3_userspace.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <nuttx/userspace.h>
+
+#include <arch/board/board_memorymap.h>
+
+#include "chip.h"
+#include "xtensa.h"
+#include "xtensa_attr.h"
+#include "esp32s3_userspace.h"
+#include "hardware/esp32s3_cache_memory.h"
+
+#ifdef CONFIG_BUILD_PROTECTED
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define USER_IMAGE_OFFSET   CONFIG_ESP32S3_USER_IMAGE_OFFSET
+
+#define MMU_BLOCK0_VADDR    SOC_DROM_LOW
+#define MMU_SIZE            0x3f0000
+#define MMU_BLOCK63_VADDR   (MMU_BLOCK0_VADDR + MMU_SIZE)
+
+/* 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))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct user_image_load_header_s
+{
+  uintptr_t drom_vma;      /* Destination address (VMA) for DROM region */
+  uintptr_t drom_lma;      /* Flash offset (LMA) for start of DROM region */
+  uintptr_t drom_size;     /* Size of DROM region */
+  uintptr_t irom_vma;      /* Destination address (VMA) for IROM region */
+  uintptr_t irom_lma;      /* Flash offset (LMA) for start of IROM region */
+  uintptr_t irom_size;     /* Size of IROM region */
+};
+
+/****************************************************************************
+ * ROM Function Prototypes
+ ****************************************************************************/
+
+extern uint32_t cache_suspend_dcache(void);
+extern void cache_resume_dcache(uint32_t val);
+extern void cache_invalidate_dcache_all(void);
+extern int cache_dbus_mmu_set(uint32_t ext_ram, uint32_t vaddr,
+                              uint32_t paddr, uint32_t psize, uint32_t num,
+                              uint32_t fixed);
+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);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct user_image_load_header_s g_header;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: calc_mmu_pages
+ *
+ * Description:
+ *   Calculate the required number of MMU pages for mapping a given region
+ *   from External Flash into Internal RAM.
+ *
+ * Input Parameters:
+ *   size          - Length of the region to map
+ *   vaddr         - Starting External Flash offset to map to Internal RAM
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+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;
+}
+
+/****************************************************************************
+ * Name: configure_flash_mmu
+ *
+ * Description:
+ *   Configure the External Flash MMU and Cache for enabling access to code
+ *   and read-only data of the userspace image.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static noinline_function IRAM_ATTR void configure_flash_mmu(void)
+{
+  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 = USER_IMAGE_OFFSET;
+  uint32_t app_drom_lma = partition_offset + g_header.drom_lma;
+  uint32_t app_drom_size = g_header.drom_size;
+  uint32_t app_drom_vma = g_header.drom_vma;
+  uint32_t app_irom_lma = partition_offset + g_header.irom_lma;
+  uint32_t app_irom_size = g_header.irom_size;
+  uint32_t app_irom_vma = g_header.irom_vma;
+
+  uint32_t autoload = cache_suspend_dcache();
+  cache_invalidate_dcache_all();
+
+  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);
+  ASSERT(cache_dbus_mmu_set(MMU_ACCESS_FLASH, drom_vma_aligned,
+                            drom_lma_aligned, 64,
+                            (int)drom_page_count, 0) == 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);
+  ASSERT(cache_ibus_mmu_set(MMU_ACCESS_FLASH, irom_vma_aligned,
+                            irom_lma_aligned, 64,
+                            (int)irom_page_count, 0) == 0);
+
+  cache_resume_dcache(autoload);
+}
+
+/****************************************************************************
+ * Name: map_flash
+ *
+ * Description:
+ *   Map a region of the External Flash memory to Internal RAM.
+ *
+ * Input Parameters:
+ *   src_addr      - Starting External Flash offset to map to Internal RAM
+ *   size          - Length of the region to map
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static noinline_function IRAM_ATTR const void *map_flash(uint32_t src_addr,
+                                                         uint32_t size)
+{
+  uint32_t src_addr_aligned;
+  uint32_t page_count;
+
+  uint32_t autoload = cache_suspend_dcache();
+  cache_invalidate_dcache_all();
+
+  src_addr_aligned = src_addr & MMU_FLASH_MASK;
+  page_count = calc_mmu_pages(size, src_addr);
+
+  ASSERT(cache_dbus_mmu_set(MMU_ACCESS_FLASH, MMU_BLOCK63_VADDR,
+                            src_addr_aligned, 64, (int)page_count, 0) == 0);
+
+  cache_resume_dcache(autoload);
+
+  return (void *)(MMU_BLOCK63_VADDR + (src_addr - src_addr_aligned));
+}
+
+/****************************************************************************
+ * Name: load_header
+ *
+ * Description:
+ *   Load IROM and DROM information from image header to enable the correct
+ *   configuration of the Flash MMU and Cache.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void load_header(void)
+{
+  size_t length = sizeof(struct user_image_load_header_s);
+  const uint8_t *data =
+    (const uint8_t *)map_flash(USER_IMAGE_OFFSET, length);
+
+  DEBUGASSERT(data != NULL);
+
+  memcpy(&g_header, data, length);
+}
+
+/****************************************************************************
+ * Name: initialize_data
+ *
+ * Description:
+ *   Initialize data sections of the userspace image.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void initialize_data(void)
+{
+  uint8_t *dest;
+  uint8_t *end;
+  size_t length = USERSPACE->us_dataend - USERSPACE->us_datastart;
+  const uint8_t *src =
+    (const uint8_t *)map_flash(USER_IMAGE_OFFSET + USERSPACE->us_datasource,
+                               length);
+
+  DEBUGASSERT(src != NULL);
+
+  dest = (uint8_t *)USERSPACE->us_datastart;
+  end  = (uint8_t *)USERSPACE->us_dataend;
+
+  while (dest != end)
+    {
+      *dest++ = *src++;
+    }
+}
+
+/****************************************************************************
+ * Name: configure_mpu
+ *
+ * Description:
+ *   Configure the MPU for kernel/userspace separation.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void configure_mpu(void)
+{
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32s3_userspace
+ *
+ * Description:
+ *   For the case of the separate user/kernel space build, perform whatever
+ *   platform specific initialization of the user memory is required.
+ *   Normally this just means initializing the userspace .data and .bss
+ *   segments.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_userspace(void)
+{
+  uint8_t *dest;
+  uint8_t *end;
+
+  /* Load IROM and DROM information from image header */
+
+  load_header();
+
+  /* Configure the Flash MMU for enabling access to the userspace image */
+
+  configure_flash_mmu();
+
+  /* Clear all of userspace .bss */
+
+  DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 &&
+              USERSPACE->us_bssstart <= USERSPACE->us_bssend);
+
+  dest = (uint8_t *)USERSPACE->us_bssstart;
+  end  = (uint8_t *)USERSPACE->us_bssend;
+
+  while (dest != end)
+    {
+      *dest++ = 0;
+    }
+
+  /* Initialize all of userspace .data */
+
+  DEBUGASSERT(USERSPACE->us_datasource != 0 &&
+              USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 &&
+              USERSPACE->us_datastart <= USERSPACE->us_dataend);
+
+  initialize_data();
+
+  /* Configure MPU to grant access to the userspace */
+
+  configure_mpu();
+}
+
+#endif /* CONFIG_BUILD_PROTECTED */
diff --git a/arch/xtensa/src/esp32s3/esp32s3_userspace.h 
b/arch/xtensa/src/esp32s3/esp32s3_userspace.h
new file mode 100644
index 0000000000..2496042ed2
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/esp32s3_userspace.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/esp32s3_userspace.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_ESP32S3_ESP32S3_USERSPACE_H
+#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_USERSPACE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32s3_userspace
+ *
+ * Description:
+ *   For the case of the separate user-/kernel-space build, perform whatever
+ *   platform specific initialization of the user memory is required.
+ *   Normally this just means initializing the user space .data and .bss
+ *   segments.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BUILD_PROTECTED
+void esp32s3_userspace(void);
+#endif
+
+#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_USERSPACE_H */
diff --git a/boards/xtensa/esp32s3/common/kernel/Makefile 
b/boards/xtensa/esp32s3/common/kernel/Makefile
new file mode 100644
index 0000000000..5a08434340
--- /dev/null
+++ b/boards/xtensa/esp32s3/common/kernel/Makefile
@@ -0,0 +1,102 @@
+############################################################################
+# boards/xtensa/esp32s3/esp32s3-devkit/kernel/Makefile
+#
+# 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.
+#
+############################################################################
+
+include $(TOPDIR)/Make.defs
+
+# The entry point name (if none is provided in the .config file)
+
+CONFIG_INIT_ENTRYPOINT ?= user_start
+ENTRYPT = $(patsubst "%",%,$(CONFIG_INIT_ENTRYPOINT))
+
+# Get the paths to the libraries and the links script path in format that
+# is appropriate for the host OS
+
+USER_LIBPATHS = $(addprefix -L,$(call CONVERT_PATH,$(addprefix 
$(TOPDIR)$(DELIM),$(dir $(USERLIBS)))))
+USER_LDSCRIPT = $(call 
CONVERT_PATH,$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)protected_memory.ld)
+USER_LDSCRIPT += $(call 
CONVERT_PATH,$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)user-space.ld)
+USER_LDSCRIPT += $(call 
CONVERT_PATH,$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_rom.ld)
+USER_HEXFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.hex)
+USER_BINFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.bin)
+
+USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(addprefix 
-T,$(addsuffix .tmp,$(USER_LDSCRIPT)))
+
+ifeq ($(CONFIG_DEBUG_LINK_MAP),y)
+USER_LDFLAGS += --cref -Map="$(TOPDIR)$(DELIM)User.map"
+endif
+
+USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS))))
+USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
+
+# Source files
+
+CSRCS = esp32s3_userspace.c
+COBJS = $(CSRCS:.c=$(OBJEXT))
+OBJS  = $(COBJS)
+
+ifeq ($(LD),$(CC))
+  LDSTARTGROUP ?= -Wl,--start-group
+  LDENDGROUP   ?= -Wl,--end-group
+  USER_LDFLAGS := $(addprefix -Xlinker ,$(USER_LDFLAGS))
+  USER_LDFLAGS += $(CFLAGS)
+else
+  LDSTARTGROUP ?= --start-group
+  LDENDGROUP   ?= --end-group
+endif
+
+# Targets:
+
+all: $(TOPDIR)$(DELIM)nuttx_user.elf
+.PHONY: nuttx_user.elf depend clean distclean
+
+$(COBJS): %$(OBJEXT): %.c
+       $(call COMPILE,$<,$@)
+
+$(addsuffix .tmp,$(USER_LDSCRIPT)): $(USER_LDSCRIPT)
+       $(call PREPROCESS,$(patsubst %.tmp,%,$@),$@)
+
+# Create the nuttx_user.elf file containing all of the user-mode code
+
+nuttx_user.elf: $(OBJS) $(addsuffix .tmp,$(USER_LDSCRIPT))
+       $(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) 
$(LDSTARTGROUP) $(USER_LDLIBS) $(LDENDGROUP) $(USER_LIBGCC)
+
+$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf
+       $(Q) echo "LD: nuttx_user.elf"
+       $(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf
+ifeq ($(CONFIG_INTELHEX_BINARY),y)
+       $(Q) echo "CP: nuttx_user.hex"
+       $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE)
+endif
+ifeq ($(CONFIG_RAW_BINARY),y)
+       $(Q) echo "CP: nuttx_user.bin"
+       $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE)
+endif
+       $(Q) $(call DELFILE,$(addsuffix .tmp,$(USER_LDSCRIPT)))
+
+.depend:
+
+depend: .depend
+
+clean:
+       $(call DELFILE,nuttx_user.elf)
+       $(call DELFILE,$(TOPDIR)$(DELIM)nuttx_user.*)
+       $(call DELFILE,$(TOPDIR)$(DELIM)User.map)
+       $(call CLEAN)
+
+distclean: clean
diff --git a/boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c 
b/boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c
new file mode 100644
index 0000000000..b5b28a1ec2
--- /dev/null
+++ b/boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/common/kernel/esp32s3_userspace.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mm/mm.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/userspace.h>
+
+#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NUTTX_USERSPACE
+#  error "CONFIG_NUTTX_USERSPACE not defined"
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* These 'addresses' of these values are setup by the linker script. */
+
+extern uint8_t _stext[];           /* Start of .text */
+extern uint8_t _etext[];           /* End+1 of .text + .rodata */
+extern const uint8_t _eronly[];    /* End+1 of read only section (.text + 
.rodata) */
+extern uint8_t _sdata[];           /* Start of .data */
+extern uint8_t _edata[];           /* End+1 of .data */
+extern uint8_t _sbss[];            /* Start of .bss */
+extern uint8_t _ebss[];            /* End+1 of .bss */
+
+extern uint8_t __ld_udram_end[];   /* End+1 of user ram section */
+
+const struct userspace_s userspace locate_data(".userspace") =
+{
+  /* General memory map */
+
+  .us_entrypoint    = CONFIG_INIT_ENTRYPOINT,
+  .us_textstart     = (uintptr_t)_stext,
+  .us_textend       = (uintptr_t)_etext,
+  .us_datasource    = (uintptr_t)_eronly,
+  .us_datastart     = (uintptr_t)_sdata,
+  .us_dataend       = (uintptr_t)_edata,
+  .us_bssstart      = (uintptr_t)_sbss,
+  .us_bssend        = (uintptr_t)_ebss,
+
+  .us_heapend       = (uintptr_t)__ld_udram_end,
+
+  /* Memory manager heap structure */
+
+  .us_heap          = &g_mmheap,
+
+  /* Task/thread startup routines */
+
+  .task_startup     = nxtask_startup,
+
+  /* Signal handler trampoline */
+
+  .signal_handler   = up_signal_handler,
+
+  /* Userspace work queue support (declared in include/nuttx/wqueue.h) */
+
+#ifdef CONFIG_LIBC_USRWORK
+  .work_usrstart    = work_usrstart,
+#endif
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */
diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld 
b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld
index 6070bc65b4..73555ec9c6 100644
--- a/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld
+++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_rom.ld
@@ -385,7 +385,7 @@ PROVIDE( Cache_Op_Addr = 0x400016a4 );
 PROVIDE( cache_invalidate_addr = 0x400016b0 );
 PROVIDE( Cache_Clean_Addr = 0x400016bc );
 PROVIDE( Cache_WriteBack_Addr = 0x400016c8 );
-PROVIDE( Cache_Invalidate_ICache_All = 0x400016d4 );
+PROVIDE( cache_invalidate_icache_all = 0x400016d4 );
 PROVIDE( cache_invalidate_dcache_all = 0x400016e0 );
 PROVIDE( Cache_Clean_All = 0x400016ec );
 PROVIDE( cache_writeback_all = 0x400016f8 );
@@ -445,7 +445,7 @@ PROVIDE( Cache_Owner_Init = 0x40001974 );
 PROVIDE( Cache_Occupy_ICache_MEMORY = 0x40001980 );
 PROVIDE( Cache_Occupy_DCache_MEMORY = 0x4000198c );
 PROVIDE( Cache_MMU_Init = 0x40001998 );
-PROVIDE( Cache_Ibus_MMU_Set = 0x400019a4 );
+PROVIDE( cache_ibus_mmu_set = 0x400019a4 );
 PROVIDE( cache_dbus_mmu_set = 0x400019b0 );
 PROVIDE( Cache_Count_Flash_Pages = 0x400019bc );
 PROVIDE( Cache_Flash_To_SPIRAM_Copy = 0x400019c8 );
diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld 
b/boards/xtensa/esp32s3/common/scripts/flat_memory.ld
similarity index 100%
copy from boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld
copy to boards/xtensa/esp32s3/common/scripts/flat_memory.ld
diff --git a/boards/xtensa/esp32s3/common/scripts/kernel-space.ld 
b/boards/xtensa/esp32s3/common/scripts/kernel-space.ld
new file mode 100644
index 0000000000..48fffb7551
--- /dev/null
+++ b/boards/xtensa/esp32s3/common/scripts/kernel-space.ld
@@ -0,0 +1,322 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/common/scripts/kernel-space.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.
+ *
+ ****************************************************************************/
+
+/* Provide these so there is no need for using config files for this */
+
+__uirom_start = ORIGIN(UIROM);
+__uirom_size = LENGTH(UIROM);
+__uirom_end = ORIGIN(UIROM) + LENGTH(UIROM);
+__udrom_start = ORIGIN(UDROM);
+__udrom_size = LENGTH(UDROM);
+__udrom_end = ORIGIN(UDROM) + LENGTH(UDROM);
+__uiram_start = ORIGIN(UIRAM);
+__uiram_size = LENGTH(UIRAM);
+__uiram_end = ORIGIN(UIRAM) + LENGTH(UIRAM);
+__udram_start = ORIGIN(UDRAM);
+__udram_size = LENGTH(UDRAM);
+__udram_end = ORIGIN(UDRAM) + LENGTH(UDRAM);
+
+/* Provide the kernel boundaries as well */
+
+__kirom_start = ORIGIN(KIROM);
+__kirom_size = LENGTH(KIROM);
+__kdrom_start = ORIGIN(KDROM);
+__kdrom_size = LENGTH(KDROM);
+__kiram_start = ORIGIN(KIRAM);
+__kiram_size = LENGTH(KIRAM);
+__kiram_end = ORIGIN(KIRAM) + LENGTH(KIRAM);
+__kdram_start = ORIGIN(KDRAM);
+__kdram_size = LENGTH(KDRAM);
+__kdram_end = ORIGIN(KDRAM) + LENGTH(KDRAM);
+
+ENTRY(_stext)
+
+_diram_i_start = 0x40378000;
+
+SECTIONS
+{
+  /* Send .iram0 code to iram */
+
+  .iram0.vectors :
+  {
+    /* Vectors go to IRAM */
+
+    _init_start = ABSOLUTE(.);
+
+    __vectors_start = ABSOLUTE(.);
+
+    /* Vectors according to 
builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
+
+    . = 0x0;
+    KEEP (*(.window_vectors.text));
+    . = 0x180;
+    KEEP (*(.xtensa_level2_vector.text));
+    . = 0x1c0;
+    KEEP (*(.xtensa_level3_vector.text));
+    . = 0x200;
+    KEEP (*(.xtensa_level4_vector.text));
+    . = 0x240;
+    KEEP (*(.xtensa_level5_vector.text));
+    . = 0x280;
+    KEEP (*(.debug_exception_vector.text));
+    . = 0x2c0;
+    KEEP (*(.nmi_vector.text));
+    . = 0x300;
+    KEEP (*(.kernel_exception_vector.text));
+    . = 0x340;
+    KEEP (*(.user_exception_vector.text));
+    . = 0x3c0;
+    KEEP (*(.double_exception_vector.text));
+    . = 0x400;
+    *(.*_vector.literal)
+
+    . = ALIGN (16);
+
+    __vectors_end = ABSOLUTE(.);
+
+    *(.entry.text)
+    *(.init.literal)
+    *(.init)
+
+    _init_end = ABSOLUTE(.);
+  } >KIRAM
+
+  .iram0.text :
+  {
+    /* Code marked as running out of IRAM */
+
+    _iram_text_start = ABSOLUTE(.);
+    *(.iram1 .iram1.*)
+    *librtc.a:(.literal .text .literal.* .text.*)
+    *libkarch.a:esp32s3_spiflash.*(.literal .text .literal.* .text.*)
+    *libkarch.a:xtensa_cpupause.*(.literal .text .literal.* .text.*)
+    *libkarch.a:xtensa_copystate.*(.literal .text .literal.* .text.*)
+    *libkarch.a:xtensa_interruptcontext.*(.literal .text .literal.* .text.*)
+    *libkarch.a:xtensa_testset.*(.literal .text .literal.* .text.*)
+
+    *libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*)
+    *libsched.a:sched_note.*(.literal .text .literal.* .text.*)
+    *libsched.a:sched_thistask.*(.literal .text .literal.* .text.*)
+    *libsched.a:spinlock.*(.literal .text .literal.* .text.*)
+    *libsched.a:irq_csection.*(.literal .text .literal.* .text.*)
+    *libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*)
+
+    /* align + add 16B for CPU dummy speculative instr. fetch */
+
+    . = ALIGN(4) + 16;
+
+    _iram_text_end = ABSOLUTE(.);
+
+    _iram_end = ABSOLUTE(.);
+  } >KIRAM
+
+  .dram0.dummy (NOLOAD) :
+  {
+    /* 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(KDRAM) + MAX(_iram_end, _diram_i_start) - _diram_i_start;
+  } >KDRAM
+
+  /* Shared RAM */
+
+  .dram0.bss (NOLOAD) :
+  {
+    /* .bss initialized on power-up */
+
+    . = ALIGN (8);
+    _sbss = ABSOLUTE(.);
+    *(.dynsbss)
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+    *(.sbss2)
+    *(.sbss2.*)
+    *(.gnu.linkonce.sb2.*)
+    *(.dynbss)
+    *(.bss)
+    *(.bss.*)
+    *(.share.mem)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+    *libkarch.a:esp32s3_spiflash.*(.bss  .bss.*  COMMON)
+    *libkarch.a:xtensa_cpupause.*(.bss  .bss.*  COMMON)
+    *libkarch.a:xtensa_copystate.*(.bss  .bss.*  COMMON)
+    *libkarch.a:xtensa_interruptcontext.*(.bss  .bss.*  COMMON)
+    *libkarch.a:xtensa_testset.*(.bss  .bss.*  COMMON)
+
+    *libsched.a:sched_suspendscheduler.*(.bss  .bss.*  COMMON)
+    *libsched.a:sched_thistask.*(.bss  .bss.*  COMMON)
+    *libsched.a:sched_note.*(.bss  .bss.*  COMMON)
+    *libsched.a:spinlock.*(.bss  .bss.*  COMMON)
+    *libsched.a:irq_csection.*(.bss  .bss.*  COMMON)
+    *libsched.a:irq_dispatch.*(.bss  .bss.*  COMMON)
+
+    . = ALIGN(8);
+    _ebss = ABSOLUTE(.);
+  } >KDRAM
+
+  .noinit (NOLOAD):
+  {
+    /* This section contains data that is not initialized during load,
+     * or during the application's initialization sequence.
+     */
+
+    *(.noinit)
+    *(.noinit.*)
+  } >KDRAM
+
+  .dram0.data :
+  {
+    /* .data initialized on power-up in ROMed configurations. */
+
+    _sdata = ABSOLUTE(.);
+    KEEP (*(.data))
+    KEEP (*(.data.*))
+    KEEP (*(.gnu.linkonce.d.*))
+    KEEP (*(.data1))
+    KEEP (*(.sdata))
+    KEEP (*(.sdata.*))
+    KEEP (*(.gnu.linkonce.s.*))
+    KEEP (*(.sdata2))
+    KEEP (*(.sdata2.*))
+    KEEP (*(.gnu.linkonce.s2.*))
+    KEEP (*(.jcr))
+    *(.dram1 .dram1.*)
+    *libphy.a:(.rodata  .rodata.*)
+    *libkarch.a:esp32s3_spiflash.*(.rodata  .rodata.*)
+    *libkarch.a:xtensa_cpupause.*(.rodata  .rodata.*)
+    *libkarch.a:xtensa_copystate.*(.rodata  .rodata.*)
+    *libkarch.a:xtensa_interruptcontext.*(.rodata  .rodata.*)
+    *libkarch.a:xtensa_testset.*(.rodata  .rodata.*)
+
+    *libsched.a:sched_suspendscheduler.*(.rodata  .rodata.*)
+    *libsched.a:sched_thistask.*(.rodata  .rodata.*)
+    *libsched.a:sched_note.*(.rodata  .rodata.*)
+    *libsched.a:spinlock.*(.rodata  .rodata.*)
+    *libsched.a:irq_csection.*(.rodata  .rodata.*)
+    *libsched.a:irq_dispatch.*(.rodata  .rodata.*)
+
+    . = ALIGN(4);
+    _edata = ABSOLUTE(.);
+
+    /* Heap starts at the end of .data */
+
+    _sheap = ABSOLUTE(.);
+  } >KDRAM
+
+  .flash.text :
+  {
+    _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;
+
+    _etext = .;
+  } >KIROM
+
+  .flash_rodata_dummy (NOLOAD) :
+  {
+    /* This dummy section represents the .flash.text section but in 
default_rodata_seg.
+     * Thus, it must have its alignment and (at least) its size.
+     */
+
+    /* Start at the same alignment constraint than .flash.text */
+
+    . = ALIGN(ALIGNOF(.flash.text));
+
+    /* Create an empty gap as big as .flash.text section */
+
+    . = SIZEOF(.flash.text);
+
+    /* Prepare the alignment of the section above. Few bytes (0x20) must be
+     * added for the mapping header.
+     */
+
+    . = ALIGN(0x10000) + 0x20;
+    _rodata_reserved_start = .;
+  } >KDROM
+
+  .flash.rodata : ALIGN(0x10)
+  {
+    _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)
+
+    . = ALIGN(4);
+
+    /* 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. */
+
+    _lit4_start = ABSOLUTE(.);
+    *(*.lit4)
+    *(.lit4.*)
+    *(.gnu.linkonce.lit4.*)
+    _lit4_end = ABSOLUTE(.);
+    _rodata_reserved_end = ABSOLUTE(.);
+    . = ALIGN(4);
+  } >KDROM
+}
diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld 
b/boards/xtensa/esp32s3/common/scripts/protected_memory.ld
similarity index 55%
rename from boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld
rename to boards/xtensa/esp32s3/common/scripts/protected_memory.ld
index ecf26a8a84..7dc58edc18 100644
--- a/boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld
+++ b/boards/xtensa/esp32s3/common/scripts/protected_memory.ld
@@ -1,11 +1,11 @@
 /****************************************************************************
- * boards/xtensa/esp32s3/common/scripts/esp32s3_memory.ld
+ * boards/xtensa/esp32s3/common/scripts/protected_memory.ld
  * ESP32-S3 Linker Script Memory Layout
  *
  * This file describes the memory layout (memory blocks) as virtual
  * memory addresses.
  *
- * esp32s3_sections.ld contains output sections to link compiler output
+ * kernel-space.ld contains output sections to link compiler output
  * into these memory blocks.
  *
  ****************************************************************************/
@@ -51,66 +51,48 @@
 
 MEMORY
 {
+  metadata (RX) :   org = 0x0, len = 0x18
+  ROM (RX) :        org = 0x18, len = 0x100000
+
   /* 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.
+   * connected to the data port of the CPU and e.g. allow bytewise access.
    */
 
-  /* IRAM for CPU */
-
-  iram0_0_seg (RX) :                 org = SRAM_IRAM_ORG, len = SRAM_IRAM_SIZE
+  KIRAM (RWX) :     org = SRAM_IRAM_ORG, len = 48K
+  UIRAM (RWX) :     org = ORIGIN(KIRAM) + LENGTH(KIRAM), len = 64K
 
   /* Flash mapped instruction data. */
 
-  /* The 0x20 offset is a convenience for the app binary image generation.
+  /* The 0x20 offset for the KIROM region is a convenience for the Kernel
+   * binary image generation in Espressif Application Image format.
    * 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).
    */
 
-  irom0_0_seg (RX) :                 org = 0x42000020, len = FLASH_SIZE - 0x20
+  KIROM (RX) :      org = 0x42000020, len = 0x80000 - 0x20
+  UIROM (RX) :      org = 0x42080000, len = 0x180000
 
-  /* Shared data RAM, excluding memory reserved for bootloader and ROM
-   * bss/data/stack.
-   */
+  /* Shared data RAM, excluding memory reserved for ROM bss/data/stack. */
 
-  dram0_0_seg (RW) :                 org = SRAM_DRAM_ORG, len = I_D_SRAM_SIZE
+  KDRAM (RW) :      org = SRAM_DRAM_ORG + 0x18000, len = 64K
+  UDRAM (RW) :      org = ORIGIN(KDRAM) + LENGTH(KDRAM), len = 192K
 
   /* Flash mapped constant data */
 
-  /* 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).
+  /* See KIROM region documentation above for the meaning of the 0x20 offset.
+   *
+   * The 0x18 offset for the UDROM region is a convenience for the User
+   * binary image generation following a custom image format, which defines
+   * a "metadata" output section containing some information that the Kernel
+   * needs for properly configuring the External Flash MMU when loading the
+   * User application image.
    */
 
-  drom0_0_seg (R) :                  org = 0x3c000020, len = FLASH_SIZE - 0x20
-
-  /* RTC fast memory (executable). Persists over deep sleep. */
-
-  rtc_iram_seg(RWX) :                org = 0x600fe000, len = 0x2000
-
-  /* RTC fast memory (same block as above), viewed from data bus */
-
-  rtc_data_seg(RW)  :                org = 0x600fe000, len = 0x2000
-
-  /* RTC slow memory (data accessible). Persists over deep sleep.
-   * Start of RTC slow memory is reserved for ULP co-processor code + data,
-   * if enabled.
-   */
-
-  rtc_slow_seg(RW)  :    org = 0x50000000 + 
CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM,
-                         len = 0x2000 - CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM
+  KDROM (R)  :      org = 0x3c000020, len = 0x80000 - 0x20
+  UDROM (R)  :      org = 0x3c080018, len = 0x180000 - 0x18
 }
 
-#ifdef CONFIG_ESP32S3_RUN_IRAM
-  REGION_ALIAS("default_rodata_seg", dram0_0_seg);
-  REGION_ALIAS("default_code_seg", iram0_0_seg);
-#else
-  REGION_ALIAS("default_rodata_seg", drom0_0_seg);
-  REGION_ALIAS("default_code_seg", irom0_0_seg);
-#endif /* CONFIG_ESP32S3_RUN_IRAM */
-
diff --git a/boards/xtensa/esp32s3/common/scripts/user-space.ld 
b/boards/xtensa/esp32s3/common/scripts/user-space.ld
new file mode 100644
index 0000000000..c39d191e11
--- /dev/null
+++ b/boards/xtensa/esp32s3/common/scripts/user-space.ld
@@ -0,0 +1,231 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/common/scripts/user-space.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.
+ *
+ ****************************************************************************/
+
+SECTIONS
+{
+  .metadata :
+  {
+    /* DROM metadata:
+     * - Destination address (VMA) for DROM region
+     * - Flash offset (LMA) for start of DROM region
+     * - Size of DROM region
+     */
+
+    LONG(ADDR(.userspace))
+    LONG(LOADADDR(.userspace))
+    LONG(SIZEOF(.userspace) + SIZEOF(.rodata))
+
+    /* IROM metadata:
+     * - Destination address (VMA) for IROM region
+     * - Flash offset (LMA) for start of IROM region
+     * - Size of IROM region
+     */
+
+    LONG(ADDR(.text))
+    LONG(LOADADDR(.text))
+    LONG(SIZEOF(.text))
+  } >metadata
+
+  /* section info */
+
+  __ld_uirom_start = ORIGIN(UIROM);
+  __ld_uirom_size = LENGTH(UIROM);
+  __ld_uirom_end = ORIGIN(UIROM) + LENGTH(UIROM);
+  __ld_udrom_start = ORIGIN(UDROM);
+  __ld_udrom_size = LENGTH(UDROM);
+  __ld_udrom_end = ORIGIN(UDROM) + LENGTH(UDROM);
+  __ld_uiram_start = ORIGIN(UIRAM);
+  __ld_uiram_size = LENGTH(UIRAM);
+  __ld_uiram_end = ORIGIN(UIRAM) + LENGTH(UIRAM);
+  __ld_udram_start = ORIGIN(UDRAM);
+  __ld_udram_size = LENGTH(UDRAM);
+  __ld_udram_end = ORIGIN(UDRAM) + LENGTH(UDRAM);
+
+  _eronly = LOADADDR(.data);
+
+  .userspace :
+  {
+    *(.userspace)
+  } >UDROM AT>ROM
+
+  /* Output sections for the Userspace image are given standard names, so
+   * instead of the Espressif-usual ".flash.text" we name it as ".text".
+   * The motivation is to ease debugging with GDB when loading symbols from
+   * both Kernel and User images since GDB's "add-symbol-file" command
+   * expects to find a .text section at the provided offset.
+   */
+
+  .rodata :
+  {
+    . = ALIGN(4);
+    _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)
+
+    . = (. + 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);
+  } >UDROM AT>ROM
+
+  .iram0.text :
+  {
+    _iram_start = ABSOLUTE(.);
+
+    *(.iram1)
+    *(.iram1.*)
+
+    _iram_end = ABSOLUTE(.);
+  } >UIRAM AT>ROM
+
+  /* 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.
+   */
+
+  .dram0.dummy (NOLOAD):
+  {
+    . = ORIGIN(UDRAM) + _iram_end - _iram_start;
+  } >UDRAM
+
+  /* Shared RAM */
+
+  .bss (NOLOAD) :
+  {
+    /* .bss initialized on power-up */
+
+    . = ALIGN (8);
+    _sbss = ABSOLUTE(.);
+
+    *(.dynsbss)
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+    *(.sbss2)
+    *(.sbss2.*)
+    *(.gnu.linkonce.sb2.*)
+    *(.dynbss)
+    KEEP (*(.bss))
+    *(.bss.*)
+    *(.share.mem)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN(8);
+
+    _ebss = ABSOLUTE(.);
+  } >UDRAM
+
+  .noinit (NOLOAD):
+  {
+    /* This section contains data that is not initialized during load,
+     * or during the application's initialization sequence.
+     */
+
+    . = ALIGN(8);
+    *(.noinit)
+    *(.noinit.*)
+    . = ALIGN(8);
+  } >UDRAM
+
+  .data :
+  {
+    _sdata = ABSOLUTE(.);
+    KEEP (*(.data))
+    KEEP (*(.data.*))
+    KEEP (*(.gnu.linkonce.d.*))
+    KEEP (*(.data1))
+    KEEP (*(.sdata))
+    KEEP (*(.sdata.*))
+    KEEP (*(.gnu.linkonce.s.*))
+    KEEP (*(.sdata2))
+    KEEP (*(.sdata2.*))
+    KEEP (*(.gnu.linkonce.s2.*))
+    KEEP (*(.jcr))
+    *(.dram1 .dram1.*)
+    _edata = ABSOLUTE(.);
+    . = ALIGN(4);
+
+    /* Heap starts at the end of .data */
+
+    _sheap = ABSOLUTE(.);
+  } >UDRAM AT>ROM
+
+  .flash_text_dummy (NOLOAD) : ALIGN(0x00010000)
+  {
+    . = SIZEOF(.userspace) + SIZEOF(.rodata);
+  } >UIROM
+
+  .text : ALIGN(0x00010000)
+  {
+    _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)
+    . = ALIGN(4);
+
+    _etext = .;
+  } >UIROM AT>ROM
+}
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/knsh/defconfig 
b/boards/xtensa/esp32s3/esp32s3-devkit/configs/knsh/defconfig
new file mode 100644
index 0000000000..2fc6f11c44
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/knsh/defconfig
@@ -0,0 +1,55 @@
+#
+# 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="esp32s3-devkit"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32S3_DEVKIT=y
+CONFIG_ARCH_CHIP="esp32s3"
+CONFIG_ARCH_CHIP_ESP32S3=y
+CONFIG_ARCH_CHIP_ESP32S3WROOM1=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_USE_MPU=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILD_PROTECTED=y
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_ESP32S3_UART0=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+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_NUTTX_USERSPACE=0x3c080018
+CONFIG_PASS1_BUILDIR="boards/xtensa/esp32s3/common/kernel"
+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_STACK_COLORATION=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_TESTING_GETPRIME=y
+CONFIG_TESTING_OSTEST=y
+CONFIG_TESTING_OSTEST_FPUTESTDISABLE=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.h 
b/boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.h
new file mode 100644
index 0000000000..6569e936c2
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/esp32s3-devkit/include/board_memorymap.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 __BOARDS_XTENSA_ESP32S3_ESP32S3_DEVKIT_INCLUDE_BOARD_MEMORYMAP_H
+#define __BOARDS_XTENSA_ESP32S3_ESP32S3_DEVKIT_INCLUDE_BOARD_MEMORYMAP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Kernel ROM */
+
+#define KIROM_START     (uintptr_t)__kirom_start
+#define KIROM_SIZE      (uintptr_t)__kirom_size
+#define KDROM_START     (uintptr_t)__kdrom_start
+#define KDROM_SIZE      (uintptr_t)__kdrom_size
+
+/* Kernel RAM */
+
+#define KIRAM_START     (uintptr_t)__kiram_start
+#define KIRAM_SIZE      (uintptr_t)__kiram_size
+#define KIRAM_END       (uintptr_t)__kiram_end
+#define KDRAM_START     (uintptr_t)__kdram_start
+#define KDRAM_SIZE      (uintptr_t)__kdram_size
+#define KDRAM_END       (uintptr_t)__kdram_end
+
+/* Exception vectors */
+
+#define VECTORS_START   (uintptr_t)__vectors_start
+#define VECTORS_END     (uintptr_t)__vectors_end
+
+/* User ROM */
+
+#define UIROM_START     (uintptr_t)__uirom_start
+#define UIROM_SIZE      (uintptr_t)__uirom_size
+#define UIROM_END       (uintptr_t)__uirom_end
+#define UDROM_START     (uintptr_t)__udrom_start
+#define UDROM_SIZE      (uintptr_t)__udrom_size
+#define UDROM_END       (uintptr_t)__udrom_end
+
+/* User RAM */
+
+#define UIRAM_START     (uintptr_t)__uiram_start
+#define UIRAM_SIZE      (uintptr_t)__uiram_size
+#define UIRAM_END       (uintptr_t)__uiram_end
+#define UDRAM_START     (uintptr_t)__udram_start
+#define UDRAM_SIZE      (uintptr_t)__udram_size
+#define UDRAM_END       (uintptr_t)__udram_end
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* Kernel ROM (RX)  */
+
+extern uint8_t          __kirom_start[];
+extern uint8_t          __kirom_size[];
+extern uint8_t          __kdrom_start[];
+extern uint8_t          __kdrom_size[];
+
+/* Kernel RAM (RW) */
+
+extern uint8_t          __kiram_start[];
+extern uint8_t          __kiram_size[];
+extern uint8_t          __kiram_end[];
+extern uint8_t          __kdram_start[];
+extern uint8_t          __kdram_size[];
+extern uint8_t          __kdram_end[];
+
+/* Exception vectors */
+
+extern uint8_t          __vectors_start[];
+extern uint8_t          __vectors_end[];
+
+/* User ROM (RX) */
+
+extern uint8_t          __uirom_start[];
+extern uint8_t          __uirom_size[];
+extern uint8_t          __uirom_end[];
+extern uint8_t          __udrom_start[];
+extern uint8_t          __udrom_size[];
+extern uint8_t          __udrom_end[];
+
+/* User RAM (RW) */
+
+extern uint8_t          __uiram_start[];
+extern uint8_t          __uiram_size[];
+extern uint8_t          __uiram_end[];
+extern uint8_t          __udram_start[];
+extern uint8_t          __udram_size[];
+extern uint8_t          __udram_end[];
+
+#endif /* __BOARDS_XTENSA_ESP32S3_ESP32S3_DEVKIT_INCLUDE_BOARD_MEMORYMAP_H */
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs 
b/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs
index 306fd42166..8f1b8c8342 100644
--- a/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/scripts/Make.defs
@@ -32,13 +32,21 @@ ARCHSCRIPT += 
$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_rom.ld
 ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld),)
   ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld
 else
-  ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld
+  ifeq ($(CONFIG_BUILD_PROTECTED),y)
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)protected_memory.ld
+  else
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)flat_memory.ld
+  endif
 endif
 
 ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld),)
   ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld
 else
-  ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld
+  ifeq ($(CONFIG_BUILD_PROTECTED),y)
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)kernel-space.ld
+  else
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld
+  endif
 endif
 
 ifneq ($(CONFIG_DEBUG_NOOPT),y)
diff --git a/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs 
b/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs
index ccb902b7f8..f2390049f8 100644
--- a/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs
+++ b/boards/xtensa/esp32s3/esp32s3-eye/scripts/Make.defs
@@ -32,13 +32,21 @@ ARCHSCRIPT += 
$(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_rom.ld
 ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld),)
   ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld
 else
-  ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_memory.ld
+  ifeq ($(CONFIG_BUILD_PROTECTED),y)
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)protected_memory.ld
+  else
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)flat_memory.ld
+  endif
 endif
 
 ifneq ($(wildcard $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld),)
   ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld
 else
-  ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld
+  ifeq ($(CONFIG_BUILD_PROTECTED),y)
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)kernel-space.ld
+  else
+    ARCHSCRIPT += $(BOARD_COMMON_DIR)$(DELIM)scripts$(DELIM)esp32s3_sections.ld
+  endif
 endif
 
 ifneq ($(CONFIG_DEBUG_NOOPT),y)
diff --git a/tools/esp32s3/Config.mk b/tools/esp32s3/Config.mk
index 94772247d1..26b876b5b1 100644
--- a/tools/esp32s3/Config.mk
+++ b/tools/esp32s3/Config.mk
@@ -80,6 +80,10 @@ endif
 
 ESPTOOL_BINS += $(FLASH_APP)
 
+ifeq ($(CONFIG_BUILD_PROTECTED),y)
+       ESPTOOL_BINS += $(CONFIG_ESP32S3_USER_IMAGE_OFFSET) nuttx_user.bin
+endif
+
 # MERGEBIN -- Merge raw binary files into a single file
 
 define MERGEBIN

Reply via email to