Author Archives: rich

ELLCC 2017-07-29 Released

A new binary release of the ELLCC cross compilation tool chain is available.
ELLCC is a pre-packaged set of tools designed to support cross compilation
for a variety of target processors.

All programs developed using ELLCC are covered by BSD and BSD-like licenses.

Major features of this release include:

  • Shared libraries fully supported.
  • Replaced ncurses with the NetBSD curses as provided by sabotage Linux
  • New ellcc command supports binary updates, installing source code, and building ELLCC from source.

More information is in the ChangeLog.

Binary tarballs are available from here.

The tool chain can build programs for ARM, Mips, PowerPC, and x86 Linux and
stand-alone targets. All host systems can build programs for all the supported targets.

The ELLCC run-time libraries are available pre-built for all targets and
are all covered with BSD-like licenses:

  • libc++ The C++ standard library
  • musl The POSIX compliant C library
  • compiler-rt Low level compiler support
  • expat XML parsing
  • libedit Command history
  • curses Terminal handling
  • zlib Compression/decompression
  • curl URL syntax data transfer
  • mbed TLS Transport Layer Security
  • c-ares Asynchronous DNS
  • libssh2 Client side SSH2
  • libmetalink Metalink support

ELLCC is entirely self hosting.

ELLCC for Linux Using Bash on Windows 10

Bash on Windows 10 has come pretty far. You can now run a regular Linux ELLCC compiler on it. It works so well that I’ve even been able to build ELLCC with itself on Windows. Here’s an example of installing and using it.

rich@windows-81:~$ uname -a
Linux windows-81 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux
rich@windows-81:~$ wget http://ellcc.org/releases/2017-07-27/ellcc-x86_64-linux-2017-07-27.bz2
--2017-07-28 07:25:18--  http://ellcc.org/releases/2017-07-27/ellcc-x86_64-linux-2017-07-27.bz2
Resolving ellcc.org (ellcc.org)... 98.144.109.26
Connecting to ellcc.org (ellcc.org)|98.144.109.26|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 114791914 (109M) [application/x-bzip2]
Saving to: ?ellcc-x86_64-linux-2017-07-27.bz2.1?

ellcc-x86_64-linux- 100%[===================>] 109.47M  9.34MB/s    in 10s

2017-07-28 07:25:33 (10.5 MB/s) - ?ellcc-x86_64-linux-2017-07-27.bz2.1? saved [114791914/114791914]

rich@windows-81:~$ tar xf ellcc-x86_64-linux-2017-07-27.bz2
rich@windows-81:~$ cd ellcc
rich@windows-81:~/ellcc$ bin/ellcc install # Finish the installation
Moving the ellcc tarball to ellcc/build for future updates.
rich@windows-81:~/ellcc$ bin/ellcc # This adds the bin directory to PATH.
rich@windows-81:~/ellcc$ cd ..
rich@windows-81:~$ cat main.cpp
#include 

int main()
{
    std::cout << "hello world" << std::endl;
}
rich@windows-81:~$ ecc++ -o hello main.cpp
rich@windows-81:~$ ./hello 
hello world
rich@windows-81:~$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /home/rich/ellcc/libecc/lib/x86_64-linux/libc.so, BuildID[sha1]=b7094ed5f6a33f41794b6e0cebb2b89e023d0a3d, not stripped
rich@windows-81:~$

Please Pardon Our Dust

If you look around the site and find that many of the pages look incomplete, it is because they are. The ELLCC project has recently gone through a massive restructuring in preparation for a new release with significant changes. The release is essentially complete and is available via subversion or from the Download page, but the supporting documentation on the site is being updated to reflect all the changes. There will be an official announcement when we’re done, but in the mean time, thank you for your patience. A few examples of the changes:

  • Binary downloads are now separated into components that can be added separately so you can download just the parts you need.
  • Releases are now tagged by date, e.g. 2017-07-16, which reflects the day that the latest sources were pulled from each of the component’s source repository or latest release tarball.
  • Shared libraries are now supported.

ELLCC 0.1.33 Released

A new binary release of the ELLCC cross compilation tool chain is available.
ELLCC is a pre-packaged set of tools designed to support cross compilation
for a variety of target processors.

This release includes pre-built binaries for 64-bit ARM Linux and
supports the -coverage option to do code coverage. You can see an example
of coverage output at http://ellcc.org/coverage

Unfortunately, I haven’t had time to debug build issues with the MinGW build. As a result the binaries of this release for this host are not available. If anyone is interested in looking into the build failure, patches welcome!

ELLCC includes:

  • ecc (a clang/LLVM based C/C++ compiler)
  • binutils
  • GDB
  • QEMU (on x86_64 Linux hosts)

