From 1d757fe5fd58a3e171ffa72260c9cb8c262dab65 Mon Sep 17 00:00:00 2001 From: dachalco Date: Mon, 22 Nov 2021 11:43:13 -0800 Subject: [PATCH] support idf app building for mcuboot images --- components/esp32/CMakeLists.txt | 20 +- components/esp32/ld/esp32.mcuboot.ld | 152 ++++++ .../esp32/ld/esp32.mcuboot.project.ld.in | 515 ++++++++++++++++++ components/esptool_py/project_include.cmake | 18 +- tools/idf_py_actions/core_ext.py | 6 + tools/idf_py_actions/tools.py | 4 + 6 files changed, 709 insertions(+), 6 deletions(-) create mode 100644 components/esp32/ld/esp32.mcuboot.ld create mode 100644 components/esp32/ld/esp32.mcuboot.project.ld.in diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index b805a5c539..4548a4473a 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -44,8 +44,19 @@ else() # Process the template file through the linker script generation mechanism, and use the output for linking the # final binary - target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" - PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/esp32.project.ld") + set(LD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ld) + if( MCUBOOT_IMAGE ) + message( STATUS "Formatting application image for esp-mcuboot" ) + target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.mcuboot.project.ld.in" + PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/esp32.project.ld") + + set( ESP32_LD ${LD_DIR}/esp32.mcuboot.ld) + else() + target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" + PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/esp32.project.ld") + + set( ESP32_LD ${LD_DIR}/esp32.ld) + endif() target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.peripherals.ld") target_link_libraries(${COMPONENT_LIB} PUBLIC gcc) @@ -53,11 +64,10 @@ else() idf_build_get_property(config_dir CONFIG_DIR) # Preprocess esp32.ld linker script to include configuration, becomes esp32_out.ld - set(LD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ld) add_custom_command( OUTPUT esp32_out.ld - COMMAND "${CMAKE_C_COMPILER}" -C -P -x c -E -o esp32_out.ld -I ${config_dir} ${LD_DIR}/esp32.ld - MAIN_DEPENDENCY ${LD_DIR}/esp32.ld ${sdkconfig_header} + COMMAND "${CMAKE_C_COMPILER}" -C -P -x c -E -o esp32_out.ld -I ${config_dir} ${ESP32_LD} + MAIN_DEPENDENCY ${ESP32_LD} ${sdkconfig_header} COMMENT "Generating linker script..." VERBATIM) diff --git a/components/esp32/ld/esp32.mcuboot.ld b/components/esp32/ld/esp32.mcuboot.ld new file mode 100644 index 0000000000..22f084d658 --- /dev/null +++ b/components/esp32/ld/esp32.mcuboot.ld @@ -0,0 +1,152 @@ +/* ESP32 Linker Script Memory Layout + + This file describes the memory layout (memory blocks) as virtual + memory addresses. + + esp32.project.ld contains output sections to link compiler output + into these memory blocks. + + *** + + This linker script is passed through the C preprocessor to include + configuration options. + + Please use preprocessor features sparingly! Restrict + to simple macros with numeric values, and/or #if/#endif blocks. +*/ +#include "sdkconfig.h" + +/* If BT is not built at all */ +#ifndef CONFIG_BT_RESERVE_DRAM +#define CONFIG_BT_RESERVE_DRAM 0 +#endif + +#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC +#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE + CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE) +#elif defined(CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP) +#define ESP_BOOTLOADER_RESERVE_RTC (CONFIG_BOOTLOADER_RESERVE_RTC_SIZE) +#else +#define ESP_BOOTLOADER_RESERVE_RTC 0 +#endif + +#if defined(CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE) + +ASSERT((CONFIG_ESP32_FIXED_STATIC_RAM_SIZE <= 0x2c200), + "Fixed static ram data does not fit.") + +#define DRAM0_0_SEG_LEN CONFIG_ESP32_FIXED_STATIC_RAM_SIZE + +#else +#define DRAM0_0_SEG_LEN 0x2c200 +#endif + +#ifdef CONFIG_FLASH_SIZE + #define ROM_SIZE CONFIG_FLASH_SIZE +#else + #define ROM_SIZE 0x400000 +#endif + + +MEMORY +{ + /* Segment for mcuboot image header */ + mcuboot_hdr (RX) : org = 0x0, len = 0x20 + + /* Segment for esp-mcuboot loader */ + loader_hdr (RX) : org = 0x20, len = 0x20 + + /* We will be loading mcuboot image from flash, while it's prepended with required headers for mcuboot + loader */ + ROM (RX) : org = 0x40, len = ROM_SIZE - 0x40 + + /* All these 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. */ + + /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */ + iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 + +#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS + /* Even though the segment name is iram, it is actually mapped to flash + */ + iram0_2_seg (RX) : org = 0x400D0000, len = 0x330000 + + /* + (0x20 offset above 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).) + */ +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + + + /* Shared data RAM, excluding memory reserved for ROM bss/data/stack. + + Enabling Bluetooth & Trace Memory features in menuconfig will decrease + the amount of RAM available. + + Note: Length of this section *should* be 0x50000, and this extra DRAM is available + in heap at runtime. However due to static ROM memory usage at this 176KB mark, the + additional static memory temporarily cannot be used. + */ + dram0_0_seg (RW) : org = 0x3FFB0000 + CONFIG_BT_RESERVE_DRAM, + len = DRAM0_0_SEG_LEN - CONFIG_BT_RESERVE_DRAM + +#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS + /* Flash mapped constant data */ + drom0_0_seg (R) : org = 0x3F400000, len = 0x400000 + + /* (See iram0_2_seg for meaning of 0x20 offset in the above.) */ +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + + /* RTC fast memory (executable). Persists over deep sleep. + */ + rtc_iram_seg(RWX) : org = 0x400C0000, len = 0x2000 + + /* RTC fast memory (same block as above), viewed from data bus */ + rtc_data_seg(RW) : org = 0x3ff80000, len = 0x2000 - ESP_BOOTLOADER_RESERVE_RTC + + /* 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_ESP32_ULP_COPROC_RESERVE_MEM, + len = 0x2000 - CONFIG_ESP32_ULP_COPROC_RESERVE_MEM + + /* external memory ,including data and text */ + extern_ram_seg(RWX) : org = 0x3F800000, + len = 0x400000 +} + +#if defined(CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE) +/* static data ends at defined address */ +_static_data_end = 0x3FFB0000 + DRAM0_0_SEG_LEN; +#else +_static_data_end = _bss_end; +#endif + +/* Heap ends at top of dram0_0_seg */ +_heap_end = 0x40000000 - CONFIG_ESP32_TRACEMEM_RESERVE_DRAM; + +_data_seg_org = ORIGIN(rtc_data_seg); + +/* The lines below define location alias for .rtc.data section based on Kconfig option. + When the option is not defined then use slow memory segment + else the data will be placed in fast memory segment */ +#ifndef CONFIG_ESP32_RTCDATA_IN_FAST_MEM +REGION_ALIAS("rtc_data_location", rtc_slow_seg ); +#else +REGION_ALIAS("rtc_data_location", rtc_data_seg ); +#endif + +#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS + REGION_ALIAS("default_code_seg", iram0_2_seg); +#else + REGION_ALIAS("default_code_seg", iram0_0_seg); +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS + +#ifdef CONFIG_APP_BUILD_USE_FLASH_SECTIONS + REGION_ALIAS("default_rodata_seg", drom0_0_seg); +#else + REGION_ALIAS("default_rodata_seg", dram0_0_seg); +#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS diff --git a/components/esp32/ld/esp32.mcuboot.project.ld.in b/components/esp32/ld/esp32.mcuboot.project.ld.in new file mode 100644 index 0000000000..cc7166876b --- /dev/null +++ b/components/esp32/ld/esp32.mcuboot.project.ld.in @@ -0,0 +1,515 @@ +/* Default entry point: */ +ENTRY(__start); + +SECTIONS +{ + /* mcuboot imgtool overwrites 0 padded header with its own */ + .mcuboot_hdr : + { + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + QUAD(0x0) + } > mcuboot_hdr + + /* esp mcuboot port's loader also expects loader header */ + .esp_mcuboot_load_hdr : + { + /* Header magic */ + LONG(0xace637d3) + + /* Entry address */ + KEEP(*(.entry)) + + /* IRAM VMA */ + LONG(ADDR(.iram0.vectors)) + + /* IRAM LMA */ + LONG(LOADADDR(.iram0.vectors)) + + /* IRAM size */ + LONG(LOADADDR(.iram0.text) + SIZEOF(.iram0.text) - LOADADDR(.iram0.vectors)) + + /* DRAM VMA */ + LONG(ADDR(.dram0.data)) + + /* DRAM LMA */ + LONG(LOADADDR(.dram0.data)) + + /* DRAM size */ + LONG(SIZEOF(.dram0.data)) + } > loader_hdr + + /* To complete loading the, the app flash rodata will be copied/cached for both CPUs */ + _image_drom_vma = ADDR(.flash.rodata); + _image_drom_lma = LOADADDR(.flash.rodata); + _image_drom_size = SIZEOF(.flash.rodata); + + /* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */ + .flash.rodata : ALIGN(0xFFFF) + { + _rodata_start = ABSOLUTE(.); + + *(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */ + *(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */ + + mapping[flash_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) + . = (. + 3) & ~ 3; + __eh_frame = ABSOLUTE(.); + KEEP(*(.eh_frame)) + . = (. + 7) & ~ 3; + /* C++ constructor and destructor tables + + Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt + */ + __init_array_start = ABSOLUTE(.); + KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*))) + __init_array_end = ABSOLUTE(.); + + KEEP (*crtbegin.*(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + /* Addresses of memory regions reserved via + SOC_RESERVE_MEMORY_REGION() */ + soc_reserved_memory_region_start = ABSOLUTE(.); + KEEP (*(.reserved_memory_address)) + soc_reserved_memory_region_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _thread_local_start = ABSOLUTE(.); + *(.tdata) + *(.tdata.*) + *(.tbss) + *(.tbss.*) + _thread_local_end = ABSOLUTE(.); + . = ALIGN(4); + } >default_rodata_seg AT>ROM + + + + + .dram0.data : + { + _data_start = ABSOLUTE(.); + _bt_data_start = ABSOLUTE(.); + *libbt.a:(.data .data.*) + . = ALIGN (4); + _bt_data_end = ABSOLUTE(.); + _btdm_data_start = ABSOLUTE(.); + *libbtdm_app.a:(.data .data.*) + . = ALIGN (4); + _btdm_data_end = ABSOLUTE(.); + _nimble_data_start = ABSOLUTE(.); + *libnimble.a:(.data .data.*) + . = ALIGN (4); + _nimble_data_end = ABSOLUTE(.); + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + + /* coredump mapping */ + _coredump_dram_start = ABSOLUTE(.); + mapping[dram_coredump] + _coredump_dram_end = ABSOLUTE(.); + + /* should be placed after coredump mapping */ + _esp_system_init_fn_array_start = ABSOLUTE(.); + KEEP (*(SORT(.esp_system_init_fn) SORT(.esp_system_init_fn.*))) + _esp_system_init_fn_array_end = ABSOLUTE(.); + + mapping[dram0_data] + + _data_end = ABSOLUTE(.); + . = ALIGN(4); + } > dram0_0_seg AT>ROM + + + + + /* Send .iram0 code to iram */ + .iram0.vectors : ALIGN(4) + { + _iram_start = ABSOLUTE(.); + /* Vectors go to IRAM */ + _vector_table = ABSOLUTE(.); + /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ + . = 0x0; + KEEP(*(.WindowVectors.text)); + . = 0x180; + KEEP(*(.Level2InterruptVector.text)); + . = 0x1c0; + KEEP(*(.Level3InterruptVector.text)); + . = 0x200; + KEEP(*(.Level4InterruptVector.text)); + . = 0x240; + KEEP(*(.Level5InterruptVector.text)); + . = 0x280; + KEEP(*(.DebugExceptionVector.text)); + . = 0x2c0; + KEEP(*(.NMIExceptionVector.text)); + . = 0x300; + KEEP(*(.KernelExceptionVector.text)); + . = 0x340; + KEEP(*(.UserExceptionVector.text)); + . = 0x3C0; + KEEP(*(.DoubleExceptionVector.text)); + . = 0x400; + _invalid_pc_placeholder = ABSOLUTE(.); + *(.*Vector.literal) + + *(.UserEnter.literal); + *(.UserEnter.text); + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + + . = ALIGN(4); + _init_end = ABSOLUTE(.); + } > iram0_0_seg AT>ROM + + + + + .iram0.text : + { + /* Code marked as runnning out of IRAM */ + _iram_text_start = ABSOLUTE(.); + + mapping[iram0_text] + + . = ALIGN (4); + _iram_text_end = ABSOLUTE(.); + + } > iram0_0_seg AT>ROM + + + + .iram0.data : + { + . = ALIGN(4); + _iram_data_start = ABSOLUTE(.); + + /* coredump mapping */ + _coredump_iram_start = ABSOLUTE(.); + mapping[iram_coredump] + _coredump_iram_end = ABSOLUTE(.); + + /* should be placed after coredump mapping */ + mapping[iram0_data] + + . = ALIGN(4); + _iram_data_end = ABSOLUTE(.); + } > iram0_0_seg AT>ROM + + + + .iram0.bss (NOLOAD) : + { + . = ALIGN(4); + _iram_bss_start = ABSOLUTE(.); + + mapping[iram0_bss] + + _iram_bss_end = ABSOLUTE(.); + . = ALIGN(4); + _iram_end = ABSOLUTE(.); + } > iram0_0_seg + + + + + + /* RTC fast memory holds RTC wake stub code, + including from any source file named rtc_wake_stub*.c + */ + .rtc.text : + { + . = ALIGN(4); + + mapping[rtc_text] + + *rtc_wake_stub*.*(.literal .text .literal.* .text.*) + + . = ALIGN(4); + _rtc_text_end = ABSOLUTE(.); + } > rtc_iram_seg AT>ROM + + + + + /* + This section is required to skip rtc.text area because rtc_iram_seg and + rtc_data_seg are reflect the same address space on different buses. + */ + .rtc.dummy : + { + _rtc_dummy_start = ABSOLUTE(.); + _rtc_fast_start = ABSOLUTE(.); + . = SIZEOF(.rtc.text); + + . = ALIGN(4); + _rtc_dummy_end = ABSOLUTE(.); + } > rtc_data_seg AT>ROM + + + + + /* This section located in RTC FAST Memory area. + It holds data marked with RTC_FAST_ATTR attribute. + See the file "esp_attr.h" for more information. + */ + .rtc.force_fast : + { + . = ALIGN(4); + _rtc_force_fast_start = ABSOLUTE(.); + + _coredump_rtc_fast_start = ABSOLUTE(.); + mapping[rtc_fast_coredump] + _coredump_rtc_fast_end = ABSOLUTE(.); + + *(.rtc.force_fast .rtc.force_fast.*) + . = ALIGN(4); + + _rtc_force_fast_end = ABSOLUTE(.); + } > rtc_data_seg AT>ROM + + + + + /* RTC data section holds RTC wake stub + data/rodata, including from any source file + named rtc_wake_stub*.c and the data marked with + RTC_DATA_ATTR, RTC_RODATA_ATTR attributes. + The memory location of the data is dependent on + CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. + */ + .rtc.data : + { + _rtc_data_start = ABSOLUTE(.); + + /* coredump mapping */ + _coredump_rtc_start = ABSOLUTE(.); + mapping[rtc_coredump] + _coredump_rtc_end = ABSOLUTE(.); + + /* should be placed after coredump mapping */ + mapping[rtc_data] + + *rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*) + _rtc_data_end = ABSOLUTE(.); + + } > rtc_data_location AT>ROM + + + + /* RTC bss, from any source file named rtc_wake_stub*.c */ + .rtc.bss (NOLOAD) : + { + _rtc_bss_start = ABSOLUTE(.); + *rtc_wake_stub*.*(.bss .bss.*) + *rtc_wake_stub*.*(COMMON) + + mapping[rtc_bss] + + _rtc_bss_end = ABSOLUTE(.); + } > rtc_data_location + + + + + /* This section holds data that should not be initialized at power up + and will be retained during deep sleep. + User data marked with RTC_NOINIT_ATTR will be placed + into this section. See the file "esp_attr.h" for more information. + The memory location of the data is dependent on + CONFIG_ESP32_RTCDATA_IN_FAST_MEM option. + */ + .rtc_noinit (NOLOAD): + { + . = ALIGN(4); + _rtc_noinit_start = ABSOLUTE(.); + *(.rtc_noinit .rtc_noinit.*) + . = ALIGN(4) ; + _rtc_noinit_end = ABSOLUTE(.); + } > rtc_data_location + + + + + /* This section located in RTC SLOW Memory area. + It holds data marked with RTC_SLOW_ATTR attribute. + See the file "esp_attr.h" for more information. + */ + .rtc.force_slow : + { + . = ALIGN(4); + _rtc_force_slow_start = ABSOLUTE(.); + *(.rtc.force_slow .rtc.force_slow.*) + . = ALIGN(4) ; + _rtc_force_slow_end = ABSOLUTE(.); + } > rtc_slow_seg + + + + + /* Get size of rtc slow data based on rtc_data_location alias */ + _rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_slow_end - _rtc_data_start) + : (_rtc_force_slow_end - _rtc_force_slow_start); + + _rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location)) + ? (_rtc_force_fast_end - _rtc_fast_start) + : (_rtc_noinit_end - _rtc_fast_start); + + ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)), + "RTC_SLOW segment data does not fit.") + + ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)), + "RTC_FAST segment data does not fit.") + + + + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + _bt_bss_start = ABSOLUTE(.); + *libbt.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _bt_bss_end = ABSOLUTE(.); + _btdm_bss_start = ABSOLUTE(.); + *libbtdm_app.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _btdm_bss_end = ABSOLUTE(.); + _nimble_bss_start = ABSOLUTE(.); + *libnimble.a:(.bss .bss.* COMMON) + . = ALIGN (4); + _nimble_bss_end = ABSOLUTE(.); + + mapping[dram0_bss] + + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } > dram0_0_seg + + ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") + + + + + /*This section holds data that should not be initialized at power up. + The section located in Internal SRAM memory region. The macro _NOINIT + can be used as attribute to place data into this section. + See the esp_attr.h file for more information. + */ + .noinit (NOLOAD): + { + . = ALIGN(4); + _noinit_start = ABSOLUTE(.); + *(.noinit .noinit.*) + . = ALIGN(4) ; + _noinit_end = ABSOLUTE(.); + } > dram0_0_seg + + + + + /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + + mapping[extern_ram] + + . = ALIGN(4); + _ext_ram_bss_end = ABSOLUTE(.); + } > extern_ram_seg + + /* To complete loading, irom data needs to be copied/cached for both CPUs */ + _image_irom_vma = ADDR(.flash.text); + _image_irom_lma = LOADADDR(.flash.text); + _image_irom_size = SIZEOF(.flash.text); + + /* Align with MMU block size, as required. i.e. LMA % 64KB == VMA % 64KB */ + .flash.text : ALIGN(0xFFFF) + { + _stext = .; + _text_start = ABSOLUTE(.); + + mapping[flash_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 + * 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; + + _text_end = ABSOLUTE(.); + _etext = .; + + /* Similar to _iram_start, this symbol goes here so it is + resolved by addr2line in preference to the first symbol in + the flash.text segment. + */ + . = ALIGN(4); + _flash_cache_start = ABSOLUTE(0); + } >default_code_seg AT>ROM + + + + + /* Marks the end of data, bss and possibly rodata */ + .dram0.heap_start (NOLOAD) : + { + . = ALIGN (8); + _heap_start = ABSOLUTE(.); + } > dram0_0_seg +} + +ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)), + "IRAM0 segment data does not fit.") + +ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), + "DRAM segment data does not fit.") diff --git a/components/esptool_py/project_include.cmake b/components/esptool_py/project_include.cmake index d3196900f7..3661d4992b 100644 --- a/components/esptool_py/project_include.cmake +++ b/components/esptool_py/project_include.cmake @@ -89,6 +89,17 @@ if(CONFIG_APP_BUILD_GENERATE_BINARIES) COMMENT "Generating binary image from built executable" ) add_custom_target(gen_project_binary DEPENDS "${build_dir}/.bin_timestamp") + + add_custom_command(OUTPUT "${build_dir}/.mcuboot_bin_timestamp" + COMMAND xtensa-esp32-elf-objcopy -O binary ${elf_dir}/${elf} ${build_dir}/${unsigned_project_binary} + COMMAND ${CMAKE_COMMAND} -E echo "Generated ${build_dir}/${unsigned_project_binary}" + COMMAND ${CMAKE_COMMAND} -E md5sum "${build_dir}/${unsigned_project_binary}" > "${build_dir}/.mcuboot_bin_timestamp" + DEPENDS ${elf} + VERBATIM + WORKING_DIRECTORY ${build_dir} + COMMENT "Generating binary image from build executable" + ) + add_custom_target(gen_mcuboot_project_binary DEPENDS "${build_dir}/.mcuboot_bin_timestamp") endif() set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" @@ -97,7 +108,12 @@ set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) if(CONFIG_APP_BUILD_GENERATE_BINARIES) - add_custom_target(app ALL DEPENDS gen_project_binary) + if( MCUBOOT_IMAGE ) + add_custom_target(app ALL DEPENDS gen_mcuboot_project_binary) + else() + add_custom_target(app ALL DEPENDS gen_project_binary) + endif() + endif() if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) diff --git a/tools/idf_py_actions/core_ext.py b/tools/idf_py_actions/core_ext.py index 4d294ca35d..5576fba1a0 100644 --- a/tools/idf_py_actions/core_ext.py +++ b/tools/idf_py_actions/core_ext.py @@ -262,6 +262,12 @@ def action_extensions(base_actions, project_path): 'hidden': True, 'default': False, }, + { + 'names': ['--mcuboot'], + 'help': "Build and format application for MCUBoot.", + 'is_flag': True, + 'default': False, + }, ], 'global_action_callbacks': [validate_root_options], } diff --git a/tools/idf_py_actions/tools.py b/tools/idf_py_actions/tools.py index 6ba0702989..7bb54dfaf6 100644 --- a/tools/idf_py_actions/tools.py +++ b/tools/idf_py_actions/tools.py @@ -206,6 +206,10 @@ def ensure_build_directory(args, prog_name, always_run_cmake=False): if args.define_cache_entry: cmake_args += ['-D' + d for d in args.define_cache_entry] + + if args.mcuboot: + cmake_args += ['-DMCUBOOT_IMAGE=1'] + cmake_args += [project_dir] run_tool('cmake', cmake_args, cwd=args.build_dir) -- 2.25.1