Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ target_sources(platform_s
target_sources(tfm_s
PRIVATE
ext/common/faults.c
ext/common/picolibc.c
)

target_link_libraries(platform_s
Expand Down
32 changes: 32 additions & 0 deletions platform/ext/common/gcc/tfm_common_bl2.ld
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,26 @@ SECTIONS
} > RAM AT > FLASH
Image$$ER_DATA$$Base = ADDR(.data);

.tdata : ALIGN_WITH_INPUT
{
*(.tdata .tdata.* .gnu.linkonce.td.*)
PROVIDE( __data_end = . );
PROVIDE( __tdata_end = . );
} >RAM AT>FLASH

.tbss (NOLOAD) :
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
PROVIDE( __tbss_end = . );
} >RAM AT>RAM

.tbss_space (NOLOAD) : {
. = ADDR(.tbss);
. = . + SIZEOF(.tbss);
} >RAM AT>RAM

.bss : ALIGN(4)
{
. = ALIGN(4);
Expand All @@ -163,6 +183,16 @@ SECTIONS
__bss_end__ = .;
} > RAM

PROVIDE( __bss_end = __bss_end__ );
PROVIDE( __data_start = ADDR(.data) );
PROVIDE( __data_source = LOADADDR(.data) );
PROVIDE( __data_size = __data_end - __data_start );
PROVIDE( __tls_base = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __bss_start = ADDR(.tbss));
PROVIDE( __bss_size = __bss_end - __bss_start );

#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
.msp_stack (NOLOAD) : ALIGN(32)
{
Expand Down Expand Up @@ -200,4 +230,6 @@ SECTIONS
Image$$ARM_LIB_HEAP$$ZI$$Limit = ADDR(.heap) + SIZEOF(.heap);

PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit);
PROVIDE( __heap_start = __HeapBase );
PROVIDE( __heap_end = __HeapLimit );
}
39 changes: 35 additions & 4 deletions platform/ext/common/gcc/tfm_common_ns.ld
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,51 @@ SECTIONS

KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;

} > RAM

.bss :
.tdata : AT (__etext + SIZEOF(.data))
{
*(.tdata .tdata.* .gnu.linkonce.td.*)
PROVIDE( __data_end = . );
PROVIDE( __data_end__ = . );
PROVIDE( __tdata_end = . );
} > RAM

.tbss (NOLOAD) :
{
. = ALIGN(4);
__bss_start__ = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
PROVIDE( __tbss_end = . );
} > RAM

.tbss_space (NOLOAD) :
{
. = ADDR(.tbss);
. = . + SIZEOF(.tbss);
} > RAM

.bss :
{
. = ALIGN(4);
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM

bss_size = __bss_end__ - __bss_start__;
PROVIDE( __bss_end = __bss_end__ );
PROVIDE( __data_start = ADDR(.data) );
PROVIDE( __data_source = LOADADDR(.data) );
PROVIDE( __data_size = __data_end - __data_start );
PROVIDE( __bss_start = ADDR(.tbss) );
PROVIDE( __bss_size = __bss_end - __bss_start );
PROVIDE( __tls_base = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );

.stack : ALIGN(32)
{
Expand All @@ -164,4 +193,6 @@ SECTIONS
} > RAM

PROVIDE(__stack = __StackTop);
PROVIDE( __heap_start = __HeapBase );
PROVIDE( __heap_end = __HeapLimit );
}
43 changes: 39 additions & 4 deletions platform/ext/common/gcc/tfm_common_s.ld.template
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ SECTIONS
. = ALIGN(4); /* This alignment is needed to make the section size 4 bytes aligned */
} > CODE_RAM AT > FLASH

/* Reset current position for subsequent sections */
. = LOADADDR(.ER_CODE_SRAM) + SIZEOF(.ER_CODE_SRAM);
Comment on lines +195 to +196
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did the linker get confused exactly? Is this really needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

. got set to LOADADDR instead of ADDR when building with binutils 2.43. I'm afraid that after spending several hours chasing this down, I didn't dig into the linker code to figure out precisely why that happened.

Copy link
Author

@keith-packard keith-packard Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've re-added this patch as it is necessary even with SDK 0.17.4.


ASSERT(S_RAM_CODE_START % 4 == 0, "S_RAM_CODE_START must be divisible by 4")

Image$$ER_CODE_SRAM$$RO$$Base = ADDR(.ER_CODE_SRAM);
Expand Down Expand Up @@ -573,13 +576,35 @@ SECTIONS
. = ALIGN(4);

} > RAM AT> FLASH

.TFM_TDATA : ALIGN_WITH_INPUT
{
*(.tdata .tdata.* .gnu.linkonce.td.*)
PROVIDE( __data_end = . );
PROVIDE( __tdata_end = . );
} > RAM AT> FLASH

