Does glibc work on bare metal or RTOS platforms? - embedded

Embedded experts, is this possible without major modifications?
I'm building firmware that has both a Linux kernel and a minimal RTOS that runs when resuming from sleep. The same toolchain, aarch64-linux-gnu, is used for both Linux and RTOS code. The reason why it doesn't need a separate bare metal toolchain for RTOS is because the vendor has their own stripped down C runtime which they use instead of glibc.
But that poorly made C runtime is missing a lot of functions, so we want to use a more full featured one. We could use newlib but that would require a 2nd toolchain, which want to avoid.
But I can't find any bare metal or RTOS project using glibc. Currently, it can build with glibc, but crashes real soon, almost certainly because we didn't call the glibc initialization code:
_start
__libc_start_main
__libc_csu_init (call C++ constructors for global variables)
main
https://github.molgen.mpg.de/git-mirror/glibc/blob/master/sysdeps/aarch64/start.S
https://github.molgen.mpg.de/git-mirror/glibc/blob/master/csu/libc-start.c
But looking at __libc_start_main, it's a lot more complicated than newlib. Seems it depends on a lot of Linux facilities that don't exist:
dynamic linking? _dl_aux_init
pthreads __pthread_initialize_minimal
On the positive side, glibc does let you override sbrk and write, which are weakly defined, so that they can call the device driver code directly instead of making syscalls to the non-existent kernel
Update: working for us means
1. malloc
2. printf,write to serial port, but not to actual files
3. C++ globals initialized correctly
4. no threading

In glibc, malloc depends on a low-level allocator such as sbrk (or mmap). You can probably fake something like sbrk on a bare-metal target, but you would have to stub out all the indirect malloc dependencies (including multi-threading support).
The glibc printf implementation is coupled to the fopen implementation, which depends on dlopen for loading character set conversion code (the gconv modules). This even applies to the statically linked case. There is really no way to escape the dynamic linker without some far-reaching changes.
C++ initialization should be fairly easy to get right, even for bare-metal targets. I do not think you need any libc for that, just a little bit of startup code that matches what your target needs. (On some targets, it is sufficient to call the magic _init function before your application.) glibc has some elaborate facilities for that as well, but they are for supporting dynamic linking and dlopen/dlclose. For statically linked binaries, they are not needed.
A high-quality port of glibc to a non-Linux. non-GNU operating system is definitely a lot of work. If the target is bare-metal or a non-POSIX RTOS, you probably have to start with a POSIX shim layer. Even then, the result will be a not-quite-glibc target, and you still need a separate toolchain.
It may be better to go with newlib (or the existing RTOS libc) and obtain the missing libc functionality via gnulib and similar projects.

Related

Portable whole-archive linking in CMake

If you want to link a static library into an shared library or executable while keeping all the symbols visible (e.g. so you can dlopen it later to find them), a non-portable way to do this on Linux/BSD is to use the flag -Wl,--whole-archive. On macOS, the equivalent flag is -Wl,-force_load,<library>; on Windows it's apparently /WHOLEARCHIVE.
Is there a portable way to do this in CMake?
I know I can add linker flags with target_link_libraries. I can detect the OS. However, since the macOS version of this includes the library name in the same string as the flag (no spaces), I think this messes with CMake's usual handling of link targets and so on. The more compatible I try to make this, the more I have to bend over backwards to make it happen.
And this is without even getting into more unusual compilers like Intel, PGI, Cray, IBM, etc. Those may not be compilers that people commonly deal with, but in some domains it's basically unavoidable to need to deal with these.
Are there any better options?
flink.cmake will help you.
target_force_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...
)

What is the need of JVM when you can pass the source code?

i am new to java.
i wanted to know this.
what is the need to create the .class file in java ?
can't we just pass the source code to every machine so that each machine can compile it according to the OS and the hardware ?
I believe it's mostly for efficiency reasons.
From wikipedia http://en.wikipedia.org/wiki/Bytecode:
Bytecode, also known as p-code (portable code), is a form of
instruction set designed for efficient execution by a software
interpreter. Unlike human-readable source code, bytecodes are compact
numeric codes, constants, and references (normally numeric addresses)
which encode the result of parsing and semantic analysis of things
like type, scope, and nesting depths of program objects. They
therefore allow much better performance than direct interpretation of
source code.
(my emphasis)
And as others have mentioned possible weak obfuscation of the source code.
The main reason for the compilation is that the Virtual Machines which are used to host java classes and run them only understands bytecode
And since compiling a class each time to the language the virtual machine understands is expensive. That's the only reason why the source code is compiled into bytecode.
But we can also use some compilers which compiles source code directly into machine code.But that's a different story which I don't know about much.

Searching for Embedded C library to operate on Big numbers which do not use standard libc?

