09/12/2017 - 11:24

This is a problem that I ran across recently. Building the whole AOSP code base is a big task, and normally you would choose a machine with plenty of RAM. But, sometimes you need to build on a lesser machine. It happened to me when I was on the road and I wanted to run a build on my laptop, which has 8 GiB RAM, and a dual core hyper-threaded Intel i7 CPU. I have used this set up with Marshmallow and earlier versions without problem – it just takes a while, that’s all.


The problem

The problem manifests itself as a failed build after 90 minutes or so with a message similar to this:

[ 45% 16221/35670] Building with Jack:...k_intermediates/with-local/classes.dex
FAILED: /bin/bash out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/with-local/classes.dex.rsp
Out of memory error (version 1.2-rc4 'Carnac' (298900 f95d7bdecfceb327f9d201a1348397ed8a843843 by
GC overhead limit exceeded.
Try increasing heap size with java option '-Xmx'.
Warning: This may have produced partial or corrupted output.
[ 45% 16221/35670] Building with Jack:...colorpicker_intermediates/classes.jack
ninja: build stopped: subcommand failed.
build/core/ recipe for target 'ninja_wrapper' failed
make: *** [ninja_wrapper] Error 1

#### make failed to build some targets (01:26:54 (hh:mm:ss)) ####

The root of the problem is that jack-server (not Jack itself) has run out of heap. So, what is jack-server?

Some background information on Jack and jack-server

Jack is an Android toolchain that compiles Java source into Android dex bytecode. It replaces the previous Android toolchain, which consists of multiple tools, such as javac, ProGuard, jarjar, and dx. Jack is used from Marshmallow onwards.

In Nougat, jack-server was introduced to handle a pool of Jack compiler instances in order to limit memory usage and benefit from already warm instances. Jack-server is written in Java and is run in a Java VM. It is installed into ~/.jack-server when you run the first AOSP build.

The Java heap

AOSP 7 requires OpenJDK 8 to build. I took these measurements using OpenJDK 8, version 1.8.0_131 on Ubuntu 16.04.2:

$ java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-2ubuntu1.16.04.3-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)

Now, let’s look at the default heap size on two different machines. The default heap size scales according to the total amount of memory fitted, ignoring the swap space. On a 16 GiB machine, it is over 3 GiB:

$ java -XshowSettings 2>&1  | grep Heap
    Max. Heap Size (Estimated): 3.47G

But, on an 8 GiB machine, it is less than 2 GiB:

$ java -XshowSettings 2>&1  | grep Heap
    Max. Heap Size (Estimated): 1.71G

It turns out that jack-server needs about 3 GiB to build a typical AOSP Nougat target, and so it fails if the machine doesn’t have enough RAM. Increasing the swap space makes no difference.
Jack-server is launched by a shell script named jack-admin which is in the prebuilts/sdk/tools directory. Digging around a little in there, I found the default arguments for the server (line 29)

JACK_SERVER_VM_ARGUMENTS="${JACK_SERVER_VM_ARGUMENTS:=-Dfile.encoding=UTF-8 -XX:+TieredCompilation}"

Lower down, I found the point that it launches jack-server (line 454)

      echo "Launching Jack server" $JACK_SERVER_COMMAND

That is all I needed to know. Now we can move on to the solution.

The solution

Once I understood the problem, it was just a question of changing the default heap size when jack-server is launched. To fix it, you need to edit
~/.jack-settings, and add this line

JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m"

Then, restart jack-server – otherwise if it is running in the background it will continue to use the old Xmx value:

$ prebuilts/sdk/tools/jack-admin kill-server
$ prebuilts/sdk/tools/jack-admin start-server
Launching Jack server java -XX:MaxJavaStackTraceDepth=-1 -Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m
-cp /home/chris/.jack-server/launcher.jar

Then you can build AOSP 7.x on an 8 GiB machine. The build is not fast – a little less than 3 hours for me - but at least it completes.

For more information about Android and AOSP, you may want to consider one of my in-depth training courses:
Android Porting and Android Internals.

Chris Simmonds, Author, trainer, consultant.

10/05/2016 - 10:36

Chris Simmonds has been working on ports of Android to the BeagleBone Black for several years, since he posted the first tutorial on running JellyBean 4.3.

Now all of that work has been consolidated into the Android4Beagle project. Android4Beagle aims to provide a vanilla Android build, based on AOSP. Currently, builds are available for KitKat, Lollipop and Marshmallow, with Nougat in the works.

10/05/2016 - 10:20

Chris Simmonds will be at the at OpenIoT Summit and Embedded Linux Conference Europe 2016. This year he will be giving two presentations:

He will be posting links to the presentations just as soon as he has finished writing them. Hope to see you there!

03/22/2016 - 11:07

Update: Brillo was abandoned by Google in December 2016 in favour of Android Things

Brillo ( is Google's operating system for devices that are connected to the IoT. They communicate with each other, with the cloud and with mobile apps using a system called Weave ( Brillo and Weave are still under wraps: you have to request an invite from the two links in order to get access to documentation, sample code, and so on. However, there is enough information publicly available to build and test a device running Brillo, which is what this blog is about. I hope to cover Weave in a later post.

Brillo is actually a cut-down version of Android. Basically, all the Java components have been stripped away leaving a much simpler embedded Linux operating system. When building Brillo, some things pop out immediately, which may give a preview of future Android builds:

  • GNU make is out: the build is run by kati/ninja (same for Android N preview)
  • GCC is out: almost all C/C++ components are compiled using clang (same for Android N preview)
  • Linux kernel source is in: the AOSP tree has vendor kernels in hardware/bsp/kernel. The kernel is built using GCC, as it is not (yet) possible to build it with clang
  • DBUS is in: I have not yet found out why
  • Toybox is in: leading to a much more Linux-like command line experience

Below, I show how to build and run the Brillo emulator

Setting up the build system

This is basically the same as building Android from AOSP: the instructions are here I used a fairly old octocore AMD machine with 16 GiB RAM running Ubuntu 14.04.4 64-bit desktop. Note that although Brillo targets do not contain any Java code, the build fails at the very beginning if you don't have OpenJDK 1.7 installed.

Getting the code

The Brillo code was pushed to AOSP in November 2015. I will start by syncing the master branch:

Allow a while for that to complete because it has 34 GiB to download.

Building the emulator

The procedure is basically the same as for any AOSP build:

$ . build/
$ lunch

Select brilloemulator_x86-eng (or, run lunch brilloemulator_x86-eng). Then build it using make, giving the number of CPU cores on the build machine as the -j parameter:

$ make -j8

The first thing you notice is this:

Running kati to generate

Kati is a GNU make clone which converts the many thousands of makefile snippets in an Android build into a single, huge, ninja file:

$ ls -lh out/ 
-rw-rw-r-- 1 chris chris 145M Mar 21 15:27 out/

The main goal, apparently, is to speed-up incremental build of Android. There is some info in the file at To speed up incremental builds, and make them more robust, kati writes the timestamps of all the files and directories to a file, so that it only has to re-read the makefiles if something has changed:

$ ls -lh out/.kati_stamp-brilloemulator_x86 
-rw-rw-r-- 1 chris chris 12M Mar 21 15:27 out/.kati_stamp-brilloemulator_x86 

The ninja file is processed by Ninja, which is a simple build system that builds according to the rules in the input file. See

One nice touch is that when the build gets going, you see a nice progress indicator:

[ 44% 7550/16800] target .......................... 

Towards the end, it builds a kernel:

[ 95% 15960/16800] Building i386 4.4 kernel... 

This is a big deal. This step is optional, in that you can set up the device build files to copy a prebuilt kernel binary as with “old” AOSP builds, but the clear intention is that the kernel source is part of the archive. In hardware/bsp/kernel there are kernels for freescale, imagination, intel, marvell qcom, and rockchip. I just can't exaggerate how pleased I am about this.

Finally, you should see this message :

#### make completed successfully (34:37 (mm:ss)) #### 

The build time is quite a lot shorter than for contemporary Android builds, mostly because there is less to build, but also because of the new build system.

Running the emulator

The emulator a version of QEMU. You start it like this (assuming that you have previously sourced build/ and selected the target via the lunch command):

$ brilloemulator-x86

Before I go on, note that quitting the emulator is, maybe, not obvious. Remember that it is just a copy of QEMU that was started without a graphics screen (-nographic). So, to quit you type Ctrl-A X. That is, you press the Ctrl and A keys together, let go, and then press the X key, and you will see:

QEMU: Terminated 

Using Brillo at the command line feels much more Linux-y than earlier versions of Android, courtesy of Toybox ( Toybox largely replaces the earlier command line tool called Toolbox. Now, commands such as “find”, “which”, and “uname” all work as on regular Linux. Even “ifconfig” works as it should, replacing the oddly crippled version in Toolbox. The shell is still the BSD Korn shell, but a later version. Both adb and logcat work as expected.

The basic directory layout is the same as Android: the init program and init*.rc scripts are in the root, which is an initramfs (ramdisk). The main system files are stored in the read-only system directory, which is much cut-down from Android:

# ls -p /system
bin/ build.prop etc/ lib/ usr/ xbin/

Run-time data storage is in /data, as normal. In here you find:

# ls -p /data
adb/      app-private/  data/       mediadrm/        resource-cache/
anr/      backup/       drm/        misc/            ss/
app/      bootchart/    local/      nativebenchmark/ system/
app-asec/ bugreports    lost+found/ nativetest/      tombstones/ 
app-lib/  dalvik-cache/ media/      property/        user/

There are some Dalvik related directories which I take to be atavistic vestiges from Android, but I could be missing something here, who knows?

Finally, this is the list of processes (with kernel threads removed for brevity):

# ps 
USER      PID   PPID  VSIZE  RSS   WCHAN            PC  NAME 
root      1     0     7820   1820           0 08143195 S /init 
root      981   1     3548   1476           0 0812f640 S /sbin/ueventd 
logd      1254  1     12304  2972           0 b75b1df1 S /system/bin/logd 
dbus      1257  1     6124   3204           0 b738fbd0 S /system/bin/dbus-daemon 
system    1258  1     6400   2024           0 b755bad6 S /system/bin/servicemanager 
shell     1261  1     4864   1720           0 b74bcdf1 S /system/bin/sh 
root      1262  1     7548   1024           0 0811d050 S /sbin/adbd 
keystore  1264  1     9384   4164           0 b714aad6 S /system/bin/keystore 
media     1265  1     32144  11788          0 b70d9ad6 S /system/bin/mediaserver 
system    1266  1     9104   4084           0 b730b8d5 S /system/bin/nativepowerman 
root      1267  1     9208   3860           0 b75498d5 S /system/bin/peripheralman 
root      1268  1     11280  4236           0 b7325ad6 S /system/bin/sensorservice 
wifi      1269  1     10900  4380           0 b7347c55 S /system/bin/wpa_supplicant 
audioserver 1270  1     18608  8568           0 b6af28d5 S /system/bin/brilloaudioservice 
root      1272  1     4864   2432           0 b744fc55 S /system/bin/sh 
metrics_coll 1273  1     11840  5772           0 b70ff8d5 S /system/bin/metrics_collector 
metricsd  1274  1     12804  5808           0 b74ec8d5 S /system/bin/metricsd 
root      1275  1     5408   1828           0 b74d9da1 S /system/xbin/perfprofd 
trunks    1277  1     13268  5112           0 b70938d5 S /system/bin/trunksd 
root      1278  1     15048  7852           0 b71f58d5 S /system/bin/update_engine 
webserv   1280  1     12848  6968           0 b71bf8d5 S /system/bin/webservd 
root      1300  1     13640  8760           0 b72c18d5 S /system/bin/shill 
firewall  1328  1     10524  6628           0 b73aa8d5 S /system/bin/firewalld 
dhcp      1340  1300  6208   1900           0 b75c58d5 S /system/bin/dhcpcd-6.8.2 
system    1342  1     6408   2100           0 b7353bd0 S avahi-daemon: running [linux.local] 
tlsdate   1343  1     6836   3584           0 b72b98d5 S /system/bin/tlsdated 
system    1344  1     16740  8888           0 b6e9b8d5 S /system/bin/weaved 
root      1345  1343  6708   368            0 b72bafa6 S /system/bin/tlsdated 
system    1347  1300  5172   1756           0 b7572c55 S /system/bin/dnsmasq 
root      1352  1261  4864   2476           0 b7580df1 S /system/bin/sh 
root      1370  1352  6208   2268           0 b7538fa6 R ps

Among the daemons you can see running, many are to do with network connectivity: wpa_supplicant, shill, firewalld, dhcpcd-6.8.2, avahi-daemon and dnsmasq. Then there is the Weave protocol manager, weaved, and a web server, webservd. Some components are obviously using binder to communicate: servicemanager and sensorservice, for example. And there is dbus-daemon...

Plainly there is still a lot to learn here. I will be following up with more blogs as time goes by.

02/23/2016 - 11:13

The story of how Linux grew to become a world-class embedded operating system is a fascinating tail of individual endeavour and collective cooperation. See the slides and accompanying paper from Chirs Simmonds' presentation at Embedded World 2016 for the full monty


02/23/2016 - 11:07

Writing device drivers to control new hardware can be hard work. Chris Simmonds, speaking at Embedded World 2016, explains how to take the easy road by writing userspace drivers.

Sample code:

08/14/2015 - 17:46

One of the fundamental questions programmers ask (or at least, they should) is: how much memory is my program using? It may be a simple question, but with a virtual memory operating system like Linux the answer is quite complex. The numbers given by top and ps don't really add up. Procrank is a tool commonly used by Android platform developers to give more accurate answers, but there is no reason why it can't be more widely used in other Linux based operating systems and it is especially useful for embedded Linux.

The code

You can get the code from Github:

There are instructions about building and usage in the README

The theory

The two most common metrics for the memory usage of a process are the virtual set size, Vss, and the resident set size, Rss: you will see see these numbers in ps and top.

Vss, also called VIRT and VSZ is the total amount of virtual memory of the process has mapped, regardless of whether it has been committed to physical memory

Rss, also called RES and RSS, is the amount of physical memory being mapped

The Vss is plainly an overestimate because applications commonly allocate memory they never use. Rss is a better measure, but still an overestimate because it does not take into account pages of memory that are shared between processes. For example, there is only one copy of the C library resident in memory because it is shared between all the processes that link with it yet Rss accounts for it multiple times.

Some years ago, Matt Mackall looked at the problem and added two new metrics called the Unique Set Size, Uss, and the Proportional Set Size, Pss, and modified the kernel to expose the information needed to calculate them, which you will find in /proc/[PID]/smaps.

Uss is unique set size, which is the amount of memory that is private to the process and is not shared with any other

Pss is the proportional set size, which is the amount of memory shared with other processes, divided by the number of processes sharing each page

To over simplify slightly, the diagram below shows three processes and the pages each has mapped into its virtual address space. The pages have been marked as being of type A, B or C where:

  • A = private memory that is mapped to physical pages of RAM. This would include the parts of the stack and heap that are being actively used
  • B = shared memory that is mapped and is shared by one or more other processes, e.g. code in shared libraries
  • C = memory that has been allocated but never touched

And so for each process:

  • Vss = A + B + C
  • Rss = A + B
  • Uss = A
  • Pss = A + B/n where n is the number of processes sharing

Calculating the Pss for the three processes gives:

Pss(1) = 2 + 3/3 + 2/2 = 4
Pss(2) = 2 + 3/3 + 2/2 = 4
Pss(3) = 2 + 3/3 = 3
Sum(Pss) = 11 = total of pages in use

As you can see, Pss gives an accurate measure of the memory a process is using, taking into account sharing between processes. The total amount of memory in use by all processes is the sum or their Pss.

The Uss is also useful because it shows the pages that are unique. You can think of it as the price you would pay in memory if you forked that process to create a copy.

There is a readily available program that shows Uss and Pss called smem, developed by Matt Mackall. The only problem with it is that it requires a Python run-time environment, which is not often available on an embedded Linux device. The Android developers encountered this problem and they wrote procrank as a command-line tool written in C, using the Android BIONIC C library. I have taken that code, made a few minor changes and added a Makefile so it will compile on most GNU/Linux environments, including cross compiling for embedded use.

06/20/2015 - 22:45

Update: This page is out of date. I have put together all of the information on running Android on BeagelBone on the Android4Beagle page

At last, here is Android Lollipop for BeagleBone Black!

Screenshot of BeagleBone running 5.1 Lollipop

This is a "work in progress" so don't expect everything to go smoothly. I have tested this build on a BBB rev A (2 GiB internal eMMC) and a LCD4 cape. Here are some issues that I have found up to now (please report any other odd behaviour you find):

1. The graphics are not accelerated and the screen flickers whenever it is updated
2. The initial boot time is long, expect to wait several minutes
3. The buttons on the LCD4 cape do not work
4. The Ethernet interface is not configured
5. The Linux 3.2 kernel is unreliable if built with the gcc 4.8 toolchain that comes with AOSP 5.x

For those of you who want to build from source, the device configuration files and information about building are at

I have also uploaded a pre-built micro SD card image, which you can get from".

To write it to microSD, plug card of at least 2 GiB capacity into your card reader: it will show up as something like /dev/mmcblk0 or /dev/sdc. Make absolutely sure that you know which it is before continuing because hard drives also show up as /dev/sd* and writing this image to your hard drive will make your computer unbootable!. Assuming that the card reader is mmcblk0, write the image using a command like this:

$ sudo sh -c "unzip -p | dd of=/dev/mmcblk0 bs=4M"

Plug it into your BeagleBone Black and boot it up.

10/05/2014 - 02:55

Once you have ported AOSP to your platform, an obvious next step is to install some apps: maybe Gmail or Angry Birds. Ideally, you would want Google Play Store so that you can select apps from the 100,000's available. But, there is a problem. Play Store, like most of the apps on Play Store, requires Google Mobile Services (GMS) to work. GMS extends the Android framework by adding the libraries, configuration files and applications required to support the extended Google APIs that most developers know simply as Google Services. Most of these components are in the system partition so either they have to be included as part of the base AOSP build or installed as root afterwards. There is also a licensing issue: the components that make up GMS and applications like Gmail, Google Maps and Google Now are proprietary to Google and require a license.

Nevertheless, you can try out GMS and get access to the Google experience. You could extract the necessary components from a running (licensed) Android handset, or from the Nexus factory images. Or you can install one of the community-maintained gapps packages. Below, I am using gapps from

To install gapps on a normal handset you would install a recovery manager, such as ClockWorkMod ROM manager, boot into recovery and use it to load the zip file. There isn't a version of CWM for BeagleBone (yet) but the following method achieves the same effect by using an adb root shell to issue the commands by hand.

Installing gapps

This only works if you have my current BeagleBone Black Android 4.4 KitKat release installed in internal flash or microSD card.

Get gapps for KitKat/4.4 from Then

$ adb push /sdcard/Download
$ adb remount

In an adb shell, issue these commands on the BeagleBone:

# mkdir /system/addon.d
# mount -o remount,rw /
# mkdir /tmp
# updater 1 1 /sdcard/Download/

The script takes a couple of minutes to run. You can ignore messages like

about to run program [/sbin/busybox] with 3 args
run_program: execv failed: No such file or directory
run_program: child exited with status 1

Then reboot, and you will see Google Play and Gmail apps are installed. You can use Play to install any others you need.

BeagleBone with Gapps

What is updater?

The Android updater command reads from a zip file which contains a script and the files to install. It takes three arguments

  • The updater binary API to use, 1, 2, or 3. Usually you want 1
  • A file descriptor to write commands to. Use '1' for standard output
  • The path name of the zip file

The zip file must contain the install script in


The script is written in "edify", the basic syntax of which is described in the AOSP directory bootable/recovery/edify/README

The updater command also understands install scripts written in an older format called "amend". In this case the script file must be named "update-script" (drop the 'r' from updater):


09/15/2014 - 19:34

Update: This page is out of date. I have put together all of the information on running Android on BeagelBone on the Android4Beagle page

I have updated the internal eMMC flash and sdcard images for BeagleBone Black. Most changes are to make U-Boot work better with fastboot, especially to make it possible to enter fastboot without having to type "fastboot" at a U-Boot prompt and so avoid the need to have a serial cable. Also, I have increased the sizes of the system and userdata partitions so that you can install more apps. I am still using Android KitKat 4.4.4 and TI Linux 3.2 kernel with SGX accelerated graphics libraries.

Improvements to eMMc

  • Added sparse image format to U-Boot, see for a detailed description
  • Made U-Boot default to fastboot if autoboot fails
  • Turn on user LED 0 when in fastboot mode
  • Added code to Linux to make "adb reboot bootloader" work
  • Increased system partition from 256 MiB to 512 MiB
  • Increased userdata partition from 256 MiB to 1047 MiB

Improvements for SD card

  • Increased system partition from 256 MiB to 512 MiB
  • Increased userdata partition from 256 MiB to 2560 MiB

Installing Android on internal eMMC flash

You will need

  • A BeagelBone Black rev A/B/C
  • A micro SD card of any capacity since you are only going to use the first 70 MiB to write a small flasher image
  • The mini USB to USB A cable supplied with the BeagleBone
  • A 5V power supply because the current used when writing to the eMMC chip may exceed that supplied by a typical USB port. See this page for examples:
1. Get and unzip it
(If you want to build from scratch, follow the instructions in at
2. Plug the microSD card into your card reader: it will show up as something like /dev/mmcblk0 or /dev/sdc. Make absolutely sure that you know which it is before continuing because hard drives also show up as /dev/sd* and writing this image to your hard drive will make your computer unbootable!. Unmount all partitions that have been automounted on the card. Next, assuming that the card reader is mmcblk0, write the image using a command like this:
$ sudo sh -c "unzip -p | dd of=/dev/mmcblk0 bs=1M"

3. With no power on the BeagleBone, insert the microSD card
4. BeagleBone Black in fastboot modePress and hold the 'Boot button' on the BeagleBone, power up the board using the external 5V power connector and release the button after the fastboot LED lights up
5. Plug in the USB cable between the mini USB port on the BeagleBone and the PC. Then, using the fastboot command from the Android SDK or an AOSP build, check that the BeagleBone has been detected by typing (on the PC)
$ fastboot devices
90:59:af:5e:94:81	fastboot

6. If instead you see
$ fastboot devices
no permissions	fastboot

Add this line to /etc/udev/rules.d/51-android.rules

SUBSYSTEM =="usb", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="d022" , MODE="0666"

Then unplug the mini USB cable and plug it back in again. Check that the permissions problem has gone away.

7. Use fastboot to format the eMMC chip and then flash the images
$ fastboot oem format
$ fastboot flash spl MLO
$ fastboot flash bootloader u-boot.img
$ fastboot flash boot boot.img
$ fastboot flash system system.img
$ fastboot flash userdata userdata.img
$ fastboot flash cache cache.img

8. Power off the board and remove the SD card
9. Power on again. Your BeagleBone will boot into Android!

Installing Android on sdcard

You will need

  • A BeagelBone Black rev A/B/C
  • A micro SD card of at least 4 GiB
  • The mini USB to USB A cable supplied with the BeagleBone
1. Get the pre-built image from
(If you want to build from scratch, follow the instructions in at
2. Plug the SD card into your card reader: it will show up as something like /dev/mmcblk0 or /dev/sdc. Make absolutely sure that you know which it is before continuing because hard drives also show up as /dev/sd* and writing this image to your hard drive will make your computer unbootable!. Assuming that the card reader is mmcblk0, write the image using a command like this:
$ sudo sh -c "unzip -p | dd of=/dev/mmcblk0 bs=4M"

3. With no power on the BeagleBone, insert the microSD card
4. Press and hold the 'Boot button' while powering up by plugging in the mini USB cable. After a minute or so it should boot into Android