xtensa/esp32s3: Enable booting from MCUboot bootloader

Add support for booting from MCUboot bootloader on ESP32-S3.

Signed-off-by: Almir Okato <almir.okato@espressif.com>
This commit is contained in:
Almir Okato
2022-12-04 22:22:43 -03:00
committed by Xiang Xiao
parent d172d8cd0f
commit 8f3c425067
12 changed files with 744 additions and 6 deletions
@@ -55,3 +55,9 @@ nsh
Basic NuttShell configuration (console enabled in UART0, exposed via Basic NuttShell configuration (console enabled in UART0, exposed via
USB connection by means of CP2102 converter, at 115200 bps). USB connection by means of CP2102 converter, at 115200 bps).
mcuboot_nsh
---
Similar configuration as nsh, except that it enables booting from
MCUboot and the experimental features configuration.
+46 -2
View File
@@ -33,7 +33,7 @@ $(BOOTLOADER_SRCDIR):
# Helpers for creating the configuration file # Helpers for creating the configuration file
cfg_en = echo "$(1)=y"; cfg_en = echo "$(1)=$(if $(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),1,y)";
cfg_val = echo "$(1)=$(2)"; cfg_val = echo "$(1)=$(2)";
$(BOOTLOADER_CONFIG): $(TOPDIR)/.config $(BOOTLOADER_CONFIG): $(TOPDIR)/.config
@@ -51,7 +51,18 @@ $(BOOTLOADER_CONFIG): $(TOPDIR)/.config
$(if $(CONFIG_ESP32S3_FLASH_FREQ_40M),$(call cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_40M)) \ $(if $(CONFIG_ESP32S3_FLASH_FREQ_40M),$(call cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_40M)) \
$(if $(CONFIG_ESP32S3_FLASH_FREQ_20M),$(call cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_20M)) \ $(if $(CONFIG_ESP32S3_FLASH_FREQ_20M),$(call cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_20M)) \
} > $(BOOTLOADER_CONFIG) } > $(BOOTLOADER_CONFIG)
ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y) ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
$(Q) { \
$(call cfg_val,CONFIG_ESP_BOOTLOADER_OFFSET,0x0000) \
$(call cfg_val,CONFIG_ESP_BOOTLOADER_SIZE,0xF000) \
$(call cfg_val,CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS,$(CONFIG_ESP32S3_OTA_PRIMARY_SLOT_OFFSET)) \
$(call cfg_val,CONFIG_ESP_APPLICATION_SIZE,$(CONFIG_ESP32S3_OTA_SLOT_SIZE)) \
$(call cfg_val,CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS,$(CONFIG_ESP32S3_OTA_SECONDARY_SLOT_OFFSET)) \
$(call cfg_en,CONFIG_ESP_MCUBOOT_WDT_ENABLE) \
$(call cfg_val,CONFIG_ESP_SCRATCH_OFFSET,$(CONFIG_ESP32S3_OTA_SCRATCH_OFFSET)) \
$(call cfg_val,CONFIG_ESP_SCRATCH_SIZE,$(CONFIG_ESP32S3_OTA_SCRATCH_SIZE)) \
} >> $(BOOTLOADER_CONFIG)
else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y)
$(Q) { \ $(Q) { \
$(call cfg_en,CONFIG_PARTITION_TABLE_CUSTOM) \ $(call cfg_en,CONFIG_PARTITION_TABLE_CUSTOM) \
$(call cfg_val,CONFIG_PARTITION_TABLE_CUSTOM_FILENAME,\"partitions.csv\") \ $(call cfg_val,CONFIG_PARTITION_TABLE_CUSTOM_FILENAME,\"partitions.csv\") \
@@ -59,6 +70,24 @@ ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y)
} >> $(BOOTLOADER_CONFIG) } >> $(BOOTLOADER_CONFIG)
endif endif
ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
BOOTLOADER_BIN = $(TOPDIR)/mcuboot-esp32s3.bin
$(BOOTLOADER_BIN): $(BOOTLOADER_CONFIG)
$(Q) echo "Building Bootloader"
$(Q) $(BOOTLOADER_SRCDIR)/build_mcuboot.sh -c esp32s3 -s -f $(BOOTLOADER_CONFIG)
$(call COPYFILE, $(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/mcuboot-esp32s3.bin, $(TOPDIR))
bootloader: $(BOOTLOADER_CONFIG) $(BOOTLOADER_SRCDIR) $(BOOTLOADER_BIN)
clean_bootloader:
$(call DELDIR,$(BOOTLOADER_SRCDIR))
$(call DELFILE,$(BOOTLOADER_CONFIG))
$(call DELFILE,$(BOOTLOADER_BIN))
else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y)
bootloader: $(BOOTLOADER_SRCDIR) $(BOOTLOADER_CONFIG) bootloader: $(BOOTLOADER_SRCDIR) $(BOOTLOADER_CONFIG)
$(Q) echo "Building Bootloader binaries" $(Q) echo "Building Bootloader binaries"
$(Q) $(BOOTLOADER_SRCDIR)/build_idfboot.sh -c esp32s3 -s -f $(BOOTLOADER_CONFIG) $(Q) $(BOOTLOADER_SRCDIR)/build_idfboot.sh -c esp32s3 -s -f $(BOOTLOADER_CONFIG)
@@ -71,11 +100,24 @@ clean_bootloader:
$(call DELFILE,$(TOPDIR)/bootloader-esp32s3.bin) $(call DELFILE,$(TOPDIR)/bootloader-esp32s3.bin)
$(call DELFILE,$(TOPDIR)/partition-table-esp32s3.bin) $(call DELFILE,$(TOPDIR)/partition-table-esp32s3.bin)
endif
else ifeq ($(CONFIG_ESP32S3_BOOTLOADER_DOWNLOAD_PREBUILT),y) else ifeq ($(CONFIG_ESP32S3_BOOTLOADER_DOWNLOAD_PREBUILT),y)
BOOTLOADER_VERSION = latest BOOTLOADER_VERSION = latest
BOOTLOADER_URL = https://github.com/espressif/esp-nuttx-bootloader/releases/download/$(BOOTLOADER_VERSION) BOOTLOADER_URL = https://github.com/espressif/esp-nuttx-bootloader/releases/download/$(BOOTLOADER_VERSION)
ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
bootloader:
$(Q) echo "Downloading Bootloader binaries"
$(Q) curl -L $(BOOTLOADER_URL)/mcuboot-esp32s3.bin -o $(TOPDIR)/mcuboot-esp32s3.bin
clean_bootloader:
$(call DELFILE,$(TOPDIR)/mcuboot-esp32s3.bin)
else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y)
bootloader: bootloader:
$(Q) echo "Downloading Bootloader binaries" $(Q) echo "Downloading Bootloader binaries"
$(Q) curl -L $(BOOTLOADER_URL)/bootloader-esp32s3.bin -o $(TOPDIR)/bootloader-esp32s3.bin $(Q) curl -L $(BOOTLOADER_URL)/bootloader-esp32s3.bin -o $(TOPDIR)/bootloader-esp32s3.bin
@@ -86,3 +128,5 @@ clean_bootloader:
$(call DELFILE,$(TOPDIR)/partition-table-esp32s3.bin) $(call DELFILE,$(TOPDIR)/partition-table-esp32s3.bin)
endif endif
endif
+84
View File
@@ -833,6 +833,48 @@ choice ESP32S3_FLASH_FREQ
endchoice # ESP32S3_FLASH_FREQ endchoice # ESP32S3_FLASH_FREQ
config ESP32S3_HAVE_OTA_PARTITION
bool
default n
if ESP32S3_HAVE_OTA_PARTITION
comment "Application Image OTA Update support"
config ESP32S3_OTA_PRIMARY_SLOT_OFFSET
hex "Application image primary slot offset"
default 0x10000
config ESP32S3_OTA_PRIMARY_SLOT_DEVPATH
string "Application image primary slot device path"
default "/dev/ota0"
config ESP32S3_OTA_SECONDARY_SLOT_OFFSET
hex "Application image secondary slot offset"
default 0x110000
config ESP32S3_OTA_SECONDARY_SLOT_DEVPATH
string "Application image secondary slot device path"
default "/dev/ota1"
config ESP32S3_OTA_SLOT_SIZE
hex "Application image slot size (in bytes)"
default 0x100000
config ESP32S3_OTA_SCRATCH_OFFSET
hex "Scratch partition offset"
default 0x210000
config ESP32S3_OTA_SCRATCH_SIZE
hex "Scratch partition size"
default 0x40000
config ESP32S3_OTA_SCRATCH_DEVPATH
string "Scratch partition device path"
default "/dev/otascratch"
endif
if ESP32S3_SPIFLASH if ESP32S3_SPIFLASH
comment "General storage MTD configuration" comment "General storage MTD configuration"
@@ -881,6 +923,18 @@ config ESP32S3_APP_FORMAT_LEGACY
This is the legacy application image format, as supported by the ESP-IDF This is the legacy application image format, as supported by the ESP-IDF
2nd stage bootloader. 2nd stage bootloader.
config ESP32S3_APP_FORMAT_MCUBOOT
bool "MCUboot-bootable format"
select ESP32S3_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 endchoice # Application Image Format
choice choice
@@ -907,6 +961,36 @@ config ESP32S3_BOOTLOADER_BUILD_FROM_SOURCE
endchoice endchoice
choice
prompt "Target slot for image flashing"
default ESP32S3_ESPTOOL_TARGET_PRIMARY
depends on ESP32S3_HAVE_OTA_PARTITION
---help---
Slot to which ESPTOOL will flash the generated binary image.
config ESP32S3_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 ESP32S3_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 ESP32S3_APP_MCUBOOT_HEADER_SIZE
int "Application image header size (in bytes)"
default 32
depends on ESP32S3_APP_FORMAT_MCUBOOT
config ESP32S3_PARTITION_TABLE_OFFSET config ESP32S3_PARTITION_TABLE_OFFSET
hex "Partition Table offset" hex "Partition Table offset"
default 0x8000 default 0x8000
+141
View File
@@ -44,6 +44,7 @@
#endif #endif
#include "hardware/esp32s3_cache_memory.h" #include "hardware/esp32s3_cache_memory.h"
#include "hardware/esp32s3_system.h" #include "hardware/esp32s3_system.h"
#include "hardware/esp32s3_extmem.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
@@ -55,20 +56,53 @@
# define showprogress(c) # define showprogress(c)
#endif #endif
#ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
#define PRIMARY_SLOT_OFFSET CONFIG_ESP32S3_OTA_PRIMARY_SLOT_OFFSET
#define HDR_ATTR locate_code(".entry_addr") used_code
/* Cache MMU address mask (MMU tables ignore bits which are zero) */
#define MMU_FLASH_MASK (~(MMU_PAGE_SIZE - 1))
#endif
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
extern uint8_t _image_irom_vma[];
extern uint8_t _image_irom_lma[];
extern uint8_t _image_irom_size[];
extern uint8_t _image_drom_vma[];
extern uint8_t _image_drom_lma[];
extern uint8_t _image_drom_size[];
#endif
/**************************************************************************** /****************************************************************************
* ROM Function Prototypes * ROM Function Prototypes
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
extern int ets_printf(const char *fmt, ...) printflike(1, 2);
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);
#endif
extern void rom_config_instruction_cache_mode(uint32_t cfg_cache_size, extern void rom_config_instruction_cache_mode(uint32_t cfg_cache_size,
uint8_t cfg_cache_ways, uint8_t cfg_cache_ways,
uint8_t cfg_cache_line_size); uint8_t cfg_cache_line_size);
extern void rom_config_data_cache_mode(uint32_t cfg_cache_size, extern void rom_config_data_cache_mode(uint32_t cfg_cache_size,
uint8_t cfg_cache_ways, uint8_t cfg_cache_ways,
uint8_t cfg_cache_line_size); uint8_t cfg_cache_line_size);
extern void cache_invalidate_dcache_all(void);
extern uint32_t cache_suspend_dcache(void); extern uint32_t cache_suspend_dcache(void);
extern void cache_resume_dcache(uint32_t val); extern void cache_resume_dcache(uint32_t val);
extern uint32_t cache_set_idrom_mmu_size(uint32_t irom_size, extern uint32_t cache_set_idrom_mmu_size(uint32_t irom_size,
@@ -88,10 +122,18 @@ extern int cache_occupy_addr(uint32_t addr, uint32_t size);
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
noreturn_function void __start(void);
#endif
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
HDR_ATTR static void (*_entry_point)(void) = __start;
#endif
/**************************************************************************** /****************************************************************************
* Public Data * Public Data
****************************************************************************/ ****************************************************************************/
@@ -332,6 +374,97 @@ void noreturn_function IRAM_ATTR __esp32s3_start(void)
for (; ; ); /* Should not return */ 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_ESP32S3_APP_FORMAT_MCUBOOT
static inline uint32_t calc_mmu_pages(uint32_t size, uint32_t vaddr)
{
return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_PAGE_SIZE - 1) /
MMU_PAGE_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_ESP32S3_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_dcache();
cache_invalidate_dcache_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_dbus_mmu_set(MMU_ACCESS_FLASH, drom_vma_aligned,
drom_lma_aligned, 64, 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);
rc = cache_ibus_mmu_set(MMU_ACCESS_FLASH, irom_vma_aligned,
irom_lma_aligned, 64, irom_page_count, 0);
regval = getreg32(EXTMEM_DCACHE_CTRL1_REG);
regval &= EXTMEM_DCACHE_SHUT_CORE0_BUS;
putreg32(regval, EXTMEM_DCACHE_CTRL1_REG);
cache_resume_dcache(autoload);
return (int)rc;
}
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -351,6 +484,14 @@ void noreturn_function IRAM_ATTR __esp32s3_start(void)
void IRAM_ATTR __start(void) void IRAM_ATTR __start(void)
{ {
#ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
if (map_rom_segments() != 0)
{
ets_printf("Failed to setup XIP, aborting\n");
while (true);
}
#endif
configure_cpu_caches(); configure_cpu_caches();
__esp32s3_start(); __esp32s3_start();
@@ -51,6 +51,21 @@
MEMORY MEMORY
{ {
#ifdef CONFIG_ESP32S3_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_ESP32S3_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_ESP32S3_APP_MCUBOOT_HEADER_SIZE, len = 0x20
ROM (RX) : org = ORIGIN(metadata) + LENGTH(metadata),
len = FLASH_SIZE - ORIGIN(ROM)
#endif
/* Below values assume the flash cache is on, and have the blocks this /* 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 * 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 * port' dram/drom regions map to the same iram/irom regions but are
@@ -63,6 +78,9 @@ MEMORY
/* Flash mapped instruction data. */ /* Flash mapped instruction data. */
#ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
irom0_0_seg (RX) : org = 0x42000000, len = FLASH_SIZE
#else
/* The 0x20 offset is a convenience for the app binary image generation. /* 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 * 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 * has a 0x18 byte file header, and each segment has a 0x08 byte segment
@@ -71,6 +89,7 @@ MEMORY
*/ */
irom0_0_seg (RX) : org = 0x42000020, len = FLASH_SIZE - 0x20 irom0_0_seg (RX) : org = 0x42000020, len = FLASH_SIZE - 0x20
#endif
/* Shared data RAM, excluding memory reserved for bootloader and ROM /* Shared data RAM, excluding memory reserved for bootloader and ROM
* bss/data/stack. * bss/data/stack.
@@ -80,6 +99,23 @@ MEMORY
/* Flash mapped constant data */ /* Flash mapped constant data */
#ifdef CONFIG_ESP32S3_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 = 0x3c000000 + ORIGIN(ROM),
len = FLASH_SIZE - ORIGIN(ROM)
#else
/* The 0x20 offset is a convenience for the app binary image generation. /* 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 * 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 * has a 0x18 byte file header, and each segment has a 0x08 byte segment
@@ -88,6 +124,7 @@ MEMORY
*/ */
drom0_0_seg (R) : org = 0x3c000020, len = FLASH_SIZE - 0x20 drom0_0_seg (R) : org = 0x3c000020, len = FLASH_SIZE - 0x20
#endif
/* RTC fast memory (executable). Persists over deep sleep. */ /* RTC fast memory (executable). Persists over deep sleep. */
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* boards/xtensa/esp32s3/common/scripts/esp32s3_sections.ld * boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
****************************************************************************/ ****************************************************************************/
/* Default entry point: */ /* Default entry point: */
@@ -0,0 +1,337 @@
/****************************************************************************
* boards/xtensa/esp32s3/common/scripts/mcuboot_sections.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: */
ENTRY(__start);
_diram_i_start = 0x40378000;
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 :
{
_rodata_reserved_start = .;
_srodata = ABSOLUTE(.);
*(EXCLUDE_FILE (esp32s3_start.*) .rodata)
*(EXCLUDE_FILE (esp32s3_start.*) .rodata.*)
*(.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);
} >drom0_0_seg AT>ROM
/* Send .iram0 code to iram */
.iram0.vectors :
{
_iram_start = ABSOLUTE(.);
/* Vectors go to IRAM. */
_init_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);
*(.entry.text)
*(.init.literal)
*(.init)
} >iram0_0_seg AT>ROM
.iram0.text :
{
/* Code marked as running out of IRAM */
*(.iram1 .iram1.*)
esp32s3_start.*(.literal .text .literal.* .text.*)
/* align + add 16B for CPU dummy speculative instr. fetch */
. = ALIGN(4) + 16;
_iram_text = ABSOLUTE(.);
} >iram0_0_seg
.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(dram0_0_seg) + MAX(_iram_end, _diram_i_start) - _diram_i_start;
} >dram0_0_seg
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
/* .bss initialized on power-up */
. = ALIGN(8);
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
*(COMMON)
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.share.mem)
*(.gnu.linkonce.b.*)
. = ALIGN(8);
_ebss = ABSOLUTE(.);
} >dram0_0_seg
.noinit (NOLOAD) :
{
/* This section contains data that is not initialized during load,
* or during the application's initialization sequence.
*/
. = ALIGN(4);
*(.noinit .noinit.*)
. = ALIGN(4);
} >dram0_0_seg
.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.*)
esp32s3_start.*(.rodata .rodata.*)
_edata = ABSOLUTE(.);
. = ALIGN(4);
/* Heap starts at the end of .data */
_sheap = ABSOLUTE(.);
} >dram0_0_seg AT>ROM
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* ESP32-S3 memprot requires 16B padding for possible CPU prefetch and
* 256B alignment for PMS split lines.
*/
. += 16;
. = ALIGN(256);
_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
* 0x00010000 (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(0x00010000)
{
/* 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.
*/
. = SIZEOF(.flash.rodata);
} >irom0_0_seg
.flash.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)
/* 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 = .;
} >irom0_0_seg AT>ROM
.rtc.text :
{
. = ALIGN(4);
*(.rtc.literal .rtc.text)
} >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_data_seg AT>ROM
}
+2 -1
View File
@@ -7,7 +7,8 @@ if ARCH_BOARD_ESP32S3_DEVKIT
config ESP32S3_STORAGE_MTD_OFFSET config ESP32S3_STORAGE_MTD_OFFSET
hex "Storage MTD base address in SPI Flash" hex "Storage MTD base address in SPI Flash"
default 0x180000 default 0x180000 if !ESP32S3_HAVE_OTA_PARTITION
default 0x250000 if ESP32S3_HAVE_OTA_PARTITION
depends on ESP32S3_MTD depends on ESP32S3_MTD
---help--- ---help---
MTD base address in SPI Flash. MTD base address in SPI Flash.
@@ -0,0 +1,48 @@
#
# 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_XTENSA=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_ESP32S3_APP_FORMAT_MCUBOOT=y
CONFIG_ESP32S3_SPIFLASH=y
CONFIG_ESP32S3_UART0=y
CONFIG_EXPERIMENTAL=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_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_SYSTEM_NSH=y
CONFIG_UART0_SERIAL_CONSOLE=y
@@ -34,7 +34,11 @@ ifeq ($(CONFIG_BUILD_PROTECTED),y)
ARCHSCRIPT += $(call FINDSCRIPT,kernel-space.ld) ARCHSCRIPT += $(call FINDSCRIPT,kernel-space.ld)
else else
ARCHSCRIPT += $(call FINDSCRIPT,flat_memory.ld) ARCHSCRIPT += $(call FINDSCRIPT,flat_memory.ld)
ARCHSCRIPT += $(call FINDSCRIPT,esp32s3_sections.ld) ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
ARCHSCRIPT += $(call FINDSCRIPT,mcuboot_sections.ld)
else
ARCHSCRIPT += $(call FINDSCRIPT,legacy_sections.ld)
endif
endif endif
ifneq ($(CONFIG_DEBUG_NOOPT),y) ifneq ($(CONFIG_DEBUG_NOOPT),y)
@@ -34,7 +34,7 @@ ifeq ($(CONFIG_BUILD_PROTECTED),y)
ARCHSCRIPT += $(call FINDSCRIPT,kernel-space.ld) ARCHSCRIPT += $(call FINDSCRIPT,kernel-space.ld)
else else
ARCHSCRIPT += $(call FINDSCRIPT,flat_memory.ld) ARCHSCRIPT += $(call FINDSCRIPT,flat_memory.ld)
ARCHSCRIPT += $(call FINDSCRIPT,esp32s3_sections.ld) ARCHSCRIPT += $(call FINDSCRIPT,legacy_sections.ld)
endif endif
ifneq ($(CONFIG_DEBUG_NOOPT),y) ifneq ($(CONFIG_DEBUG_NOOPT),y)
+36
View File
@@ -69,6 +69,11 @@ ifdef ESPTOOL_BINDIR
FLASH_BL := $(BL_OFFSET) $(BOOTLOADER) FLASH_BL := $(BL_OFFSET) $(BOOTLOADER)
FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE) FLASH_PT := $(PT_OFFSET) $(PARTITION_TABLE)
ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT) ESPTOOL_BINS := $(FLASH_BL) $(FLASH_PT)
else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
BL_OFFSET := 0x0000
BOOTLOADER := $(ESPTOOL_BINDIR)/mcuboot-esp32s3.bin
FLASH_BL := $(BL_OFFSET) $(BOOTLOADER)
ESPTOOL_BINS := $(FLASH_BL)
endif endif
endif endif
@@ -76,6 +81,21 @@ ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y)
APP_OFFSET := 0x10000 APP_OFFSET := 0x10000
APP_IMAGE := nuttx.bin APP_IMAGE := nuttx.bin
FLASH_APP := $(APP_OFFSET) $(APP_IMAGE) FLASH_APP := $(APP_OFFSET) $(APP_IMAGE)
else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
ifeq ($(CONFIG_ESP32S3_ESPTOOL_TARGET_PRIMARY),y)
VERIFIED := --confirm
APP_OFFSET := $(CONFIG_ESP32S3_OTA_PRIMARY_SLOT_OFFSET)
else ifeq ($(CONFIG_ESP32S3_ESPTOOL_TARGET_SECONDARY),y)
VERIFIED :=
APP_OFFSET := $(CONFIG_ESP32S3_OTA_SECONDARY_SLOT_OFFSET)
endif
APP_IMAGE := nuttx.bin
FLASH_APP := $(APP_OFFSET) $(APP_IMAGE)
IMGTOOL_ALIGN_ARGS := --align 4
IMGTOOL_SIGN_ARGS := --pad $(VERIFIED) $(IMGTOOL_ALIGN_ARGS) -v 0 -s auto \
-H $(CONFIG_ESP32S3_APP_MCUBOOT_HEADER_SIZE) --pad-header \
-S $(CONFIG_ESP32S3_OTA_SLOT_SIZE)
endif endif
ESPTOOL_BINS += $(FLASH_APP) ESPTOOL_BINS += $(FLASH_APP)
@@ -103,6 +123,7 @@ endef
# MKIMAGE -- Convert an ELF file into a compatible binary file # MKIMAGE -- Convert an ELF file into a compatible binary file
ifeq ($(CONFIG_ESP32S3_APP_FORMAT_LEGACY),y)
define MKIMAGE define MKIMAGE
$(Q) echo "MKIMAGE: ESP32-S3 binary" $(Q) echo "MKIMAGE: ESP32-S3 binary"
$(Q) if ! esptool.py version 1>/dev/null 2>&1; then \ $(Q) if ! esptool.py version 1>/dev/null 2>&1; then \
@@ -120,6 +141,21 @@ define MKIMAGE
$(Q) echo nuttx.bin >> nuttx.manifest $(Q) echo nuttx.bin >> nuttx.manifest
$(Q) echo "Generated: nuttx.bin (ESP32-S3 compatible)" $(Q) echo "Generated: nuttx.bin (ESP32-S3 compatible)"
endef endef
else ifeq ($(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT),y)
define MKIMAGE
$(Q) echo "MKIMAGE: ESP32-S3 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.bin image."; \
exit 1; \
fi
imgtool sign $(IMGTOOL_SIGN_ARGS) nuttx.hex nuttx.bin
$(Q) echo nuttx.bin >> nuttx.manifest
$(Q) echo "Generated: nuttx.bin (MCUboot compatible)"
endef
endif
# POSTBUILD -- Perform post build operations # POSTBUILD -- Perform post build operations