And so it is with Contraption, my project to overlay a GNU environment on top of the otherwise very un-GNU-like Android on the Beagle Board. Like the citizens of Beszel and Ul Qoma, the GNU and Android environments co-exist in close proximity, within the same geographic file system and random access memory, yet kept separate through the auspices of the Breach-like Linux kernel. You can interact with Android from one one screen while running GNU-based software from a bash shell inside an ssh session from another. For the most part the two systems simply unsee one another by virtue of using different PATH and LD_LIBRARY_PATH environmental variables and by being dynamically linked to different shared objects. The Linux kernel and the dynamic loader keep it all separate.
This isn't some kind of virtual machine magic. It's just a trick of engineering. GNU software lives in /usr/sbin, /usr/bin, and /bin. Android software lives in /sbin, /system/sbin, /system/bin, and /system/xbin. GNU shared objects live in /lib, necessary because some GNU software ignores LD_LIBRARY_PATH. Android shared objects live in /system/lib. Android doesn't use /etc at all, opting instead for /system/etc. While Android forgoes all the usual user-level authentication mechanisms like /etc/passwd, GNU has full access to all of it, enabling for example the dropbear ssh server and the busybox telnet daemon to run unmodified. GNU software dynamically links to the GNU-based shared objects from the Sourcery G++ Lite ARM tool chain from CodeSourcery. Android software dynamically links to the shared objects from the Android ARM tool chain (which is a modified version of the CodeSourcery toolchain) from the FroYo release of the Rowboat port of Android to the Beagle Board.
The only directory conflict was /sbin, which on Android contains only adbd, the Android debugging daemon that serves as a proxy on the target (the Beagle Board) for a development environment running on the host (my desktop). To allow Android to unsee the executables that would normally have been in GNU /sbin, I moved them to /usr/sbin where there were no conflicts with other GNU-based executables.
The utilities, shared object, and memory mapped device driver from my Diminuto project that I described in Memory Mapped Devices on the Beagle Board with Android live in /usr/local/bin, /usr/local/lib, and /lib/modules respectively. They work just as before, except the Android insmod and the busybox insmod have slightly different syntax!
The Contraption project consists almost solely of a single Makefile that configures and builds the necessary software, including the modified Linux kernel, the Android root file system, and the various GNU-based packages such as busybox, bash, strace, and dropbear, creates an SD card of the Android system that can be booted on the Beagle Board, then overlays Contraption on top of it.
Here is the cinema display showing an Eclipse IDE with the Contraption Makefile, a bash shell running via an ssh session on Beagle Board, a serial console to Beagle Board; a little green Android figure standing next to the Beagle Board; a second display showing a web browser running on Android on the Beagle Board.
Here's a screen snapshot of a of the Beagle Board serial console. I booted up Android and fired up the dropbear ssh server from the command line. (See below for some notes on how to automate this.)
Here's a screen snapshot of a bash session via ssh to the Beagle Board. I ran the busybox ps command and used grep to pick out some processes.
Here's a close up of the Beagle Board sitting between the two displays.
As I worked on the design of this, I began to realize the architects of Android must have wanted it to be possible for their system to be used this way, probably to make Android easier to integrate with existing Linux-based mobile phone platforms. Even though I've worked in the telecommunications field for most of the past fifteen years, my inspiration for this project wasn't smart phones. It was the student paper "Using Android in Industrial Automation" by Manuel Di Cerbo and Andreas Rudolf at the University of Applied Sciences at Northwestern Switzerland that impressed me with the possibilities of using Android in other embedded domains.
To make the Android platform really usable in this way I felt it had to be able to easily exploit the huge volume of GNU-based software. Even if one had to reside in Beszel and the other in Ul Qoma.
(You can find a link to a tar ball containing the Contraption distribution on the project web page at the Digital Aggregates Corporation web site.)
I added some screen snapshots since I originally published this article.
I modified the /init.rc boot script to automate some of the stuff described here.
In the on boot section I changed
setprop net.dns1 220.127.116.11
setprop net.dns2 18.104.22.168
where 22.214.171.124 and 126.96.36.199 are Google's public DNS servers.
At the bottom I added
service dropbear /usr/sbin/dropbear
to start the ssh server automatically. The oneshot option is important: the server is a daemon which appears to Android to exit, and you don't want Android to continuously restart it, otherwise wackiness will ensue.