Implementation Details
In many ways, Zephyr provides support like any POSIX OS; API bindings are provided in the C programming language, POSIX headers are available in the standard include path, when configured.
Unlike other multi-purpose POSIX operating systems
Zephyr is not “a POSIX OS”. The Zephyr kernel was not designed around the POSIX standard, and POSIX support is an opt-in feature
Zephyr apps are not linked separately, nor do they execute as subprocesses
Zephyr, libraries, and application code are compiled and linked together, running similarly to a single-process application, in a single (possibly virtual) address space
Zephyr does not provide a POSIX shell, compiler, utilities, and is not self-hosting.
Note
Unlike the Linux kernel or FreeBSD, Zephyr does not maintain a static table of system call numbers for each supported architecture, but instead generates system calls dynamically at build time. See System Calls for more information.
Design
As a library, Zephyr’s POSIX API implementation makes an effort to be a thin abstraction layer between the application, middleware, and the Zephyr kernel.
Some general design considerations:
The POSIX interface and implementations should be part of Zephyr’s POSIX library, and not elsewhere, unless required both by the POSIX API implementation and some other feature. An example where the implementation should remain part of the POSIX implementation is
getopt()
. Examples where the implementation should be part of separate libraries are multithreading and networking.When the POSIX API and another Zephyr subsystem both rely on a feature, the implementation of that feature should be as a separate Zephyr library that can be used by both the POSIX API and the other library or subsystem. This reduces the likelihood of dependency cycles in code. When practical, that rule should expand to include macros. In the example below,
libposix
depends onlibzfoo
for the implementation of some functionality “foo” in Zephyr. Iflibzfoo
also depends onlibposix
, then there is a dependency cycle. The cycle can be removed via mutual dependency,libcommon
.
POSIX API calls should be provided as regular callable C functions; if a Zephyr System Call is needed as part of the implementation, the declaration and the implementation of that system call should be hidden behind the POSIX API.