Liviu Gheorghisan
Liviu Gheorghisan

Reputation: 423

What are the differences between C/C++ bare-metal compilation and compilation for a specific OS (Linux)?

Suppose you have a cross-compilation tool-chain that produces binaries for the ARM architecture.

Your tool-chain is like this (running on a X86_64 machine with Linux):

... and the plethora of other tools for cross-compilation on ARM.

Points that I'm interested in are:

Upvotes: 7

Views: 5362

Answers (3)

Stephen M. Webb
Stephen M. Webb

Reputation: 1869

Your toolchain is specific to a particular environment, and environments can differ. A lot.

In the case of the GNU toolchains in you example, the arm-linux-gnueabi-gcc driver will invoke a GNU C compiler that will generate instructions for a 32-bit ARMv7 processor and invoke the GNU binutils BFD linker for the Linux operating system kernel using the GNU C standard library, using the ELF executable format with ABI extensions from ARM Holdings PLC.

The arm-gcc driver will invoke a similar GNU compiler and use a similar linker to create a standalone binary that is intended to run on bare metal, with you supplying the C standard library functions and using only ARM-defined standard calling conventions.

I can tell all that from the GNU "target triple" naming convention, which uses an ARCH-KERNEL-ENVIRONMENT construct in which an ARCH of "arm" indicates 7-bit ARMv7, a KERNEL of "linux" indicates the Linux kernel, and an ENVIRONMENT of "gnueabi" means the GNU C runtime with ARM ABI extensions (which refer mostly to the way exceptions are handled by the C++ runtime, or Ada, or ...). No KERNEL and not ENVIRONMENT means, well, no kernel and no environment: bare metal.

The C ABIs in terms of calling conventions (ie. which registers must be preserved across calls, how parameters and return results are passed between functions, and so on) are pretty much identical between hosted and bare metal. The main difference is what services are available to you (with bare metal, you talk to hardware, and with a kernel you talk to the kernel which talks to hardware for you, or maybe have calls routed to another process that talks to hardware for you). Without an environment you have to do all the runtime things yourself, including handling memory allocation. Note that you can have an OS or kernel without an environment, in which case you have to do your own kernel calls but the kernel talks to the hardware.

Upvotes: 0

auselen
auselen

Reputation: 28087

  • ABI differences is up to how you invoke the compiler, for example GCC has -mabi and that can be one of ‘apcs-gnu’, ‘atpcs’, ‘aapcs’, ‘aapcs-linux’ and ‘iwmmxt’.
  • On bare-metal limitations for various runtime features exists because someone hasn't provided them. Be them initializing zero allocated areas or providing C++ features. If you can supply them, they will work.
  • Binary level differences is also up to how you invoke compiler.

You can check GCC ARM options online.

Upvotes: 3

Richard Pennington
Richard Pennington

Reputation: 19985

I recently started a little project to use a Linux standard C library in a bare-metal environment. I've been describing it on my blog: http://ellcc.org/blog/?page_id=289

Basically what I've done is set up a way to handle Linux system calls so that by implementing simplified versions of certain system calls I can use functions from the standard library. For example, the current state for the ARM implements simplified versions of read(), readv(), write(), writev() and brk(). This allows me to use printf(), fgets(), and malloc() unchanged.

In my case, I use the same compiler for targeting Linux and bare-metal. Since it is Clang/LLVM based, I can also use the same compiler to target other processors. I'm working on a bare-metal example for the MIPS right now.

So I guess the answer is that there doesn't have to be any difference.

Upvotes: 1

Related Questions