Installing Busybox

Having described in two previous posts how to obtain some ‘execution space’ in the Android file system, the question of what to do next is answered by ‘Install Busybox!’ Busybox is program that aims to provide the whole list of Unix command line utilities in a single executable program.

I have cached a very nice version of Busybox (as busybox.bin) in my bin-arm6 archive online here, and as I mentioned before, this is an essential component of the Android command line experience. This stripped, dynamically linked (to libc and libm; at 889532 bytes), and carefully compiled version supports the following standard Linux utilities:

[, [[, acpid, adjtimex, ar, arp, arping, ash,
awk, base64, basename, beep, blkid, blockdev,
bootchartd, brctl, bunzip2, bzcat, bzip2, cal,
cat, catv, chat, chattr, chgrp, chmod, chown,
chpst, chroot, chrt, chvt, cksum, clear, cmp,
comm, cp, cpio, crond, crontab, cryptpw,
cttyhack, cut, date, dc, dd, depmod, devmem, df,
dhcprelay, diff, dirname, dmesg, dnsd,
dnsdomainname, dos2unix, du, dumpleases, echo,
ed, egrep, env, envdir, envuidgid, ether-wake,
expand, expr, fakeidentd, false, fbset,
fbsplash, fdflush, fdformat, fdisk, fgconsole,
fgrep, find, findfs, flock, fold, free,
freeramdisk, fsck, fsck.minix, fsync, ftpd,
ftpget, ftpput, fuser, getopt, grep, gunzip,
gzip, halt, hd, hdparm, head, hexdump, hostname,
httpd, hush, hwclock, id, ifconfig, ifdown,
ifup, inetd, init, insmod, install, ionice,
iostat, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink,
iproute, iprule, iptunnel, kill, killall,
killall5, klogd, length, less, linuxrc, ln,
logger, logread, losetup, ls, lsattr, lsmod,
lspci, lsusb, lzcat, lzma, lzop, lzopcat,
makedevs, man, md5sum, mdev, mesg, microcom,
mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2,
mkfs.minix, mkfs.vfat, mknod, mkpasswd, mkswap,
mktemp, modinfo, modprobe, more, mount,
mountpoint, mpstat, mv, nameif, nbd-client, nc,
netstat, nice, nmeter, nohup, nslookup, ntpd,
od, patch, pgrep, pidof, ping, ping6,
pipe_progress, pivot_root, pkill, pmap,
poweroff, powertop, printenv, printf, ps, pscan,
pwd, raidautorun, rdate, rdev, readahead,
readlink, readprofile, realpath, reboot, renice,
reset, resize, rev, rm, rmdir, rmmod, route,
rtcwake, run-parts, runsv, runsvdir, rx, script,
scriptreplay, sed, seq, setconsole, setlogcons,
setsid, setuidgid, sh, sha1sum, sha256sum,
sha512sum, showkey, slattach, sleep, smemcap,
softlimit, sort, split, start-stop-daemon, stat,
strings, stty, sum, sv, svlogd, swapoff, swapon,
switch_root, sync, sysctl, syslogd, tac, tail,
tar, tcpsvd, tee, telnet, telnetd, test, tftp,
tftpd, time, timeout, top, touch, tr,
traceroute, traceroute6, true, tty, ttysize,
tunctl, ubiattach, ubidetach, udhcpc, udhcpd,
udpsvd, umount, uname, unexpand, uniq, unix2dos,
unlzma, unlzop, unxz, unzip, uptime, usleep,
uudecode, uuencode, vconfig, vi, volname, wall,
watch, watchdog, wc, wget, which, whoami, xargs,
xz, xzcat, yes, zcat, zcip

I particularly note:

httpd: a very nice cgi capable http server

wget: versitile net file downloader

vi: editor for the ages

telnetd: telnet server for your phone — use your laptop keyboard for your phone’s command line

ftpd and tfpd: file access servers

du: disk usage lister

ash: Bash-like shell, particularly useful on Android version < 4.0

Of course, many of these utility functions are not accessible on a non-rooted phone, but are left in the Busybox binary. The ones you will miss mount volumes and swap space.

If you have your execution space set up as previously discussed (with $BIN pointing to the directory with execution privileges where busybox lives, and $PATH includes $BIN first), then the command busybox would list all the commands supported and busybox command commandargs would execute a command, for example busybox du /sdcard/.

This is, however, too much typing, particularly if you are using an onscreen keyboard. Fortunately Busybox looks at the first argument (number 0), the program name, to see if it is not ‘busybox’, and if not tries to find a utility with that name to execute. This means that we can create symbolic links from ‘cat, ‘ls’, etc. to busybox, and the proper utility will be called. So to set up all of the utilities so that they may be called simply, change directory to $BIN, and then

for c in $(busybox –list); do busybox ln -sf busybox $c; done

Now you should be able to execute du /sdcard/ from the command line — and be sure to try ls -asCF $BIN to see what is going on. All the new files are zero in size!

Now we have a capable command line.

More information is at Busybox.net.

Java, via Dalvik, at the Android Command Line

If one, at the command line provided by Jack Palevich’s Terminal Emulator, or any of many other terminal apps, tries to execute a compiled java application, say HelloWorld.class, via the Dalvik Java VM, by say dalvikvm HelloWorld where HelloWorld.class is an appropriately compiled java command line application in the appropriate directory, the effort will fail with some variant of “class not found.” Running dalvikvm -help is not particularly helpful.

There are two reasons for this failure, and both are easily correctable. The first is that the Dalvik VM does not execute the raw Java bytecode emitted by Java compilers such as javac or ecj (the eclipse project java compiler), requiring instead a translation step from bytecode to so-called dex code. The second failure is that dalvikvm needs cache space in order to unpack dex compressed code before execution, and you, as a terminal user, do not have the needed permissions to use the default cache directory.

So first we must convert HelloWorld.class to HelloWorld.dex, which might be done on Windows or Linux, given an installed Android SDK and its associated tools. We need in particular a library dx.jar, and a suitable Java vm to run it. I’ll show the particulars of doing that later, but in the interests of rapid exposition, you could download HelloWorld.dex from vkfox.com/android/dex/, where you will find my archive of pre-dexed Java executables.

In order to solve the problem of Dalvik’s cache, we can simply make a directory called dalvik-cache in a conveniant place — say mkdir /sdcard/dalvik-cache. Then running a java program from could then be as simple as

ANDROID_DATA=/sdcard dalvikvm -cp HelloWorld.dex HelloWorld

which, if you do not it try right away, you are not really a programmer.

So the syntax rules here are that the environmental variable ANDROID_DATA must point to a directory that has a subdirectory named dalvik-cache, the classpath (after -cp
or -classpath) must point to a dex (or dex.jar) file that can resolve the last argument, a class name with a public main method.

Note that these developments are independent of execution permissions — the only “program” privileges we used are those of the terminal emulator.  In fact, since we can ‘source’ shell scripts that reside on the sdcard (or other external flash media) without execution privileges, we can build a suite of scripts to simply run a suite of dexed jar files containing our favourite Java applications.

And guess what? Out of the fathomless goodness of my heart, I have placed a very nice set of dexed utilities at vkfox.com/android/dex, notably

ecj.dex.jar: the Eclipse project java compiler

dx.dex.jar: the Android dexer

android.jar: stubbed version of the Android boot classes — use this to compile java for Android version 8 and above.

Thus with the stubbed library, two ‘dexjars,’ and a suitable editor could write, compile, dex and run a non-graphical Java program. For an editor, the ‘920 Editor’ or ‘TextWarrior’ applications (in utf-8 mode) are my choices among the free, open-source offerings, or, if you have my Busybox installed per earlier posts, and have figured out how to generate control keys with your terminal emulator, try vi.

There are helper shell scripts (ecj.sh, dx.sh, java.sh), requiring path editing, in the repository. But this would be the sequence:

1) define a home directory on a storage device, say mkdir /sdcard/home; export HOME=/sdcard/home

2) create the file (utf-8 format) HelloWorld.java there containing:

class HelloWorld {
  public static void main(String args[]) {
    System.out.println("Hello, World");
  }
}

 

3) Create the cache sub-directory via mkdir $HOME/dalvik-cache. (You may see a warning.)