Image$$ER_TFM_DATA$$RW$$Base = ADDR(.TFM_DATA);
Image$$ER_TFM_DATA$$RW$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA);
Image$$ER_TFM_DATA$$RW$$Limit = ADDR(.TFM_TDATA) + SIZEOF(.TFM_TDATA);

.TFM_BSS ALIGN(4) (NOLOAD) :
.TFM_TBSS (NOLOAD) :
{
__bss_start__ = .;

*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end = . );
PROVIDE( __tbss_end = . );
} > RAM AT> RAM

.TFM_TBSS_SPACE (NOLOAD) :
{
. = ADDR(.TFM_TBSS);
. = . + SIZEOF(.TFM_TBSS);
} > RAM AT> RAM

.TFM_BSS ALIGN(4) (NOLOAD) :
{
/* The runtime partition placed order is same as load partition */
__partition_runtime_start__ = .;
KEEP(*(.bss.part_runtime_priority_00))
Expand All @@ -600,16 +625,26 @@ SECTIONS
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__bss_end = .;
} > RAM AT> RAM
Image$$ER_TFM_DATA$$ZI$$Base = ADDR(.TFM_BSS);
Image$$ER_TFM_DATA$$ZI$$Base = ADDR(.TFM_TBSS);
Image$$ER_TFM_DATA$$ZI$$Limit = ADDR(.TFM_BSS) + SIZEOF(.TFM_BSS);
Image$$ER_PART_RT_POOL$$ZI$$Base = __partition_runtime_start__;
Image$$ER_PART_RT_POOL$$ZI$$Limit = __partition_runtime_end__;
Image$$ER_SERV_RT_POOL$$ZI$$Base = __service_runtime_start__;
Image$$ER_SERV_RT_POOL$$ZI$$Limit = __service_runtime_end__;

Image$$ER_TFM_DATA$$Base = ADDR(.TFM_DATA);
Image$$ER_TFM_DATA$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA) + SIZEOF(.TFM_BSS);
Image$$ER_TFM_DATA$$Limit = ADDR(.TFM_BSS) + SIZEOF(.TFM_BSS);

PROVIDE( __data_start = ADDR(.TFM_DATA) );
PROVIDE( __data_source = LOADADDR(.TFM_DATA) );
PROVIDE( __data_size = __data_end - __data_start );
PROVIDE( __bss_start = ADDR(.TFM_TBSS) );
PROVIDE( __bss_size = __bss_end - __bss_start );
PROVIDE( __tls_base = SIZEOF(.TFM_TDATA) ? ADDR(.TFM_TDATA) : ADDR(.TFM_TBSS) );
PROVIDE( __tls_align = MAX(ALIGNOF(.TFM_TDATA), ALIGNOF(.TFM_TBSS)) );
PROVIDE(__arm32_tls_tcb_offset = MAX(8, __tls_align) );

#if defined(CONFIG_TFM_USE_TRUSTZONE)
Image$$ER_VENEER$$Base = ADDR(.gnu.sgstubs);
Expand Down
46 changes: 44 additions & 2 deletions platform/ext/common/gcc/tfm_isolation_s.ld.template
Original file line number Diff line number Diff line change
Expand Up @@ -210,20 +210,22 @@ SECTIONS
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
PROVIDE_HIDDEN (__bothinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);

. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__bothinit_array_end = .);

. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);

Expand Down Expand Up @@ -251,6 +253,10 @@ SECTIONS
LONG (ADDR(.ER_CODE_SRAM))
LONG (SIZEOF(.ER_CODE_SRAM) / 4)
#endif
LONG (LOADADDR(.TFM_TDATA))
LONG (ADDR(.TFM_TLS_BASE))
LONG (SIZEOF(.TFM_TDATA) / 4)

__copy_table_end__ = .;

/* .zero.table */
Expand All @@ -265,6 +271,10 @@ SECTIONS
LONG (ADDR(.TFM_SP_META_PTR))
LONG (SIZEOF(.TFM_SP_META_PTR) / 4)
#endif

LONG (ADDR(.TFM_TLS_BASE) + SIZEOF(.TFM_TDATA))
LONG ((SIZEOF(.TFM_TLS_BASE) - SIZEOF(.TFM_TDATA)) / 4)

__zero_table_end__ = .;

/* Capture all remaining code (except RAM code) in the privileged TF-M
Expand Down Expand Up @@ -327,6 +337,9 @@ SECTIONS
. = ALIGN(4); /* This alignment is needed to make the section size 4 bytes aligned */
} > CODE_RAM AT > FLASH

/* Reset current position for subsequent sections */
. = LOADADDR(.ER_CODE_SRAM) + SIZEOF(.ER_CODE_SRAM);

