Toybox combines many common Linux command line utilities together into a single BSD-licensed executable. I wanted to to see how hard it would be to compile and cross compile it using ELLCC. It turned out to be pretty easy after I added a few Linux specific header files. These are the files I added:
[~/ellcc] dev% ls ~/ellcc/libecc/include/linux fs.h if_vlan.h loop.h nbd.h rfkill.h rtc.h sched.h sockios.h soundcard.h
The needed include files are in the ELLCC source tree now and are available in the 0.1.22 binary release. Here’s all you need to do to build Toybox:
[rich@dev ~]$ mkdir toybox [rich@dev ~]$ cd toybox [rich@dev toybox]$ wget http://landley.net/toybox/downloads/toybox-0.6.1.tar.gz --2015-12-23 17:02:37-- http://landley.net/toybox/downloads/toybox-0.6.1.tar.gz Resolving landley.net (landley.net)... 208.113.171.142 Connecting to landley.net (landley.net)|208.113.171.142|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 736371 (719K) [application/x-tar] Saving to: ‘toybox-0.6.1.tar.gz’ toybox-0.6.1.tar.gz 100%[=====================>] 719.11K 845KB/s in 0.9s 2015-12-23 17:02:38 (845 KB/s) - ‘toybox-0.6.1.tar.gz’ saved [736371/736371] [rich@dev toybox]$ tar xfp toybox-0.6.1.tar.gz [rich@dev toybox]$ cd toybox-0.6.1/ [rich@dev toybox-0.6.1]$ CC="/home/rich/ellcc/bin/ecc -target armv6-linux-engeabihf" CFLAGS="-Wno-format-extra-args -Wno-uninitialized" make defconfig toybox cc -o kconfig/conf kconfig/conf.c kconfig/zconf.tab.c -DKBUILD_NO_NLS=1 \ -DPROJECT_NAME=\"ToyBox\" scripts/genconfig.sh kconfig/conf -D /dev/null Config.in > /dev/null scripts/make.sh Generate headers from toys/*/*.c... generated/newtoys.h Library probe....... Make generated/config.h from .config. generated/flags.h generated/globals.h generated/help.h Compile toybox................................................................................................................................................................strip: Unable to recognise the format of the input file `toybox_unstripped' strip failed, using unstripped .
Oops. The strip failed because the standard x86_64 Linux strip doesn’t understand ARM object file formats. We can use ecc-strip:
[rich@dev toybox-0.6.1]$ ~/ellcc/bin/ecc-strip -o toybox toybox_unstripped [rich@dev toybox-0.6.1]$ file toybox toybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=11e423037c6fb0e4ee10ef5f53a421fca86a81e3, stripped [rich@dev toybox-0.6.1]$ size toybox text data bss dec hex filename 401916 3208 21020 426144 680a0 toybox
Lest’s send it over to my trusty Raspberry Pi:
[rich@dev toybox-0.6.1]$ scp toybox rich@192.124.43.98: rich@192.124.43.98's password: scp: ./toybox: Permission denied [rich@dev toybox-0.6.1]$ ssh rich@192.124.43.98 rich@192.124.43.98's password: The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sun Dec 20 19:20:36 2015 from 192.124.43.2
What commands does Toybox have?
rich@raspberrypi:~$ ./toybox acpi base64 basename blkid blockdev bunzip2 bzcat cal cat catv chattr chgrp chmod chown chroot chvt cksum clear cmp comm count cp cpio cut date df dirname dmesg dos2unix du echo egrep eject env expand factor fallocate false fgrep find flock free freeramdisk fstype fsync grep groups halt head help hexedit hostid hostname hwclock id ifconfig inotifyd insmod install ionice iorenice kill killall killall5 link ln login logname losetup ls lsattr lsmod lspci lsusb makedevs md5sum mix mkdir mkfifo mknod mkpasswd mkswap mktemp modinfo mount mountpoint mv nbd-client nc netcat nice nl nohup nproc nsenter od oneit partprobe passwd paste patch pidof pivot_root pmap poweroff printenv printf ps pwd pwdx readahead readlink realpath reboot renice reset rev rfkill rm rmdir rmmod sed seq setsid sh sha1sum shred sleep sort split stat strings su swapoff swapon switch_root sync sysctl tac tail taskset tee time timeout touch toysh true truncate tty umount uname uniq unix2dos unlink uptime usleep uudecode uuencode vconfig vmstat w wc which who whoami xargs xxd yes rich@raspberrypi:~$ ./toybox ls -l total 3112 -rwxr-x--x 1 rich rich 141580 2015-12-20 19:22 hello -r-xr-xr-x 1 rich rich 1446476 2015-12-23 21:21 toybox
Now let’s build for the x86_64:
rich@raspberrypi:~$ logout Connection to 192.124.43.98 closed. [rich@dev toybox-0.6.1]$ make clean rm -f kconfig/zconf.hash.c kconfig/zconf.tab.c kconfig/lex.zconf.c kconfig/conf kconfig/mconf rm -rf toybox toybox_unstripped generated change .singleconfig* [rich@dev toybox-0.6.1]$ CC="/home/rich/ellcc/bin/ecc -target x86_64-linux-eng" CFLAGS="-Wno-format-extra-args -Wno-uninitialized" make defconfig toybox cc -o kconfig/conf kconfig/conf.c kconfig/zconf.tab.c -DKBUILD_NO_NLS=1 \ -DPROJECT_NAME=\"ToyBox\" scripts/genconfig.sh kconfig/conf -D /dev/null Config.in > /dev/null scripts/make.sh Generate headers from toys/*/*.c... generated/newtoys.h Library probe....... Make generated/config.h from .config. generated/flags.h generated/globals.h generated/help.h Compile toybox................................................................................................................................................................. [rich@dev toybox-0.6.1]$ file toybox toybox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=6d60409b768431310a5ce6085e595b6a98a66d45, stripped [rich@dev toybox-0.6.1]$ size toybox text data bss dec hex filename 376786 6192 22152 405130 62e8a toybox [rich@dev toybox-0.6.1]$
Cool stuff.