Skip to content

[DEMO] Building executable for Raspberry Pi Zero/1B/1B+ using gcc-arm-linux-gnueabihf cross‑compiler

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE.deb
Notifications You must be signed in to change notification settings

RoEdAl/rpi0-cross-compile

Repository files navigation

[DEMO] Building executable for Raspberry Pi Zero/1B/1B+ using gcc-arm-linux-gnueabihf cross‑compiler

This is demonstration of building executable for Raspberry Pi Zero/1B/1B+ using standard gcc-arm-linux-gnueabihf cross‑compiler on Debian or Ubuntu.

Important

This demo is intended to use in dockerized environment. In VS Code just reopen this repo in container. devcontainer.json is provided.

As a bonus this CMake project also show you:

  • How to use external arm-none-linux-gnueabihf cross-compiler from ARM GNU Toolchain if you need a more recent version of GCC.
  • How to properly use CLang compiler (armv6-unknown-linux-gnueabihf target) to generate binaries for Raspberry Pi.
  • How to create Debian package using CPack.

Background

Thoretically if you want to build executable or shared library for Raspberry Pi you can use standard arm-linux-gnueabihf-gcc cross-compiler from Debian or Ubuntu. Just proper compilation flags should be specified. You can use flags described here:

arm-linux-gnueabihf-gcc -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -o hello-world hello-world.c

but compiler generates an error:

hello-world.c: In function ‘main’:
hello-world.c:3:6: sorry, unimplemented: Thumb-1 hard-float VFP ABI
    3 | void main()
      |      ^~~~

This issue can be easly fixed just by adding -marm option (-mthumb is a default in modern compilers):

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

Now executable gets created but if you try to run it on real hardware application just segfaults:

pi@raspberrypi:~ $ ./hello-world
Segmentation fault

Now things gets complicated. Let's examine generated binary a bit using readelf utility:

$ arm-linux-gnueabihf-readelf -A hello-world
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "7-A"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_FP_arch: VFPv3-D16
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_rounding: Needed
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_VFP_args: VFP registers
  Tag_CPU_unaligned_access: v6
  Tag_Virtualization_use: TrustZone

and below is output of similar command executed on Raspberry Pi OS (Raspbian):

pi@raspberrypi:~ $ readelf -A /bin/bash
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "6"
  Tag_CPU_arch: v6
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_FP_arch: VFPv2
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_rounding: Needed
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_VFP_args: VFP registers
  Tag_CPU_unaligned_access: v6

The core difference is Tag_CPU_arch. v6 is an expected value. So binary has been created for wrong CPU architecture. Generated code works fine on newer models of Raspberry Pi but it is incompatible with RPi Zero/1B/1B+ models with older CPU (SoC).

This demo code shows how to build binary with proper (v6) CPU architecture. In general you have to:

  • prepare sysroot from Raspberry Pi OS,
  • fix startup files.

More information you can find on Wiki pages of this project.

About

[DEMO] Building executable for Raspberry Pi Zero/1B/1B+ using gcc-arm-linux-gnueabihf cross‑compiler

Resources

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE.deb

Stars

Watchers

Forks