Skip to content

Commit 6f5ffba

Browse files
committed
[zep noup] Use picolibc instead of newlib-nano
1. Support picolibc stdio. There was already picolibc support code present in the library for the ARM LLVM toolchain. The conditionals which selected it have been changed to use __PICOLIBC__ instead of __clang_major__. 2. Add _exit stub. Code using assert or abort end up calling _exit through the picolibc signal handling code. 3. Switch to picolibc.specs. This is needed for toolchains which don't use picolibc by default, and can also be used without trouble in toolchains where picolibc is the default. 4. Define CONFIG_PICOLIBC when using picolibc. This is enabled by default, but can be disabled on the cmake command line. 5. Define picolibc_startup to initialize all .data and .bss segments using the standard tf-m arrays. 6. Add picolibc.c to many source lists when CONFIG_PICOLIBC is defined. If this file is missign, picolibc_startup will not be defined which should cause a failure at link time. Signed-off-by: Keith Packard <keithp@keithp.com>
1 parent f48bb03 commit 6f5ffba

File tree

17 files changed

+140
-9
lines changed

17 files changed

+140
-9
lines changed

bl1/bl1_1/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ target_link_options(bl1_1
4040
target_sources(bl1_1
4141
PRIVATE
4242
main.c
43+
$<$<BOOL:${CONFIG_PICOLIBC}>:${CMAKE_SOURCE_DIR}/platform/ext/common/picolibc.c>
4344
$<$<BOOL:${CONFIG_GNU_SYSCALL_STUB_ENABLED}>:${CMAKE_SOURCE_DIR}/platform/ext/common/syscalls_stub.c>
4445
)
4546

bl1/bl1_2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ target_link_options(bl1_2
4242
target_sources(bl1_2
4343
PRIVATE
4444
main.c
45+
$<$<BOOL:${CONFIG_PICOLIBC}>:${CMAKE_SOURCE_DIR}/platform/ext/common/picolibc.c>
4546
$<$<BOOL:${CONFIG_GNU_SYSCALL_STUB_ENABLED}>:${CMAKE_SOURCE_DIR}/platform/ext/common/syscalls_stub.c>
4647
)
4748

bl2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ add_executable(bl2
128128
$<$<BOOL:${DEFAULT_MCUBOOT_FLASH_MAP}>:src/default_flash_map.c>
129129
$<$<BOOL:${MCUBOOT_DATA_SHARING}>:src/shared_data.c>
130130
$<$<BOOL:${PLATFORM_DEFAULT_PROVISIONING}>:src/provisioning.c>
131+
$<$<BOOL:${CONFIG_PICOLIBC}>:${CMAKE_SOURCE_DIR}/platform/ext/common/picolibc.c>
131132
$<$<BOOL:${CONFIG_GNU_SYSCALL_STUB_ENABLED}>:${CMAKE_SOURCE_DIR}/platform/ext/common/syscalls_stub.c>
132133
)
133134

cmake/install.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,11 @@ install(DIRECTORY $<BUILD_INTERFACE:${CMSIS_PATH}/CMSIS/Core/Include>
254254
$<BUILD_INTERFACE:${CMSIS_PATH}/CMSIS/Driver/Include>
255255
DESTINATION ${INSTALL_PLATFORM_NS_DIR}/ext/cmsis)
256256

257+
if(CONFIG_PICOLIBC)
258+
install(FILES ${PLATFORM_DIR}/ext/common/picolibc.c
259+
DESTINATION ${INSTALL_PLATFORM_NS_DIR}/ext/common)
260+
endif()
261+
257262
if(PLATFORM_DEFAULT_UART_STDOUT)
258263
install(FILES ${PLATFORM_DIR}/ext/common/uart_stdout.c
259264
${PLATFORM_DIR}/ext/common/uart_stdout.h

cmake/spe-CMakeLists.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ add_subdirectory(platform)
104104

105105
target_sources(platform_ns
106106
PRIVATE
107+
$<$<BOOL:${CONFIG_PICOLIBC}>:${CMAKE_CURRENT_SOURCE_DIR}/platform/ext/common/picolibc.c>
107108
$<$<BOOL:${PLATFORM_DEFAULT_UART_STDOUT}>:${CMAKE_CURRENT_SOURCE_DIR}/platform/ext/common/uart_stdout.c>
108109
)
109110

platform/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ target_sources(platform_s
8181
$<$<BOOL:${PLATFORM_DEFAULT_PROVISIONING}>:ext/common/provisioning.c>
8282
$<$<OR:$<BOOL:${TEST_S_FPU}>,$<BOOL:${TEST_NS_FPU}>>:${CMAKE_SOURCE_DIR}/platform/ext/common/test_interrupt.c>
8383
$<$<BOOL:${TFM_SANITIZE}>:ext/common/tfm_sanitize_handlers.c>
84+
$<$<BOOL:${CONFIG_PICOLIBC}>:ext/common/picolibc.c>
8485
./ext/common/tfm_fatal_error.c
8586
)
8687

@@ -203,6 +204,7 @@ if(BL2)
203204
$<$<OR:$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>,$<BOOL:${PLATFORM_DEFAULT_OTP}>>:ext/common/template/flash_otp_nv_counters_backend.c>
204205
$<$<BOOL:${PLATFORM_DEFAULT_OTP}>:ext/common/template/otp_flash.c>
205206
$<$<BOOL:${BL2_SANITIZE}>:ext/common/tfm_sanitize_handlers.c>
207+
$<$<BOOL:${CONFIG_PICOLIBC}>:ext/common/picolibc.c>
206208
./ext/common/tfm_fatal_error.c
207209
)
208210

@@ -304,6 +306,7 @@ if(BL1 AND PLATFORM_DEFAULT_BL1)
304306
$<$<BOOL:${PLATFORM_DEFAULT_OTP}>:ext/common/template/flash_otp_nv_counters_backend.c>
305307
$<$<BOOL:${PLATFORM_DEFAULT_OTP}>:ext/common/template/otp_flash.c>
306308
$<$<OR:$<BOOL:${BL1_1_SANITIZE}>,$<BOOL:${TFM_BL1_2_SANITIZE}>>:ext/common/tfm_sanitize_handlers.c>
309+
$<$<BOOL:${CONFIG_PICOLIBC}>:ext/common/picolibc.c>
307310
./ext/common/tfm_fatal_error.c
308311
)
309312

@@ -359,6 +362,7 @@ if(BL1 AND PLATFORM_DEFAULT_BL1)
359362
$<$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>:ext/common/template/nv_counters.c>
360363
$<$<OR:$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>,$<BOOL:${PLATFORM_DEFAULT_OTP}>>:ext/common/template/flash_otp_nv_counters_backend.c>
361364
$<$<BOOL:${PLATFORM_DEFAULT_OTP}>:ext/common/template/otp_flash.c>
365+
$<$<BOOL:${CONFIG_PICOLIBC}>:ext/common/picolibc.c>
362366
)
363367

