Building Android for BeagleBone Black with Kernel 3.2

beaglebone-black

Note: SGX (hardware-accelerated OpenGL) is supported only in Kernel 3.2

Get source (using TI DevKit)

mkdir ~/ti-android-bbb
cd ~/ti-android-bbb
repo init -u git://gitorious.org/rowboat/manifest.git -m TI-Android-JB-4.2.2-DevKit-4.1.1.xml
repo sync

Setup

export PATH=~/ti-android-bbb/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH

Build U-Boot and X-Loader

cd ~/ti-android-bbb/u-boot
make CROSS_COMPILE=arm-eabi- distclean
make CROSS_COMPILE=arm-eabi- am335x_evm_config
make CROSS_COMPILE=arm-eabi-

Build Android and Kernel with SGX On

cd ~/ti-android-bbb
make TARGET_PRODUCT=beagleboneblack OMAPES=4.x
make TARGET_PRODUCT=beagleboneblack fs_tarball

Creating the SD Card

mkdir ~/android-bbb-image
cp ti-android-bbb/kernel/arch/arm/boot/uImage ~/android-bbb-image
cp ti-android-bbb/u-boot/MLO ~/android-bbb-image
cp ti-android-bbb/u-boot/u-boot.img ~/android-bbb-image
cp ti-android-bbb/external/ti_android_utilities/am335x/u-boot-env/uEnv_beagleboneblack.txt ~/android-bbb-image
cp ti-android-bbb/out/target/product/beagleboneblack/rootfs.tar.bz2 ~/android-bbb-image
cp ti-android-bbb/external/ti_android_utilities/am335x/mk-mmc/mkmmc-android.sh ~/android-bbb-image
cd ~/android-bbb-image
sudo./mkmmc-android.sh /dev/sdX MLO u-boot.img uImage uEnv_beagleboneblack.txt rootfs.tar.bz2

Compiling Android with Kernel 3.8

Replace Rowboat default Kernel with Kernel 3.8

Note 1: SGX is not yet supported on Kernel 3.8 so there is no hardware-accelerated OpenGL on this release./pre>
Note 2: Consider Rowboat for BeagleBone Black was cloned at ~/rowboat-android-bbb and Kernel 3.8 is at ~/linux-dev

cd ~/rowboat-android-bbb
mv kernel kernel.bkp
ln -s ~/linux-dev/KERNEL kernel

Compiling Android for BeagleBone Black

Let's modify some Makefiles in order to use 'arm-linux-gnueabihf-' instead of 'arm-eabi' for compiling.

chmod 644 ~/rowboat-android-bbb/Makefile
vi ~/rowboat-android-bbb/Makefile

And add a # (comment) in front of export PATH :=$(PATH):$(ANDROID_INSTALL_DIR)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin.
Below that (new) comment add the following two lines and save

export PATH :=~/linux-dev/dl/gcc-linaro-arm-linux-gnueabihf-4.7-2013.04-20130415_linux/bin:$(PATH)
export CC_PREFIX := arm-linux-gnueabihf-

Search the Makefile for references to arm-eabi- and replace them with $(CC_PREFIX). Once all the changes are saved, go on building Android with SGX support.
$ make TARGET_PRODUCT=beagleboneblack OMAPES=4.x droid -j4 (It takes more or less 2 hours on a Intel i5 with 8GB of RAM.)

Compiling Android for BeagleBone Black

U-Boot for BeagleBone Black

Getting U-Boot and patching

Note: Use this guide only if you are building Android with Kernel 3.8

cd ~/
mkdir u-boot-bbb
cd u-boot-bbb
git clone git://git.denx.de/u-boot.git
cd u-boot/
git checkout v2013.04 -b tmp
wget https://raw.github.com/eewiki/u-boot-patches/master/v2013.04/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch

Compiling U-Boot

We will compile U-Boot using the same toolchain used for compiling the Kernel, and not the one present in Rowboat-Android

export PATH=$PATH:~/linux-dev/dl/gcc-linaro-arm-linux-gnueabihf-4.7-2013.04-20130415_linux/bin/
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am335x_evm_config
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

U-Boot for BeagleBone Black

Output files

The output files are ./MLO and u-boot.img. Copy these two files into a new folder in your home directory (i.e.: ~/bbb-android-image)
Next: Compiling Android with Kernel 3.8

