Wednesday, July 11, 2012

Embassykernel: Overlaying GNU on Android on the ODROID-A4

In The System & The System: Overlaying GNU on Android on the Beagle Board I described my Contraption project where I ran both the Android Frozen Yogurt (FroYo) software stack and a small GNU software stack side by side on the BeagleBoard-xM. Both stacks ran under on a common Linux 2.6.32 kernel on a TI OMAP system-on-a-chip with an ARM Cortex-A8 core. It was a hack, no doubt about it, but for me it was a useful one. I'll go into why in a bit.

For my Conestoga project, I have worked the same hack: this time running both the Android Ice Cream Sandwich (ICS) software stack and a small GNU software stack side by side on the ODROID-A4. The A4 is a Samsung platform reference device made by Hardkernel with the same form factor as the Samsung Galaxy Android smartphones. Both stacks run under a common Linux 3.0.15 kernel on a Samsung Exynos system-on-a-chip with dual ARM Cortex-A9 cores.

You can see the A4 below displaying the time (as it happens, while I am SSHed into it from my desktop Mac), with a debug board attached to its TTA20 debug port. The debug port has a USB cable attached at its bottom providing access for the Android Debug Bridge (adb), and a cable attached to its console serial port at its left. Also visible to the upper right of the A4 is the all important reset tool (a bent paperclip).

ODROID-A4 with Reset Tool and Debug Board

Below is a screen snapshot of a terminal window on my desktop Mac through which I SSHed into the A4, logging in with a guest account with a password just as if the A4 were a server. My first ssh attempt was before I started the dropbear SSH server on the A4.

Mac Terminal: ssh to ODROID_A4 as guest

Below is a screen snapshot of the Android serial console in which a ps command shows the dropbear SSH server running along with the login bash shell used by a guest account. (You can click on the image to see a larger version.)

Android Debug Console: ps output

In China MiĆ©ville's Hugo-nominated novel Embassytown, he weaves a tale of a small human colony on a distant planet attempting to live among a race whose entire approach to language is so alien that neither individual humans nor their machines can be understood by the Arikei even when it sounds as if we speak their language perfectly. The cognitive barrier between the humans and the Arikei reminded me of the separation between the Android and GNU software stacks, living side by side on the same Linux kernel but for the most part unable to communicate.

This hack on Conestoga differed substantially from the same one on Contraption, not just because the former was running the ICS Android release instead of FroYo, but because the underlying A4 platform  was quite different from that of the BeagleBoard.

The BeagleBoard uses a two-stage boot process, starting with X-Loader loaded from flash on-board the OMAP chip itself, then to U-Boot. U-Boot booted up and ran Linux and the Android stack (and eventually the GNU stack) directly off its microSD card containing an EXT3 file system.

The A4 boots U-Boot from its microSD card, then loads the Linux kernel and a RAM-resident disk image from the microSD card. This ramdisk has most of the files needed by the platform layer that sits below Android and is mounted read-only. The A4 separates Android into two separate EXT4 file systems, system and userdata, and mounts the former read-only. There is also an EXT4 cache file system, and a FAT32 (a.k.a. VFAT) file system for user media like music, videos, and ringtones.

Because of the way I plumbed Conestoga into Android, I had to reverse-engineer, modify, and repackage the ramdisk and system filesystems, and push (via adb) an overlay (really: a tarball) onto the userdata file system which is created by the target itself when necessary (for example, on a new microSD card on which it does not already exist). There was a lot of web searching, lengthy sessions of source code pondering, and a few hex dumps. In the end, most of the changes to ramdisk and system were merely adding soft-links; the bulk of Conestoga resides in the read-write userdata file system under the directory /data/conestoga.

One piece of useful collateral was a tool I wrote to unpack the compressed EXT4 file system format generated by the A4 software build process. Files in this format are what is transmitted to the A4 via the fastboot mechanism, a way to download and install new file system images to the microSD card on the A4 via USB using only U-Boot. Below is a snippet of commands illustrating how decompressext4 might be used on the system.img produced by the A4 build.