364368
target_link_libraries(platform_bl1_2

platform/ext/common/picolibc.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright © 2025, Keith Packard <keithp@keithp.com>
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+
#ifdef __PICOLIBC__
13+
14+
/*
15+
* Picolibc's startup code only initializes a single data and bss
16+
* segment. Replace that to initialize all of the segments using
17+
* the lists provided by the linker script.
18+
*/
19+
20+
void __libc_init_array(void);
21+
void _start(void);
22+
int main(int, char **);
23+
24+
void
25+
_start(void)
26+
{
27+
typedef struct __copy_table {
28+
uint32_t const* src;
29+
uint32_t* dest;
30+
uint32_t wlen;
31+
} __copy_table_t;
32+
33+
typedef struct __zero_table {
34+
uint32_t* dest;
35+
uint32_t wlen;
36+
} __zero_table_t;
37+
38+
extern const __copy_table_t __copy_table_start__;
39+
extern const __copy_table_t __copy_table_end__;
40+
extern const __zero_table_t __zero_table_start__;
41+
extern const __zero_table_t __zero_table_end__;
42+
43+
for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) {
44+
memcpy(pTable->dest, pTable->src, pTable->wlen << 2);
45+
}
46+
47+
for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) {
48+
memset(pTable->dest, 0, pTable->wlen << 2);
49+
}
50+
51+
__libc_init_array();
52+
main(0, NULL);
53+
return;
54+
}
55+
56+
#endif /* __PICOLIBC__ */

platform/ext/common/provisioning_bundle/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ target_sources(provisioning_bundle
5454
PRIVATE
5555
./provisioning_code.c
5656
./provisioning_data.c
57+
$<$<BOOL:${CONFIG_PICOLIBC}>:${CMAKE_SOURCE_DIR}/platform/ext/common/picolibc.c>
5758
$<$<BOOL:${CONFIG_GNU_SYSCALL_STUB_ENABLED}>:${CMAKE_SOURCE_DIR}/platform/ext/common/syscalls_stub.c>
5859
)
5960

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)