Building and Deploying the Mainline (Vanilla) Android Master Source for the Beaglebone Black

Texas Instruments “AM335x” ARM platform has been gaining a lot of traction during the past couple of years. With the Beaglebone Black, a low cost board for developing on the platform is available. With the upcoming launch of the Arduino TRE which is based widely on the BBB, the platform is becoming even more interesting for the embedded industry.

In this post we would like to cover of how to get started with embedded Android development on the Beaglebone Black. While there are already excellent tutorials available of how to Build Yocto and Android Jellybean (based on the rowboat development project), this article covers building the Android Mainline (and vanilla) source code.

As a result of being vanilla, drivers such as graphics, are not addressed and software graphics acceleration will be used for the example. While the user interface clearly lacks the needed hardware boost of the graphics chip, Texas Instruments have decided to not compile their graphics driver for Android 4.4 Kitkat (and +). Search for the term “SGX” and “AM335” on the TI forums to get an idea of the current state of the driver. Since it is closed source and there have been no notable efforts nor results of reverse engineering it, all the hope of getting hw acceleration sadly remains with the TI team.

However, even if the performance is not optimal, it is possible to configure, compile and build Android for the platform, and very simple applications are still possible to deploy and use.

For this article the following configuration is used:

OS: Ubuntu 14.04 64 bit
Android: Master (
Date: 18 May 2014

This article is based on resources of Robert C Nelson, which is doing an excellent job of keeping the Kernel patches for mainline AM335x and iMX6 boards up to date! Find a multitude of tutorials of how to get started with Embedded Linux on the eewiki website.

Initializing Build Environment

For deploying a functional Android the following software components are required.

The Android Source Code
The Linux Kernel Source Code
The u-boot Source Code

Similar to Embedded Linux development, the three components work together.

U-Boot: The bootloader initializes memory and loads a Kernel image as well as a device tree blog into the RAM. Depending on the configuration those files can be acquired in various ways (tftp, nfs, ext4, fat, from SD, from EMMC …). Once loaded, the Kernel will be started (in our case as uImage binary).

Kernel: For this article we are using the 3.14 Kernel provided by the git repository from Robert C Nelson. Selecting the Android drivers under the “Staging” section, is enough to get Android running. Be aware though that for using Android in a more professional environment, merging with the Android Kernel source is advised.

Android Source: At the point of this writing, the current main branch version of android is Kitkat (working branch Instead of focusing on a specific version, this article points out a recipe of getting Android to run on almost any configuration.

Build Environment Setup

Start by following the environment setup steps provided by the Android source code website (here) and make sure to install some additional tools as shown below:

sudo apt-get update
sudo apt-get install git-core gnupg flex bison gperf build-essential \
  zip curl libc6-dev libncurses5-dev x11proto-core-dev \
  libx11-dev:i386 libreadline6-dev:i386 \
  libgl1-mesa-dev g++-multilib mingw32 openjdk-6-jdk tofrodos \
  python-markdown libxml2-utils xsltproc zlib1g-dev:i386 \
  u-boot-tools minicom lib32ncurses5-dev \
  uuid-dev:i386 liblzo2-dev:i386 minicom
sudo apt-get install gparted
sudo apt-get install openjdk-7-jdk
sudo apt-get install -f

If you happen to have troubles running the ADT Bundle on 14.04 (get errors with adb) then you need to download these additional libraries. (Thanks to

sudo apt-get install lib32stdc++6 lib32z1

The package “minicom” is used to communicate and interact with u-boot and linux via serial command line on the BBB. Gparted is a very helpful tool for partitioning the SD-Card. The OpenJDK is newly used to compile Android – a big step forward! Installing the proprietary oracle binary is finally no longer necessary.

For building and compiling the components, create a new working directory and give yourself access permission to read/write.

# create an android directory at the root
# we are on a machine with user "nx" and host "nx"
nx@nx:~$ sudo mkdir /android
nx@nx:~$ sudo chown nx.nx /android
nx@nx:~$ cd /android

Make sure you have enough disk space available for the next steps. Android alone will require around 25G of free disk space, a full build will take another 15G. We recommend at least having 60G of free disk space available for building Android.

Also while it is possible to use a virtual machine, performance for compiling will be significantly better when opting to go for a native Linux install.

Building on an octa-core processor will take around 40 minutes. Performance is improved by CPU power, amount and speed of memory, speed of hard drive in that order.

Pro Tip: If your system happens to be set up by somebody other than yourself, do make sure you have a swap partition available. A build will fail if the system requires swap space during the compile process without any good hints of why it crashed. If you ever happen to get segmentation faults during the compile process, check your memory, it might be defect.

Downloading Android Sources

Downloading the Android source will take a while depending on the throughput of your network connection. The 15G large source code will be downloaded in a compressed version. The source with the build version will take up around 50GB of disk space.

If you are joining our Embedded Android workshop copy the source code from the hard drive available. If you are doing this from outside the course, then issue the following commands.

# first download repo, it is the source code control tool
# of android and the chrome-os project
nx@nx:/android$ mkdir ~/bin
nx@nx:/android$ curl > ~/bin/repo

# now log out of your ubuntu system and back in
# this is important, since the ~bin directory will
# only be added to your PATH variable if it exists
# during the time of your login into the system.

nx@nx:~$ cd /android
nx@nx:/android$ repo init -u
nx@nx:/android$ repo sync

# this command will download the entire android source code
# once done, you are ready to start configuring and building

Downloading the Kernel

Thanks to the patch set of Robert C Nelson, the BBB can be used with a few patches applied on the vanilla kernel. While this might not seem significant, this is an enormous advantage of the platform towards competitors. Having mainline support is in many cases a key factor in selecting hardware components for manufacturers.

# clone the kernel inside the android directory

nx@nx:/android$ git clone

# now check out the 3.14 version of the kernel

nx@nx:/android$ cd kernel
nx@nx:/android/kernel$ git checkout origin/3.14 -b beaglebone-3.14

# next, execute the, which will download
# the vanilla kernel and check out the 3.14y branch

nx@nx:/android/kernel$ ./

Another kernel/kernel directory is now holding the sources of the Linux kernel.

Downloading U-Boot

The AM335x processor is using u-boot as its default bootloader. Another key advantage is that it can boot a vanilla variant of u-boot which is (similar to the kernel) patched in order to adjust the boot environment. Again, the patches (and also commands) have been provided by Robert C Nelson and are accessible via github.

# download the mainline u-boot
nx@nx:/android$ git clone git://
nx@nx:/android$ cd u-boot
nx@nx:/android/u-boot$ git checkout v2014.04 -b tmp
nx@nx:/android/u-boot$ wget -c
nx@nx:/android/u-boot$ patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch

This closes the initialization part of the article, now it is time for configuring and building.

Building the bootloader, u-boot

Since the downloaded Android source ships with the arm toolchain, we do not require to download an additional one.

nx@nx:/android/u-boot$ export ARCH=arm

# export the toolchain, use the one provided
# by the Android source code

nx@nx:/android/u-boot$ export CROSS_COMPILE=/android/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-

# clean and compile

nx@nx:/android/u-boot$  make clean
nx@nx:/android/u-boot$  make am335x_evm_config
nx@nx:/android/u-boot$  make -j16

The last command will start the compile process of the bootloader.

The output files necessary for deployment are “MLO” and “u-boot.img”.

U-Boot Environment

In order to boot Android properly, place the following uEnv.txt file onto the boot partition of the SD-Card.

# these are the contents of the uEnv.txt file
# placed on the first partition of the sdcard

mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} androidboot.console=ttyO0 mem=512M init=/init ip=off androidboot.hardware=bbb
mmcroot=/dev/mmcblk0p2 rw
uenvcmd=if run loaduimage; then run loadfdt;run mmcbootimage;fi
loaduimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
mmcbootimage=echo Booting from mmc ...; run mmcargs; bootm ${loadaddr} - ${fdtaddr}

Building and Configuring the Kernel

Building and configuring the kernel is an integral part of the process. With the help of “menuconfig” configuration is done comfortably.

# change into the kernel source directory

nx@nx:/android/u-boot$ cd /android/kernel/kernel

# copy the beaglebone config into ".config"

nx@nx:/android/kernel/kernel$ cp ../configs/beaglebone .config
nx@nx:/android/kernel/kernel$ export CROSS_COMPILE=/android/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-
nx@nx:/android/kernel/kernel$ export ARCH=arm
nx@nx:/android/kernel/kernel$ export LOADADDR=0x80008000

# the next command starts the kernel configuration
# via menuconfig

nx@nx:/android/kernel/kernel$ make menuconfig

# once you are done, save and exit and start building the
# kernel image as well as the device tree blob

nx@nx:/android/kernel/kernel$ make -j16 uImage dtbs

# the resulting files will be in the
# arch/arm/boot/ directory
# 1. arch/arm/boot/uImage
# 2. arch/arm/boot/dts/am335x-boneblack.dtb

Since the needed Android drivers are already selected in the provided config file (configs/beaglebone), it is not necessary to reconfigure the kernel. However, to include other drivers, such as CDC-ACM for instance, you may use configure the kernel with menuconfig as described above.

The resulting uImage and am335x-boneblack.dtb need to be copied into the second partition of the SD-Card (ext4) inside the directory “/boot” as required by the $bootdir and $fdtdir property of uEnv.txt.

At this point, deployment is already possible to an SD-Card. Although no user space has been built, the kernel can already be started and output can be analyzed on the serial command line.

Deploying Kernel and U-Boot

While Android has not been built yet, this is a good moment to check if the kernel boots properly. Therefore, a first deployment step can be very helpful.

Micro SD-Card Setup

In order to deploy Android at a later stage, formating the SD-Card properly is required. Although the setup can be changed according to your needs, this simple layout will help the project to get started.


Use the gparted tool installed earlier in order to partition the micro SD-Card as provided by the image above. After partitioning, make sure to set the boot flag for the BOOT partition.

The RFS partition should be at least 200 MB while BOOT can be around 10 MB in size.

Assign the largest bulk of the SD-card to the data partition, and a size of around 100 MB to the cache.

Copy the MLO, uEnv.txt and u-boot.img onto the BOOT partition and copy the uImage and am335x-boneblack.dtb onto the RFS partition under /boot.

# u-boot deployment

nx@nx:/android/$ cp u-boot/MLO /media/$USER/BOOT/
nx@nx:/android/$ cp u-boot/u-boot.img /media/$USER/BOOT/

# kernel deployment

nx@nx:/android/$ sudo mkdir /media/$USER/RFS/boot
nx@nx:/android/$ sudo cp kernel/kernel/arch/arm/boot/dts/am335x-boneblack.dtb /media/$USER/RFS/boot/
nx@nx:/android/$ sudo cp kernel/kernel/arch/arm/boot/uImage /media/$USER/RFS/boot/

# sync and unmount

nx@nx:/android/$ sync
nx@nx:/android/$ sudo umount /media/$USER/*

Make sure the internal flash of the Beaglebone is cleared (as described here).

Building and Deploying Android

The only thing missing at this point is a user space system. For this we need to configure, compile and deploy Android to the root file system of the SD-Card.

Building Android

# first change into the Android directory
# then start the configuration and build process

nx@nx:/android/$ source build/
nx@nx:/android/$ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
nx@nx:/android/$ choosecombo 1 mini_armv7a_neon 3
nx@nx:/android/$ time make -j16

# this will take some time now

On an up to date octa-core CPU this process is taking around 40 minutes. Thanks to a change in the new version of Android, the Oracle java development kit has finally been dropped in favor of openjdk.

The root file system will be compiled into the directory out/target/product/mini_armv7a_neon/

Deploying Android

While in most configurations Android will be shipped with a ramdisk, it is also possible to place the files onto the external SD Card storage.

For this step it is important that the labels of the SD-Card are according to the section “Micro SD-Card Setup” above. (otherwise just adjust the the variables in

Two helper scripts will create tarballs from the output directory and extract them with the correct file mods into the SD-Card directory.

Place the export-script altogether with a modified version of into your /android directory.

nx@nx:/android/$ source build/
nx@nx:/android/$ wget
nx@nx:/android/$ wget
nx@nx:/android/$ chmod a+x
nx@nx:/android/$ chmod a+x
nx@nx:/android/$ ./

# execute it twice, since the first time an additional tool will be built
nx@nx:/android/$ ./

Make sure you are executing from within a shell that is set up with “source build/”. Furthermore, make sure the SD-card is mounted and the second partition is labelled as RFS (or otherwise adjust the variables in the beginning of the script).

Deploying the Kernel

While in the last step the Android root file system has been exported, the kernel still needs to be placed in the according location on the SD-Card. For this purpose a new “boot” directory on the RFS partition will be created and two relevant files “uImage” & “am335x-boneblack.dtb” will be copied into it.

nx@nx:/android/$ sudo mkdir /media/$USER/RFS/boot
nx@nx:/android/$ sudo cp kernel/kernel/arch/arm/boot/dts/am335x-boneblack.dtb /media/$USER/RFS/boot/
nx@nx:/android/$ sudo cp kernel/kernel/arch/arm/boot/uImage /media/$USER/RFS/boot/

Deploying the u-boot Bootloader

Lastly, if not already done so as shown in the previous steps, deploy the generated files for the bootloader and also download our example uEnv.txt in order to boot Android properly.

nx@nx:/android/$ cp u-boot/MLO /media/$USER/BOOT/
nx@nx:/android/$ cp u-boot/u-boot.img /media/$USER/BOOT/

# if not done so earlier, create the uEnv.txt (or download it)

nx@nx:/android/$ wget
nx@nx:/android/$ cp uEnv.txt /media/$USER/BOOT/

The uEnv.txt file defines a small set of environment variables in order to boot Android properly with the SD-Card formatted as described above.

Booting Android

It is time to boot Android the first time on the Beaglebone Black. While not having configured any of the build files, it is expected to run into troubles the first time booting. However, at this point properly booting into the bootloader, kernel and user space successively, are very helpful to verify basic functionality of the deployment.

Make always sure to sync and umount before you remove the SD-CARD from your host system!

nx@nx:/android/$ sync
nx@nx:/android/$ sudo umount /media/$USER/*

If you haven’t cleared the internal flash of the Beaglebone Black yet then make sure you follow these steps first before proceeding with this article. This step is very important, since otherwise your Angstrom distribution will boot from the internal flash.

Connect the USB-Serial (UART) Adapter with the Beaglebone Black, and start up minicom. See this excellent guide from which explains which connectors are compatible and to which pins to hook them up.

Follow these instructions to set up minicom and connect to the serial command line of the Beaglebone. Once set up, insert the SD-Card into the Beaglebone Black and you should see an output similar to this:

U-Boot 2014.04-dirty (May 18 2014 - 21:18:08)

I2C:   ready
DRAM:  512 MiB
NAND:  0 MiB
*** Warning - readenv() failed, using default environment

Net:   <ethaddr> not set. Validating first E-fuse MAC
cpsw, usb_ether
Hit any key to stop autoboot:  0 
gpio: pin 53 (gpio 53) value is 1
mmc0 is current device
gpio: pin 54 (gpio 54) value is 1
SD/MMC found on device 0
reading uEnv.txt
492 bytes read in 4 ms (120.1 KiB/s)
gpio: pin 55 (gpio 55) value is 1
Loaded environment from uEnv.txt
Importing environment from mmc ...
Checking if uenvcmd is set ...
gpio: pin 56 (gpio 56) value is 1
Running uenvcmd ...
3802728 bytes read in 253 ms (14.3 MiB/s)
31547 bytes read in 39 ms (789.1 KiB/s)
Booting from mmc ...
## Booting kernel from Legacy Image at 82000000 ...
   Image Name:   Linux-3.14.1+
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3802664 Bytes = 3.6 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 88000000
   Booting using the fdt blob at 0x88000000
   Loading Kernel Image ... OK
   Using Device Tree in place at 88000000, end 8800ab3a

Starting kernel ...



Android is now booting, however, the surfaceflinger will crash, since it expects to find an opengl implementation which is not compiled yet. Also no data partition will be found nor mounted. This needs to be corrected. While for a professional setup, these files and changes should always be incorporated in the specific and .

Post Build Configuration

In order to fix this problem, a couple of files and binaries are necessary.

First, build the software opengl renderer.

nx@nx:/android/$ source build/
nx@nx:/android/$ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
nx@nx:/android/$ choosecombo 1 mini_armv7a_neon 3
nx@nx:/android/$ mmm -j16 frameworks/native/opengl/libagl/

# insert the SD-Card into the host

nx@nx:/android/$ sudo mkdir /media/$USER/RFS/system/lib/egl
nx@nx:/android/$ sudo cp out/target/product/armv7-a-neon/system/lib/egl/ /media/$USER/RFS/system/lib/egl
nx@nx:/android/$ sudo chmod 644 /media/$USER/RFS/system/lib/egl/
nx@nx:/android/$ sync

Next, download the fstab.bbb and init.bbb.rc and copy them to the root folder (also adjust modes).

nx@nx:/android/$ wget
nx@nx:/android/$ wget
nx@nx:/android/$ sudo cp fstab.bbb /media/$USER/RFS/
nx@nx:/android/$ sudo cp init.bbb.rc /media/$USER/RFS/
nx@nx:/android/$ sudo chmod 644 /media/$USER/RFS/fstab.bbb
nx@nx:/android/$ sudo chmod 750 /media/$USER/RFS/init.bbb.rc

# dont forget to sync and umount!

nx@nx:/android/$ sync
nx@nx:/android/$ sudo umount /media/$USER/*

Plug your SD-Card back into the Beaglebone Black and hit the reset button.

Android will now boot and you should be able to get visuals on your HDMI screen. Congratulations, you just booted an entirely vanilla master Android / Linux configuration.

8 Replies to “Building and Deploying the Mainline (Vanilla) Android Master Source for the Beaglebone Black”

  1. Hi

    thanks for the nice tutorial…do you think it will work also on Wandboard, using Robert Nelson kernel as base?

  2. Hi guys
    Thanks for the wonderful post. I am trying to follow the steps and when it comes to building android, i am getting an error. I got android 4.4.4_r2 (bleeding edge) and when i build, I get:

    Yacc: aidl <= frameworks/base/tools/aidl/aidl_language_y.y
    prebuilts/misc/linux-x86/bison/bison -d -o out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.cpp frameworks/base/tools/aidl/aidl_language_y.y
    /bin/bash: prebuilts/misc/linux-x86/bison/bison: No such file or directory

    When i look at the file "prebuilts/misc/linux-x86/bison/bison", it is a 32 bit binary . So i am not sure why its picking that version when my host is a 32 bit.

    Here is the environment details:


    Any help is much appreciated,


  3. Thank you for this excellent guide.
    But at the end surfaceflinger still crashed with message “couldn’t find an OpenGL ES implementation” in log.
    system/lib/egl/ is compiled and copied to target.

  4. Following all the steps including openGL, fstab.bbb, init.bbb.rc etc. Inserted the SD card into BBB. Booting reaches to a stage where small “ANDROID” is shown at the left side of the screen.
    But then nothing happens beyond this point.
    Please guide.

    1. Hi Hemant,

      did you resolved the issue?
      if yes, please share how it has been solved.
      We are struct at the same point.


Leave a Reply

Your email address will not be published. Required fields are marked *