4) Use the downloaded ecj.dex.jar and android.jar to compile HelloWorld.java to HelloWorld.class (all in one line, and ~ is Linux shorthand for the HOME directory):

ANDROID_DATA=~ dalvikvm -cp ~/ecj.dex.jar org.eclipse.jdt.internal.compiler.batch.Main -bootclasspath ~/android.jar HelloWorld.java

5) Change HelloWorld.class into a dexed file HelloWorld.dex via (in one line):

ANDROID_DATA=~ dalvikvm -cp ~/dx.dex.jar com.android.dx.command.Main --dex --output=HelloWorld.dex HelloWorld.class

6) Run HelloWorld.dex via:

ANDROID_DATA=~ dalvikvm -cp HelloWorld.dex HelloWorld

7) Praise the goddess, sing haleylooya, see Hello, World.

 

If this last command line were in a file HelloWorld.sh, then

.  ./HelloWorld.sh

would run it, since 'sourcing' shell scripts in this way does not require execution privileges. So make scripts to generalize all these steps, and you will be good.

Non-Root Android Command Line – Option 2

The previous post described a method for obtaining useable execution space on your Android phone via a separate computer running ADB, the Android debug bridge,  and attached via USB.  But here I describe a simpler method that does not require any separate equipment or software.

Each of the popular “terminal emulator” applications establishes its own execution space, and within that space you can make a directory under your own execution control. For example, Jack Palavich’s Terminal Emulator creates /data/data/jackpal.androidterm and you could, when using that terminal emulator, cd to that directory, mkdir bin; chmod 777 bin and then copy, for example, the busybox downloaded from vkfox.com/android/bin-arm6/busybox.bin via something like cat /sdcard/Download/busybox.bin > bin/busybox; chmod 755 bin/busybox; bin/busybox ls -l to set up and test busybox.Similarly VX Connectbot, with local connection, uses the directory /data/data/sk.vx.connectbot for execution space. (I am, by the way, using the “System Info for Android” app from ElectricSheep to determine the correct paths for the terminal apps.)

