libc #
This page explains the LionsOS libc implementation and how to configure and build it using the provided Makefile snippet.
Overview #
LionsOS uses a custom libc setup based on our fork of musllibc. We also provide implementations of a POSIX subset and vendored compiler runtime helpers. This setup is compatible with the sDDF build system.
The final libc.a is built from three main sources:
- musllibc (our fork): Provides core libc functionality, with system calls redirected to a general dispatcher.
- Syscall implementations: Functionality found in
lib/libc/posix/. - Compiler runtime helpers: Low-level arithmetic and runtime support from
lib/libc/compiler_rt/.
Available Functionality #
Syscall implementation covers a subset of POSIX sufficient for many embedded applications. Below is a summary of available functionality.
- Standard I/O:
STDOUTandSTDERRare opened by default on the expected file descriptors and output to a connected serial subsystem, enablingprintf. - File System: Standard operations
openat,read/readv,write/writev,lseek,close,fstat/fstatat,mkdirat, andunlinkatare available. Symbolic links are not supported. - Networking: TCP sockets (IPv4 only) are supported for both client and server
applications, including
socket,bind,listen,accept,connect,sendto,recvfrom,getsockname,getpeername, andppoll(timeout and sigmask are ignored). UDP is not supported. - Time:
clock_gettime(monotonic) andnanosleepare available. - Memory: Heap allocation via
brkand anonymousmmap, drawing from a static 1MB pool. Memory cannot be freed. - Other:
getrandomprovides pseudo-random data (insecure, usesrand).fcntlsupportsF_GETFL/F_SETFLfor non-blocking I/O.
musllibc Fork: Syscall Redirection #
Our musllibc fork replaces architecture-specific inline assembly syscall traps
(like svc 0 on AArch64) with a generic function call mechanism. Instead of
invoking syscalls directly with assembly, musl’s internal __syscallN functions
now call a dispatcher function via __sysinfo.
In upstream musl, __sysinfo is normally a hook for vDSO (Virtual Dynamic
Shared Object) support on Linux systems, letting musl call kernel-provided
user-space functions without a full syscall. We’ve repurposed it as a general
syscall dispatcher, since all our syscalls are provided in a user-space library.
As a result, all libc syscall invocations are routed through the LionsOS POSIX
syscall handler, which is implemented in the lib/libc/posix/ layer.
For example:
#define CALL_SYSINFO(n, ...) ((long(*)(long,...))__sysinfo)(n, ##__VA_ARGS__)
static inline long __syscall3(long n, long a1, long a2, long a3) {
return CALL_SYSINFO(n, a1, a2, a3);
}
LionsOS provides the __sysinfo implementation in libc_init():
void libc_init() {
/* Syscall table init */
__sysinfo = sel4_vsyscall;
...
Usage #
To build the LionsOS libc, include the lib/libc/libc.mk snippet in your
top-level Makefile:
include $(LIONSOS)/lib/libc/libc.mk
This snippet defines and builds the following targets:
$(LIONS_LIBC): The absolute path to the libc build directory.$(LIONS_LIBC)/include: The installed musl headers for components requiring libc. This is also a build target for musllibc, allowing you to specify the headers as a build prerequisite.$(LIONS_LIBC)/lib/libc.a: The final static libc archive combining musl, syscalls, and compiler runtime objects. This must be linked into your final binary. Please note that libmath (libm.a) is bundled with ourlibc.a, so there is no need to link to this explicitly.
For sDDF components, do not set SDDF_CUSTOM_LIBC. Instead, define the
following:
SDDF_LIBC_INCLUDE := $(LIONS_LIBC)/include
include <path_to_sddf_snippet.mk>
More information on SDDF_LIBC_INCLUDE can be found in the
sDDF docs.
Note that the LionsOS libc.mk automatically adds the headers to CFLAGS as an
include path so there is no need to do this explicitly.
This ensures sDDF components use the LionsOS library headers instead of falling back to sDDF’s internal, vendored libc. Since sDDF components list this as a prerequisite, it also guarantees the headers are available before compilation begins.
POSIX Implementations and Compiler Runtime Support #
The extra functionality is provided via:
lib/libc/posix/*.c: POSIX wrappers and syscall implementations.lib/libc/compiler_rt/*.c: Arithmetic helpers and low-level runtime support.
These files are compiled into objects and simply bundled into the final libc.a
archive.