Accessing your Android from Ubuntu and compiling stuff

So you got an Android mobile phone and you want to access it from your Ubuntu. You can get shell access to your phone, you can copy files from/to, and much more. In this post I cover the overall process.

You connect your mobile phone to your computer with a USB cable. Most Android phones come with either a microUSB, a miniUSB or some proprietary-to-USB cable. If your phone did not come with such a cable, you need to get one.

When you connect your phone to the computer, it might be initialised as a CDROM device (uses the usb-storage kernel module) that comes with Windows drivers. It is the same issue you get with many 3g USB dongles that are initially recognised as CDROM devices. You need to use usb_modeswitch with the correct parameters in order to pass to the next stage (which makes the phone appear as a phone device, not a CDROM). If you do not have ‘usb_modeswitch’, install the usb-modeswitch package.

How do you find whether you need usb-modeswitch? And what parameters you need? See the usb-modeswitch project page and their helpful forum. You can also google with your device model number and the keyword usb-modeswitch.

Then, the next thing to do is to add a udev rule so that the correct permissions as set for your Android device. Use lsusb to identify the Vendor:Product ID of your phone. It looks like 1d6b:0001, and the Vendor ID in this case would be 1d6b. Then, run

gedit /lib/udev/51-android.rules

and type in

SUBSYSTEM=="usb", SYSFS(idVendor)=="XXXX", MODE="0666"

You need to replace XXXX with your correct USB Vendor ID. Save and exit.

Finally, restart udev with

sudo restart udev

Afterwards, you can download the Android SDK for Linux. It’s a 17MB file, and (at the moment of writing) the filename is android-sdk_r07-linux_x86.tgz. The download pages talk about installing Eclipse and other stuff. For the purposes of shell access and copying files, it is OK to get the Android SDK only. Once you download it, uncompress. Locate the directory android-sdk-linux_x86/tools/. In there you get the adb (Android Debug Bridge) tool.

Run ./adb start-server in order to start the server on the host side.

Then, see whether your phone has been identified, with ./adb devices

> ./adb devices
List of devices attached 
SOMEDEVICENAME    device
> _

If you do not get the last line mentioning ‘SOMEDEVICENAME  device’, then your phone was not detected (probably the usb_modeswitch issue needs to be done). If you get the line but with ‘(no permissions)’, then something was wrong with udev setting up the permissions earlier. A shortcut is to ./adb kill-server and then run the same command with a sudo at the start.

Finally, we can

> ./adb shell
$ id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
$ uname -a
Linux localhost 2.6.29-perf #1 PREEMPT Tue Aug 3 20:01:27 EET 2010 armv6l GNU/Linux
$ _

If you managed to root your Android phone, you can also

$ su
# id
uid=0(root) gid=0(root)
# _

You can search at http://forum.xda-developers.com/ on how to root your phone. Most Android phones can be rooted. Note that things can go horribly wrong so there is a big chance to mess up with your phone if you are not careful. Study well before you root.

You copy files to and from the phone with

./adb push myfile.txt /sdcard/       # copies file myfile.txt from your computer to the /sdcard directory on the phone.
./adb pull /sdcard/myfile.txt .      # copies file /sdcard/myfile.txt from the phone to the current directory.

Once you master these command, you can do more interesting things, such as cross-compiling programs on your Linux and then installing on your phone. Let’s see how to write our own program.

Visit http://www.codesourcery.com/sgpp/lite/arm/portal/release1293 and download the IA32 GNU/Linux TAR package. Uncompress it. You get an arm-2010q1 directory with the ARM GCC cross-compiler.

Let’s write a program, hello.c,

#include <stdio.h>
int main(void)
{
 printf("Hello, world!\n");
 return 0;
}

We compile on our Ubuntu with the command

> arm-2010q1/bin/arm-none-linux-gnueabi-gcc hello.c -static -o hello_static
> _

We need the -static keyword in order to make a static executable. Static means that our executable has everything that is required to run, and does not depend on other phone software/libraries.

Copy to the phone,

> ./adb push hello_static /sdcard
1687 KB/s (647869 bytes in 0.374s)
> _

Then, connect to the phone,

> ./adb shell
$ cd /sdcard
$ ls -l hello_static
-rwxrwxrwx system   system     647869 2010-11-14 14:17 hello_static
$ ./hello_static
./hello_static: permission denied
$ _

What went wrong? When we type mount, we see that the /sdcard partition is mounted with the noexec flag. We cannot run stuff from /sdcard. What to do then? Copy stuff on the phone memory?

It appears that the SD card file system is also available from the /data/hwvefs mount point. There must be some background here, but the gist is that you can access the /sdcard content from /data/hwvefs/sdcard, and you can run them!

$ cd /data/hwvefs/sdcard
$ ./hello_static
Hello, world!
$ _

The commands you come to expect on your Ubuntu system are not available on Anroid. You can install Busybox for Android. Still, these commands do not have the features you expect to get on Ubuntu.

Let’s compile the bash shell. We download bash and uncompress.

We add the cross compiler to our path,

export PATH=/home/myusername/arm-2010q1/bin:$PATH

Then, we enter the bash-4.1 directory and run (assumes we installed build-essential)

> ./configure --prefix=/opt/arm_bash --host=arm-none-linux-gnueabi --enable-static-link --without-bash-malloc
configure: WARNING: If you wanted to set the --build type, don't use --host.
 If a cross compiler is detected then cross compile mode will be used.
checking build system type... x86_64-unknown-linux-gnu
checking host system type... arm-none-linux-gnueabi
checking for emacs... no
checking for xemacs... no

Beginning configuration for bash-4.1-release for arm-none-linux-gnueabi
...
$ _

Then,

make
sudo make install

The bash for the ARM is available at /opt/arm_bash/bin/bash

Let’s examine it,

> file /opt/arm_bash/bin/bash
bash: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
> _

The important part is the mention to ARM. If there was a mistake in the configuration, you might see x86_64 here, which is your own computer!

As we did with hello_static, we install bash, and run it.

$ ./bash --version
GNU bash, version 4.1.0(1)-release (arm-unknown-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ ./bash
bash-4.1$ _

Reading the UDS proceedings we see a big push for development on the ARM platform for mobile devices. There was mention for a packaged ARM cross compiler on the Ubuntu repositories (?) which would make things easier and more natural. It would be great to get as much of the user experience we are used to from the Linux desktop down to the mobile devices. Future looks great.

3 comments

  • Bupahs

    Or simply use ADBuix – “Adbuix is a Graphic User Interface (GUI) for the Android Debug Bridge (ADB) on the Linux Operating System. It eliminates the work of remembering commands or typing out directory paths when using ADB to modify files on your Android device.” I have used it on Ubuntu 9.10, 10.04.1 and 10.10 with no issues.

    http://forum.xda-developers.com/showthread.php?t=641385

    [ Thanks for the link. Their website is not working at the moment. I’ll try the tool once it is available again. –simos]

  • Marius Gedminas

    Shouldn’t we, I dunno, file bugs or something so this kind of low-level usb-modeswitch hackery wouldn’t be necessary in the future?

    »»» [From the usb-modeswitch homepage: USB_ModeSwitch makes the last step considerably easier by taking the important parameters from a configuration file and doing all the initialization and communication stuff.
    From version 1.0.3 upwards there is a simple framework for integrating the switching with udev (the device manager) to make it fully automatic.

    This tool is now on the way to be integrated into the big distributions; soon you should not be having to install from the source packages here anymore.
    But I strongly advise against using packaged versions before 1.1.0.

    usb-modeswitch is doing this specialised job pretty well. — simos]

  • Pantelis Koukousoulas

    Sorry for reading this post / comments so late, but:

    usb_modeswitch has now been integrated as a udev helper, the way it should have been from the beginning 🙂 🙂

    See /lib/udev/rules.d/40-usb_modeswitch.rules, patch accordingly for your device and send the patch to udev.

    Cheers,
    Pantelis

Leave a Reply

%d bloggers like this: