Running Android Oreo on Raspberry Pi 3B

4 minute read

Setup Build Environment (Ubuntu 16.04)

Add these two lines to ~/.bashrc

export USE_CCACHE=1
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx6g"

Install required packages:

sudo apt-get install openjdk-8-jdk -y
sudo apt-get install lib32z-dev -y
sudo apt-get install libxml2-utils
sudo apt-get install lib32ncurses5-dev -y
sudo apt-get install python-mako -y

# toolchain for building kernel
sudo apt-get install gcc-arm-linux-gnueabihf -y

Create Swap Partition/File

sudo dd if=/dev/zero of=/opt/swapfile bs=1024 count=20M
sudo mkswap /opt/swapfile
sudo swapon /opt/swapfile

Download Android Source Code

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-8.1.0_r46 --repo-url=https://github.com/fudongbai/git-repo
git clone https://github.com/android-rpi/local_manifests .repo/local_manifests -b oreo
repo sync -c

Be sure clone local_manifests before doing repo sync, because we need to remove duplicated projects.

Build Oreo

prebuilts/misc/linux-x86/ccache/ccache -M 50G
. build/envsetup.sh
lunch rpi3-eng
make -j5

Trouble Shooting

  1. Out of memory error (version 1.3-rc7 ‘Douarn’xxxx) GC overhead limit exceeded Try increasing heap size with java option ‘-Xmx'
    export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx6g"
    jack-admin kill-server && jack-admin start-server
    
  2. Communication error with Jack server (56). Try ‘jack-diagnose’
    sed -i 's/jack.server.max-service=4/jack.server.max-service=1/g' $HOME/.jack-server/config.properties
    
  3. critical error: ext4_create_fs_aux_info: filesystem size too small
fdbai@fdbai-desktop:~/oreo/aosp/device/brcm/rpi3$ git diff
diff --git a/BoardConfig.mk b/BoardConfig.mk
index 2dd9b5c..3a24c24 100644
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -14,7 +14,7 @@ TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
 TARGET_USERIMAGES_USE_EXT4 := true

 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 536870912 # 512M
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 134217728 # 128M
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 268435456 # 256M

 BOARD_FLASH_BLOCK_SIZE := 4096

Build Kernel Image

cd kernel/rpi
ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2709_defconfig kernel/configs/android-base.config kernel/configs/android-base-arm.config kernel/configs/android-recommended.config
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make zImage -j5
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make dtbs

Make sdcard image

Buildroot project using genimage to generate final image that can be flashed into sdcard with dd command or Etcher tool, android-rpi project does not provide a method to make a bootable sdcard image, so, we can make it with genimage tool.

First install genimage and its dependency libconfuse:

sudo apt-get install libconfuse-dev
git clone https://github.com/pengutronix/genimage.git
cd genimage
./autogen.sh && ./configure && make &&sudo make install

Then prepare the needed binaries for booting from sdcard, the files required for sdcard boot are listed in file genimage-raspberrypi3.cfg, copy them to android output:

diff --git a/rpi3.mk b/rpi3.mk
index 0bd8d7d..41ed1c6 100644
--- a/rpi3.mk
+++ b/rpi3.mk
@@ -47,6 +47,9 @@ PRODUCT_COPY_FILES := \
     frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml \
     frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \
     frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
+    kernel/rpi/arch/arm/boot/dts/bcm2710-rpi-3-b.dtb:bcm2710-rpi-3-b.dtb \
+    kernel/rpi/arch/arm/boot/dts/overlays/vc4-kms-v3d.dtbo:fw/overlays/vc4-kms-v3d.dtbo \
+    kernel/rpi/arch/arm/boot/zImage:zImage \
     $(LOCAL_PATH)/manifest.xml:system/vendor/manifest.xml \
     $(LOCAL_PATH)/rpi3_core_hardware.xml:system/etc/permissions/rpi3_core_hardware.xml \
     $(LOCAL_PATH)/init.rpi3.rc:root/init.rpi3.rc \
@@ -58,6 +61,11 @@ PRODUCT_COPY_FILES := \
     $(LOCAL_PATH)/firmware/brcm/brcmfmac43430-sdio.txt:root/lib/firmware/brcm/brcmfmac43430-sdio.txt \
     $(LOCAL_PATH)/firmware/brcm/brcmfmac43455-sdio.bin:root/lib/firmware/brcm/brcmfmac43455-sdio.bin \
     $(LOCAL_PATH)/firmware/brcm/brcmfmac43455-sdio.txt:root/lib/firmware/brcm/brcmfmac43455-sdio.txt \
+    $(LOCAL_PATH)/boot/bootcode.bin:${TARGET_OUT}/fw/bootcode.bin \
+    $(LOCAL_PATH)/boot/cmdline.txt:${TARGET_OUT}/fw/cmdline.txt \
+    $(LOCAL_PATH)/boot/config.txt:${TARGET_OUT}/fw/config.txt \
+    $(LOCAL_PATH)/boot/fixup.dat:${TARGET_OUT}/fw/fixup.dat \
+    $(LOCAL_PATH)/boot/start.elf:${TARGET_OUT}/fw/start.elf \
     $(PRODUCT_COPY_FILES)

 # media configurations

To generate sdcard image, genimage need a config file, this is the config file taken from buildroot project with minor modifications:

diff --git a/genimage.cfg b/genimage.cfg
new file mode 100644
index 0000000..684b10d
--- /dev/null
+++ b/genimage.cfg
@@ -0,0 +1,42 @@
+# SD card image for Raspberry PI 3B+
+#
+image boot.vfat {
+       vfat {
+               files = {
+                       "bcm2710-rpi-3-b.dtb",
+                       "fw/bootcode.bin",
+                       "fw/cmdline.txt",
+                       "fw/config.txt",
+                       "fw/fixup.dat",
+                       "fw/start.elf",
+                       "ramdisk.img",
+                       "zImage",
+               }
+               file overlays/ {
+                       image = "fw/overlays/vc4-kms-v3d.dtbo"
+               }
+       }
+       size = 64M
+}
+
+image rpi3-sdcard.img {
+       hdimage {
+       }
+
+       partition boot {
+               partition-type = 0xC
+               bootable = "true"
+               image = "boot.vfat"
+       }
+
+       partition system {
+               partition-type = 0x83
+               image = "system.img"
+               size = 1024M
+       }
+
+       partition userdata {
+               partition-type = 0x83
+               image = "userdata.img"
+       }
+}

The final step is to pass the above config to genimage to generate the image, through command line or script, here we use script to type less keystroks. And the final image can be found in directory out/target/product/rpi3 named rpi3-sdcard.img:

diff --git a/gen-rpi-sdimg.sh b/gen-rpi-sdimg.sh
new file mode 100755
index 0000000..20a35bb
--- /dev/null
+++ b/gen-rpi-sdimg.sh
@@ -0,0 +1,15 @@
+BOARD_DIR="$(dirname $0)"
+GENIMAGE_CFG="${BOARD_DIR}/genimage.cfg"
+TARGET_OUT="../../../out/target/product/rpi3"
+GENIMAGE_TMP="${TARGET_OUT}/.genimage.tmp"
+
+rm -fr "${GENIMAGE_TMP}"
+
+genimage                           \
+       --rootpath "${TARGET_OUT}/root"     \
+       --tmppath "${GENIMAGE_TMP}"    \
+       --inputpath "${TARGET_OUT}"  \
+       --outputpath "${TARGET_OUT}" \
+       --config "${GENIMAGE_CFG}"
+
+exit $?

Till now, android can boot, but display is not working properly, in the next section we will make it working.

LCD Display

First things first, apply patches listed in Oreo : patch framework source.

I bought a HDMI display with touchscreen support in taobao, here is the specifications:

  • resolution: 800x480
  • interface: HDMI
  • fresh rate: 60Hz
  • aspect ratio: 4:3

According to the Video options, we need to change config.txt as follows:

+# display
 hdmi_force_hotplug=1
 hdmi_drive=2
+hdmi_group=2
+hdmi_mode=87
+hdmi_cvt=800 480 60 1
 config_hdmi_boost=4
-hdmi_group=1
-hdmi_mode=4
 disable_overscan=1
-framebuffer_width=1280
-framebuffer_height=720
+
+# framebuffer_width=1280
+# framebuffer_height=720

Now, flash sdcard image and power up, wait a minute, why the android bootanimation displayed at the bottom right corner, there must be something wrong with the display resolution.

So I took a screenshot with screencap then pull to the host computer, and file says it is 1280x720:

/tmp/rpi3.png: PNG image data, 1280 x 720, 8-bit/color RGBA, non-interlaced

This was set in build.prop named debug.drm.mode.force, which was built into system by PRODUCT_PROPERTY_OVERRIDES in device/brcm/rpi3/rpi3.mk:

 PRODUCT_PROPERTY_OVERRIDES += \
-    debug.drm.mode.force=1280x720 \
     ro.opengles.version=131072 \
     ro.sf.lcd_density=213 \
     wifi.interface=wlan0

References