Skip to content

Commit 01be64f

Browse files
committed
Use picolibc instead of newlib-nano
Add picolibc bits to linker scripts. Support picolibc stdio. Add _exit stub. Switch to picolibc.specs Signed-off-by: Keith Packard <[email protected]>
1 parent 00eca70 commit 01be64f

File tree

14 files changed

+349
-36
lines changed

14 files changed

+349
-36
lines changed

platform/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ target_sources(platform_s
9090
target_sources(tfm_s
9191
PRIVATE
9292
ext/common/faults.c
93+
ext/common/picolibc.c
9394
)
9495

9596
target_link_libraries(platform_s

platform/ext/common/gcc/tfm_common_bl2.ld

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,26 @@ SECTIONS
153153
} > RAM AT > FLASH
154154
Image$$ER_DATA$$Base = ADDR(.data);
155155

156+
.tdata : ALIGN_WITH_INPUT
157+
{
158+
*(.tdata .tdata.* .gnu.linkonce.td.*)
159+
PROVIDE( __data_end = . );
160+
PROVIDE( __tdata_end = . );
161+
} >RAM AT>FLASH
162+
163+
.tbss (NOLOAD) :
164+
{
165+
*(.tbss .tbss.* .gnu.linkonce.tb.*)
166+
*(.tcommon)
167+
PROVIDE( __tls_end = . );
168+
PROVIDE( __tbss_end = . );
169+
} >RAM AT>RAM
170+
171+
.tbss_space (NOLOAD) : {
172+
. = ADDR(.tbss);
173+
. = . + SIZEOF(.tbss);
174+
} >RAM AT>RAM
175+
156176
.bss : ALIGN(4)
157177
{
158178
. = ALIGN(4);
@@ -163,6 +183,16 @@ SECTIONS
163183
__bss_end__ = .;
164184
} > RAM
165185

186+
PROVIDE( __bss_end = __bss_end__ );
187+
PROVIDE( __data_start = ADDR(.data) );
188+
PROVIDE( __data_source = LOADADDR(.data) );
189+
PROVIDE( __data_size = __data_end - __data_start );
190+
PROVIDE( __tls_base = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) );
191+
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
192+
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
193+
PROVIDE( __bss_start = ADDR(.tbss));
194+
PROVIDE( __bss_size = __bss_end - __bss_start );
195+
166196
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
167197
.msp_stack (NOLOAD) : ALIGN(32)
168198
{
@@ -200,4 +230,6 @@ SECTIONS
200230
Image$$ARM_LIB_HEAP$$ZI$$Limit = ADDR(.heap) + SIZEOF(.heap);
201231

202232
PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit);
233+
PROVIDE( __heap_start = __HeapBase );
234+
PROVIDE( __heap_end = __HeapLimit );
203235
}

platform/ext/common/gcc/tfm_common_ns.ld

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,51 @@ SECTIONS
128128

129129
KEEP(*(.jcr*))
130130
. = ALIGN(4);
131-
/* All data end */
132-
__data_end__ = .;
133131

134132
} > RAM
135133

136-
.bss :
134+
.tdata : AT (__etext + SIZEOF(.data))
135+
{
136+
*(.tdata .tdata.* .gnu.linkonce.td.*)
137+
PROVIDE( __data_end = . );
138+
PROVIDE( __data_end__ = . );
139+
PROVIDE( __tdata_end = . );
140+
} > RAM
141+
142+
.tbss (NOLOAD) :
137143
{
138144
. = ALIGN(4);
139145
__bss_start__ = .;
146+
*(.tbss .tbss.* .gnu.linkonce.tb.*)
147+
*(.tcommon)
148+
PROVIDE( __tls_end = . );
149+
PROVIDE( __tbss_end = . );
150+
} > RAM
151+
152+
.tbss_space (NOLOAD) :
153+
{
154+
. = ADDR(.tbss);
155+
. = . + SIZEOF(.tbss);
156+
} > RAM
157+
158+
.bss :
159+
{
160+
. = ALIGN(4);
140161
*(.bss*)
141162
*(COMMON)
142163
. = ALIGN(4);
143164
__bss_end__ = .;
144165
} > RAM
145166

