How to cross compile for ARM

How to cross compile for ARM
What is Cross compilation ?

According to Wikipedia, cross compilation is a process of compiling and creating executable code for a platform other than the one on which the compiler is running.

Practical example :- A compiler that runs on a Windows-10 PC but generates code that runs on Android smart-phone is a process of cross compilation

Cross compilation in more technical terms

Most commonly it is used with reference to compilation for architectures that are not binary-compatible for instance,

  • Building RISC binaries on a CISC CPU platform,
  • OR 64-bit binaries on a 32-bit system.
  • OR Building firmware intended to run on embedded devices (perhaps using the ARM CPU architecture) on Intel PC-based OSs.

Difference between Native and Cross compiler

  • A native compiler is one that compiles programs for the same architecture or operating system that it is running on. For instance, a compiler running on an x86 processor and creating x86 binaries.
  • A cross-compiler is one that compiles binaries for architectures other than its own, such as compiling ARM binaries on a Intel’s x86 processor.
  • A “cross compiler” executes in one environment and generates code for another. A “native compiler” generates code for its own execution environment.

What is Tool-chain ?

A Tool-chain is the set of compiler + linker + librarian + any other tools you need to produce the executable (+ shared libraries, etc) for the target. A debugger and/or IDE may also count as part of a Tool-chain.

Why we require ARM Tool-chain ?

Tool-chain plays very important role in embedded system development. Tool-chain required to produce final executable and Architecture specific code out of source code.

For example:- If you want to run your C program on your ARM based smart-phone, then you have to cross compile your C program and you need ARM compiler, linker, library, etc. In short you need tool-chain.

Configuring tool-chain

Download Tool-chain first from here

I have got tar file named “gcc-arm-none-eabi-4_9-2015q1-20150306-linux.tar.bz2”

 

After extracting tar file you would get “opt” directory go to that directory and find bin directory where you can get compiler and all that stuff required for cross compilation.

Set PATH variable to bin of tool-chain, so that your OS load binaries from that directory too. Use following line to do that

 

To check whether your OS use binaries from your tool-chain folder, write arm and press tab it will show you different binaries of tool-chain. Like follows

Toochain ARM(Click on image to zoom )

Let’s Compile C program for ARM architecture

Write hello world program in C (my file name is test.c here)

Compiling

 

When you compile first time, you may encounter this error(if your system is 64-bit)

 

Solution: You need to install ia32-libs to work with 64-bit architecture, to install that use this command sudo apt-get install ia32-libs.

Now try again, and everything goes good, after compilation you will see the output binary file “test” in same folder.

To check this binary is compiled successfully or not use this

 

and it will display like this

Let’s understanding tool-chain

GCC is a popular, open source tool-chain that can generate code for a wide range of architectures including Intel’s x86, ARM v4/5/6/7, TI’s MSP, Atmel’s AVR, and many others.

Note: when the host and target architectures are different, the tool-chain is also called a cross compiler

A typical GNU (GNU’s Not Unix) assembler tool-chain includes several programs that interact as shown in

  • as is the assembler and it converts human-readable assembly language programs into binary machine language code. It typically takes as input .s assembly files and outputs .o object files.
  • ld is the linker and it is used to combine multiple object files by resolving their external symbol references and relocating their data sections, and outputting a single executable file. It typically takes as input .o object files and .ld linker scripts and outputs .out executable files.
  • objcopy is a translation utility that copies and converts the contents of an object file from one format (e.g. .out) another (e.g. .bin).
  • objdump is a disassembler but it can also display various other information about object files. It is often used to disassemble binary files (e.g. .out) into a canonical assembly language listing (e.g. .lst).
  • ar is a utility for creating, modifying and extracting from archives.
  • nlmconv converts object code into an NLM.
  • nm lists symbols from object files.
  • ranlib generates an index to the contents of an archive.
  • readelf displays information from ELF-format object file.
  • size displays the sections of an object or archive, and their sizes.
  • strip Discards symbols embedded in object files.

If you search for an ARM compiler, you might stumble across the following toolchains: arm-none-linux-gnueabi, arm-none-eabi, arm-eabi, and arm-softfloat-linux-gnu, among others. This might leave you wondering about the method to the naming madness.

Unix cross compiler’s naming convention uses the form like

[arch] – [vendor] – [os] – [abi]

  • The arch refers to the target architecture, which in our case is ARM.
  • The vendor nominally refers to the tool-chain supplier.
  • The os refers to the target operating system, if any, and is used to decide which libraries (e.g. newlib, glibc, crt0, etc.) to link and which syscall conventions to employ.
  • The abi specifies which application binary interface convention is being employed, which ensures that binaries generated by different tools can inter-operate.

Some examples :

arm-none-eabi is the tool-chain we use in this class. This tool-chain targets the ARM architecture, has no vendor, does not target an operating system (i.e. targets a “bare metal” system), and complies with the ARM EABI.

i686-apple-darwin10-gcc-4.2.1 is the version of GCC on my MacBook Pro. This tool-chain targets the Intel i686 architecture, the vendor is Apple, and the target OS is Darwin version 10.

arm-none-linux-gnueabi is the tool-chain that can be installed in Debian-based systems using a package manager like apt (the package is called gcc-arm-linux-gnueabi). This toolchain targets the ARM architecture, has no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI. In other words, it is used to target ARM-based Linux systems.

arm-eabi  Android ARM compiler

What is ABI ?

Each architecture or architecture/os couple has an ABI. The ABI (Application binary Interface) describes how functions should be called, syscalls numbers, arguments passed, which registers can be used …

The abi describes how the compiler should generate the assembler.

If you use only assembler you don’t need to care about the ABI.

EABI, on the other hand, defines how functions interact. It doesn’t care how the data is represented on disk but rather how it is represented in memory. It answers questions of where the arguments are present, where the return value is stored, which registers are caller saved and which are callee saved, etc.

What is ELF ?

EABI stands for Embedded ABI, which is the definition of the Application Binary Interface for certain targets (e.g. PPC). ELF is the Executable and Linking Format which defines the ELF file format.

ELF is the currently preferred file format on most Unix like environments (e.g. Linux). This is the file format that the compiler will emit object files to, the format the linker will read (the previously generated object files), and the format the linker will emit binaries in. It will also come into play with the loader (and potentially the kernel). It defines how the data is written into a file.

So in some senses, ELF is the on disk representation of the data (though, in reality, it will also be in memory as the image will be mapped into memory for execution) and EABI defines the runtime representation of the (intermediate) data of the application.

What is the difference between arm-linux-gcc, arm-none-linux-gnueabi-gcc and arm-linux-gnueabi toolchains?

Toolchains have a loose name convention like  [arch] – [vendor] – [os] – [abi]

  • arch is for architecture: arm, mips, x86, i686…
  • vendor is tool chain supplier: apple,
  • os is for operating system: linux, none (bare metal)
  • abi is for application binary interface convention: eabi, gnueabi, gnueabihf

For your question, arm-none-linux-gnueabi and arm-linux-gnueabi is same thing. arm-linux-gcc is actually binary for gcc which produces objects for ARM architecture to be run on Linux with default configuration (abi) provided by toolchain.SystemSoureCode