Once set up in this way, these directories and executable utilities can be interchangeably used by all of the various terminal emulation programs. By defining an environmental variable and new PATH, by say export BIN=/data/data/jackpal.androidterm/bin; export PATH=$BIN:$PATH, one can simply execute the utilities by name, e g. busybox.This gets even simpler when using apps like CCTools, Terminal IDE, or C4droid (paid app) where these directory structures and installed busybox are combined with a built-in terminal emulator.In future posts, I will cover the full installation and other peculiarities of busybox, provide descriptions and setup instructions, when needed, for the other utilities at vkfox.com/android, and, separately, describe how java programs can be developed and used at the command line.

Android Command Line Without Root

When reading about using the Linux command line of an Android device, one is invariably advised that “rooting” (adding a root user account via a security hole) your device is required to gain the ability to install and use the Linux utilities of your choice. This is untrue; I will show how, in this and subsequent blog posts, that it is reasonably easy to set up a home in the Android file system, install a reasonable and useful set of command line utilities (including C, C++, Pascal, Java, etc., compilers, Python, Perl, PHP, Tcl, Basic and myriad other interpreters, editors, file managers, and system tools), and gain thereby most of the comforts of the ordinary Linux user account.

Using a terminal emulator such as Jack Palovich’s Terminal Emulator,  or VX Connectbot, or SManager (Script Manager, ad supported), one can access a Linux-like command line on Android devices. The built-in utilities available include a primitive and featureless shell and the bare minimum of file manipulation tools.

Naive attempts to install more useful tools such as bash and busybox reveal that the file system is locked up by ownership permissions everywhere except the /sdcard directory, and there prevented by the NOEXEC attribute on that volume. This system of security is completed by the fact that mounting new volumes is reserved for the root user. An exception allowed in Linux is that you may place a shell script on the sdcard and execute it with the “source” command, i. e.,

$ . /sdcard/examplescript.sh

There are some interesting programs hiding in /system/bin. For example, ‘am’ can start apps, and ‘pm’ can install apps from downloaded apk files. But even ‘cp’ (the Linux copy command) is missing, and one must work around innumerable limitations.

Nontheless, Android users without root can install and use many common utilities that have been properly compiled and linked for this platform, and I will describe here two methods for accomplishing this and point out others. Furthermore, I maintain my own archival set of arm5tel compiled utilities for download; these should work on all ARM based phones (with some caveats mentioned later). Find them at http://vkfox.com/android/bin-arm6.

The goal then is to obtain access to a bit of execution space within the Android file system, and then install busybox, the essential utility program.

The first method is based on the fact that the ADB (Android Debug Bridge), the telnet-like tool included in the Android SDK, has a high enough priviledge level to make executable directories. So if you have installed the SDK and can get your phone connected in debugging mode and can connect with “adb -d shell” then you can, for example, create a new directory with (for Android version 2.x)


mkdir /data/local/bin
chmod 777 /data/local/bin

(For Android versions 4.x, the hosting directory should be ‘/data/local/tmp’ rather than ‘/data/local’.)

Now, after the phone is disconnected from ADB, you can fire up one of the terminal emulators I mentioned, and move downloaded binaries into this directory for execution; for example (using cat to copy):


cat /sdcard/Downloads/busybox.bin > /data/local/bin/busybox
chmod 755 /data/local/bin/busybox

The two utilities considered most essential are bash and busybox; bash is a fully competent shell with tab completion, and busybox will supply you with the tools needed to unpack, install and launch other major applications. The versions I supply are stripped to reduce size — all executables except scripts must be in the precious main ramdisk area in the Android system rather than on the flash card.