decompressext4 -v < system.img > system.ext4
fsck.ext4 system.ext4
mkdir mnt
sudo mount -o loop system.ext4 mnt
ls -lR mnt
sudo make_ext4fs -s -l 524288000 system-new.img mnt
sudo umount mnt
rm -rf mnt
fastboot flash system system-new.img

The C source code for decompressext4 is open source and is included in the Conestoga distribution (which otherwise is not much more than a big Makefile), a link to which can be found on the project web page.

Why Android?

For reasons of cost and schedule you must to work as high on the abstraction ladder as possible, even when you are working in embedded systems. This means you don't write in assembler when you can use C. Don't use C when you can use more advanced languages like C++. Don't use compiled languages at all when you can use managed languages like Java or scripting languages like bash, perl or even python.

The fact that a high-capability open-source software stack like Android, mostly written in Java, can run on a pocket-sized smartphone makes it a potential framework for other embedded applications, mobile or not. It's also why I build the bash shell as part of both Contraption and Conestoga: not so much for its use as an interactive shell, but to use as a scripting language.

Why GNU?

There is a wealth of software written for the GNU environment. GNU is in fact the API against which developers are writing when they say they are writing for Linux. Maybe porting C and C++ GNU code to the Android Native Development Kit (NDK) is what you want to do in the long run. But the NDK environment, with its bionic C library, is quite different from GNU. The ability to quickly sling some existing legacy GNU code onto an Android-based project for purposes of prototyping is a big win in my book. Once you prove it can work, you can look at the cost of the NDK port.

Example: I got my GNU-based memtool application built and running on the A4 in just a few minutes using Conestoga. memtool is a command line tool that makes it easy to read and modify the memory mapped registers of hardware devices. I've written about its use in my own Linux/GNU-based embedded systems and on Android on the BeagleBoard. It's found its way into a number of products I've worked on for paying clients.

Tools like memtool are a huge win for debugging, integrating, and even for production use in system control and maintenance scripts. Using utilities like memtool and leveraging the tighter iteration cycle affording by scripting using bash, I've slung together scripts in an afternoon that would have taken days to develop, test, and debug in C, and produced utilities that I was later able to modify and adapt to changing circumstances while testing in the field. If you've never done this kind of work, you might be surprised how many times you want to read or set a bit in a register in an FPGA if only you had access to it somehow from the command line.

Why the ODROID-A4?

The A4 has much of the same hardware as the Samsung Galaxy Android smartphones; it's the platform reference device recommended by Samsung on their web site. To say that the Galaxy smartphones are popular is putting it mildly; let's just say that when another manufacturer of a popular smartphone tries to suppress your device, you just can't buy that kind of advertising. Samsung might as well have ads saying "Endorsed by Apple, manufacturer of the iPhone".

The A4 has a dual-core ARM-based processor. I've written before how important I think it is that all developers, including embedded developers, get on the multi-core train as quickly as possible. We all need to get experience with developing multi-threaded (concurrent) software on true multi-processing (parallel) hardware. Writing multi-threaded software for uni-processor systems opens the doors for race conditions that may never be detected. Multi-core is clearly the future, even in the embedded realm, as processor manufacturers try to continue climbing up the legacy performance curve by any means necessary.

The A4 runs Ice Cream Sandwich and the Linux 3.0.15 kernel. This was my first experience with both the ICS Android release and with the Linux 3.0 kernel. It was a useful learning experience to build, modify, and run both of them, as well as the A4's unique flavor of U-Boot, from scratch.

Oh, and the ODROID-A4 is a pretty usable Android mini-tablet all by itself.

Why me?

I make a good living mostly down in the platform layer. Application developers routinely depend on me to help them port and debug their code. I am often called upon to reverse engineer systems about which I formerly knew nothing, and to play a key role in hardware-firmware-software integration and testing.

This is the kind of stuff I get paid to do, and undertaking projects like Contraption and Conestoga keeps my skills up to date and gives me an opportunity to test my hypothesis about using Android as an embedded framework.

No comments: