Friday, February 11, 2011

The System & The System: Overlaying GNU on Android on the Beagle Board

One of the best novels I read last year was The City & The City by China MiƩville. This police procedural set in the present day takes place in the fictional European city-states of Beszel and Ul Qoma. What places this novel squarely in the realm of weird fiction is that Beszel and Ul Qoma occupy the same geographical space. Citizens of one city must unsee the citizens and features of the other city even as they live among them. This seperation extends even to buildings, where some floors or even rooms are in Beszel while others are in Ul Qoma. Citizens of each city must ignore the other lest they fall prey to Breach, a secret police whose operatives are apparently the only ones who can cross from one city to the other at will. It is a tribute to MiƩville's ability that this bizarre concept is carried off without calling upon the reader to assume any supernatural agency; it is an act of perception and conditioning on behalf of the inhabitants of both cities.

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.

The System & The System

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.)

macwise console android

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.

ssh bash android

And here is a close up of the second display.

Android Browser on the Beagle Board

Here's a close up of the Beagle Board sitting between the two displays.

Beagle Board and Zippy2 Expansion Board

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.)

Update (2011-02-18)

I added some screen snapshots since I originally published this article.

Update (2011-02-25)

I modified the /init.rc boot script to automate some of the stuff described here.

In the on boot section I changed

hostname localhost


hostname contraption

and added

setprop net.dns1
setprop net.dns2

where and 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.


Anonymous said...

Thumbs up from an ex-unix admin geek. Very cool idea to have two OSes running parallel. Have you had any problems with memory management or I/O conflicts?

Think Peace,
- Alan

Chip Overclock said...

It's two software environments, but one kernel and set of device drivers. All applications run under a single Linux kernel on a single system image. I am a little concerned about the Android shared objects and the GNU shared objects having completely different ideas about the state of things. But for any shared system resources, the kernel and its device drivers will keep it straight. Time will tell.