Dalvik Virtual Machine on TS-7800 SBC

You can find the details of porting Dalvik Virtual Machine on the TS-7800 embedded board in this article. You may also find basic the procedures to build Android OS from scratch.

Basic setup of the SBC can be seen from Figure.1. TS-7800 has an 88F5182 XScale ARM processor, 128 MB SDRAM and GPIOs, you may find more on the official web site of the product. Incidentally, I was about to forget, I used kernel 2.6.34 on this embedded board. Unfortunately the firmware image which is shipped with the product provides kernel 2.6.21-ts, and it is not convenient to port ashmem device (which is specific to Android Kernel) on this kernel version. You should download the latest firmware.

Figure.1: TS-7800 Single Board Computer with XScale ARM proccessor.

Dalvik Virtual Machine is the main component of Google Android OS, so if we want to port Android OS on a new platform, first we need to port Dalvik Virtual Machine into it. Let’s build Android Operating System, and by the way I am not going to talk about detailed build procedures. You may find these steps from official Google Android web site.

$ mkdir ~/bin
$ PATH=~/bin:$PATH

$ curl https://android.git.kernel.org/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

$ mkdir ~/android
$ cd ~/android

$ repo init -u git://android.git.kernel.org/platform/manifest.git
$ repo init -u git://android.git.kernel.org/platform/manifest.git -b froyo

$ repo sync

$ export TARGET_ARCH=arm
$ export TARGET_ARCH_VERSION=armv5tej
$ export TARGET_CPU_ENDIAN=EL
$ export USE_CCACHE=1
$ source build/envsetup.sh
$ choosecombo 
Build for the simulator or the device?
     1. Device
     2. Simulator

Which would you like? [1] 1

Build type choices are:
     1. release
     2. debug

Which would you like? [1] 2

Which product would you like? [generic] generic

Variant choices are:
     1. user
     2. userdebug
     3. eng
Which would you like? [eng] 3

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.2.1
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=debug
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=MASTER
============================================

$ make -j4 PRODUCT-generic-eng

Last operation will take an hour or more depending on your CPU processing speed. After the compilation we need to copy Android Binaries into target root file system.

$ cp -a ~/android/out/debug/target/product/generic/system /dev/rfs

In this setup, I used the SD flash memory as the root file system drive, and it is mounted on /dev/rfs on my PC in order to copy Android Binaries.

Until here, operations are simple procedures, and easy to find from Google Android web site. But the problem is, there are not clear procedures to make Dalvik Virtual Machine up and running on a new platform. This is too important, and Android Operating System does not use SysV shared memory methods in order to achieve IPC, therefore, you have to implement Android Shared Memory/dev/ashmem– device on your system.

Figure.2: Dalvik Virtual Machine Kernel Dependencies.

These are the steps to port ashmem device on kernel 2.6.34,

1- $ cp ashmem.c linux-2.6.34/mm
   $ cp ashmem.h linux-2.6.34/include/linux/

2- Open linux-2.6.34/mm/Kconfig file, and add these lines on the bottom of the file,

config ASHMEM_MODULE
	tristate "asmem module"
	depends on ARM
	default m if ARM
	help
		Android ashmem module. Provides specific shared memeory interface 
		to DalvikVM.

3- Open linux-2.6.34/mm/Makefile, and add this line on the bottom of the file,

obj-$(CONFIG_ASHMEM_MODULE) += ashmem.o

There are also two important issues to port ashmem.c. You need to add the extra C codes below,

/*B.D. begin*/
#include <linux/ashmem.h>
#include <linux/swap.h>
 
static LIST_HEAD(shrinker_list);
static DECLARE_RWSEM(shrinker_rwsem);
 
/*http://android.git.kernel.org/?p=kernel/common.git;a=blob;f=mm/memory.c*/
static const struct vm_operations_struct shmem_vm_ops;
static void shmem_set_file(struct vm_area_struct *vma, struct file *file) 
{
	if (vma->vm_file) 
		fput(vma->vm_file); 
	vma->vm_file = file; 
	vma->vm_ops = &shmem_vm_ops; 
} 
/*B.D. end*/

and export register_shrinker, unregister_shrinker kernel API’s

EXPORT_SYMBOL(register_shrinker);
EXPORT_SYMBOL(unregister_shrinker);

to allow dynamic linking.

For now, we are ready to go, and we need to compile the kernel, but I am not going to talk about kernel compilation. You may find the details from here.

After compilation of the kernel, we need to copy asmem.ko file into the root file system under
/lib/modules/2.6.34/kernel/android.
Now we are done, we can load the ashmem device by typing,

   $ insmod /lib/modules/2.6.34/kernel/android/ashmem.ko

OK, let’s verify Dalvik,

You may use the sample java code below to run on Dalvik Virtual Machine,

class Foo { 
	public static void main(String[] args) {
        for (int i = 1; i < 100; i++) {
            try {
                System.out.println("DalvikVM on ts-7800! : " + i);
                Thread.sleep(250);
            } catch (InterruptedException x) {
            }
        }
	} 
}

In order to convert class file into Dalvik eXecutable (DX), you should install Android SDK on your development machine(in my case Ubuntu 11.04-i386).

$ javac Foo.java
$ dx --dex --output=foo.jar Foo.class

We can test our sample dx application now! First we need to prepare a sample bash script to prepare environment variables for Dalvik Virtual Machine execution on the SBC,

#!/bin/bash
 
export ANDROID_ROOT=/system
export BOOTCLASSPATH=/system/framework/core.jar:\
/system/framework/ext.jar:/system/framework/framework.jar:\
/system/framework/android.policy.jar:/system/framework/services.jar
 
export ANDROID_DATA=/tmp/dalvik_$USER
mkdir -p $ANDROID_DATA/dalvik-cache
exec dalvikvm $@
Figure.3: Output of the sample application.

then we need to copy DX file (foo.jar) into the embedded system. We can run dalvikvm now. I hope, it will work for you applications.

Any feedback is welcome!