Valid HTML 4.01 Transitional

HTC G1 Cellphone
Debian on the G1

Jim Carter, 2009-03-30

Introduction

It's a phone!

The G1 is not a server, nor is it a program development machine. Android is designed to do phone things, and to support its Java applications. It is not POSIX compliant; there isn't even a test command for its shell. Once you get root access you will find that your normal UNIX procedures are not going to get you very far. Here are a few tricks to tide you over:

However, this limited repertoire is essentially useless for anything a normal system administrator or UNIX hacker would want to do. Therefore a number of people have worked out various schemes to put a real UNIX distro onto the G1.

Goals and Issues

Ext3 Filesystem on the Memory Card

Can I mount a non-VFAT memory card at all? The MMC devices appear automatically as /dev/block/mmcblk0p1 etc, or equivalently, /dev/block/vold/179:1 etc. Minor device 0, or mmcblk0 without the partition, refers to the raw device. Neither /dev/block nor /dev/block/vold exist on my kernel 2.6.27 (from OpenSuSE 11.1), and in a Google search I see them mentioned only with Android. Android's automatic mount supervisor fails to mount partition 1 unless it is formatted as VFAT (not too surprising). Although the mount command's usage message says that the filesystem type is optional, in fact an ext3 partition cannot be mounted without -t ext3. So it's time to hack.

