Monday, September 05, 2011

Android ARM assembly: Device set up (Part 1)

This is part one of a multipart series about learning ARM assembly programming with Android. This covers motivation and device set up.

=> Part 1: Motivation and device set up
Part 2: A walk-through of a simple ARM assembly program
Part 3: Registers, memory, and addressing modes
Part 4: Gnu tools for assembly; GCC and GDB
Part 5: Stack and Functions
Part 6: Arithmetic and Logical Expressions
Part 7: Conditional Execution
Part 8: Assembly in Android code

The articles follow in series, each article builds on the previous.

Motivation

You might not realise it, but ARM processors are ubiquitous. When I look around my house, I can count eight ARM processors in routers, phones, eBook readers and web servers. There are more ARM processors in my house than Intel processors.

ARM assembly language is perhaps the easiest assembly language in widespread use. The Intel instruction set was developed over years of CPU revisions, which made the Complex Instruction Set (CISC) even more complex. In case you want to learn assembly, the ARM instruction set is simple to learn. Once you know how to write ARM assembly, it is easier to learn Intel assembly.

Finally, ARM processors are being used everywhere. Whether you like the iPhone or Android, they both use ARM processors. ARM processors excel at low-power computing, which makes them valuable for mobile computing, and consumer electronic devices like routers, NAS storage, eBook readers, game consoles and cell phones. Unlike desktop computers, resources are very limited on mobile devices. On such devices optimisation makes the difference between a slow and unusable application and a fast and responsive one.

Thanks to the profusion of Android devices, you can start programming ARM assembly within minutes and at low cost. You don't need to sign an NDA or pay for development tools. If you have an Android phone and a computer, you already have everything you need. Assembly language programming will not require the buttons or the touch-screen. Any device with a working USB port and with root access will do.

Setting up an ARM device with Linux was a monumental effort: you had to buy a dev-kit which easily ran in the hundreds of dollars. Then you struggled to shoe-horn Linux onto the tiny device. With Android, you already get an ARM device running Linux. All the device drivers are in place. All you need is a Linux distribution that allows you to get the native development tools. This is considerably easier. It should take around an hour of effort.

At this point, you have a choice. You can either go with setting up your own device, which lets you develop on a real ARM computer. Or you can download a prebuilt QEMU image.

Choice A: Emulation
This is the easy choice. For this, you need a computer: Windows, Mac, Linux, all are good.

QEMU is a full CPU emulator that can emulate an ARM computer. It is capable of running the full Android stack, and is shipped with the Android SDK. QEMU is much easier than setting up Linux on Android. To start, download and install QEMU on your system and a utility to extract RAR files. I have prepared QEMU images with the full software development environment.

Download all three files [part 1], [part 2], [part 3], and then run this command:
$  unrar x arm-qemu.part1.rar
This will create a directory called ARM. You can enter that directory and run the command runme.sh. It will start up the virtual machine. The virtual machine is slow, so be patient. The administrator has username "root" and password "root".

Choice B: Using a real device
In this case you install Linux on your Android phone.

You need:
  1. Android phone with 2GB free space on the SD card
  2. Any computer with USB
Obtain an Android phone on which you can get root access. If you have a working Android phone, you can use that. Otherwise you can buy a used Android phone. Install Debian on it using Jay Freeman's instructions on getting Debian on an Android phone.

Another option is to buy an ARM device like this Zipit.  This is a harder option. Many devices have poor support, and installing Linux can be a herculean task. I would recommend sticking to an Android phone unless you have easy access to an ARM device and you know that you can install Linux on it easily.

Once you have Debian working, you need to create a user and install ssh to allow easy access to the device from your laptop or desktop:
phone$ sudo adduser # Create a normal user for dev purposes.
phone$ sudo apt-get install openssh-server
phone$ sudo /etc/init.d/ssh start
 
You now have a working Debian installation that you can access using SSH. To ssh into your device, you can use port forwarding with the Android Debug Bridge (adb) to forward the desktop's port 2222 to port 22 on the phone as follows:
desktop$ adb forward tcp:2222 tcp:22
Finally, you can login to your phone from your desktop as follows:
desktop$ ssh user@localhost -p 2222

Once the port forwarding is working correctly, you can also login from any computer on your network as follows:
desktop$ ssh user@mydesktop -p 2222
This allows you to connect to your ARM device from any computer in your house. You can punch holes in your firewall by forwarding ports from the firewall to port 2222 on your desktop's IP address, and be able to access your ARM device from anywhere in the world. Even if the screen has turned off, you will be able to ssh into it, edit, compile and debug programs.

Congratulations. You now have a completely silent ARM device which you can connect to from anywhere.

Once you have Debian installed on your device, you can get the development system using apt-get:
phone$ sudo apt-get install gcc gdb make vi emacs
Install the editor you prefer: vi or emacs. Now, your phone is a fully capable ARM dev environment.


Test the development tools
You can try a simple C program to verify the setup.
/* hello.c: Hello World program */
#include <stdio.h>

int main(int argc, char* argv[]){
  printf("Hello ARM World\n");
  return 0;
}

You can compile this and run this as follows:
phone$ gcc hello.c -o hello && ./hello 
If you have got this far, you can get a sneak peak at ARM assembly with the following command:
phone$ gcc hello.c -S && cat ./hello.s 
This shows you the intermediate Assembly language from the Hello world program.

Congratulations, you have turned your Android phone into a full-featured ARM dev kit. The next article will cover programming your device in Assembly language.