Unit Syscalls
Return to Unit Reference
Contents
Description
Ultibo Newlib C Library Syscalls Interface unit
This unit provides the system calls (syscalls) interface for the Newlib C library implementation to allow code compiled with GCC to be linked with Ultibo applications.
The Newlib C library is a portable C library designed to be used in embedded environments as well as many other situations. It is made available by RedHat from the sourceware.org website, new releases are made at least yearly and this unit has been developed using 2.4.0 but should work mostly unchanged with future releases.
The build process below creates the libc.a, libm.a and libg.a static libraries, in addition to those GCC also requires the libgcc.a support library which is built at the same time as the compiler and provided in the distribution.
The build process is documented for Debian but should be translatable to other platforms. As documented this will produce a version of Newlib that has support for recursive library calls, has dynamic support for multiple threads and is compiled for the specific architectures that are supported by Ultibo.
Note that Newlib supports code compiled with other C compilers so it should be completely possible to link code generated by other C compilers with Ultibo applications. At this stage it has only been tested with GCC.
For the official documentation of the functions supported by this unit please see:
- POSIX threads (pthreads) - http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html
- POSIX threads (pthreads) - http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html
Building Newlib
Flags:
REENTRANT_SYSCALLS_PROVIDED
__DYNAMIC_REENT__
__LARGE64_FILES (Note: Not currently supported by Newlib, need to modify \newlib\configure.host to enable stdio64 support for arm-none-eabi or aarch64-none-elf)
Options:
Raspberry Pi
-mabi=aapcs -marm -march=armv6 -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard
Raspberry Pi2/3 (32-bit)
-mabi=aapcs -marm -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard
Raspberry Pi3 (64-bit)
-mabi=lp64 (Note: Supported only by later versions of GCC) -march=armv8-a
Build:
Download Newlib (currently 2.4.0) from ftp://sourceware.org/pub/newlib/index.html
Unpack to folder $HOME/newlib-2.4.0
Build ARMv6:
cd mkdir build-newlib-armv6 cd build-newlib-armv6 export PATH=$HOME/gcc-arm-none-eabi-5_4-2016q2/bin:$PATH ../newlib-2.4.0/configure --disable-multilib --target=arm-none-eabi CFLAGS_FOR_TARGET="-O2 -mabi=aapcs -marm -march=armv6 -mfpu=vfp -mfloat-abi=hard -DREENTRANT_SYSCALLS_PROVIDED -D__DYNAMIC_REENT__" make all
Dump:
cd arm-none-eabi/newlib arm-none-eabi-objdump -d libc.a > libc.list arm-none-eabi-objdump -d libg.a > libg.list arm-none-eabi-objdump -d libm.a > libm.list
Build ARMv7:
cd mkdir build-newlib-armv7 cd build-newlib-armv7 export PATH=$HOME/gcc-arm-none-eabi-5_4-2016q2/bin:$PATH ../newlib-2.4.0/configure --disable-multilib --target=arm-none-eabi CFLAGS_FOR_TARGET="-O2 -mabi=aapcs -marm -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard -DREENTRANT_SYSCALLS_PROVIDED -D__DYNAMIC_REENT__" make all
Dump:
cd arm-none-eabi/newlib arm-none-eabi-objdump -d libc.a > libc.list arm-none-eabi-objdump -d libg.a > libg.list arm-none-eabi-objdump -d libm.a > libm.list
Build ARMv8:
cd mkdir build-newlib-armv8 cd build-newlib-armv8 export PATH=$HOME/gcc-linaro-aarch64-none-elf-4.8-2014.04_linux/bin:$PATH ../newlib-2.4.0/configure --disable-multilib --target=aarch64-none-elf CFLAGS_FOR_TARGET="-O2 -march=armv8-a -DREENTRANT_SYSCALLS_PROVIDED -D__DYNAMIC_REENT__" make all
Dump:
cd aarch64-none-elf/newlib aarch64-none-elf-objdump -d libc.a > libc.list aarch64-none-elf-objdump -d libg.a > libg.list aarch64-none-elf-objdump -d libm.a > libm.list
Notes:
File handles (fd) passed to and returned from this unit are int values which are 32-bit however internally Newlib stores these into the _file member of a _FILE structure (see below) and this is defined as short which is only 16-bit. Because of this we have to map each Ultibo handle to a TSyscallsEntry and use the functions SyscallsAddEntry, SyscallsRemoveEntry and SyscallsGetEntry which start at zero and increment to 65535.
The global errno variable (not used for reentrant version ) is defined in:
\newlib\libc\reent\reent.c int errno;
The global environ variable is defined in:
\newlib\libc\stdlib\environ.c char **environ = &initial_env[0];
The TZ environment variable is used by a number of functions in Newlib including tzset and strftime. This variable can be set on the command line or using the SetEnvironmentVariable() function in the Ultibo unit. See the GNU C library reference for details of the format and value of the TZ environment variable:
https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
Memory management for the C library and code compiled to use it is handled by Newlib itself which provides a complete implementation of malloc(), free(), calloc(), realloc() and others.
This implementation relies on the underlying platform to implement sbrk() (_sbrk_r for the reentrant build of the library) and this unit provides all of the necessary details of this to allow full functionality of the memory management within the C library.
Because sbrk() expects a contiguous heap space that grows upward in response to each request the Ultibo implementation uses the virtual memory functionality of the processor to map blocks of (possibly not contiguous) memory allocated from the Ultibo heap manager into an address space dedicated to supporting the C library.
There are a number of parameters in the GlobalConfig unit which can be used to adjust the default behaviour of this as follows:
SYSCALLS_HEAP_BASE - The starting point (bottom) of the virtual heap provided by sbrk() (Default: $C0000000)
SYSCALLS_HEAP_MIN - The minimum (initial) allocation made to the virtual heap during startup (Default: 2MB)
SYSCALLS_HEAP_MAX - The maximum size the virtual heap will be allowed to grow to (Default: 1GB)
SYSCALLS_HEAP_BLOCKSIZE - The size of each block added to the virtual heap (Default: 1MB)
Under normal usage these parameters should not need to be changed but they are available for advanced use cases which may require them.
Constants
Refer to the official documentation links above
Type definitions
Refer to the official documentation links above
Public variables
Refer to the official documentation links above
Function declarations
Refer to the official documentation links above
Return to Unit Reference