Rimio Rimio - 9 months ago 52
Linux Question

"Illegal instruction" when running ARM code targeting my CPU

I'm compiling a rather large project for ARM. I'm using an AT91SAM9G25-EK as a devboard running a Debian ARM image. All libraries and executables in the image seem to be compiled for the armv4t instruction set.

My CPU is an ARM926EJ-S, which should run armv5tej code.

I'm using GCC to cross compile for my board. My CXX flags look like the following:

set(CMAKE_CXX_FLAGS "--signed-char --sysroot=${SYSROOT} -mcpu=arm926ej-s -mtune=arm926ej-s -mfloat-abi=softfp" CACHE STRING "" FORCE)

If I try to run this on my board, I get an Illegal Instruction signal (
) during initialization of one of my dependencies (using armv4t).

If I enable thumb mode (
-mthumb -mthumb-interwork
) it works, but uses Thumb for all the code, which in my case runs slower (I'm doing some serious number crunching).

In this case, if I specify one function to be compiled for ARM mode (using
) it will run fine until that function is called, then exit with

I'm lost. Is it that bad I'm linking against libraries using armv4t? Am I misunderstanding the way ARM modes work? Is it something in the linux kernel?

Answer Source

What softfp means is to use using the soft-float calling convention between functions, but still use the hardware FPU within them. Assuming your cross-compiler is configured with a default -mfpu option other than "none" (run arm-whatever-gcc -v and look for --with-fpu= to check), then you've got a problem, because as far as I can see from the Atmel datasheet, SAM9G25 doesn't have an FPU.

My first instinct would be to slap GDB on there, catch the signal and disassemble the offending instruction to make sure, but the fact that Thumb code works OK is already a giveaway (Thumb before ARMv6T2 doesn't include any coprocessor instructions, and thus can't make use of an FPU).

In short, use -mfloat-abi=soft to ensure the ARM code actually uses software floating-point and avoids poking a non-existent FPU. And if the "serious number crunching" involves a lot of floating-point, perhaps consider getting a different MCU...