Tag Archives: Lua

Building Lua with ELLCC This Time With a Twist

In a previous post, I used ELLCC to cross build Lua for the ARM running Linux. Subsequently I’ve done a bit of work to make ELLCC more configurable, and also to handle bare metal compilation more easily. I had a little time on my hands tonight so I thought I’d try out the changes with the latest Lua 5.2.3 version.
First, I modified the lua-5.2.3/src/Makefile to add the following around line 27:

# Start of ELLCC definitions.
PLAT= generic
ELLCC= /home/rich/ellcc
ELLCCBIN= $(ELLCC)/bin/
CC= $(ELLCCBIN)ecc
ELLCCPREFIX= $(ELLCCBIN)ecc-
AR= $(ELLCCPREFIX)ar rcu
RANLIB= $(ELLCCPREFIX)ranlib

TARGET= x86_64-linux-eng
MYCFLAGS= -target $(TARGET)
MYLDFLAGS= -target $(TARGET)
# End of ELLCC definitions.

Then I build for my host system, an x86_64 Linux box:

[~/lua-5.2.3/src] dev% make
/home/rich/ellcc/bin/ecc -O2 -Wall -DLUA_COMPAT_ALL  -target x86_64-linux-eng   -c -o lapi.o lapi.c
...
/home/rich/ellcc/bin/ecc -O2 -Wall -DLUA_COMPAT_ALL  -target x86_64-linux-eng   -c -o linit.o linit.c
/home/rich/ellcc/bin/ecc-ar rcu liblua.a lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o 
/home/rich/ellcc/bin/ecc-ranlib liblua.a
/home/rich/ellcc/bin/ecc -O2 -Wall -DLUA_COMPAT_ALL  -target x86_64-linux-eng   -c -o lua.o lua.c
/home/rich/ellcc/bin/ecc -o lua  -target x86_64-linux-eng lua.o liblua.a -lm  
/home/rich/ellcc/bin/ecc -O2 -Wall -DLUA_COMPAT_ALL  -target x86_64-linux-eng   -c -o luac.o luac.c
/home/rich/ellcc/bin/ecc -o luac  -target x86_64-linux-eng luac.o liblua.a -lm  
[~/lua-5.2.3/src] dev% ./lua
Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print ("hello")
hello
> 
[~/lua-5.2.3/src] dev% 

So far so good. How about a cross compile?

[~/lua-5.2.3/src] dev% make clean
rm -f liblua.a lua luac lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o  lua.o luac.o
[~/lua-5.2.3/src] dev% make TARGET=arm-linux-engeabi
/home/rich/ellcc/bin/ecc -O2 -Wall -DLUA_COMPAT_ALL  -target arm-linux-engeabi   -c -o lapi.o lapi.c
...
/home/rich/ellcc/bin/ecc -o lua  -target arm-linux-engeabi lua.o liblua.a -lm  
/home/rich/ellcc/bin/ecc -O2 -Wall -DLUA_COMPAT_ALL  -target arm-linux-engeabi   -c -o luac.o luac.c
/home/rich/ellcc/bin/ecc -o luac  -target arm-linux-engeabi luac.o liblua.a -lm  
[~/lua-5.2.3/src] dev% ~/ellcc/bin/qemu-arm lua
Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print ("hello")
hello
> 
[~/lua-5.2.3/src] dev% 

Now for a real test. How about a bare metal test on the ARM?