The ELLCC run-time libraries are supplied pre-built for all targets and
are all covered with BSD-like licenses:

  • libc++ The C++ standard library
  • musl The POSIX compliant C library
  • compiler-rt Low level compiler support
  • expat XML parsing
  • libedit Command history
  • ncurses Terminal handling
  • zlib Compression/decompression
  • curl URL syntax data transfer
  • libevent Event notification
  • mbed TLS Transport Layer Security
  • c-ares Asynchronous DNS
  • libssh2 Client side SSH2
  • libmetalink Metalink support
  • openldap Lightweight directory access protocol
  • nanomsg Several common communication patterns

ELLCC is entirely self hosting.

From the ChangeLog:

version 0.1.33:

* Update to GDB 7.12,
* Update to LLVM r283663.
* Added 64 bit ARM hosts to the pre-built binaries.
* Fixed libedit configuration rules.
* Update to LLVM r283106.
* Update the c-ares library to version 1.12.0.
* Update to LLVM r283004.
* Update the nghttp2 library to version 1.15.0. 
* Update the curl library to version 7.50.3.
* Update to LLVM r282329.
* Update to LLVM r281818.
* Update to LLVM r281453.
* Update to LLVM r281321.
* Update to LLVM r280704.
* Update to libedit-20160903-3.1.
* Update to QEMU 2.7.0.
* Update the nghttp2 library to version 1.14.0.
* Update to LLVM r279916.
* Update to LLVM r279342.
* Update to LLVM r278565.
* Enhanced llvm-cov HTML output.
* Enable code coverage with the -coverage option.

Binary tarballs are available from here.

The tool chain can build programs for ARM, Mips, PowerPC, and x86 Linux and
stand-alone targets and x86 Windows systems.

Pre-built binaries are available for ARM, Mips, and x86 Linux host systems
as well as x86_64 Windows and Mac OS X hosts.

All host systems can build programs for all the supported targets.

Available targets are listed here.

Cross Building tcsh with ELLCC: Revisted

A long time ago, I wrote a post about building the tcsh shell with ELLCC. The subject came up again recently, so I thought that a revisit might be in order.

First, I downloaded the latest tcsh sources with wget and unpacked them with tar:

rich@dev:~$ wget ftp://ftp.astron.com/pub/tcsh/tcsh-6.19.00.tar.gz
--2016-08-31 16:16:59--  ftp://ftp.astron.com/pub/tcsh/tcsh-6.19.00.tar.gz
           => ‘tcsh-6.19.00.tar.gz’
Resolving ftp.astron.com (ftp.astron.com)... 38.117.134.18
Connecting to ftp.astron.com (ftp.astron.com)|38.117.134.18|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done.    ==> PWD ... done.
==> TYPE I ... done.  ==> CWD (1) /pub/tcsh ... done.
==> SIZE tcsh-6.19.00.tar.gz ... 947135
==> PASV ... done.    ==> RETR tcsh-6.19.00.tar.gz ... done.
Length: 947135 (925K) (unauthoritative)

tcsh-6.19.00.tar.gz 100%[===================>] 924.94K  2.17MB/s    in 0.4s    

2016-08-31 16:17:00 (2.17 MB/s) - ‘tcsh-6.19.00.tar.gz’ saved [947135]

rich@dev:~$ tar xfp tcsh-6.19.00.tar.gz
rich@dev:~$ 

I used wget to get tcsh, but you could also use a web browser.

Next I went into the source directory and ran configure to set up for an ELLCC build:

