Android Tips
NTDMENU
WARNING: This information comes with no warranty or guarantee expressed or implied. Unix does not protect you from doing something stupid and turning your fancy equipment into a smoldering brick. This page is more guidelines and advice than a canned recipe. If you don't understand what your doing, please read up first.
Android phones have become cheap and rather ubiquitous. Here's some info on making them bearable for old *nix hands.
1. Android for Linux Users
Android is based on the Linux kernel, but its userland deviates significantly from typical conventions, the POSIX standard, and perhaps even good sense. Here's an outline of some various quirks:
- Basic utilities are provided by BusyBox, which omits many features and GNU extensions to minimize size.
- Android uses a nonstandard init. It runs the /init.rc file which
has a nonstandard syntax. This process seems to handle things that
are often done using an initrd. At some point, it executes scripts
under
/etc/init.d
. You can hook into it with a script at/sd-ext/userinit.sh
(this is an ext2/3/4 partition on the sdcard), which will get called by Android's init scripts. This gets run by the/etc/init.d/20userinit
script. - The filesystem hierarchy is rather bizarre. Most of a normal filesystem is under /system. The vfat partition on the sdcard is mounted at /mnt/sdcard with a symlink from /sdcard. An ext2/3/4 partition on the sdcard will be mounted at /sd-ext
- The sdcard must have a vfat partition for Marketplace apps to use
it (security be damned). You can add an ext2/3/4 partition as well.
The extX needs to be the second partition. The
/sd-ext
gets setup by the/etc/init.d/05mountsd
script. - There is no
/etc/{passwd,shadow,group}
. If have no idea where the OS is mapping uids to usernames. - Android uses unix users and groups to manage permissions. Individual applications downloaded through Android Marketplace run as separate users. Group membership is required for things such as sdcard or network access.
2. Debian Chroot
This is perhaps the laziest way to get a standard *nix setup running on an Android phone. We use a stock or (preferably) third-party Android OS for the kernel and to mange touchscreen, cell-phone capabilities, etc.; this means the phone still works as a ''phone'' without any (too much) fiddling around on our part. Then, we install a Debian filesystem on a subdirectory of the sdcard. This lets us chroot into the debian install and then have a pretty much typical Linux setup.
2.1. Basic Installation
- Get the Android SDK. You'll need this to access the device over USB in order to copy files to the internal flash and get a shell.
- Connect the Android device to your PC via usb.
- Root your phone, and (preferably) install cyanogenmod.
- Partition the sdcard with one vfat and one ext2/3/4 partition. This can be done through the Clockwork Recovery, or manually by mounting the card on your PC.
Check that the partitions mount on android
PC$ adb shell android# df tmpfs 189796 32 189764 0% /dev tmpfs 189796 0 189796 0% /mnt/asec tmpfs 189796 0 189796 0% /mnt/obb /dev/block/mmcblk0p25 419028 149740 269288 36% /system /dev/block/mmcblk0p26 1340488 67316 1205076 5% /data /dev/block/mmcblk0p27 203070 40284 152301 21% /cache /dev/block/mmcblk0p28 20336 17232 3104 85% /devlog /dev/block/mmcblk1p2 3937268 693896 3043364 19% /sd-ext none 189796 4 189792 0% /tmp /dev/block/vold/179:33 3754360 523660 3230700 14% /mnt/sdcard /dev/block/vold/179:33 3754360 523660 3230700 14% /mnt/secure/asec android# exit
Get the debootstrap package. (If you're not on Debian or Ubuntu, this will be harder)
PC$ sudo apt-get install debootstrap
Mount the sdcard on the pc again and prepare the initial filesystem.
PC# mkdir /media/sd-ext/debian PC# debootstrap --arch=armel --foreign squeeze /mnt/sd-ext http://ftp.us.debian.org/debian
- Unmount the sdcard on the PC. You may need to also reboot the phone at this time.
On the phone, setup /sd-ext/userinit.sh to bind mount proc and tmp in the debian chroot
# configure debian chroot if [ -d /sd-ext/debian/proc ] && [ ! -d /sd-ext/debian/proc/1 ] ; then mount -o bind /proc /sd-ext/debian/proc fi if [ -d /sd-ext/debian/dev/.udev ] ; then mount -o bind /dev /sd-ext/debian/dev mount -o bind /dev/pts /sd-ext/debian/dev/pts fi if [ -d /sd-ext/debian/mnt/sdcard/ ] && [ ! -d /sd-ext/debian/mnt/sdcard/Android ] ; then mount -o bind /mnt/sdcard /sd-ext/debian/mnt/sdcard fi
Run the userinit.sh to get the filesystems mounted
android# /sd-ext/userinit.sh
Finish the debootstrap process
android# chroot /sd-ext/debian /debootstrap/debootstrap --second-stage
Copy DNS servers
android# cp /etc/resolv.conf /sd-ext/debian/etc/
Chroot into the debian.
android# chroot /sd-ext/debian /bin/bash debian#
Configure apt sources. Add the following to /etc/apt/sources.list
deb http://ftp.gtlib.gatech.edu/debian/ squeeze main non-free deb http://security.debian.org/ squeeze/updates main contrib non-free deb http://ftp.debian.org/debian squeeze-updates main
apt-get update
debian# apt-get update
Fix Locales
debian# apt-get install locales debian# dpkg-reconfigure locales
Create a user account. Android-land doesn't seem to use UID 500, so let's give that to the debian user.
debian# apt-get install sudo debian# adduser --uid 500 ntd debian# adduser ntd sudo
Inform debian about Android-specific groups. We need this for our user account to use the sdcard and network. Put the following in /etc/groups
system:x:1000:ntd sdcard_r:x:1015:ntd inet:x:3003:ntd
Install ssh server
debian# apt-get install openssh-server
Add the following to /sd-ext/userinit.sh (back outside the chroot) to start the debian sshd.
# start debian ssh chroot /sd-ext/debian service ssh start
- That should do it. Reboot the phone and make sure you can ssh in and everything works. Now you can install all your favorite packages and never be without emacs, nethack, and a C compiler ever again!
2.2. Using Inetd
To conserve a bit of memory, you can run daemons from inetd. This isn't a huge improvement, since unix the daemons here are generally well written and don't consume gobbs and gobbs of memory like a typical Android app. But it should be a small improvement nonetheless.
Install openbsd-inetd on the phone
debian # apt-get install openbsd-inetd
Configure
/etc/inetd.conf
in the debian chroot. Here's a setup for ssh and samba:# SSH 22 stream tcp nowait root /usr/sbin/sshd sshd -i # SAMBA 139 stream tcp nowait root /usr/sbin/smbd smbd 137 dgram udp wait root /usr/sbin/nmbd nmbd
Configure Android's
/sd-ext/userinit.sh
to start inetd. Note that you will NOT want to start ssh and samba as separate services.# start debian ssh chroot /sd-ext/debian /usr/sbin/service openbsd-inetd start
3. Scripts
- /sd-ext/userinit.sh: Called by Android init system. Sets up the debian chroot.
- /data/local/bin/godeb: script to chroot into the debian install and su to the user account
4. Unresolved Issues
4.1. Name Resolution
- How to resolve the hostname of our phone as we move between networks?
- Mostly, I want to ssh/sftp to the phone from both my laptop and my lab workstation.
4.1.1. Options
- Sounds like a job for: mDNS
- Android doesn't support multicast, maybe?
- Dyndns: doesn't update fast enough
- ipv6 link local addresses: still flaky support in applications
- kernel/application can't figure which interface to use for link-local connections (sounds ironic, right?)
- can sometimes specify interface manually, but it's going to change, ie laptop on wired vs. wifi
4.2. WIFI
- WIFI Sleep Policy: seems to change nothing on CM7
- Screen On:
- Ping Time: ~10ms
- Bandwidth: 25 Mbps
- Screen Off:
- Ping Time: ~300MS
- Bandwidth: 5 Mbps