BeagleBone Black and Linux Kernel 3.8 with Android support

beaglebone-black

Building Kernel 3.8 (with Device Tree)

cd ~/
git clone git://github.com/RobertCNelson/linux-dev.git
cd linux-dev/
git checkout origin/am33x-v3.8 -b tmp
./build_kernel.sh

If ./build_kernel.sh fails with ‘undefined references’ to some functions in files like ‘menubox.c’ try running: sudo apt-get install libncurses5 libncurses5-dev libelf-dev libncurses5 libncursesw5-dev and then retry with ./build_kernel.sh.

Setting up Kernel 3.8.x for Android

Once in the Kernel Configuration Utility (kConfig) scroll down, and enter, ‘Device Drivers’.

Beaglebone Black - Kernel Config for AndroidMake sure the ‘Staging drivers’ are enabled, or enable them (an asterisk will appear between brackets)

Beaglebone Black - Kernel Config for Android

Then, enter ‘Staging drivers’ -> ‘Android’. Enable all Android drivers. I recommend you to include them into the kernel, and not build them as module.

Beaglebone Black - Kernel Config for Android

Exit ‘kConfig’ and the Kernel will begin building.

Beaglebone Black - Kernel Config for Android

When it is done you will see something like

Beaglebone Black - Kernel Config for Android

Next: U-Boot for BeagleBone Black

Increasing Java Heap size in Android from source code

Under /frameworks/base/core/jni/ there is a file called AndroidRuntime.cpp where the Dalvik VM parameters are set. You can do a search over the file for “dalvik.vm.heapsize” and you will find out something like this:

/*
* The default starting and maximum size of the heap. Larger
* values should be specified in a product property override.
*/
strcpy(heapstartsizeOptsBuf, "-Xms");
property_get("dalvik.vm.heapstartsize", heapstartsizeOptsBuf+4, "4m");
opt.optionString = heapstartsizeOptsBuf;
mOptions.add(opt);
strcpy(heapsizeOptsBuf, "-Xmx");
property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
opt.optionString = heapsizeOptsBuf;
mOptions.add(opt);

change “16m” for any other value, taking into account, the available memory in your device. For example, setting the heap size to 48m it is a good choice in a Beagleboard xM or Beaglebone Black, both with nearly 512Megabytes of RAM.

Installing busybox (for Android) on BeagleBoard

Busybox

BusyBox provides several stripped-dowUnix tools in a single executable file. It runs in a variety of POSIX environments such as Linux, and Android. Some of these tools are

  • ssty
  • su
  • gzip
  • ping
  • netstat
  • tar
  • arp
  • wc
  • microcom

Why is busybox necessary on a BeagleBoard running Android?

The default Android build does not have many useful tools like stty, so there it is where this swiss army knife comes to rescue.

Installing busybox

  1. Download ‘busybox’ from http://benno.id.au/android/busybox
  2. Connect to the board using ADB. ./adb shell
  3. Create a busybox directory inside data. mkdir /data/busybox
  4. Exit ADB. exit
  5. Push the downloaded file to the board. ./adb push busybox /data/busybox/busybox
  6. Enter Shell again. ./adb shell
  7. And change permission in order to let any app execute busybox. chmod 777 /data/busybox/busybox

Beagleboard xM & native FTDI VCP driver

beaglebone-black

Adding the driver to the Kernel

cd ~/rowboat-android/kernel
make ARCH=arm CROSS_COMPILE=arm-eabi- distclean
make ARCH=arm CROSS_COMPILE=arm-eabi- omap3_beagle_android_defconfig

Up to this point everything goes as normal. Now let’s add the FTDI support as a driver (NOT as a module). FTDI published a very detailed tutorial that can be found at http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_132_Adding_FTDI_Devices_VCP_Driver_Support_to_Android.pdf.
make ARCH=arm CROSS_COMPILE=arm-eabi- menuconfig
If ‘menuconfig’ is not present in the host (Ubuntu), install it using the following code:
sudo aptitude install lib32ncurses5-dev
As the documentation presented by FTDI says, it is necessary to enable a few things:

  1. “Device Drivers” -> “USB Support” -> pres ‘y’ over “Support for Host-side USB”
  2. “Device Drivers” -> “USB Support” -> “USB Serial Converter support” -> press ‘y’ over “FTDI Single Port Serial Driver”

 

 
Now save this configuration and build the Kernel using
make ARCH=arm CROSS_COMPILE=arm-eabi- -j4
When connecting a FTDI device to the BB xM with this modified Kernel, you will see a ttyUSBx directory inside /dev.

Connecting the FTDI device to the Beagleboard

First of all it will be very useful to connect the Beagleboard Serial port to the host machine and establish a connection using Minicom (or something like that). Once you got there it will be very easy to see if the driver was properly included, and the device is recognized.
See the following screenshot. It shows the device console before the FTDI converter was connected and after that. The device was recognized perfectly, and ttyUSB0 was created under /dev.

 

A simple test from shell

If you have busybox on Android you can make a simple test in order to see if the driver is well configured (In case you don’t have busybox, you can follow my post on how to install busybox on BeagleBoard).

  1. Connect RX and TX on the FTDI IC
  2. Connect to board using ADB. ./adb shell
  3. Setup ttyUSB0. /data/busybox/busybox stty -F /dev/ttyUSB0 115200
  4. Open microcom (similar to minicom) /data/busybox/busybox microcom -s 115200 /dev/ttyUSB0
  5. Write something and it will be echoed. If you disconnect the RX and TX, what you send it will not be echoed.

 

Writing to ttyUSB from C

Init the ttyUSB interface

system("/data/busybox/busybox stty -F /dev/ttyUSB0 115200");
The ttyUSB interface can also be initiated from /init.rc file at the end of “on boot” section.

Getting a File Descriptor

FILE * usbdev = fopen("/dev/ttyUSB0", "rw+");

Read and Write from the File Descriptor

char message[20]; /* buffer of data to send */
char rMessage[20]; /* receive buffer */
fwrite(message, sizeof(char), 8, usbdev);
fread(rMessage, sizeof(char), 8, usbdev);

Closing the File Descriptor

fclose(usbdev);

Writing to ttyUSB from Java

Connecting to ttyUSB from Java requires a little bit of extra work. By default, a device under “dev” has permissions only for root. And if your Java app it is not running with root (or your base board is not rooted) you have to change permissions to ttyUSB0 in order to let other apps to write and read from the file (using JNI, of course).
This can be done using several methods, for example:
chmod 777 /dev/ttyUSB0

ADB over Ethernet in BeagleBoard

Setting up device

First of all we need to ensure that we have an Ethernet connection up and running. Connect your PC to the Beagleboard using a USB to Serial converter. USB side on your host and Serial on the RS232 debug port of the Beagleboard.
Then connect using minicom (or any other term program) at 115200bps 8N1. This will let you access a simple linux shell. At the prompt type:
root@android:/ # netcfg
You should see something like

lo   UP      127.0.0.1/0
sit0 DOWN
usb0 UP      192.168.1.118/24

if not, try running netcfg eth0 dhcp or netcfg usb0 dhcp in order to obtain a connection.
Once the connection is established, we will change the ADB TCPIP port and then restart ADB Daemon (adbd)

root@android:/ # setprop service.adb.tcp.port 5555
root@android:/ # stop adbd
root@android:/ # start adbd

Setting up host

Back on your host machine, start ADB in TCPIP mode and then connect to your device like this

$ sudo ./adb tcpio 5555
$ sudo ./adb connect 192.168.1.118

Once you are connected you can check that everything is working running an adb command like:

$ sudo ./adb devices
List of devices attached
192.168.1.118:5555 device

or

$ sudo ./adb logcat

Android 4.1.2 Image for Beagleboard XM

This Image can be loaded into an SD Card (4GBytes min). It can run entirely from the SD Card, or the Android OS can run from a USB Flash, and U-Boot, X-Loader and the Kernel on the SD Card.

Configure U-Boot

For running entirely from the SD Card

Setup U-BOOT for Android and Kernel on SD Card

./mkbootscr

For running Android OS from a USB Drive

Setup U-BOOT for Android on USB and Kernel on SD Card

./mkbootscrUSB

copy rootfs.tar.bz2 to USB Drive and untar (all these commands should be executed as Administrator)

Create SDCard

Note: Script not yet optimized for configuration with USB Drive (it is not necessary to copy rootfs to SD Card when booting from USB)
sudo ./mkmmc.sh /dev/sdb MLO u-boot uImage boot.scr rootfs.tar.bz2

Files: Android Image for BeagleBoard xM