I have to operate on Very large numbers may be 2048 bytes for implementation of RSA. As per the rules of Automotive domain i cant use bignum library which uses standard libc. I have searched for GMP and Polarssl but they all uses malloc() and other things.
So is there any library/method available that do not rely on libc and also manages such big numbers..? ???
I don't think you will find any decent big integer C library, that not use malloc, calloc and possibly realloc or whatever dynamic allocation, because the whole point of arbitrary precision numbers is to go beyond limited, platform-dependent stack size and for second it's much more flexible method than compile-time static memory allocation.
My guess is to adapt mini-gmp package to overcome your specific limitations. (you will find it under main directory along with some tests). It contains one header file and C-source file, so it should be a lot simpler to "cut-off" libc dependency rather than fully-featured release, however it will be not that fast as GMP relies heavily on highly-optimized assembly code for various CPU architectues.
As suggested by kkrambo you may also try BigDigits library with NO_ALLOCS option, that is available since version 2.2:
Added the NO_ALLOCS option to compile the "mp" library without using
any memory allocation.

Is this possible to update a Objective-C library in run time?

Just leave alone the Apple policy, just talking about the Objective-C language only,
Assume that my programme calling a .a library. Is this possible to grep the .a from the
internet, and run a newer version of .a instead of old .a?
Thanks.
Not for statically linked libraries (.a), at least with any level of sanity. You can certainly do it with dynamically loaded libraries (.so); it's one of the normal use cases. Have a look at dlopen, dlclose and dlsym from the dynamic loader (https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/MachOReference/Reference/reference.html).
This is not just iOS, but OS X apps (and probably other Unixes in general)
Static libraries (.a files) cannot be replaced while the program is running because they are part of the application binary. The application binary is mapped into the process's address space. If you try to change any part of it, you'll almost certainly end up crashing the app.
Dynamic libraries (.so files) are replaceable in theory. However, most applications load them up once at the beginning or when first needed and then they become part of the application's address space. I've heard that it is theoretically possible for an application to unload a dynamic library, but I've never seen it done in any real Cooca application.

Does Ada have a preprocessor?

To support multiple platforms in C/C++, one would use the preprocessor to enable conditional compiles. E.g.,
#ifdef _WIN32
#include <windows.h>
#endif
How can you do this in Ada? Does Ada have a preprocessor?
The answer to your question is no, Ada does not have a pre-processor that is built into the language. That means each compiler may or may not have one and there is not "uniform" syntax for pre-processing and things like conditional compilation. This was intentional: it's considered "harmful" to the Ada ethos.
There are almost always ways around a lack of a preprocessor but often times the solution can be a little cumbersome. For example, you can declare the platform specific functions as 'separate' and then use build-tools to compile the correct one (either a project system, using pragma body replacement, or a very simple directory system... put all the windows files in /windows/ and all the linux files in /linux/ and include the appropriate directory for the platform).
All that being said, GNAT realized that sometimes you need a preprocessor and has created gnatprep. It should work regardless of the compiler (but you will need to insert it into your build process). Similarly, for simple things (like conditional compilation) you can probably just use the c pre-processor or even roll your own very simple one.
AdaCore provides the gnatprep preprocessor, which is specialized for Ada. They state that gnatprep "does not depend on any special GNAT features", so it sounds as though it should work with non-GNAT Ada compilers. Their User Guide also provides some conditional compilation advice.
I have been on a project where m4 was used as well, with the Ada spec and body files suffixed as ".m4s" and ".m4b", respectively.
My preference is really to avoid preprocessing altogether, and just use specialized bodies, setting up CM and the build process to manage them.
No but the CPP preprocessor or m4 can be called on any file on the command line or using a building tool like make or ant. I suggest calling your .ada file something else. I have done this for some time on java files. I call the java file .m4 and use a make rule to create the .java and then build it in the normal way.
I hope that helps.
Yes, it has.
If you are using GNAT compiler, you can use gnatprep for doing the preprocessing, or if you use GNAT Programming Studio you can configure your project file to define some conditional compilation switches like
#if SOMESWITCH then
-- Your code here is executed only if the switch SOMESWITCH is active in your build configuration
#end if;
In this case you can use gnatmake or gprbuild so you don't have to run gnatprep by hand.
That's very useful, for example, when you need to compile the same code for several different OS's using even different cross-compilers.
Some old Ada1983-era compilers have a package called a.app that utilized a #-prefixed subset of Ada (interpreted at build-time) as a preprocessing language for generating Ada (to be then translated to machine code at compile-time). Rational's Verdix Ada Development System (VADS) appears to be the progenitor of a.app among several Ada compilers. Sun Microsystems, for example, derived the Ada SPARCompiler from VADS and thus also had a.app. This is not unlike the use of PL/I as the preprocessor of PL/I, which IBM did.
Chapter 2 is some documentation of what a.app looks like: http://dlc.sun.com/pdf/802-3641/802-3641.pdf
No, it does not.
If you really want one, there are ways to get one (Use C's, use a stand-alone one, etc.) However I'd argue against it. It was a purposeful design decision to not have one. The whole idea of a preprocessor is very un-Ada.
Most of what C's preprocessor is used for can be accomplished in Ada in other more reliable ways. The only major exception is in making minor changes to a source file for cross-platform support. Given how much this gets abused in a typical cross-platform C program, I'm still happy there's no support for it in Ada. Very few C/C++ developers can control themselves enough to keep the changes "minor". The result may work, but is often nearly impossible for a human to read.
The typical Ada way to accomplish this would be to put the different code in different files and use your build system to somehow choose between them at compile time. Make is plenty powerful enough to help you do this.