rich@dev:~$ cd tcsh-6.19.00/
rich@dev:~/tcsh-6.19.00$ CC="/home/rich/ellcc/bin/ecc -target x86_64-linux" CPP="${CC} -E" ./configure
checking for a BSD-compatible install... /usr/bin/install -c
[snip lot's of configure output]
config.status: creating config.h
config.status: executing ./atconfig commands
rich@dev:~/tcsh-6.19.00$ 

In this case I configured for an x86_64-linux host. A little later I’ll configure the build for a MIPS.

Now for the build:

rich@dev:~/tcsh-6.19.00$ make
grep 'ERR_' ./sh.err.c | grep '^#define' >> sh.err.h.tmp
sh.err.h recreated.
/home/rich/ellcc/bin/ecc -target x86_64-linux -E -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    -D_h_tc_const\
    ./tc.const.c | \
    sed -n -e 's/^\(Char STR[a-zA-Z0-9_]*\) *\[ *\].*/extern \1[];/p' | \
    sort >> tc.const.h.tmp
tc.const.h recreated.
/home/rich/ellcc/bin/ecc -target x86_64-linux -c -g -O2 -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    sh.c
/home/rich/ellcc/bin/ecc -target x86_64-linux -c -g -O2 -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    [snip lots of files compiled]
/home/rich/ellcc/bin/ecc -target x86_64-linux -c -g -O2 -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    sh.proc.c
sh.proc.c:155:16: error: variable has incomplete type 'union wait'
    union wait w;
               ^
sh.proc.c:155:11: note: forward declaration of 'union wait'
    union wait w;
          ^
1 error generated.
Makefile:465: recipe for target 'sh.proc.o' failed
make: *** [sh.proc.o] Error 1
rich@dev:~/tcsh-6.19.00$ 

It turns out the ELLCC’s standard C library doesn’t support a BSD style wait, so I added a conditional compilation around lin 50 of sh.proc.c:

#if defined(_BSD) || (defined(IRIS4D) && __STDC__) || defined(__lucid) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
# if !defined(__ANDROID__) && !defined(__ELLCC__)
#  define BSDWAIT
# endif
#endif /* _BSD || (IRIS4D && __STDC__) || __lucid || glibc */

Now the make succeeded, but when I tried to run the shell I got:

rich@dev:~/tcsh-6.19.00$ ./tcsh
(nil) current memory allocation:
free:       0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
used:       0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
        Total in use: 0, total free: 0
        Allocated memory from 0x1a00000 to 0xffffffffffffffff.  Real top at 0x1a00000
nbytes=56: Out of memory
Aborted (core dumped)
rich@dev:~/tcsh-6.19.00$ 

Not good! It turned out that tcsh tries to to its own memory allocation using sbrk() rather than malloc() by default. A quick edit of config_f.h (around line 213) adding another conditional compilation fixed it:

#if defined(__MACHTEN__) || defined(PURIFY) || defined(MALLOC_TRACE) || defined(_OSD_POSIX) || defined(__MVS__) || defined (__CYGWIN__) || defined(__GLIBC__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__ELLCC__)
# define SYSMALLOC
#else
# undef SYSMALLOC
#endif

You have to manually delete tc.alloc.o and run make again for this change to take affect:

rich@dev:~/tcsh-6.19.00$ rm tc.alloc.o
rich@dev:~/tcsh-6.19.00$ make
/home/rich/ellcc/bin/ecc -target x86_64-linux -E -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    -D_h_tc_const\
    ./tc.const.c | \
    sed -n -e 's/^\(Char STR[a-zA-Z0-9_]*\) *\[ *\].*/extern \1[];/p' | \
    sort >> tc.const.h.tmp
tc.const.h unchanged.
/home/rich/ellcc/bin/ecc -target x86_64-linux -c -g -O2 -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    tc.alloc.c
rm -f tcsh core
/home/rich/ellcc/bin/ecc -target x86_64-linux -o tcsh  -g -O2 -I. -I. sh.o sh.dir.o sh.dol.o sh.err.o sh.exec.o sh.char.o sh.exp.o sh.file.o sh.func.o sh.glob.o sh.hist.o sh.init.o sh.lex.o sh.misc.o sh.parse.o sh.print.o sh.proc.o sh.sem.o sh.set.o sh.time.o glob.o dotlock.o mi.termios.o ma.setp.o vms.termcap.o tw.help.o tw.init.o tw.parse.o tw.spell.o tw.comp.o tw.color.o ed.chared.o ed.refresh.o ed.screen.o ed.init.o ed.inputl.o ed.defns.o ed.xmap.o ed.term.o tc.alloc.o tc.bind.o tc.const.o tc.defs.o tc.disc.o tc.func.o tc.nls.o tc.os.o tc.printf.o tc.prompt.o tc.sched.o tc.sig.o tc.str.o tc.vers.o tc.who.o  -lncurses   
clang-3.9: warning: argument unused during compilation: '-g'
make[1]: Entering directory '/home/rich/tcsh-6.19.00/nls'
make[1]: Nothing to be done for 'catalogs'.
make[1]: Leaving directory '/home/rich/tcsh-6.19.00/nls'

Now when I run tcsh I get:

rich@dev:~/tcsh-6.19.00$ ./tcsh
[~/tcsh-6.19.00] dev% set
_
addsuffix
anyerror
arch    Linux-x86_64
arch1   Linux
arch2   x86_64
arch3
argv    ()
autolist
cdpath  (.. /home/rich /usr/rich/src /usr/src /sys/arch/i386 /usr/local/etc/httpd/htdocs)
cdtohome
csubstnonl
cwd     /home/rich/tcsh-6.19.00
dirstack        /home/rich/tcsh-6.19.00
echo_style      both
edit
elegant /home/rich/elegant
euid    1000
euser   rich
gid     1000
group   rich
histdup erase
history 1000
home    /home/rich
iarch   Linux-x86_64
killring        30
notify
owd
path    (/opt/microchip/mplabc32/v2.01/bin /opt/jdk1.5.0_06/jre/bin /usr/local/bin /sbin /usr/sbin /usr/lib64/qt-3.3/bin /usr/lib64/ccache /usr/local/bin /usr/bin /bin /usr/games /usr/local/sbin /usr/sbin /home/rich/.local/bin /home/rich/bin)
prompt  [%~] %m% 
prompt2 %R? 
prompt3 CORRECT>%R (y|n|e|a)? 
promptchars     $#
savehist        (1024 merge)
shell   /usr/local/bin/tcsh
shlvl   4
sourced 0
status  0
tcsh    6.19.00
term    xterm
uid     1000
user    rich
version tcsh 6.19.00 (Astron) 2015-05-21 (x86_64-unknown-linux) options wide,nls,dl,al,kan,rh,color,filec
[~/tcsh-6.19.00] dev% exit
exit
rich@dev:~/tcsh-6.19.00$

Nice! Now what about the MIPS? I cleaned up and did a new configure, but it failed:

rich@dev:~/tcsh-6.19.00$ make distclean
make[1]: Entering directory '/home/rich/tcsh-6.19.00/nls'
rm -f C.cat et.cat finnish.cat french.cat german.cat greek.cat italian.cat ja.cat pl.cat russian.cat spanish.cat ukrainian.cat
make[1]: Leaving directory '/home/rich/tcsh-6.19.00/nls'
rm -f a.out strings x.c xs.c tcsh tcsh.a _MAKE_LOG gethost
rm -f *.o *.i *.s
rm -f sh.prof.c ed.defns.h tc.const.h sh.err.h tc.defs.c
rm -f tcsh.*.m tcsh.*.cat
rm -f Makefile config.h config_p.h
rm -f config.status config.cache config.log tcsh.ps
rm -f missing
rm -rf autom4te.cache
rm -f *~ #*
rich@dev:~/tcsh-6.19.00$ CC="/home/rich/ellcc/bin/ecc -target mips32r2el-linux" CPP="${CC} -E" ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking cached host tuple... ok
Tcsh will use configuration file `linux'.
checking for gcc... /home/rich/ellcc/bin/ecc -target mips32r2el-linux
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... configure: error: in `/home/rich/tcsh-6.19.00':
configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
See `config.log' for more details
rich@dev:~/tcsh-6.19.00$

Not a big deal, though. All I have to do is tell configure that I’m cross compiling:

rich@dev:~/tcsh-6.19.00$  CC="/home/rich/ellcc/bin/ecc -target mips32r2el-linux" CPP="${CC} -E" ./configure -host=x86_64-linux
checking for a BSD-compatible install... /usr/bin/install -c
[snip lots of configure output]
config.status: executing ./atconfig commands
rich@dev:~/tcsh-6.19.00$ make
grep 'ERR_' ./sh.err.c | grep '^#define' >> sh.err.h.tmp
sh.err.h recreated.
/home/rich/ellcc/bin/ecc -target mips32r2el-linux -E -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    -D_h_tc_const\
    ./tc.const.c | \
    sed -n -e 's/^\(Char STR[a-zA-Z0-9_]*\) *\[ *\].*/extern \1[];/p' | \
    sort >> tc.const.h.tmp
tc.const.h recreated.
/home/rich/ellcc/bin/ecc -target mips32r2el-linux -c -g -O2 -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    sh.c
[snip lots of make output]
make[1]: Leaving directory '/home/rich/tcsh-6.19.00/nls'
rich@dev:~/tcsh-6.19.00$ 

Now I can run file on the tcsh executable to see what it is, and then try to run it:

ich@dev:~/tcsh-6.19.00$ file tcsh
tcsh: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1, statically linked, BuildID[sha1]=778f05c34a07a583f3e56ad979235b0bbcb55279, not stripped  
rich@dev:~/tcsh-6.19.00$ ~/ellcc/bin/qemu-mipsel tcsh
exit
rich@dev:~/tcsh-6.19.00$

The good news is that the MIPS executable runs. The bad news is that it exits immediately. A little poking around finds that the MIPS tcsh can run single commands:

rich@dev:~/tcsh-6.19.00$ ~/ellcc/bin/qemu-mipsel tcsh -c set
_
addsuffix
anyerror
arch    Linux-x86_64
arch1   Linux
arch2   x86_64
arch3
argv    ()
cdpath  (.. /home/rich /usr/rich/src /usr/src /sys/arch/i386 /usr/local/etc/httpd/htdocs)
cdtohome
command set
csubstnonl
cwd     /home/rich/tcsh-6.19.00
dirstack        /home/rich/tcsh-6.19.00
echo_style      both
edit
elegant /home/rich/elegant
euid    1000
euser   rich
gid     1000
group   rich
histdup erase
history 1000
home    /home/rich
iarch   Linux-x86_64
killring        30
notify
owd
path    (/opt/microchip/mplabc32/v2.01/bin /opt/jdk1.5.0_06/jre/bin /usr/local/bin /sbin /usr/sbin /usr/lib64/qt-3.3/bin /usr/lib64/ccache /usr/local/bin /usr/bin /bin /usr/games /usr/local/sbin /usr/sbin /home/rich/.local/bin /home/rich/bin)
prompt  [%~] %m% 
savehist        (1024 merge)
shell   /usr/local/bin/tcsh
shlvl   4
sourced 0
status  0
tcsh    6.19.00
term    xterm
uid     1000
user    rich
version tcsh 6.19.00 (Astron) 2015-05-21 (mips-unknown-linux) options wide,nls,dl,al,kan,sm,rh,color,filec
rich@dev:~/tcsh-6.19.00$

I tried mips32r2-linux (big endian) and it failed exactly the same way. I also tried a similar cross build for arm32v7-linux and it worked fine. My guess is that there is a bug in QEMU that isn’t handling a MIPS system call correctly, but that investigation will have to be on another day. I’d love to test the binary on a real MIPS system, but I don’t have one. I suspect it might just work.

ELLCC 0.1.32 Released

A new binary release of the ELLCC cross compilation tool chain is available.
ELLCC is a pre-packaged set of tools designed to support cross compilation
for a variety of target processors.

This release supports MIPS and PowerPC 64 bit targets.

Unfortunately, I haven’t had time to debug build issues with the MinGW build. As a result the binaries of this release for this host are not available. If anyone is interested in looking into the build failure, patches welcome!

ELLCC includes:

  • ecc (a clang/LLVM based C/C++ compiler)
  • binutils
  • GDB
  • QEMU (on x86_64 Linux hosts)

The ELLCC run-time libraries are supplied pre-built for all targets and
are all covered with BSD-like licenses:

  • libc++ The C++ standard library
  • musl The POSIX compliant C library
  • compiler-rt Low level compiler support
  • expat XML parsing
  • libedit Command history
  • ncurses Terminal handling
  • zlib Compression/decompression
  • curl URL syntax data transfer
  • libevent Event notification
  • mbed TLS Transport Layer Security
  • c-ares Asynchronous DNS
  • libssh2 Client side SSH2
  • libmetalink Metalink support
  • openldap Lightweight directory access protocol
  • nanomsg Several common communication patterns

ELLCC is entirely self hosting.

From the ChangeLog:

version 0.1.32:

* Update the curl library to version 7.50.1.
* Update to binutils 2.27.
* Update the libssh2 library to version 1.7.0.
* Update to LLVM r277813.
* Update to libedit-20160618-3.1.
* Update to GDB 7.11.1.
* Update the nghttp2 library to version 1.13.0.
* Update the expat library to version 2.2.0.
* Update the curl library to version 7.50.0.
* Update ithe mbedtls library to version 2.3.0.
* Added support for 64 bit LE PowerPC 64.
* Added support for 64 bit MIPS.
* Update to musl 1.1.15.

Binary tarballs are available from here.

The tool chain can build programs for ARM, Mips, PowerPC, and x86 Linux and
stand-alone targets and x86 Windows systems.

Pre-built binaries are available for ARM, Mips, and x86 Linux host systems
as well as x86_64 Windows and Mac OS X hosts.

All host systems can build programs for all the supported targets.

Available targets are listed here.

ELLCC 0.1.28 Released

A new binary release of the ELLCC cross compilation tool chain is available.
ELLCC is a pre-packaged set of tools designed to support cross compilation
for a variety of target processors.

This release has simple instructions for cross building Linux for the
Raspberry Pi and updates several libraries.
This is the last release which will be built with autohell. I hope that I can
figure out how to use cmake soon for the next release.

ELLCC includes:

  • ecc (a clang/LLVM based C/C++ compiler)
  • binutils
  • GDB
  • QEMU (on x86_64 Linux hosts)

The ELLCC run-time libraries are supplied pre-built for all targets and
are all covered with BSD-like licenses:

  • libc++ The C++ standard library
  • musl The POSIX compliant C library
  • compiler-rt Low level compiler support
  • expat XML parsing
  • libedit Command history
  • ncurses Terminal handling
  • zlib Compression
  • curl ULR syntax data transfer
  • libevent Event notification
  • mbed TLS TLS
  • c-ares Asynchronous DNS
  • libssh2 Client side SSH2
  • libmetalink Metalink support
  • openldap Lightweight directory access protocol
  • nanomsg Several common communication patterns

ELLCC is entirely self hosting.

From the ChangeLog:

version 0.1.28:

* Update to curl 7.47.0.
* Update to binutils 2.26.
* Update autoconf files for several libraries.
* Update to LLVM r258477.
* Added missing aarch64 compiler-rt functions: __floatditf, etc.
* Add wireless tools build to ecclinux.
* Update to LLVM r257984.
* Add less build to ecclinux.

Binary tarballs are available from here.

The tool chain can build programs for ARM, Mips, PowerPC, and x86 Linux and
stand-alone targets and x86 Windows systems.

Pre-built binaries are available for ARM, Mips, and x86 Linux host systems
as well as x86_64 Windows and Mac OS X hosts.

All host systems can build programs for all the supported targets.

Available targets are listed here.

From 0 to Raspberry Pi Linux in 45 Minutes

I thought it would be cool to see how long it takes to make a boot-able Raspberry Pi disk using ELLCC. This is a timed experiment. In the end we’ll have an SD card that can be booted on the Pi. First, get a binary ELLCC release:

[~/ellcc-release] dev% mkdir test
[~/ellcc-release] dev% cd test
[~/test] dev% wget http://ellcc.org/releases/ellcc-x86_64-linux-eng-0.1.27.tgz
--2016-01-12 22:00:19--  http://ellcc.org/releases/ellcc-x86_64-linux-eng-0.1.27.tgz
Resolving ellcc.org (ellcc.org)... 174.102.201.124
Connecting to ellcc.org (ellcc.org)|174.102.201.124|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 650187071 (620M) [application/x-gzip]
Saving to: ‘ellcc-x86_64-linux-eng-0.1.27.tgz’

ellcc-x86_64-linux-e 100%[=====================>] 620.07M  11.0MB/s   in 56s    

2016-01-12 22:01:15 (11.1 MB/s) - ‘ellcc-x86_64-linux-eng-0.1.27.tgz’ saved [650187071/650187071]
[~/test] dev% tar xvfp ellcc-x86_64-linux-eng-0.1.27.tgz

Second, check what the options are:

[~/test] dev% cd ellcc/libecc/ecclinux/
[~/test/ellcc/libecc/ecclinux] dev% ./build 
usage: ./build [options] target
  options:
    -packages 'packag1 package2 ...'    Specific packages to build
    -exclude  'packag1 package2 ...'    Specific packages to exclude
    -extras                             Include additional packages
    -clean                              Clean up a previous build
  targets:
    help                                This message
    bcmrpi                              Raspberry Pi    (ARMv6)
    bcm2709                             Raspberry Pi 2  (ARMv7)
  available packages:
    kernel sinit sbase ubase smdev nldev nlmon svc sdhcp loksh
          ntfs3g iproute2 e2fsprogs vim dropbear
  extra packages:
    ellcc
  packages not buildable on the Mac:
    uboot iproute2 e2fsprogs vim

Third, build an image for the Pi 2 that includes the ELLCC tool chain (-extras):

[~/test/ellcc/libecc/ecclinux] dev% ./build -extras bcm2709j
...

Fourth, insert an SD card and install:

[~/test/ellcc/libecc/ecclinux] dev% su
Password: 
[root@dev ecclinux]# ./install
Warning! This command will destroy all data on /dev/sdc.
Continue? [yes/no] yes
...

Put the SD in the Pi and boot. Voila!

Cross Building Linux With ELLCC: Part 5 – Making an SD Card to Boot the Pi.

UPDATE: A more streamlined version of this process is available: From 0 to Raspberry Pi Linux in 45 Minutes

In previous posts I’ve described building the Linux kernel using ELLCC, building Linux for a Raspberry Pi B+, building Linux for the Pi 2, and building Linux on a Mac. In this post we’ll build enough userland and create an SD card that will boot on the Raspberry Pi 2. I just got it to boot this evening and it only gets to the login prompt where I can log in as root, but I think it is pretty cool nonetheless.

I mentioned the ellcc/libecc/ecclinux directory that is in the ELLCC source tree and is included in the ELLCC binary distributions. In this directory, there is a little script that will get sources for the Linux kernel from kernel.org, and a bunch of userland programs from suckless.org and other places. The script will then patch the sources if necessary and build them.

These are the steps I took to create a boot-able SD card. I happened to have a 32 Gig SD card lying around, so I decided to use it. On my Linux box, an SD card shows up as /dev/sdc* so the following commands reflect that. Your system may assign different name. You should verify the name by using df, or something similar, to determine what a newly inserted SD card is.

I’m going to go into a bit of detail here because it is the first time I did this for Linux and I want to keep a detailed record.

UPDATE: I made a little script that populates the SD card. It is in the source repository. The script replaces/enhances the rest of this post.

The first thing I did was to remove the old partitions on the card.

  sudo parted /dev/sdc print
    Model: Generic- SD/MMC (scsi)
    Disk /dev/sdc: 32.1GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags: 

    Number  Start   End     Size    Type     File system  Flags
     1      512B    62.9MB  62.9MB  primary
     2      62.9MB  67.1MB  4209kB  primary

My card had 2 partitions that I got rid of:

  sudo parted /dev/sdc rm 1
    Information: You may need to update /etc/fstab.

  sudo parted /dev/sdc rm 2
    Information: You may need to update /etc/fstab.

  sudo parted /dev/sdc print                                       
    Model: Generic- SD/MMC (scsi)
    Disk /dev/sdc: 32.1GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags: 

    Number  Start  End  Size  Type  File system  Flags

Now that the old partitions are gone, we can make new partitions for the Pi. The Pi boots using two partitions, one is in MS-DOS or FAT format, the other is in Linux ext4 format. The Pi has an interesting boot sequence, which is nicely described on this page, but basically the GPU starts up first and executes a first and second stage boot loader, which is really the GPU’s OS, before the ARM is brought up and the Linux kernel is booted. The FAT partition is used by the GPU and contains all the files it needs. The ext4 partition contains the rest of the Linux userland. The FAT partition os mounted as /boot after the ext4 partition is mounted as /.So the next step is to create these two partitions. First the FAT partition:

sudo parted -a optimal /dev/sdc unit chs mkpart primary 0,130,2 8,40,31
sudo parted /dev/sdc set 1 lba on

Now we can fill the rest of the disk with the ext4 partition:

sudo parted -a optimal /dev/sdc mkpart primary 67.1MB 100%

Now we’ll format the file systems:

  sudo mkfs -t fat /dev/sdc1
    mkfs.fat 3.0.27 (2014-11-12)

Then the ext4 partition:

  sudo mkfs -t ext4 /dev/sdc2
    mke2fs 1.42.12 (29-Aug-2014)
    Creating filesystem with 7820288 4k blocks and 1957888 inodes
    Filesystem UUID: 3823b7f5-66b6-4e9f-a10e-4a6658d6469f
    Superblock backups stored on blocks: 
            32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
            4096000

    Allocating group tables: done                            
    Writing inode tables: done                            
    Creating journal (32768 blocks): done
    Writing superblocks and filesystem accounting information: done   

We have to mark the first partition as the boot partition:

  sudo parted /dev/sdc set 1 lba on
    Information: You may need to update /etc/fstab.

  sudo parted /dev/sdc print
    Model: Generic- SD/MMC (scsi)
    Disk /dev/sdc: 32.1GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags: 

    Number  Start   End     Size    Type     File system  Flags
     1      4194kB  67.1MB  62.9MB  primary  fat16        lba
     2      67.1MB  32.1GB  32.0GB  primary  ext4

Now we can populate the card. First, build everything using the script. If you run the script with no arguments, it will give you a hint about how to run it:

[~] dev% cd ellcc/libecc/ecclinux
[~/ellcc/libecc/ecclinux] dev% ./build 
usage: ./build [options] target
  options:
    -packages 'packag1 package2 ...'    Specific packages to build
    -exclude  'packag1 package2 ...'    Specific packages to exclude
    -clean                              Clean up a previous build
  targets:
    help                                This message
    bcmrpi                              Raspberry Pi    (ARMv6)
    bcm2709                             Raspberry Pi 2  (ARMv7)
  available packages:
    uboot kernel sinit sbase ubase smdev nldev nlmon svc sdhcp loksh
          ntfs3g iproute2 e2fsprogs vim ellcc
  packages not buildable on the Mac:
    uboot iproute2 e2fsprogs vim

In this case I’ll build for the Raspberry Pi 2:

[~/ellcc/libecc/ecclinux] dev% ./build bcm2709
  CHK     include/config/kernel.release
  GEN     ./Makefile
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  Using /home/rich/ellcc/libecc/ecclinux/linux-4.1.15 as source for kernel
...

The SD card can be populated after the build completes:

 
  mkdir boot root
  sudo mount /dev/sdc1 boot
  sudo mount /dev/sdc2 root
  cp -r image/arm-linux-engeabihf/bcm2709/* boot
  sudo cp boot/vmlinuz-4.1.15-v7 boot/kernel7.img
  cd image/arm-linux-engeabihf/
  tar cvfp - bin etc lib sbin usr var | (cd ../../root; sudo tar xfp -)
  cd cm2709/
  rm -fr *.old
  tar cvfp - * | ( cd ../../../boot ; sudo tar xfp - )
  cd ../../..
  cd etc
  chmod oug+x rc.*
  cp * ../root/etc/
  cd ../sbin
  tar cvfp - * | ( cd ../root/sbin/ ; sudo tar xf - )
  cd ../bin
  chmod oug+x *
  tar cvfp - * | ( cd ../root/bin/ ; sudo tar xf - )
  sudo cp boot.rpi/* boot/
  cd root
  sudo mkdir root proc sys var/run
  sudo mknod dev/tty0 c 4 0
  cd ..
  sudo umount boot root

I popped the SD card into my Pi 2 and finally got the login: prompt. The initial root password is empty.

This has been a busy weekend. I got a boot, the Packers won, and it is late Sunday night and I have to work early tomorrow. I will be making the SD create steps into a script soon, but for now I’ll put up a new binary release of ELLCC, version 0.1.26, that has all the changes if you want to try this out.

Cross Building Linux With ELLCC: Part 4 – Building Linux on the Mac

In a previous post I described cross compiling the Linux kernel and userland for the Raspberry Pi using ELLCC. In this post, I’ll do the same thing on Mac OS X.
I’d like to thank Emmanuel Blot for making this possible. He sent the necessary patches. Thanks Emmanuel!

First we need to make a case insensitive file system:

[~] Richards-Mac-mini% hdiutil create -size 10g -type SPARSEBUNDLE -nospotlight -volname ellcc -fs "Case-sensitive Journaled HFS+" -attach ./ellcc.dmg
/dev/disk1              GUID_partition_scheme           /dev/disk1s1           EFI
/dev/disk1s2            Apple_HFS                       /Volumes/ellcc
created: /Users/rich/ellcc.dmg.sparsebundle

Then get the the latest binary release of ELLCC:

[~] Richards-Mac-mini% cd /Volumes/ellcc/
[/Volumes/ellcc] Richards-Mac-mini% wget http://ellcc.org/releases/ellcc-Mac_OS_X_10.11.2-0.1.25.tgz
--2016-01-06 17:58:38--  http://ellcc.org/releases/ellcc-Mac_OS_X_10.11.2-0.1.25.tgz
Resolving ellcc.org... 174.102.201.124
Connecting to ellcc.org|174.102.201.124|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 417609504 (398M) [application/x-gzip]
Saving to: 'ellcc-Mac_OS_X_10.11.2-0.1.25.tgz'
ellcc-Mac_OS_X_10.11 100%[===================>] 398.26M  11.2MB/s    in 40s
2016-01-06 17:59:18 (10.0 MB/s) - 'ellcc-Mac_OS_X_10.11.2-0.1.25.tgz' saved [417609504/417609504]
[/Volumes/ellcc] Richards-Mac-mini% tar xvfp ellcc-Mac_OS_X_10.11.2-0.1.25.tgz
...

Now we can build. Check for supported boards and choose the one you want:

[/Volumes/ellcc] Richards-Mac-mini% cd ellcc/libecc/ecclinux/
[/Volumes/ellcc/ellcc/libecc/ecclinux] Richards-Mac-mini% ./build 
usage: ./build [options] target
  options:
    -nokernel           Don't build the Linux kernel
    -clean              Clean up a previous build
  targets:
    help                This message
    bcmrpi              Raspberry Pi    (ARMv6)
    bcm2709             Raspberry Pi 2  (ARMv7)
[/Volumes/ellcc/ellcc/libecc/ecclinux] Richards-Mac-mini% ./build bcm2709
...
Generating configuration file for e2fsprogs version 1.42.13
Release date is May, 2015
checking build system type... x86_64-apple-darwin15.2.0
checking host system type... x86_64-apple-darwin15.2.0
checking for gcc... /Volumes/ellcc/ellcc/bin/ecc -target arm-linux-engeabihf
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... configure: error: in `/Volumes/ellcc/ellcc/libecc/ecclinux/arm-linux-engeabihf/e2fsprogs':
configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
See `config.log' for more details
[/Volumes/ellcc/ellcc/libecc/ecclinux] Richards-Mac-mini%

Looks like I have a problem with the userland build, but the kernel built. I’ll look at that tomorrow. It’s late. Nice!