Use the source, Luke! I found answers for several of the above points in the sources for vold, installed as /system/bin/vold. This program is the first to start at boot, even before d-bus. It seems to do the same job as udev on a normal distro, but specialized for the palmtop role: when the memory card is hotplugged it creates the /dev/block inodes described previously, it coordinates (I didn't study the details) exporting these devices by the USB connection, and it mounts the partition(s) including running the appropriate file system check program (which, to my knowledge, no desktop distro manages to do, and neither does Maemo for Nokia tablets, and Maemo really needs to because corruption is endemic). Vold also starts the media indexer on each partition.

As installed, vold only knows about VFAT. However, ext3 support is already in the code and to turn it on you only have to uncomment one table row. I did so, and it was able to identify the filesystem on the card and mount it, for both VFAT and ext3. But although the code is written to mount arbitrarily many partitions, it only mounted the first one. I decided to not try to debug it, but instead to put only one partition on the card. For software upgrades I will put the image onto a VFAT card and that into the G1.

In the tale below I'm skipping numerous failed attempts, presenting only what was on the main line to success.

Various Howto's

Jimc's Procedure

Hacking Vold

According to the sources in ./system/core/vold/volmgr.c, the config file vold.conf is read by a generic subroutine (config_load_file). It consists of key-value pairs. The outer layer is a name (must begin with volume_) and a stanza in { }. The keys that may be in the stanza are these:

media_type mmc or devmapper (required)
media_path String, the path to the whole disc device directory in sysfs, omitting the mount point /sys (required). For devmapper, apparently there can be up to 8 media_paths. Example:
/devices/platform/msm_sdcc.2/mmc_host/mmc1
For mmc:
mount_point String, mount the partition here (required)
emu_media_path String, media_path to be used on the emulator. Example:
/devices/platform/goldfish_mmc.0/mmc_host/mmc0
ums_path String, path in sysfs to the USB export device. Example:
/devices/platform/usb_mass_storage/lun0
For devmapper (all are required):
dm_src String, no interpretation discovered
dm_src_type String
dm_src_size_mb Integer
dm_target String
dm_target_params String
dm_target_fs String

It is a little strange to see the device mapper getting into the act, since Android doesn't have one. However, I suspect that Solaris' vold was the model for Android's, and on a Solaris server a big RAID and/or LVM setup would be expected.

When a memory card is hotplugged (signalled by HAL), vold iterates over each partition, identifies the filesystem type, runs fsck (filesystem checker), mounts it, and then starts the media inventory scanner. A desktop distro would use object oriented fsck and mount programs, that is, these programs would identify the filesystem type and would run the appropriate variant automatically. But in Android, type identification and switching are handled by vold. It has a virtual table hardcoded, which in the stock configuration has only one row for VFAT. However, the row for ext3 (not ext2) is present but commented out. All it takes to get vold to auto-switch between VFAT and ext3 filesystems is to uncomment that row and recompile.

I never did get vold to actually mount any partitions beyond the first, even though it recognizes that there are multiple partitions and even though the code to do it is present. I started debugging this issue, but decided that my higher priority was to install Debian (on one partition) and to use it for testing and hacking.

Mounting the Memory Card

To get the ext3 partition mounted, you need some prerequisites:

I restored the backed-up memory card content. A VFAT partition has very feeble permissions. Rather than doing research on improving security, I pretty much replicated the VFAT behavior: changed all files to mode 666 and directories to 777, hiss, boo. Later I need to review these and find out how to tighten up these awful permissions. I checked out all the content on the card (by programs, not every single file individually), and everything still worked.

Installing Debian

As of 2009-02-14 the standard (stable) version of Debian is Lenny. This is the one I used. It is the first to have complete support for the armel architecture. There are over 25000 packages in Lenny, of varying usefulness on the handheld device, or on any device.

A prerequisite for installing Debian turns out to be Busybox, because standard Android lacks a chroot command. See this blog post about Debian on Android by Saurik (Jay Freeman, dated 2008, earlier than 2008-11-19). He has a link to a statically linked, working version of Busybox, which I used.

I followed Pavel Machek's instructions to install Debian. Specifically, on the laptop locate and install a recent version of the debootstrap package that includes an install script for Lenny. If your distro uses RPM, as mine does, you will need to disassemble and install the Debian package by hand (follow link). Mount the memory card, let's say on /mnt. I decided to put my Debian files in a separate directory with sane permissions called .../deb. Do stage 1 of the installation, which downloads the package files:

mkdir /mnt/deb
debootstrap --foreign --arch armel lenny /mnt/deb/

This took me about 15 minutes and put 130Mb of package files onto the card. Unmount it when finished. Connect the USB cable to the phone. Suppress sleeping when on charge; this is Settings - Applications - Development - Stay Awake. (And of course USB Debugging, on the same screen, has to already be turned on.) Even if you're using the Terminal Emulator you need external power because the following process will empty your battery. Mount the memory card on the G1; I'm assuming, as in my case, that it will mount on /sdcard. Gotcha: when mounting the card, vold specifies the options noexec, npdev, nosuid (actually, the MS_NOEXEC (etc.) flags for mount(2)). You will need to remount it by hand omitting those options. (Adjust the device if necessary. The command line is folded for readability.)

cat /proc/mounts #Check what device is used
mount -o remount,rw,nodiratime,errors=continue,data=ordered \
-t ext3 /dev/block/vold/179:1 /sdcard

Now start stage 2 of the installation, which unpacks and installs all the packages. (The command line is folded for readability, so your browser does not fold it at some arbitrary point.)

PATH=/usr/sbin:/usr/bin:/sbin:/bin /system/xbin/busybox \
chroot /sdcard/deb debootstrap/debootstrap --second-stage

You need to set the PATH to where the utility programs are in Debian, and you need to chroot so it installs itself in its own area (and can find the utilities and libraries). The installation process took 18 minutes and put 860Mb on the card. The result is a minimal Debian system that can be used to download and install your keystone packages: the ones you use to accomplish your mission. Quite a bit of the 860Mb can actually be gotten rid of, if space is a problem.

Using Debian

As noted previously with e2fsck, Debian packages expect to find basic infrastructure in standard places like /lib and /usr/lib, which don't exist on Android. There are various maneuvers to deal with this and Saurik's blog post goes into quite a lot of detail on the topic.

Android Paranoid Network

Initially, none of the networking applications in Debian do anything; it is as if the network does not exist. This Google Groups thread by leemgs (2009-04-09) posts "features" of kernel 2.6.29 for Android: Paranoid network (doesn't give details). A subsequent commenter mentions that ANDROID_PARANOID_NETWORK is the kernel config symbol.

The Android source package includes complete kernel sources with this patch present and enabled. ./Documentation/android.txt lists all the required and forbidden configuration options that Android's userspace expects, including this one. It is used in ./net/ipv4/af_inet.c and ./net/ipv6/af_inet6.c and ./net/bluetooth/af_bluetooth.c. All three files are similar: linux/android_aid.h is included, which defines AID_INET = 3003, AID_NET_RAW = 3004, AID_NET_BT = 3002. For inet and inet6, current_has_network() tests for AID_INET or AID_NET_RAW; current_has_cap() tests for AID_NET_RAW. I believe the latter is the limiting factor, at least when root runs the program. Bluetooth is similar except with AID_NET_BT.

So I copied several net programs (ping, traceroute, wget) to /tmp and made them setGID to group 3004. They were then able to function. Clearly this is a workaround for testing, not a longterm solution.

Miscellaneous Tidbits