feat(esp_tee): Reclaim unused TEE IRAM memory as heap

- Changed the default TEE code placement to use the flash
  text section instead of IRAM text, making it consistent
  with the default data placement.
This commit is contained in:
Laukik Hase
2025-10-09 14:27:10 +05:30
parent 20344640e3
commit 9de1d631b4
11 changed files with 500 additions and 630 deletions
+2 -2
View File
@@ -19,8 +19,8 @@ menu "ESP-TEE (Trusted Execution Environment)"
config SECURE_TEE_DRAM_SIZE
hex "DRAM region size"
default 0x5000
range 0x4000 0x7000
default 0x4000
range 0x3000 0x7000
help
This configuration sets the DRAM size for the TEE module.
This should be 256-byte (0x100) aligned.
@@ -0,0 +1,74 @@
#include "sdkconfig.h"
/**
* This section is not included in the binary image; it is only present in the ELF file.
* It is used to keep certain symbols in the ELF file.
*/
.noload 0 (INFO) :
{
/* Reserve first 4 bytes as zero for vars pointed to NULL */
. = 0;
LONG(0);
_noload_keep_in_elf_start = ABSOLUTE(.);
KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*))
mapping[noload_keep_in_elf]
_noload_keep_in_elf_end = ABSOLUTE(.);
}
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
/* DWARF 3 */
.debug_ranges 0 : { *(.debug_ranges) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* GNU DWARF 2 extensions */
.debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) }
.debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) }
/* DWARF 4 */
.debug_types 0 : { *(.debug_types) }
/* DWARF 5 */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.comment 0 : { *(.comment) }
.note.GNU-stack 0: { *(.note.GNU-stack) }
#if CONFIG_IDF_TARGET_ARCH_RISCV
.riscv.attributes 0: { *(.riscv.attributes) }
/DISCARD/ :
{
/**
* Discarding .rela.* sections results in the following mapping:
* .rela.text.* -> .text.*
* .rela.data.* -> .data.*
* And so forth...
*/
*(.rela.*)
*(.got .got.plt) /* TODO: GCC-382 */
}
#endif
@@ -1,32 +1,29 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "ld.common"
#define SRAM_IRAM_START (0x40800000)
#define SRAM_IRAM_TEE_ORG (SRAM_IRAM_START)
#define SRAM_DRAM_TEE_ORG (SRAM_IRAM_START)
#define SRAM_TEE_SEG_START (0x40800000)
#define SRAM_REE_SEG_START (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#define SRAM_IRAM_ORG (SRAM_IRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#define SRAM_TEE_DRAM_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
#define SRAM_TEE_DRAM_END (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE)
#define SRAM_DRAM_TEE_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
#define SRAM_DRAM_TEE_END (SRAM_DRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
#define I_D_SRAM_TEE_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
#define SRAM_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE)
/* TEE interrupt stack is placed at the end of the TEE DRAM segment.
* The top of the TEE stack is before the end of interrupt stack
* and the bottom of the stack is at _heap_end.
*/
#define SRAM_STACK_TEE_ORG (SRAM_DRAM_TEE_END)
#define SRAM_INTR_STACK_TEE_ORG (SRAM_DRAM_TEE_END + CONFIG_SECURE_TEE_STACK_SIZE)
#define SRAM_TEE_STACK_SEG_START (SRAM_TEE_DRAM_END)
#define SRAM_TEE_INTR_STACK_SEG_START (SRAM_TEE_DRAM_END + CONFIG_SECURE_TEE_STACK_SIZE)
#define FLASH_IROM_TEE_ORG (0x42000000)
#define FLASH_DROM_TEE_ORG (0x42000000)
#define I_D_FLASH_TEE_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
#define FLASH_TEE_SEG_START (0x42000000)
#define FLASH_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
/**
* These values are the same in every app binary for the same chip target.
@@ -36,9 +33,9 @@
*/
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x22b0 );
PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x22b0 );
#else
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x2b0 );
PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x2b0 );
#endif
PROVIDE ( GDMA = 0x60080000 );
@@ -48,60 +45,95 @@ ENTRY(esp_tee_init);
MEMORY
{
/* IRAM Configuration */
iram_tee_seg (RX) : org = SRAM_IRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
/* Flash text section */
irom_tee_seg (RX): org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20
/* DRAM Configuration */
dram_tee_seg (RW) : org = SRAM_DRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
/* Flash data section */
drom_tee_seg (R) : org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20
/* TEE Stack Configuration */
stack_tee_seg (RW) : org = SRAM_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_STACK_SIZE
/* I/DRAM section */
sram_tee_seg (RWX) : org = SRAM_TEE_SEG_START, len = SRAM_TEE_SEG_SIZE
/* TEE Interrupt Stack Configuration */
intr_stack_tee_seg (RW) : org = SRAM_INTR_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
/* Stack section */
stack_tee_seg (RW) : org = SRAM_TEE_STACK_SEG_START, len = CONFIG_SECURE_TEE_STACK_SIZE
/* TEE flash data section */
flash_data_seg (R) : org = FLASH_DROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
/* TEE flash text section */
flash_text_seg (RX): org = FLASH_IROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
/* Interrupt stack section */
intr_stack_tee_seg (RW) : org = SRAM_TEE_INTR_STACK_SEG_START, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
}
SECTIONS
{
/**
* This section is required to skip .iram.tee_text area because iram_tee_seg and
* dram_tee_seg reflect the same address space on different buses.
*/
.dram.tee_dummy (NOLOAD):
.iram.tee.text :
{
. = ORIGIN(dram_tee_seg) + CONFIG_SECURE_TEE_IRAM_SIZE;
} > dram_tee_seg
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
ALIGNED_SYMBOL(4, _invalid_pc_placeholder)
_tee_vec_end = ABSOLUTE(.);
.dram.tee.bss (NOLOAD) :
{
. = ALIGN (8);
_tee_dram_start = ABSOLUTE(.);
_tee_bss_start = ABSOLUTE(.);
*(.bss .bss.*)
*(.sbss .sbss.*)
. = ALIGN (8);
_tee_bss_end = ABSOLUTE(.);
} > dram_tee_seg
/* Code marked as running out of IRAM */
_tee_iram_start = ABSOLUTE(.);
*(.iram1 .iram1.*)
/* TEE initialization */
*libmain.a:esp_tee_init.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_secure_sys_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_pmp_pma_prot_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_apm_prot_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:brownout.c*(.literal .text .literal.* .text.*)
*libmain.a:multi_heap.c*(.literal .text .literal.* .text.*)
/* Panic handler */
*libmain.a:esp_tee_panic.c*(.literal .text .literal.* .text.*)
*libmain.a:panic_helper_riscv.c*(.literal .text .literal.* .text.*)
/* Service call execution */
*libmain.a:esp_tee_vectors_clic.S*(.literal .text .literal.* .text.*)
*libmain.a:esp_secure_dispatcher.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_secure_services_iram.c*(.literal .text .literal.* .text.*)
/* Interrupt configuration */
*libmain.a:esp_tee_intr.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_apm_intr.c*(.literal .text .literal.* .text.*)
/* HAL */
*libhal.a:mmu_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:cache_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.c*(.literal .text .literal.* .text.*)
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
/* IDF components */
*libbootloader_support.a:*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:*(.literal .text .literal.* .text.*)
*liblog.a:*(.literal .text .literal.* .text.*)
*libriscv.a:*(.literal .text .literal.* .text.*)
/* TEE services: Secure storage, OTA, attestation */
*libtee_flash_mgr.a:*(.literal .text .literal.* .text.*)
*libtee_sec_storage.a:*(.literal .text .literal.* .text.*)
*libtee_ota_ops.a:*(.literal .text .literal.* .text.*)
*libtee_attestation.a:*(.literal .text .literal.* .text.*)
/* Align the end of code region as per PMP region granularity */
ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end)
} > sram_tee_seg
.dram.tee.data :
{
_data_start = ABSOLUTE(.);
_tee_dram_start = ABSOLUTE(.);
_tee_data_start = ABSOLUTE(.);
*(.data .data.*)
*(.sdata .sdata.*)
*(.dram1 .dram1.*)
. = ALIGN(4);
_data_end = ABSOLUTE(.);
} > dram_tee_seg
_tee_data_end = ABSOLUTE(.);
} > sram_tee_seg
.dram.tee.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _tee_bss_start)
*(.bss .bss.*)
*(.sbss .sbss.*)
ALIGNED_SYMBOL(8, _tee_bss_end)
} > sram_tee_seg
.dram.tee.rodata :
{
_rodata_start = ABSOLUTE(.);
_tee_rodata_start = ABSOLUTE(.);
/* TEE flash manager */
*libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*)
*libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*)
@@ -114,189 +146,69 @@ SECTIONS
/* HAL (noflash) */
*libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*)
*libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*)
_rodata_end = ABSOLUTE(.);
_tee_rodata_end = ABSOLUTE(.);
_tee_dram_end = ABSOLUTE(.);
} > dram_tee_seg
} > sram_tee_seg
.dram.tee.heap :
.dram.tee.heap (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_heap_start = ABSOLUTE(.);
. = ORIGIN(dram_tee_seg) + LENGTH(dram_tee_seg);
. = ORIGIN(sram_tee_seg) + LENGTH(sram_tee_seg);
_tee_heap_end = ABSOLUTE(.);
} > dram_tee_seg
} > sram_tee_seg
.dram.tee.stack :
.dram.tee.stack (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_stack_bottom = ABSOLUTE(.);
. = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg);
_tee_stack = ABSOLUTE(.);
} > stack_tee_seg
.dram.tee.intr_stack :
.dram.tee.intr_stack (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_intr_stack_bottom = ABSOLUTE(.);
. = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg);
_tee_intr_stack = ABSOLUTE(.);
} > intr_stack_tee_seg
.flash.rodata :
.flash.tee.rodata : ALIGN(0x10)
{
_tee_xip_data_start = ABSOLUTE(.);
_tee_flash_data_start = ABSOLUTE(.);
*(.rodata_desc .rodata_desc.*) /* Should be the first. TEE App version info. DO NOT PUT ANYTHING BEFORE IT! */
*(.rodata .rodata.*)
*(.srodata .srodata.*)
*(.gcc_except_table .gcc_except_table.*)
_tee_xip_data_end = ABSOLUTE(.);
} > flash_data_seg
_tee_flash_data_end = ABSOLUTE(.);
} > drom_tee_seg
.flash.text_dummy (NOLOAD):
.flash.tee.text_dummy (NOLOAD):
{
. = ALIGN(ALIGNOF(.flash.rodata));
/* Create an empty gap as big as .flash.rodata section */
. = . + SIZEOF(.flash.rodata);
/* Prepare the alignment of the section above. Few bytes (0x20) must be
* added for the mapping header. */
. = ALIGN(CONFIG_MMU_PAGE_SIZE) + 0x20;
} > flash_text_seg
/* Create an empty gap as big as .flash.tee.rodata section */
. = ALIGN(ALIGNOF(.flash.tee.rodata)) + SIZEOF(.flash.tee.rodata);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > irom_tee_seg
/* HAL modules and their memory placement:
*
* +-----------+---------------+--------+
* | Module | Section | Memory |
* +-----------+---------------+--------+
* | MMU | text+rodata | SRAM |
* | CACHE | text+rodata | SRAM |
* | WDT | text | SRAM |
* | APM | text | Flash* |
* | AES | text | Flash |
* | SHA | text | Flash |
* | HMAC | text | Flash |
* | DS | text | Flash |
* | ECC | text | Flash |
* | BROWNOUT | text | Flash |
* | EFUSE | text | Flash |
* | LPTIMER | text | Flash |
* | SPI_FLASH | text | Flash |
* +-----------+---------------+--------+
*
* By default, for ESP-TEE, text sections are placed in SRAM while rodata sections go to the flash.
* Therefore, only HAL modules that require SRAM placement for proper functionality are located there,
* while the remaining modules are placed in flash memory.
*/
.flash.text :
.flash.tee.text :
{
_tee_xip_text_start = ABSOLUTE(.);
/* Secure Services */
*libmain.a:esp_secure_services.c*(.literal .text .literal.* .text.*)
/* HAL */
*libhal.a:aes_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:sha_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
/* NOTE: There is a possibility of APM violations (SPI1 flash protection)
* being triggered with the flash cache disabled */
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
#endif
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
*libesp_hal_mspi.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
*libhal.a:efuse_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:lp_timer_hal.c*(.literal .text .literal.* .text.*)
/* Mbedtls for TEE */
*libmbedtls.a:*(.literal .text .literal.* .text.*)
*libmbedcrypto.a:*(.literal .text .literal.* .text.*)
/* HMAC-DS layer */
*libesp_security.a:*(.literal .text .literal.* .text.*)
/* NVS flash and related modules */
*libnvs_flash.a:*(.literal .text .literal.* .text.*)
*libstdc++.a:*(.literal .text .literal.* .text.*)
*libgcc.a:*(.literal .text .literal.* .text.*)
/* esp_partition API */
*libesp_partition.a:*(.literal .text .literal.* .text.*)
/* TEE attestation module */
*libattestation.a:*(.literal .text .literal.* .text.*)
*json_generator.a:*(.literal .text .literal.* .text.*)
/* TEE test module */
*libtest_sec_srv.a:*(.literal .text .literal.* .text.*)
_tee_xip_text_end = ABSOLUTE(.);
_tee_xip_end = ABSOLUTE(.);
} > flash_text_seg
.iram.tee.text :
{
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
. = ALIGN(4);
_invalid_pc_placeholder = ABSOLUTE(.);
_tee_vec_end = ABSOLUTE(.);
_tee_iram_start = ABSOLUTE(.);
*(.literal .text .iram1 .literal.* .text.* .iram1.*)
_tee_flash_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.*)
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
_tee_iram_end = ABSOLUTE(.);
} > iram_tee_seg
/**
* 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
*/
. += _esp_flash_mmap_prefetch_pad_size;
_tee_flash_text_end = ABSOLUTE(.);
} > irom_tee_seg
.riscv.attributes 0: { *(.riscv.attributes) }
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
/* DWARF 3 */
.debug_ranges 0 : { *(.debug_ranges) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* GNU DWARF 2 extensions */
.debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) }
.debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) }
/* DWARF 4 */
.debug_types 0 : { *(.debug_types) }
/* DWARF 5 */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.comment 0 : { *(.comment) }
.note.GNU-stack 0: { *(.note.GNU-stack) }
/**
* Discarding .rela.* sections results in the following mapping:
* .rela.text.* -> .text.*
* .rela.data.* -> .data.*
* And so forth...
*/
/DISCARD/ : { *(.rela.*) }
#include "elf_misc.ld.in"
}
ASSERT ((_tee_iram_end < _tee_dram_start), "Error: TEE IRAM segment overflowed into the DRAM segment!");
ASSERT ((_tee_iram_end <= _tee_dram_start),
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
@@ -1,32 +1,29 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "ld.common"
#define SRAM_IRAM_START (0x40800000)
#define SRAM_IRAM_TEE_ORG (SRAM_IRAM_START)
#define SRAM_DRAM_TEE_ORG (SRAM_IRAM_START)
#define SRAM_TEE_SEG_START (0x40800000)
#define SRAM_REE_SEG_START (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#define SRAM_IRAM_ORG (SRAM_IRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#define SRAM_TEE_DRAM_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
#define SRAM_TEE_DRAM_END (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE)
#define SRAM_DRAM_TEE_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
#define SRAM_DRAM_TEE_END (SRAM_DRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
#define I_D_SRAM_TEE_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
#define SRAM_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE)
/* TEE interrupt stack is placed at the end of the TEE DRAM segment.
* The top of the TEE stack is before the end of interrupt stack
* and the bottom of the stack is at _heap_end.
*/
#define SRAM_STACK_TEE_ORG (SRAM_DRAM_TEE_END)
#define SRAM_INTR_STACK_TEE_ORG (SRAM_DRAM_TEE_END + CONFIG_SECURE_TEE_STACK_SIZE)
#define SRAM_TEE_STACK_SEG_START (SRAM_TEE_DRAM_END)
#define SRAM_TEE_INTR_STACK_SEG_START (SRAM_TEE_DRAM_END + CONFIG_SECURE_TEE_STACK_SIZE)
#define FLASH_IROM_TEE_ORG (0x42000000)
#define FLASH_DROM_TEE_ORG (0x42000000)
#define I_D_FLASH_TEE_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
#define FLASH_TEE_SEG_START (0x42000000)
#define FLASH_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
/**
* These values are the same in every app binary for the same chip target.
@@ -36,9 +33,9 @@
*/
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x22e0 );
PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x22e0 );
#else
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x2e0 );
PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x2e0 );
#endif
PROVIDE ( GDMA = 0x60080000 );
@@ -48,60 +45,95 @@ ENTRY(esp_tee_init);
MEMORY
{
/* IRAM Configuration */
iram_tee_seg (RX) : org = SRAM_IRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
/* Flash text section */
irom_tee_seg (RX): org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20
/* DRAM Configuration */
dram_tee_seg (RW) : org = SRAM_DRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
/* Flash data section */
drom_tee_seg (R) : org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20
/* TEE Stack Configuration */
stack_tee_seg (RW) : org = SRAM_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_STACK_SIZE
/* I/DRAM section */
sram_tee_seg (RWX) : org = SRAM_TEE_SEG_START, len = SRAM_TEE_SEG_SIZE
/* TEE Interrupt Stack Configuration */
intr_stack_tee_seg (RW) : org = SRAM_INTR_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
/* Stack section */
stack_tee_seg (RW) : org = SRAM_TEE_STACK_SEG_START, len = CONFIG_SECURE_TEE_STACK_SIZE
/* TEE flash data section */
flash_data_seg (R) : org = FLASH_DROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
/* TEE flash text section */
flash_text_seg (RX): org = FLASH_IROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
/* Interrupt stack section */
intr_stack_tee_seg (RW) : org = SRAM_TEE_INTR_STACK_SEG_START, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
}
SECTIONS
{
/**
* This section is required to skip .iram.tee_text area because iram_tee_seg and
* dram_tee_seg reflect the same address space on different buses.
*/
.dram.tee_dummy (NOLOAD):
.iram.tee.text :
{
. = ORIGIN(dram_tee_seg) + CONFIG_SECURE_TEE_IRAM_SIZE;
} > dram_tee_seg
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
ALIGNED_SYMBOL(4, _invalid_pc_placeholder)
_tee_vec_end = ABSOLUTE(.);
.dram.tee.bss (NOLOAD) :
{
. = ALIGN (8);
_tee_dram_start = ABSOLUTE(.);
_tee_bss_start = ABSOLUTE(.);
*(.bss .bss.*)
*(.sbss .sbss.*)
. = ALIGN (8);
_tee_bss_end = ABSOLUTE(.);
} > dram_tee_seg
/* Code marked as running out of IRAM */
_tee_iram_start = ABSOLUTE(.);
*(.iram1 .iram1.*)
/* TEE initialization */
*libmain.a:esp_tee_init.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_secure_sys_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_pmp_pma_prot_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_apm_prot_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:brownout.c*(.literal .text .literal.* .text.*)
*libmain.a:multi_heap.c*(.literal .text .literal.* .text.*)
/* Panic handler */
*libmain.a:esp_tee_panic.c*(.literal .text .literal.* .text.*)
*libmain.a:panic_helper_riscv.c*(.literal .text .literal.* .text.*)
/* Service call execution */
*libmain.a:esp_tee_vectors_plic.S*(.literal .text .literal.* .text.*)
*libmain.a:esp_secure_dispatcher.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_secure_services_iram.c*(.literal .text .literal.* .text.*)
/* Interrupt configuration */
*libmain.a:esp_tee_intr.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_apm_intr.c*(.literal .text .literal.* .text.*)
/* HAL */
*libhal.a:mmu_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:cache_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.c*(.literal .text .literal.* .text.*)
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
/* IDF components */
*libbootloader_support.a:*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:*(.literal .text .literal.* .text.*)
*liblog.a:*(.literal .text .literal.* .text.*)
*libriscv.a:*(.literal .text .literal.* .text.*)
/* TEE services: Secure storage, OTA, attestation */
*libtee_flash_mgr.a:*(.literal .text .literal.* .text.*)
*libtee_sec_storage.a:*(.literal .text .literal.* .text.*)
*libtee_ota_ops.a:*(.literal .text .literal.* .text.*)
*libtee_attestation.a:*(.literal .text .literal.* .text.*)
/* Align the end of code region as per PMP region granularity */
ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end)
} > sram_tee_seg
.dram.tee.data :
{
_data_start = ABSOLUTE(.);
_tee_dram_start = ABSOLUTE(.);
_tee_data_start = ABSOLUTE(.);
*(.data .data.*)
*(.sdata .sdata.*)
*(.dram1 .dram1.*)
. = ALIGN(4);
_data_end = ABSOLUTE(.);
} > dram_tee_seg
_tee_data_end = ABSOLUTE(.);
} > sram_tee_seg
.dram.tee.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _tee_bss_start)
*(.bss .bss.*)
*(.sbss .sbss.*)
ALIGNED_SYMBOL(8, _tee_bss_end)
} > sram_tee_seg
.dram.tee.rodata :
{
_rodata_start = ABSOLUTE(.);
_tee_rodata_start = ABSOLUTE(.);
/* TEE flash manager */
*libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*)
*libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*)
@@ -114,189 +146,69 @@ SECTIONS
/* HAL (noflash) */
*libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*)
*libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*)
_rodata_end = ABSOLUTE(.);
_tee_rodata_end = ABSOLUTE(.);
_tee_dram_end = ABSOLUTE(.);
} > dram_tee_seg
} > sram_tee_seg
.dram.tee.heap :
.dram.tee.heap (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_heap_start = ABSOLUTE(.);
. = ORIGIN(dram_tee_seg) + LENGTH(dram_tee_seg);
. = ORIGIN(sram_tee_seg) + LENGTH(sram_tee_seg);
_tee_heap_end = ABSOLUTE(.);
} > dram_tee_seg
} > sram_tee_seg
.dram.tee.stack :
.dram.tee.stack (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_stack_bottom = ABSOLUTE(.);
. = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg);
_tee_stack = ABSOLUTE(.);
} > stack_tee_seg
.dram.tee.intr_stack :
.dram.tee.intr_stack (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_intr_stack_bottom = ABSOLUTE(.);
. = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg);
_tee_intr_stack = ABSOLUTE(.);
} > intr_stack_tee_seg
.flash.rodata :
.flash.tee.rodata : ALIGN(0x10)
{
_tee_xip_data_start = ABSOLUTE(.);
_tee_flash_data_start = ABSOLUTE(.);
*(.rodata_desc .rodata_desc.*) /* Should be the first. TEE App version info. DO NOT PUT ANYTHING BEFORE IT! */
*(.rodata .rodata.*)
*(.srodata .srodata.*)
*(.gcc_except_table .gcc_except_table.*)
_tee_xip_data_end = ABSOLUTE(.);
} > flash_data_seg
_tee_flash_data_end = ABSOLUTE(.);
} > drom_tee_seg
.flash.text_dummy (NOLOAD):
.flash.tee.text_dummy (NOLOAD):
{
. = ALIGN(ALIGNOF(.flash.rodata));
/* Create an empty gap as big as .flash.rodata section */
. = . + SIZEOF(.flash.rodata);
/* Prepare the alignment of the section above. Few bytes (0x20) must be
* added for the mapping header. */
. = ALIGN(CONFIG_MMU_PAGE_SIZE) + 0x20;
} > flash_text_seg
/* Create an empty gap as big as .flash.tee.rodata section */
. = ALIGN(ALIGNOF(.flash.tee.rodata)) + SIZEOF(.flash.tee.rodata);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > irom_tee_seg
/* HAL modules and their memory placement:
*
* +-----------+---------------+--------+
* | Module | Section | Memory |
* +-----------+---------------+--------+
* | MMU | text+rodata | SRAM |
* | CACHE | text+rodata | SRAM |
* | WDT | text | SRAM |
* | APM | text | Flash* |
* | AES | text | Flash |
* | SHA | text | Flash |
* | HMAC | text | Flash |
* | DS | text | Flash |
* | ECC | text | Flash |
* | BROWNOUT | text | Flash |
* | EFUSE | text | Flash |
* | LPTIMER | text | Flash |
* | SPI_FLASH | text | Flash |
* +-----------+---------------+--------+
*
* By default, for ESP-TEE, text sections are placed in SRAM while rodata sections go to the flash.
* Therefore, only HAL modules that require SRAM placement for proper functionality are located there,
* while the remaining modules are placed in flash memory.
*/
.flash.text :
.flash.tee.text :
{
_tee_xip_text_start = ABSOLUTE(.);
/* Secure Services */
*libmain.a:esp_secure_services.c*(.literal .text .literal.* .text.*)
/* HAL */
*libhal.a:aes_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:sha_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
/* NOTE: There is a possibility of APM violations (SPI1 flash protection)
* being triggered with the flash cache disabled */
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
#endif
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
*libesp_hal_mspi.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
*libhal.a:efuse_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:lp_timer_hal.c*(.literal .text .literal.* .text.*)
/* Mbedtls for TEE */
*libmbedtls.a:*(.literal .text .literal.* .text.*)
*libmbedcrypto.a:*(.literal .text .literal.* .text.*)
/* HMAC-DS layer */
*libesp_security.a:*(.literal .text .literal.* .text.*)
/* NVS flash and related modules */
*libnvs_flash.a:*(.literal .text .literal.* .text.*)
*libstdc++.a:*(.literal .text .literal.* .text.*)
*libgcc.a:*(.literal .text .literal.* .text.*)
/* esp_partition API */
*libesp_partition.a:*(.literal .text .literal.* .text.*)
/* TEE attestation module */
*libattestation.a:*(.literal .text .literal.* .text.*)
*json_generator.a:*(.literal .text .literal.* .text.*)
/* TEE test module */
*libtest_sec_srv.a:*(.literal .text .literal.* .text.*)
_tee_xip_text_end = ABSOLUTE(.);
_tee_xip_end = ABSOLUTE(.);
} > flash_text_seg
.iram.tee.text :
{
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
. = ALIGN(4);
_invalid_pc_placeholder = ABSOLUTE(.);
_tee_vec_end = ABSOLUTE(.);
_tee_iram_start = ABSOLUTE(.);
*(.literal .text .iram1 .literal.* .text.* .iram1.*)
_tee_flash_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.*)
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
_tee_iram_end = ABSOLUTE(.);
} > iram_tee_seg
/**
* 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
*/
. += _esp_flash_mmap_prefetch_pad_size;
_tee_flash_text_end = ABSOLUTE(.);
} > irom_tee_seg
.riscv.attributes 0: { *(.riscv.attributes) }
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
/* DWARF 3 */
.debug_ranges 0 : { *(.debug_ranges) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* GNU DWARF 2 extensions */
.debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) }
.debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) }
/* DWARF 4 */
.debug_types 0 : { *(.debug_types) }
/* DWARF 5 */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.comment 0 : { *(.comment) }
.note.GNU-stack 0: { *(.note.GNU-stack) }
/**
* Discarding .rela.* sections results in the following mapping:
* .rela.text.* -> .text.*
* .rela.data.* -> .data.*
* And so forth...
*/
/DISCARD/ : { *(.rela.*) }
#include "elf_misc.ld.in"
}
ASSERT ((_tee_iram_end < _tee_dram_start), "Error: TEE IRAM segment overflowed into the DRAM segment!");
ASSERT ((_tee_iram_end <= _tee_dram_start),
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
@@ -1,32 +1,29 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "ld.common"
#define SRAM_IRAM_START (0x40800000)
#define SRAM_IRAM_TEE_ORG (SRAM_IRAM_START)
#define SRAM_DRAM_TEE_ORG (SRAM_IRAM_START)
#define SRAM_TEE_SEG_START (0x40800000)
#define SRAM_REE_SEG_START (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#define SRAM_IRAM_ORG (SRAM_IRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + CONFIG_SECURE_TEE_DRAM_SIZE)
#define SRAM_TEE_DRAM_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
#define SRAM_TEE_DRAM_END (SRAM_TEE_SEG_START + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE)
#define SRAM_DRAM_TEE_SIZE (CONFIG_SECURE_TEE_DRAM_SIZE - CONFIG_SECURE_TEE_STACK_SIZE - CONFIG_SECURE_TEE_INTR_STACK_SIZE)
#define SRAM_DRAM_TEE_END (SRAM_DRAM_TEE_ORG + CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
#define I_D_SRAM_TEE_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_DRAM_TEE_SIZE)
#define SRAM_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IRAM_SIZE + SRAM_TEE_DRAM_SIZE)
/* TEE interrupt stack is placed at the end of the TEE DRAM segment.
* The top of the TEE stack is before the end of interrupt stack
* and the bottom of the stack is at _heap_end.
*/
#define SRAM_STACK_TEE_ORG (SRAM_DRAM_TEE_END)
#define SRAM_INTR_STACK_TEE_ORG (SRAM_DRAM_TEE_END + CONFIG_SECURE_TEE_STACK_SIZE)
#define SRAM_TEE_STACK_SEG_START (SRAM_TEE_DRAM_END)
#define SRAM_TEE_INTR_STACK_SEG_START (SRAM_TEE_DRAM_END + CONFIG_SECURE_TEE_STACK_SIZE)
#define FLASH_IROM_TEE_ORG (0x42000000)
#define FLASH_DROM_TEE_ORG (0x42000000)
#define I_D_FLASH_TEE_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
#define FLASH_TEE_SEG_START (0x42000000)
#define FLASH_TEE_SEG_SIZE (CONFIG_SECURE_TEE_IROM_SIZE + CONFIG_SECURE_TEE_DROM_SIZE)
/**
* These values are the same in every app binary for the same chip target.
@@ -36,9 +33,9 @@
*/
#if CONFIG_ESP_DEBUG_INCLUDE_OCD_STUB_BINS
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x22e0 );
PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x22e0 );
#else
PROVIDE ( esp_tee_app_config = SRAM_IRAM_ORG + 0x2e0 );
PROVIDE ( esp_tee_app_config = SRAM_REE_SEG_START + 0x2e0 );
#endif
PROVIDE ( GDMA = 0x60080000 );
@@ -48,60 +45,95 @@ ENTRY(esp_tee_init);
MEMORY
{
/* IRAM Configuration */
iram_tee_seg (RX) : org = SRAM_IRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
/* Flash text section */
irom_tee_seg (RX): org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20
/* DRAM Configuration */
dram_tee_seg (RW) : org = SRAM_DRAM_TEE_ORG, len = I_D_SRAM_TEE_SIZE
/* Flash data section */
drom_tee_seg (R) : org = FLASH_TEE_SEG_START + 0x20, len = FLASH_TEE_SEG_SIZE - 0x20
/* TEE Stack Configuration */
stack_tee_seg (RW) : org = SRAM_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_STACK_SIZE
/* I/DRAM section */
sram_tee_seg (RWX) : org = SRAM_TEE_SEG_START, len = SRAM_TEE_SEG_SIZE
/* TEE Interrupt Stack Configuration */
intr_stack_tee_seg (RW) : org = SRAM_INTR_STACK_TEE_ORG, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
/* Stack section */
stack_tee_seg (RW) : org = SRAM_TEE_STACK_SEG_START, len = CONFIG_SECURE_TEE_STACK_SIZE
/* TEE flash data section */
flash_data_seg (R) : org = FLASH_DROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
/* TEE flash text section */
flash_text_seg (RX): org = FLASH_IROM_TEE_ORG + 0x20, len = I_D_FLASH_TEE_SIZE - 0x20
/* Interrupt stack section */
intr_stack_tee_seg (RW) : org = SRAM_TEE_INTR_STACK_SEG_START, len = CONFIG_SECURE_TEE_INTR_STACK_SIZE
}
SECTIONS
{
/**
* This section is required to skip .iram.tee_text area because iram_tee_seg and
* dram_tee_seg reflect the same address space on different buses.
*/
.dram.tee_dummy (NOLOAD):
.iram.tee.text :
{
. = ORIGIN(dram_tee_seg) + CONFIG_SECURE_TEE_IRAM_SIZE;
} > dram_tee_seg
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
ALIGNED_SYMBOL(4, _invalid_pc_placeholder)
_tee_vec_end = ABSOLUTE(.);
.dram.tee.bss (NOLOAD) :
{
. = ALIGN (8);
_tee_dram_start = ABSOLUTE(.);
_tee_bss_start = ABSOLUTE(.);
*(.bss .bss.*)
*(.sbss .sbss.*)
. = ALIGN (8);
_tee_bss_end = ABSOLUTE(.);
} > dram_tee_seg
/* Code marked as running out of IRAM */
_tee_iram_start = ABSOLUTE(.);
*(.iram1 .iram1.*)
/* TEE initialization */
*libmain.a:esp_tee_init.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_secure_sys_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_pmp_pma_prot_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_apm_prot_cfg.c*(.literal .text .literal.* .text.*)
*libmain.a:brownout.c*(.literal .text .literal.* .text.*)
*libmain.a:multi_heap.c*(.literal .text .literal.* .text.*)
/* Panic handler */
*libmain.a:esp_tee_panic.c*(.literal .text .literal.* .text.*)
*libmain.a:panic_helper_riscv.c*(.literal .text .literal.* .text.*)
/* Service call execution */
*libmain.a:esp_tee_vectors_plic.S*(.literal .text .literal.* .text.*)
*libmain.a:esp_secure_dispatcher.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_secure_services_iram.c*(.literal .text .literal.* .text.*)
/* Interrupt configuration */
*libmain.a:esp_tee_intr.c*(.literal .text .literal.* .text.*)
*libmain.a:esp_tee_apm_intr.c*(.literal .text .literal.* .text.*)
/* HAL */
*libhal.a:mmu_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:cache_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:wdt_hal_iram.c*(.literal .text .literal.* .text.*)
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
/* IDF components */
*libbootloader_support.a:*(.literal .text .literal.* .text.*)
*libesp_hw_support.a:*(.literal .text .literal.* .text.*)
*liblog.a:*(.literal .text .literal.* .text.*)
*libriscv.a:*(.literal .text .literal.* .text.*)
/* TEE services: Secure storage, OTA, attestation */
*libtee_flash_mgr.a:*(.literal .text .literal.* .text.*)
*libtee_sec_storage.a:*(.literal .text .literal.* .text.*)
*libtee_ota_ops.a:*(.literal .text .literal.* .text.*)
*libtee_attestation.a:*(.literal .text .literal.* .text.*)
/* Align the end of code region as per PMP region granularity */
ALIGNED_SYMBOL(_esp_pmp_align_size, _tee_iram_end)
} > sram_tee_seg
.dram.tee.data :
{
_data_start = ABSOLUTE(.);
_tee_dram_start = ABSOLUTE(.);
_tee_data_start = ABSOLUTE(.);
*(.data .data.*)
*(.sdata .sdata.*)
*(.dram1 .dram1.*)
. = ALIGN(4);
_data_end = ABSOLUTE(.);
} > dram_tee_seg
_tee_data_end = ABSOLUTE(.);
} > sram_tee_seg
.dram.tee.bss (NOLOAD) :
{
ALIGNED_SYMBOL(8, _tee_bss_start)
*(.bss .bss.*)
*(.sbss .sbss.*)
ALIGNED_SYMBOL(8, _tee_bss_end)
} > sram_tee_seg
.dram.tee.rodata :
{
_rodata_start = ABSOLUTE(.);
_tee_rodata_start = ABSOLUTE(.);
/* TEE flash manager */
*libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*)
*libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*)
@@ -114,191 +146,69 @@ SECTIONS
/* HAL (noflash) */
*libhal.a:mmu_hal.c*(.rodata .srodata .rodata.* .srodata.*)
*libhal.a:cache_hal.c*(.rodata .srodata .rodata.* .srodata.*)
_rodata_end = ABSOLUTE(.);
_tee_rodata_end = ABSOLUTE(.);
_tee_dram_end = ABSOLUTE(.);
} > dram_tee_seg
} > sram_tee_seg
.dram.tee.heap :
.dram.tee.heap (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_heap_start = ABSOLUTE(.);
. = ORIGIN(dram_tee_seg) + LENGTH(dram_tee_seg);
. = ORIGIN(sram_tee_seg) + LENGTH(sram_tee_seg);
_tee_heap_end = ABSOLUTE(.);
} > dram_tee_seg
} > sram_tee_seg
.dram.tee.stack :
.dram.tee.stack (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_stack_bottom = ABSOLUTE(.);
. = ORIGIN(stack_tee_seg) + LENGTH(stack_tee_seg);
_tee_stack = ABSOLUTE(.);
} > stack_tee_seg
.dram.tee.intr_stack :
.dram.tee.intr_stack (NOLOAD): ALIGN(0x10)
{
. = ALIGN (16);
_tee_intr_stack_bottom = ABSOLUTE(.);
. = ORIGIN(intr_stack_tee_seg) + LENGTH(intr_stack_tee_seg);
_tee_intr_stack = ABSOLUTE(.);
} > intr_stack_tee_seg
.flash.rodata :
.flash.tee.rodata : ALIGN(0x10)
{
_tee_xip_data_start = ABSOLUTE(.);
_tee_flash_data_start = ABSOLUTE(.);
*(.rodata_desc .rodata_desc.*) /* Should be the first. TEE App version info. DO NOT PUT ANYTHING BEFORE IT! */
*(.rodata .rodata.*)
*(.srodata .srodata.*)
*(.gcc_except_table .gcc_except_table.*)
_tee_xip_data_end = ABSOLUTE(.);
} > flash_data_seg
_tee_flash_data_end = ABSOLUTE(.);
} > drom_tee_seg
.flash.text_dummy (NOLOAD):
.flash.tee.text_dummy (NOLOAD):
{
. = ALIGN(ALIGNOF(.flash.rodata));
/* Create an empty gap as big as .flash.rodata section */
. = . + SIZEOF(.flash.rodata);
/* Prepare the alignment of the section above. Few bytes (0x20) must be
* added for the mapping header. */
. = ALIGN(CONFIG_MMU_PAGE_SIZE) + 0x20;
} > flash_text_seg
/* Create an empty gap as big as .flash.tee.rodata section */
. = ALIGN(ALIGNOF(.flash.tee.rodata)) + SIZEOF(.flash.tee.rodata);
/* Add alignment of MMU page size + 0x20 bytes for the mapping header. */
. = ALIGN(_esp_mmu_page_size) + 0x20;
} > irom_tee_seg
/* HAL modules and their memory placement:
*
* +-----------+---------------+--------+
* | Module | Section | Memory |
* +-----------+---------------+--------+
* | MMU | text+rodata | SRAM |
* | CACHE | text+rodata | SRAM |
* | WDT | text | SRAM |
* | APM | text | Flash* |
* | AES | text | Flash |
* | SHA | text | Flash |
* | HMAC | text | Flash |
* | DS | text | Flash |
* | ECC | text | Flash |
* | BROWNOUT | text | Flash |
* | EFUSE | text | Flash |
* | LPTIMER | text | Flash |
* | SPI_FLASH | text | Flash |
* +-----------+---------------+--------+
*
* By default, for ESP-TEE, text sections are placed in SRAM while rodata sections go to the flash.
* Therefore, only HAL modules that require SRAM placement for proper functionality are located there,
* while the remaining modules are placed in flash memory.
*/
.flash.text :
.flash.tee.text :
{
_tee_xip_text_start = ABSOLUTE(.);
/* Secure Services */
*libmain.a:esp_secure_services.c*(.literal .text .literal.* .text.*)
/* HAL */
*libhal.a:aes_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:sha_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
/* NOTE: There is a possibility of APM violations (SPI1 flash protection)
* being triggered with the flash cache disabled */
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
#endif
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
*libesp_hal_mspi.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
*libhal.a:efuse_hal.c*(.literal .text .literal.* .text.*)
*libhal.a:lp_timer_hal.c*(.literal .text .literal.* .text.*)
/* Mbedtls for TEE */
*libmbedtls.a:*(.literal .text .literal.* .text.*)
*libmbedcrypto.a:*(.literal .text .literal.* .text.*)
/* HMAC-DS layer */
*libesp_security.a:*(.literal .text .literal.* .text.*)
/* NVS flash and related modules */
*libnvs_flash.a:*(.literal .text .literal.* .text.*)
*libstdc++.a:*(.literal .text .literal.* .text.*)
*libgcc.a:*(.literal .text .literal.* .text.*)
/* esp_partition API */
*libesp_partition.a:*(.literal .text .literal.* .text.*)
/* TEE attestation module */
*libattestation.a:*(.literal .text .literal.* .text.*)
*json_generator.a:*(.literal .text .literal.* .text.*)
/* snprintf-related functions */
*libc_nano.a:(.literal .text .literal.* .text.*)
/* TEE test module */
*libtest_sec_srv.a:*(.literal .text .literal.* .text.*)
_tee_xip_text_end = ABSOLUTE(.);
_tee_xip_end = ABSOLUTE(.);
} > flash_text_seg
.iram.tee.text :
{
/* Vectors go to start of IRAM */
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
_tee_vec_start = ABSOLUTE(.);
KEEP(*(.exception_vectors_table.text));
KEEP(*(.exception_vectors.text));
. = ALIGN(4);
_invalid_pc_placeholder = ABSOLUTE(.);
_tee_vec_end = ABSOLUTE(.);
_tee_iram_start = ABSOLUTE(.);
*(.literal .text .iram1 .literal.* .text.* .iram1.*)
_tee_flash_text_start = ABSOLUTE(.);
*(.literal .text .literal.* .text.*)
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
_tee_iram_end = ABSOLUTE(.);
} > iram_tee_seg
/**
* 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
*/
. += _esp_flash_mmap_prefetch_pad_size;
_tee_flash_text_end = ABSOLUTE(.);
} > irom_tee_seg
.riscv.attributes 0: { *(.riscv.attributes) }
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_pubtypes 0 : { *(.debug_pubtypes) }
/* DWARF 3 */
.debug_ranges 0 : { *(.debug_ranges) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* GNU DWARF 2 extensions */
.debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) }
.debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) }
/* DWARF 4 */
.debug_types 0 : { *(.debug_types) }
/* DWARF 5 */
.debug_addr 0 : { *(.debug_addr) }
.debug_line_str 0 : { *(.debug_line_str) }
.debug_loclists 0 : { *(.debug_loclists) }
.debug_macro 0 : { *(.debug_macro) }
.debug_names 0 : { *(.debug_names) }
.debug_rnglists 0 : { *(.debug_rnglists) }
.debug_str_offsets 0 : { *(.debug_str_offsets) }
.comment 0 : { *(.comment) }
.note.GNU-stack 0: { *(.note.GNU-stack) }
/**
* Discarding .rela.* sections results in the following mapping:
* .rela.text.* -> .text.*
* .rela.data.* -> .data.*
* And so forth...
*/
/DISCARD/ : { *(.rela.*) }
#include "elf_misc.ld.in"
}
ASSERT ((_tee_iram_end < _tee_dram_start), "Error: TEE IRAM segment overflowed into the DRAM segment!");
ASSERT ((_tee_iram_end <= _tee_dram_start),
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
@@ -0,0 +1,32 @@
#include "sdkconfig.h"
#define ALIGN_UP(SIZE, AL) (((SIZE) + (AL - 1)) & ~(AL - 1))
#define ALIGN_DOWN(SIZE, AL) ((SIZE) & ~((AL) - 1))
/* CPU instruction prefetch padding size for flash mmap scenario */
#define _esp_flash_mmap_prefetch_pad_size 16
/*
* PMP region granularity size
* Software may determine the PMP granularity by writing zero to pmp0cfg, then writing all ones
* to pmpaddr0, then reading back pmpaddr0. If G is the index of the least-significant bit set,
* the PMP granularity is 2^G+2 bytes.
*/
#ifdef CONFIG_SOC_CPU_PMP_REGION_GRANULARITY
#define _esp_pmp_align_size CONFIG_SOC_CPU_PMP_REGION_GRANULARITY
#else
#define _esp_pmp_align_size 0
#endif
#if CONFIG_APP_BUILD_TYPE_RAM
#define _esp_mmu_page_size 0
#else
#define _esp_mmu_page_size CONFIG_MMU_PAGE_SIZE
#endif
#define ALIGNED_SYMBOL(X, SYMBOL) . = ALIGN(X); SYMBOL = ABSOLUTE(.);
#define QUOTED_STRING(STRING) #STRING
#define ASSERT_SECTIONS_GAP(PREV_SECTION, NEXT_SECTION) \
ASSERT((ADDR(NEXT_SECTION) == ADDR(PREV_SECTION) + SIZEOF(PREV_SECTION)), \
QUOTED_STRING(The gap between PREV_SECTION and NEXT_SECTION must not exist to produce the final bin image.))
@@ -58,8 +58,10 @@ static void esp_tee_configure_invalid_regions(void)
assert(IS_PMA_ENTRY_UNLOCKED(13));
assert(IS_PMA_ENTRY_UNLOCKED(14));
assert(IS_PMA_ENTRY_UNLOCKED(15));
extern int _tee_iram_end;
PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE);
PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_S_IRAM_END, PMA_TOR | PMA_RX);
PMA_RESET_AND_ENTRY_SET_TOR(14, (int)&_tee_iram_end, PMA_TOR | PMA_RX);
PMA_RESET_AND_ENTRY_SET_TOR(15, SOC_S_DRAM_END, PMA_TOR | PMA_RW);
}
@@ -66,8 +66,10 @@ static void esp_tee_configure_invalid_regions(void)
assert(IS_PMA_ENTRY_UNLOCKED(13));
assert(IS_PMA_ENTRY_UNLOCKED(14));
assert(IS_PMA_ENTRY_UNLOCKED(15));
extern int _tee_iram_end;
PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE);
PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_S_IRAM_END, PMA_TOR | PMA_RX);
PMA_RESET_AND_ENTRY_SET_TOR(14, (int)&_tee_iram_end, PMA_TOR | PMA_RX);
PMA_RESET_AND_ENTRY_SET_TOR(15, SOC_S_DRAM_END, PMA_TOR | PMA_RW);
}
@@ -68,8 +68,10 @@ static void esp_tee_configure_invalid_regions(void)
assert(IS_PMA_ENTRY_UNLOCKED(13));
assert(IS_PMA_ENTRY_UNLOCKED(14));
assert(IS_PMA_ENTRY_UNLOCKED(15));
extern int _tee_iram_end;
PMA_RESET_AND_ENTRY_SET_TOR(13, SOC_S_IRAM_START, PMA_NONE);
PMA_RESET_AND_ENTRY_SET_TOR(14, SOC_S_IRAM_END, PMA_TOR | PMA_RX);
PMA_RESET_AND_ENTRY_SET_TOR(14, (int)&_tee_iram_end, PMA_TOR | PMA_RX);
PMA_RESET_AND_ENTRY_SET_TOR(15, SOC_S_DRAM_END, PMA_TOR | PMA_RW);
}
@@ -2,11 +2,14 @@
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
# Reducing TEE DRAM and STACK sizes
# 21KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x5400
# 2.5KB
CONFIG_SECURE_TEE_STACK_SIZE=0xa00
# Reducing TEE I/DRAM sizes
# 24KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x6000
# 12KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x3000
# Disable TEE logs (also disable all panic logs)
CONFIG_SECURE_TEE_DEBUG_MODE=n
# Disabling ATTESTATION
CONFIG_SECURE_TEE_ATTESTATION=n
@@ -0,0 +1,21 @@
# Reducing TEE I/DRAM sizes
# 28KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x7000
# 16KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x4000
# TEE Secure Storage: Release mode
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
# Disabling support for SECP192R1 signature
CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=n
# Disabling flash protection over SPI1
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=n
# Secure Boot
CONFIG_PARTITION_TABLE_OFFSET=0xf000
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES=y
CONFIG_SECURE_BOOT_SIGNING_KEY="test_keys/secure_boot_signing_key.pem"