8

I would like to crosscompile some piece of C++ software in a way that I can run on every Raspberry Pi. I am confused about the parameter -march.

I've found a great deal of resources recommending to use armv6zk to be compatible with all versions of the RPi, while some other mentioned armv6 or even armv6z. See for example:

I then tried to print the architecture used by g++ on my RPi 1 Model B, and I got an armv6l. Is there even a difference between armv6, armv6z, armv6zk and armv6l?
It is clear to me that

  • the earliest RPi have an ARMv6 architecture
  • Raspbian is compiled for armv6 for compatibility, while the kernel should be running in the "correct" architecture of the RPi
  • All RPis have a hard float and VFP support, thus the remaining part of the compiler parameters are -mfpu=vfp -mfloat-abi=hard.

What is the exact architecture parameter for each Raspberry Pi model?

and

What is the most specific parameter I can use to be compatible with all models?

Pietro Saccardi
  • 296
  • 1
  • 8

1 Answers1

7

I believe I figured it out after quite some fiddling.

What is the most specific parameter I can use to be compatible with all models?

Raspbian FAQ's contain the final answer:

-march=armv6
-mfpu=vfp
-mfloat-abi=hard

Note that the packages in Debian compiled for the armhf architecture are not the same as in Raspbian: Raspbian has been derived from Debian specifically to contain binaries for armv6; the armhf architecture in Debian is compiled for armv7, not v6.

This is reinforced by inspecting a binary in Raspbian using readelf -a -W from binutils:

Tag_CPU_name: "6"
Tag_CPU_arch: v6
Tag_THUMB_ISA_use: Thumb-1
Tag_FP_arch: VFPv2
Tag_ABI_VFP_args: VFP registers
Tag_CPU_unaligned_access: v6

(this is /usr/bin/g++-6 from the g++-6 package in Raspbian Stretch). Note that you would get a different answer (namely ARM 7) if you were to inspect the package with the same name in Debian!

Is there even a difference between armv6, armv6z, armv6zk and armv6l?

I figured the suffix l stands for "little endian", m, z and k are actual microarchitectures.

This means that my Raspberry Pi has an actual armv6, a revision 000d with the following features:

Model name:            ARMv6-compatible processor rev 7 (v6l)
Flags:                 half thumb fastmult vfp edsp java tls

(obtained by running lscpu). There is a bit of confusion on Z and K, but I think the best way to illustrate the difference between these architectures (rather than digging up the official papers by ARM) is looking into LLVM's definition at llvm/lib/Target/ARM/ARM.td for these architectures:

def ARMv6     : Architecture<"armv6",     "ARMv6",    [HasV6Ops,
                                                       FeatureDSP]>;

def ARMv6t2   : Architecture<"armv6t2",   "ARMv6t2",  [HasV6T2Ops,
                                                       FeatureDSP]>;

def ARMv6k    : Architecture<"armv6k",    "ARMv6k",   [HasV6KOps]>;

def ARMv6kz   : Architecture<"armv6kz",   "ARMv6kz",  [HasV6KOps,
                                                       FeatureTrustZone]>;

def ARMv6m    : Architecture<"armv6-m",   "ARMv6m",   [HasV6MOps,
                                                       FeatureNoARM,
                                                       ModeThumb,
                                                       FeatureDB,
                                                       FeatureMClass,
                                                       FeatureStrictAlign]>;

def ARMv6sm   : Architecture<"armv6s-m",  "ARMv6sm",  [HasV6MOps,
                                                       FeatureNoARM,
                                                       ModeThumb,
                                                       FeatureDB,
                                                       FeatureMClass,
                                                       FeatureStrictAlign]>;

What is the exact architecture parameter for each Raspberry Pi model?

Now that some light was shed on the acronyms, from RPi's website:

  • Raspberry Pi 1, Model A, B, B+, the Compute Module, and the Raspberry Pi Zero: ARM11 76JZF-S, which is part of the ARM11 family has armv6, in a BCM2835 SoC.
  • Raspberry Pi 2 Model B, rev 1.1: ARM Cortex-A7, part of the Cortex-A family has armv7a in a BCM2836 SoC.
  • Raspberry Pi 2, rev 1.2, and Raspberry Pi 3: ARM Cortex-A53, also Cortex-A family, has armv8a, in a BCM2837 SoC.
  • Raspberry Pi 3 A+ and B+: ARM Cortex-A53, thus armv8a in a BCM2837B0 SoC.

The list above not include the various extra features, such as Thumb.

Pietro Saccardi
  • 296
  • 1
  • 8