146-
bss_size = __bss_end__ - __bss_start__;
167+
PROVIDE( __bss_end = __bss_end__ );
168+
PROVIDE( __data_start = ADDR(.data) );
169+
PROVIDE( __data_source = LOADADDR(.data) );
170+
PROVIDE( __data_size = __data_end - __data_start );
171+
PROVIDE( __bss_start = ADDR(.tbss) );
172+
PROVIDE( __bss_size = __bss_end - __bss_start );
173+
PROVIDE( __tls_base = SIZEOF(.tdata) ? ADDR(.tdata) : ADDR(.tbss) );
174+
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
175+
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
147176

148177
.stack : ALIGN(32)
149178
{
@@ -164,4 +193,6 @@ SECTIONS
164193
} > RAM
165194

166195
PROVIDE(__stack = __StackTop);
196+
PROVIDE( __heap_start = __HeapBase );
197+
PROVIDE( __heap_end = __HeapLimit );
167198
}

platform/ext/common/gcc/tfm_common_s.ld.template

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -576,13 +576,35 @@ SECTIONS
576576
. = ALIGN(4);
577577

578578
} > RAM AT> FLASH
579+
580+
.TFM_TDATA : ALIGN_WITH_INPUT
581+
{
582+
*(.tdata .tdata.* .gnu.linkonce.td.*)
583+
PROVIDE( __data_end = . );
584+
PROVIDE( __tdata_end = . );
585+
} > RAM AT> FLASH
586+
579587
Image$$ER_TFM_DATA$$RW$$Base = ADDR(.TFM_DATA);
580-
Image$$ER_TFM_DATA$$RW$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA);
588+
Image$$ER_TFM_DATA$$RW$$Limit = ADDR(.TFM_TDATA) + SIZEOF(.TFM_TDATA);
581589

582-
.TFM_BSS ALIGN(4) (NOLOAD) :
590+
.TFM_TBSS (NOLOAD) :
583591
{
584592
__bss_start__ = .;
585593

594+
*(.tbss .tbss.* .gnu.linkonce.tb.*)
595+
*(.tcommon)
596+
PROVIDE( __tls_end = . );
597+
PROVIDE( __tbss_end = . );
598+
} > RAM AT> RAM
599+
600+
.TFM_TBSS_SPACE (NOLOAD) :
601+
{
602+
. = ADDR(.TFM_TBSS);
603+
. = . + SIZEOF(.TFM_TBSS);
604+
} > RAM AT> RAM
605+
606+
.TFM_BSS ALIGN(4) (NOLOAD) :
607+
{
586608
/* The runtime partition placed order is same as load partition */
587609
__partition_runtime_start__ = .;
588610
KEEP(*(.bss.part_runtime_priority_00))
@@ -603,16 +625,26 @@ SECTIONS
603625
*(COMMON)
604626
. = ALIGN(4);
605627
__bss_end__ = .;
628+
__bss_end = .;
606629
} > RAM AT> RAM
607-
Image$$ER_TFM_DATA$$ZI$$Base = ADDR(.TFM_BSS);
630+
Image$$ER_TFM_DATA$$ZI$$Base = ADDR(.TFM_TBSS);
608631
Image$$ER_TFM_DATA$$ZI$$Limit = ADDR(.TFM_BSS) + SIZEOF(.TFM_BSS);
609632
Image$$ER_PART_RT_POOL$$ZI$$Base = __partition_runtime_start__;
610633
Image$$ER_PART_RT_POOL$$ZI$$Limit = __partition_runtime_end__;
611634
Image$$ER_SERV_RT_POOL$$ZI$$Base = __service_runtime_start__;
612635
Image$$ER_SERV_RT_POOL$$ZI$$Limit = __service_runtime_end__;
613636

614637
Image$$ER_TFM_DATA$$Base = ADDR(.TFM_DATA);
615-
Image$$ER_TFM_DATA$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA) + SIZEOF(.TFM_BSS);
638+
Image$$ER_TFM_DATA$$Limit = ADDR(.TFM_BSS) + SIZEOF(.TFM_BSS);
639+
640+
PROVIDE( __data_start = ADDR(.TFM_DATA) );
641+
PROVIDE( __data_source = LOADADDR(.TFM_DATA) );
642+
PROVIDE( __data_size = __data_end - __data_start );
643+
PROVIDE( __bss_start = ADDR(.TFM_TBSS) );
644+
PROVIDE( __bss_size = __bss_end - __bss_start );
645+
PROVIDE( __tls_base = SIZEOF(.TFM_TDATA) ? ADDR(.TFM_TDATA) : ADDR(.TFM_TBSS) );
646+
PROVIDE( __tls_align = MAX(ALIGNOF(.TFM_TDATA), ALIGNOF(.TFM_TBSS)) );
647+
PROVIDE(__arm32_tls_tcb_offset = MAX(8, __tls_align) );
616648

617649
#if defined(CONFIG_TFM_USE_TRUSTZONE)
618650
Image$$ER_VENEER$$Base = ADDR(.gnu.sgstubs);

platform/ext/common/gcc/tfm_isolation_s.ld.template

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,20 +210,22 @@ SECTIONS
210210
. = ALIGN(4);
211211
/* preinit data */
212212
PROVIDE_HIDDEN (__preinit_array_start = .);
213+
PROVIDE_HIDDEN (__bothinit_array_start = .);
213214
KEEP(*(.preinit_array))
214215
PROVIDE_HIDDEN (__preinit_array_end = .);
215216

216217
. = ALIGN(4);
217218
/* init data */
218219
PROVIDE_HIDDEN (__init_array_start = .);
219-
KEEP(*(SORT(.init_array.*)))
220+
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)))
220221
KEEP(*(.init_array))
221222
PROVIDE_HIDDEN (__init_array_end = .);
223+
PROVIDE_HIDDEN (__bothinit_array_end = .);
222224

223225
. = ALIGN(4);
224226
/* finit data */
225227
PROVIDE_HIDDEN (__fini_array_start = .);
226-
KEEP(*(SORT(.fini_array.*)))
228+
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
227229
KEEP(*(.fini_array))
228230
PROVIDE_HIDDEN (__fini_array_end = .);
229231

@@ -251,6 +253,10 @@ SECTIONS
251253
LONG (ADDR(.ER_CODE_SRAM))
252254
LONG (SIZEOF(.ER_CODE_SRAM) / 4)
253255
#endif
256+
LONG (LOADADDR(.TFM_TDATA))
257+
LONG (ADDR(.TFM_TLS_BASE))
258+
LONG (SIZEOF(.TFM_TDATA) / 4)
259+
254260
__copy_table_end__ = .;
255261

256262
/* .zero.table */
@@ -265,6 +271,10 @@ SECTIONS
265271
LONG (ADDR(.TFM_SP_META_PTR))
266272
LONG (SIZEOF(.TFM_SP_META_PTR) / 4)
267273
#endif
274+
275+
LONG (ADDR(.TFM_TLS_BASE) + SIZEOF(.TFM_TDATA))
276+
LONG ((SIZEOF(.TFM_TLS_BASE) - SIZEOF(.TFM_TDATA)) / 4)
277+
268278
__zero_table_end__ = .;
269279

270280
/* Capture all remaining code (except RAM code) in the privileged TF-M
@@ -552,6 +562,10 @@ SECTIONS
552562
. = ALIGN(4);
553563
} > RAM AT > FLASH
554564

565+
PROVIDE(__data_source = LOADADDR(.TFM_DATA));
566+
PROVIDE(__data_start = ADDR(.TFM_DATA));
567+
PROVIDE(__data_size = SIZEOF(.TFM_DATA));
568+
555569
.TFM_BSS ALIGN(4) (NOLOAD) :
556570
{
557571
__bss_start__ = .;
@@ -577,6 +591,31 @@ SECTIONS
577591
. = ALIGN(4);
578592
__bss_end__ = .;
579593
} > RAM
594+
595+
PROVIDE(__bss_start = ADDR(.TFM_BSS));
596+
PROVIDE(__bss_size = SIZEOF(.TFM_BSS));
597+
598+
.TFM_TDATA :
599+
{
600+
PROVIDE( __tls_start_addr = . );
601+
*(.tdata .tdata.* .gnu.linkonce.td.*)
602+
} > RAM
603+
604+
.TFM_TBSS :
605+
{
606+
*(.tbss .tbss.* .gnu.linkonce.tb.*)
607+
*(.tcommon)
608+
PROVIDE( __tls_end_addr = . );
609+
} > RAM
610+
611+
.TFM_TLS_BASE : {
612+
. = . + (__tls_end_addr - __tls_start_addr);
613+
} > RAM
614+
PROVIDE( __tls_base = ADDR(.TFM_TLS_BASE) );
615+
PROVIDE( __tls_align = MAX(ALIGNOF(.TFM_TDATA), ALIGNOF(.TFM_TBSS)) );
616+
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
617+
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );
618+
580619
Image$$ER_PART_RT_POOL$$ZI$$Base = __partition_runtime_start__;
581620
Image$$ER_PART_RT_POOL$$ZI$$Limit = __partition_runtime_end__;
582621
Image$$ER_SERV_RT_POOL$$ZI$$Base = __service_runtime_start__;

platform/ext/common/picolibc.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright © 2025, Keith Packard <[email protected]>
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*
6+
*/
7+
8+
#include <stdint.h>
9+
#include <string.h>
10+
#include "config_impl.h"
11+
12+
/*
13+
* Picolibc's startup code only initializes a single data and bss
14+
* segment. Augment that by initializing the remaining segments using
15+
* the lists provided by the linker script in a constructor which will
16+
* be called from _start
17+
*/
18+
19+
#if defined(__PICOLIBC__) && TFM_ISOLATION_LEVEL > 0
20+
21+
static void __attribute__((constructor))
22+
picolibc_startup(void)
23+
{
24+
typedef struct __copy_table {
25+
uint32_t const* src;
26+
uint32_t* dest;
27+
uint32_t wlen;
28+
} __copy_table_t;
29+
30+
typedef struct __zero_table {
31+
uint32_t* dest;
32+
uint32_t wlen;
33+
} __zero_table_t;
34+
35+
extern const __copy_table_t __copy_table_start__;
36+
extern const __copy_table_t __copy_table_end__;
37+
extern const __zero_table_t __zero_table_start__;
38+
extern const __zero_table_t __zero_table_end__;
39+
40+
for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) {
41+
memcpy(pTable->dest, pTable->src, pTable->wlen << 2);
42+
}
43+
44+
for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) {
45+
memset(pTable->dest, 0, pTable->wlen << 2);
46+
}
47+
}
48+
#endif

platform/ext/common/syscalls_stub.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
#include <stddef.h>
1515
#include <stdint.h>
1616

17+
#ifdef __PICOLIBC__
18+
__attribute__((weak))
19+
void _exit(int status)
20+
{
21+
(void) status;
22+
for(;;);
23+
}
24+
#else
1725
__attribute__((weak))
1826
void _close(void)
1927
{
@@ -53,3 +61,5 @@ __attribute__((weak))
5361
void _write(void)
5462
{
5563
}
64+
65+
#endif /* !__PICOLIBC__ */

platform/ext/common/uart_stdout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ int fputc(int ch, FILE *f)
8585
/* Redirect sdtio for PicoLib in LLVM toolchain
8686
as per https://github.com/picolibc/picolibc/blob/main/doc/os.md
8787
'fputch()' named intentionally different from 'fputc()' from picolib */
88-
#elif defined(__clang_major__)
88+
#elif defined(__PICOLIBC__)
8989

9090
int fputch(char ch, struct __file *f)
9191
{

0 commit comments

Comments
 (0)