3

I am trying to cross-compile for raspberry B/raspberry zero on ubuntu18.04 using crossbuild-essential-armhf. I installed it using :

apt-get install -y crossbuild-essential-armhf

In order to test I am using a simple hello world file hello.c:

#include <stdio.h> 
int main() {
        printf("hello\n");
        return 0; 
}

Using :

arm-linux-gnueabihf-gcc hello.c

The executable crash with segmentation violation, the stack is then :

#0  0x0044f5c2 in ?? ()
#1  0x0040040e in _start ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

So I tried to build using different commands searching on internet like :

arm-linux-gnueabihf-gcc -marm -march=armv6 hello.c
arm-linux-gnueabihf-gcc -marm -mcpu=arm1176jzf-s hello.c
arm-linux-gnueabihf-gcc -marm -march=armv6 -mfpu=vfp -mfloat-abi=hard hello.c

But the stack is always the same.

Using the "historical" https://github.com/raspberrypi/tools.git is working but this gcc-4.8 compiler is far too old to compile modern code.

Is there a way to produce raspberry B/raspberry zero binaries using a gcc-7 cross compiler ?

4
  • As far as I'm aware, stock distro cross-compilers are arm7, so you can compile for the multi-core models but not the single core ones. The one from the rpi tools repo, on the other hand, should be good for all of them. – goldilocks May 2 '19 at 18:24
  • @goldilocks: I tried to compile using -marm -march=armv6 but it crash the same. The assembly is different using it. – mpromonet May 2 '19 at 18:27
  • The _start address is different with rpi-tools 000082f0 <_start>, and with crossbuild-essential-armhf 000003fc <_start> – mpromonet May 2 '19 at 18:42
  • You might have a look at gcc -v for both. I think you are right that if it accepted the switch, it must be armv6 capable, but can't hurt to check (-v will list a Target). – goldilocks May 2 '19 at 19:02
3

I ran into a similar issue trying to cross-compile code for the Raspberry PI Zero (armv6) using a newer GCC 8.

Current toolchains are often not built with the --with-arch=armv6 flag. This results in binaries which are not compatible with armv6 and therefore you may get Illegal Instruction error.

I created a github repo where you can download a toolchain based on a current GCC version for the Raspi Zero (and also for all the other RasPI)

https://github.com/Pro/raspi-toolchain

3

Using the compiler toolchain from https://sourceforge.net/projects/raspberry-pi-cross-compilers/

For pizero the cross-compiler is available from the link cross-gcc-9.1.0-pi_0-1.tar.gz

This compiler version is :

Using built-in specs.
COLLECT_GCC=/opt/cross-pi-gcc-9.1.0-0/bin/arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/opt/cross-pi-gcc-9.1.0-0/bin/../libexec/gcc/arm-linux-gnueabihf/9.1.0/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../configure --prefix= --target=arm-linux-gnueabihf --enable-languages=c,c++,fortran --with-sysroot=/arm-linux-gnueabihf/libc --with-build-sysroot=/opt/cross-pi-gcc-9.1.0-0/arm-linux-gnueabihf/libc --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib
Thread model: posix
gcc version 9.1.0 (GCC)

Building with :

arm-linux-gnueabihf-gcc hello.c

build an executable that run on raspberry zero.

2

If you need to build static binaries without any dependencies, you can use the toolchains at https://musl.cc/. I've managed to successfully build (on WSL, Ubuntu 18.04) with this toolchain: https://more.musl.cc/9.2.1/x86_64-linux-musl/ with settings -march=armv6zk -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfpu=vfp

2

The problem is that command line architecture flags change the behavior of the compiler, but they don't change the precompiled runtime support code that is linked in to every executable.

So when you try to build armv6 binaries with a toolchain that is built for armv7, they don't work.

1
  • Thanks! Just confirmed that when I add -nostdlib readelf starts showing Tag_CPU_Arch: v6, the compiled file is not runnable obviously, but good to know what is actually happening. I wonder how the same arm-linux-gnueabihf toolchain works to compile RPI Linux kernel for armv6, is it because it's not using any standard libraries? – axk Apr 24 at 19:29
1

Here's what I do for C++

sudo apt-get install build-essential
sudo apt-get install g++-arm-linux-gnueabihf
sudo apt-get install gdb-multiarch

then arm-linux-gnueabihf-g++ -v to test the installation.

After that, open "testing.cpp" and put in

#include <iostream>
using namespace std;

int main() 
{
    cout << "Hello, World!";
    return 0;
}

Finally,

arm-linux-gnueabihf-g++ -O3 -g3 -Wall -c -o -fPIC "hello.o" "hello.cpp"
arm-linux-gnueabihf-g++ -o "hello" hello.o

Check the binary to make sure it's been compiled correctly: file hello should yield hello: ELF 32-bit LSB executable,ARM, EABI5 version 1 (SYSV)... The ARM is what you're looking for. If it's present, you're good to go.

3
  • 1
    For C++ I have the same segv, this is why I try to simplify using C. Independently of the option using file I get ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV). I run sudo apt-get install build-essential g++-arm-linux-gnueabihf gdb-multiarch, compile with arm-linux-gnueabihf-g++ -O3 -g3 -Wall -fPIC hello.cpp and it crash the same with your hello.cpp. Are you using ubuntu bionic ? – mpromonet May 2 '19 at 18:19
  • @mpromonet No, I'm not using Ubuntu, I'm on Debian. – user96931 May 2 '19 at 18:35
  • The raspberry I am using is a raspberry pi B+ (BCM2835 revision 0010) – mpromonet May 2 '19 at 18:45
0

All answers are great! But ensure that you are using the latest cross-compiler 10.2.0

For setting up your environment see this .. Cross Compiler: Installation Instructions

GCC provides great documentation for ARM devices and which flags work best (GCC documentation)

Create a hello.c file for hello world and try this:

arm-linux-gnueabihf-gcc hello.c -march=armv6 -mfpu=vfp -mfloat-abi=hard -o rpi-hello.so

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.