I've got a CMake project I'd like to cross-compile for Raspberry Pi zero.
I'm able to compile my code using the gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf
toolchain and run it over Raspberry Pi 3B+, but on the zero I'm getting Illegal instruction
.
I tried to verify that the binary is legit:
pi@raspberrypi:~/mylib $ file mylib.so
mylib.so: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=478ce6fb9de7f4dfbc87199c3f7618a17afacf9e, with
debug_info, not stripped
What am I doing wrong? I'm invoking CMake with:
CMAKE_DEFINES="$CMAKE_DEFINES -DCMAKE_SYSTEM_NAME=Linux"
CMAKE_DEFINES="$CMAKE_DEFINES -DCMAKE_C_COMPILER=$TOOLCHAIN_PATH/bin/arm-linux-gnueabihf-gcc"
CMAKE_DEFINES="$CMAKE_DEFINES -DCMAKE_CXX_COMPILER=$TOOLCHAIN_PATH/bin/arm-linux-gnueabihf-g++"
cmake ../src -G"Unix Makefiles" $CMAKE_DEFINES
1 Answer 1
I think the issue is down to the differences in the processors. The Rasberry Pi 3B+ has a ARM Cortex-A53 and the Pi Zero has a ARM1176JZF-S processor. Both are ARM CPUs, but the 3B+'s CPU is a much newer ARMv8 architecture compared to the Zeros' ARMv6 architecture. They are similar, but not exactly the same. Think Intel Core 2 Duo vs Core i7. The i7 can run applications specifically compiled for the Core 2 Duo, but not necessarily vice-versa.
gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf
targets ARMv7 (the Raspberry Pi 2 and 3's ARM Cortex-A7 CPU architecture), which is compatible with the Pi 3+ and 4, but not Zero.
To cross-compile for ARMv6 it looks like there are a couple of options. The first is to use the older official cross-compiler available from https://github.com/raspberrypi/tools. This is gcc 4.9.3 which isn't recent, but should still be fine for a lot of code. A more recent option appears to be available on SourceForge at https://sourceforge.net/projects/raspberry-pi-cross-compilers/files/Raspberry%20Pi%20GCC%20Cross-Compiler%20Toolchains/GCC%209.1.0/Raspberry%20Pi%201%2C%20Zero/ (via https://github.com/abhiTronix/raspberry-pi-cross-compilers).
The only other option that I can find for now would be to be compile your own cross-compiler. Unless you're fairly confident with Linux I wouldn't go this route, but broadly speaking download and extract the binutils, glibc, and gcc source archives from https://ftpmirror.gnu.org/binutils/, etc., the compile them in that order. Specify --target=arm-linux-gnueabihf --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib
as configure options. More detailed directions are available with a bit of searching, e.g. https://gist.github.com/sol-prog/94b2ba84559975c76111afe6a0499814.
-
Nice, compete answer. I wonder if buildroot or crosstool-NG has a target for the ARMv6/PiZero yet and might be an option for compiling a cross-compiler from source?Roger Jones– Roger Jones2019年09月20日 08:51:02 +00:00Commented Sep 20, 2019 at 8:51
-
1Yup, crosstool-NG has a
armv6-rpi-linux-gnueabi
target for the ARM1176JZF-S: github.com/crosstool-ng/crosstool-ng/tree/master/samples/… and buildroot has a PIZero (as well as PiZeroW) target: git.buildroot.net/buildroot/tree/configs/raspberrypi0_defconfigRoger Jones– Roger Jones2019年09月20日 08:56:50 +00:00Commented Sep 20, 2019 at 8:56 -
Really useful answer! This clears up a question I had, but raises another: How is it that Pi 0W uses same binaries as Pi 3 & Pi4?Seamus– Seamus2022年05月29日 19:40:59 +00:00Commented May 29, 2022 at 19:40