[~/lua-5.2.3/src] dev% rm lua
[~/lua-5.2.3/src] dev% make TARGET=arm-elk-engeabi
/home/rich/ellcc/bin/ecc -o lua  -target arm-elk-engeabi lua.o liblua.a -lm  
[~/lua-5.2.3/src] dev%  ~/ellcc/bin/qemu-system-arm -M vexpress-a9 -m 128M -nographic -kernel lua
audio: Could not init `oss' audio driver
unhandled system call (256) args: 1, 268472376, 1610613215, 1610613023, 1207961673, 1241513744
Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print ("hello")
unhandled system call (175) args: 1, 1241512616, 0, 8, 237792, 0
unhandled system call (174) args: 2, 1241512644, 1241512624, 8, 237792, 0
hello
unhandled system call (174) args: 2, 1241512644, 1241512624, 8, 237792, 0
> 

As described in the previous post, the unhandled system calls are those that haven’t been implemented in ELK yet. In this case, they are

...
#define __NR_rt_sigaction       174
#define __NR_rt_sigprocmask     175
...
#define __NR_set_tid_address    256
...

none of which are needed in my little test. Bare metal Lua. Luanix?

After I had this little bit of excitement, I remembered that I had configured ELK with the task scheduler and system timer. I figured it might be worth a try to see if at least the interrupt driven timer was working. Sure enough:

> print (os.date())
unhandled system call (174) args: 2, 1241512644, 1241512624, 8, 1207961832, 1241512696
unhandled system call (5) args: 276151, 657408, 0, 1, 1241510728, 1241511520
Thu Jan  1 00:07:22 1970
unhandled system call (174) args: 2, 1241512644, 1241512624, 8, 1207961832, 1241512696
> print (os.date())
unhandled system call (174) args: 2, 1241512644, 1241512624, 8, 1207961832, 1241512696
Thu Jan  1 00:07:45 1970
unhandled system call (174) args: 2, 1241512644, 1241512624, 8, 1207961832, 1241512696
> 

Time keeps on ticking. Fun stuff.

Building Lua for ARM with ELLCC

Today someone mentioned Lua the scripting language and how it was a nice embed-able language well suited to small embedded systems. I decided to see how well ELLCC could do building Lua for an ARM Linux target. You can build the ELLCC compiler package by following the instructions here.

I downloaded the latest Lua tarball from their download page and was off to the races. I extracted Lua into my ~/ellcc directory:

[~] dev% cd ~/ellcc
[~/ellcc] dev% tar xvfpz Downloads/lua-5.2.2.tar.gz

I made a few small changes to their configuration to use ecc for the ARM:

[~] dev% diff -r -c lua-5.2.2 ellcc/lua-5.2.2/
diff -r -c lua-5.2.2/src/luaconf.h ellcc/lua-5.2.2/src/luaconf.h
*** lua-5.2.2/src/luaconf.h     2013-03-16 16:10:18.000000000 -0500
--- ellcc/lua-5.2.2/src/luaconf.h       2013-11-08 09:59:56.000000000 -0600
***************
*** 43,49 ****
  #if defined(LUA_USE_LINUX)
  #define LUA_USE_POSIX
  #define LUA_USE_DLOPEN                /* needs an extra library: -ldl */
! #define LUA_USE_READLINE      /* needs some extra libraries */
  #define LUA_USE_STRTODHEX     /* assume 'strtod' handles hex formats */
  #define LUA_USE_AFORMAT               /* assume 'printf' handles 'aA' specifiers */
  #define LUA_USE_LONGLONG      /* assume support for long long */
--- 43,49 ----
  #if defined(LUA_USE_LINUX)
  #define LUA_USE_POSIX
  #define LUA_USE_DLOPEN                /* needs an extra library: -ldl */
! // #define LUA_USE_READLINE   /* needs some extra libraries */
  #define LUA_USE_STRTODHEX     /* assume 'strtod' handles hex formats */
  #define LUA_USE_AFORMAT               /* assume 'printf' handles 'aA' specifiers */
  #define LUA_USE_LONGLONG      /* assume support for long long */
diff -r -c lua-5.2.2/src/Makefile ellcc/lua-5.2.2/src/Makefile
*** lua-5.2.2/src/Makefile      2012-12-27 04:51:43.000000000 -0600
--- ellcc/lua-5.2.2/src/Makefile        2013-11-08 21:34:36.494043682 -0600
***************
*** 6,14 ****
  # Your platform. See PLATS for possible values.
  PLAT= none
  
! CC= gcc
  CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
  LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
  LIBS= -lm $(SYSLIBS) $(MYLIBS)
  
  AR= ar rcu
--- 6,16 ----
  # Your platform. See PLATS for possible values.
  PLAT= none
  
! CC= /home/rich/ellcc/bin/ecc
  CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
+ CFLAGS+= -target arm-ellcc-linux-eabi -mcpu=armv6z -mfpu=vfp -mfloat-abi=softfp
  LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
+ LDFLAGS+= -target arm-ellcc-linux-eabi
  LIBS= -lm $(SYSLIBS) $(MYLIBS)
  
  AR= ar rcu
***************
*** 103,109 ****
  generic: $(ALL)
  
  linux:
!       $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
  
  macosx:
        $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
--- 105,111 ----
  generic: $(ALL)
  
  linux:
!       $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl"
  
  macosx:
        $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
[~] dev% 

Then I just typed:

[~/ellcc] dev% cd lua-5.2.2/
[~/ellcc/lua-5.2.2] dev% make linux

I now have my ARM lua exectiable:

[~/ellcc/lua-5.2.2] dev% file src/lua
src/lua: ELF 32-bit LSB executable, ARM, version 1, statically linked, BuildID[sha1]=0x635737dc31e9d493f06b8f9fa5d2e7e3c1fe93ee, not stripped
[~/ellcc/lua-5.2.2] dev% 

Which I can run with QEMU (I use an x86_64 Linux box and don’t have ARM hardware handy):

[~/ellcc/lua-5.2.2] dev% ~/ellcc/bin/qemu-arm src/lua
Lua 5.2.2  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> 

I then went to Lua’s live demo page and cut and pasted an example program:

> -- hello.lua
-- the first program in every language

io.write("Hello world, from ",_VERSION,"!\n")> > > 
Hello world, from Lua 5.2!
> 

Nice!