ASSERT(S_RAM_CODE_START % 4 == 0, "S_RAM_CODE_START must be divisible by 4")

Image$$ER_CODE_SRAM$$RO$$Base = ADDR(.ER_CODE_SRAM);
Expand Down Expand Up @@ -549,6 +562,10 @@ SECTIONS
. = ALIGN(4);
} > RAM AT > FLASH

PROVIDE(__data_source = LOADADDR(.TFM_DATA));
PROVIDE(__data_start = ADDR(.TFM_DATA));
PROVIDE(__data_size = SIZEOF(.TFM_DATA));

.TFM_BSS ALIGN(4) (NOLOAD) :
{
__bss_start__ = .;
Expand All @@ -574,6 +591,31 @@ SECTIONS
. = ALIGN(4);
__bss_end__ = .;
} > RAM

PROVIDE(__bss_start = ADDR(.TFM_BSS));
PROVIDE(__bss_size = SIZEOF(.TFM_BSS));

.TFM_TDATA :
{
PROVIDE( __tls_start_addr = . );
*(.tdata .tdata.* .gnu.linkonce.td.*)
} > RAM

.TFM_TBSS :
{
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tls_end_addr = . );
} > RAM

.TFM_TLS_BASE : {
. = . + (__tls_end_addr - __tls_start_addr);
} > RAM
PROVIDE( __tls_base = ADDR(.TFM_TLS_BASE) );
PROVIDE( __tls_align = MAX(ALIGNOF(.TFM_TDATA), ALIGNOF(.TFM_TBSS)) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );

Image$$ER_PART_RT_POOL$$ZI$$Base = __partition_runtime_start__;
Image$$ER_PART_RT_POOL$$ZI$$Limit = __partition_runtime_end__;
Image$$ER_SERV_RT_POOL$$ZI$$Base = __service_runtime_start__;
Expand Down
3 changes: 3 additions & 0 deletions platform/ext/common/llvm/tfm_isolation_s.ld.template
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ SECTIONS
. = ALIGN(4); /* This alignment is needed to make the section size 4 bytes aligned */
} > CODE_RAM AT > FLASH

/* Reset current position for subsequent sections */
. = LOADADDR(.ER_CODE_SRAM) + SIZEOF(.ER_CODE_SRAM);

ASSERT(S_RAM_CODE_START % 4 == 0, "S_RAM_CODE_START must be divisible by 4")

Image$$ER_CODE_SRAM$$RO$$Base = ADDR(.ER_CODE_SRAM);
Expand Down
48 changes: 48 additions & 0 deletions platform/ext/common/picolibc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright © 2025, Keith Packard <[email protected]>
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/

#include <stdint.h>
#include <string.h>
#include "config_impl.h"

/*
* Picolibc's startup code only initializes a single data and bss
* segment. Augment that by initializing the remaining segments using
* the lists provided by the linker script in a constructor which will
* be called from _start
*/

#if defined(__PICOLIBC__) && TFM_ISOLATION_LEVEL > 0

static void __attribute__((constructor))
picolibc_startup(void)
{
typedef struct __copy_table {
uint32_t const* src;
uint32_t* dest;
uint32_t wlen;
} __copy_table_t;

typedef struct __zero_table {
uint32_t* dest;
uint32_t wlen;
} __zero_table_t;

extern const __copy_table_t __copy_table_start__;
extern const __copy_table_t __copy_table_end__;
extern const __zero_table_t __zero_table_start__;
extern const __zero_table_t __zero_table_end__;

for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) {
memcpy(pTable->dest, pTable->src, pTable->wlen << 2);
}

for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) {
memset(pTable->dest, 0, pTable->wlen << 2);
}
}
#endif
10 changes: 10 additions & 0 deletions platform/ext/common/syscalls_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
#include <stddef.h>
#include <stdint.h>

#ifdef __PICOLIBC__
__attribute__((weak))
void _exit(int status)
{
(void) status;
for(;;);
}
#else
__attribute__((weak))
void _close(void)
{
Expand Down Expand Up @@ -53,3 +61,5 @@ __attribute__((weak))
void _write(void)
{
}

#endif /* !__PICOLIBC__ */
2 changes: 1 addition & 1 deletion platform/ext/common/uart_stdout.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ int fputc(int ch, FILE *f)
/* Redirect sdtio for PicoLib in LLVM toolchain
as per https://github.com/picolibc/picolibc/blob/main/doc/os.md
'fputch()' named intentionally different from 'fputc()' from picolib */
#elif defined(__clang_major__)
#elif defined(__PICOLIBC__)

int fputch(char ch, struct __file *f)
{
Expand Down
Loading