Hello julia-dev!
For the past week or so I've been working on a (possibly crazy) idea to get Julia running on the Lego Mindstorms EV3 brick (Lego and Julia being two of my favorite technologies), so that we can expand Julia to educational robotics. The ev3 is a small, ARM-powered Linux computer, and it seems like it just *might* be powerful enough to run Julia. However, so far, I've been unable to get a working REPL. The ev3 is an armv5 processor, so as far as I know, this is uncharted territory. Specifically, it has:
cpu: arm926ej-s
march: armv5te
float-abi: soft
fpu: (none)
RAM: 64MB
I've tried a *lot* of different approaches, all of which have failed at various points. All of my builds have been inside brickstrap:
https://github.com/ev3dev/brickstrap a tool for building EV3 images and cross-compiling using qemu. The builds are based on ev3dev, which is itself based on Debian jessie. I've gotten several complete builds to work, but none have actually resulted in a working REPL. Specifically, I've tried:
1) Letting Julia build all of its own dependencies except OpenBLAS (building OpenBLAS through Julia fails, because it assumes a hard-float system). To get OpenBLAS working, I downloaded the latest source release, and configured it with the following options:
TARGET = ARMV5
DYNAMIC_ARCH = 0
USE_THREAD = 0
NO_LAPACK = 1
NO_LAPACKE = 1
MAX_STACK_ALLOC = 64
ifeq ($(CORE), ARMV5)
CCOMMON_OPT += -marm -mfloat-abi=soft -march=armv5te
FCOMMON_OPT += -marm -mfloat-abi=soft -march=armv5te
endif
This resulted in a functional OpenBLAS (or, at least, one for which the ctests passed), on ev3. That was very exciting, since various reports had indicated that OpenBLAS could not possibly be run on a soft-float machine.
With that OpenBLAS, I edited Julia's Make.user and set:
override MARCH=armv5te
override JULIA_CPU_TARGET=arm926ej-s
override prefix=/usr/local/
override USE_SYSTEM_BLAS=1
override LIBBLAS := -lopenblas
override LIBBLASNAME := libopenblas
Eventually, the Julia build completed successfully. But running it on the EV3 segfaults. GDB reports:
(gdb) r
Starting program: /opt/julia-0.4.1/julia
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabi/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0xb6e84310 in extensions () from /opt/julia-0.4.1/usr/bin/../lib/libjulia.so
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
2) I tried a completely separate build with mostly pre-packaged dependencies, but with a few flags set in Julia:
override USE_SYSTEM_BLAS=1
override USE_SYSTEM_LAPACK=1
override USE_SYSTEM_LIBM=1
override USE_SYSTEM_FFTW=1
override USE_SYSTEM_GMP=1
override USE_SYSTEM_MPFR=1
override USE_SYSTEM_ARPACK=1
prefix=/usr/local/
override MARCH=armv5te
override JULIA_CPU_TARGET=arm926ej-s
LLVM_FLAGS+="--with-float=soft --with-abi=aapcs-linux"
That resulted in a totally trouble-free build, which is great! But launching the Julia REPL gave another segfault. Again, gdb says:
(gdb) r
Starting program: /opt/julia-0.4.1/julia
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabi/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0xb6e844e0 in extensions () from /opt/julia-0.4.1/usr/bin/../lib/libjulia.so
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
3) I tried building Julia master in case that helped, using the separate OpenBLAS install, with:
override MARCH=armv5te
override JULIA_CPU_TARGET=arm926ej-s
override prefix=/usr/local/
override USE_SYSTEM_BLAS=1
LLVM_FLAGS+="--with-float=soft --with-abi=aapcs-linux"
override LIBBLAS := -lopenblas
override LIBBLASNAME := libopenblas
but this build failed with:
CC src/runtime_ccall.o
In file included from /opt/julia-master/usr/include/llvm/ADT/SmallVector.h:20:0,
from /opt/julia-master/usr/include/llvm/Support/Allocator.h:24,
from /opt/julia-master/usr/include/llvm/ADT/StringMap.h:18,
from /opt/julia-master/usr/include/llvm/Support/Host.h:17,
from /opt/julia-master/src/runtime_ccall.cpp:6:
/opt/julia-master/usr/include/llvm/Support/MathExtras.h:74:7: warning: "_MSC_VER" is not defined [-Wundef]
#elif _MSC_VER
^
/opt/julia-master/usr/include/llvm/Support/MathExtras.h:90:7: warning: "_MSC_VER" is not defined [-Wundef]
#elif _MSC_VER
^
/opt/julia-master/usr/include/llvm/Support/MathExtras.h:143:7: warning: "_MSC_VER" is not defined [-Wundef]
#elif _MSC_VER
^
/opt/julia-master/usr/include/llvm/Support/MathExtras.h:159:7: warning: "_MSC_VER" is not defined [-Wundef]
#elif _MSC_VER
^
CC src/threadgroup.o
{standard input}: Assembler messages:
{standard input}:690: Error: selected processor does not support ARM mode `dmb'
{standard input}:740: Error: selected processor does not support ARM mode `wfe'
{standard input}:819: Error: selected processor does not support ARM mode `dmb'
{standard input}:918: Error: selected processor does not support ARM mode `wfe'
{standard input}:1047: Error: selected processor does not support ARM mode `wfe'
Makefile:94: recipe for target 'threadgroup.o' failed
make[1]: *** [threadgroup.o] Error 1
Makefile:87: recipe for target 'julia-src-release' failed
make: *** [julia-src-release] Error 2
(brickstrap)root@paladin-21:/opt/julia-master#
I've also tried about a dozen other combinations, but none were quite as promising as these, so I'll spare you the details.
Is there any hope? Do any of these results suggest that this might be possible? I've got a fair amount of experience debugging and developing, but this is getting beyond my ability to proceed. I'd definitely appreciate any advice, help, or gentle suggestions that what I'm trying to do is impossible ;-)
Thanks,
-Robin