Android 10 on Raspberry Pi 4

J-P Nurmi
4 min readJul 28, 2020

--

I recently came across the android-rpi project and immediately thought it would be an interesting platform for running Flutter on Raspberry Pi 4. This article walks through the entire process from cloning the android-rpi repositories to building and flashing the images.

Settings app — About screen

Download

The exercise begins with a (massive) download of Android, which is then extended with android-rpi/local_manifests.

Tip: passing --depth=1 to repo init helps to save some time and bandwidth, and passing --verbose to repo sync provides a lot more progress information. Furthermore, -j1 limits syncing to one parallel job at a time might be useful if your connection is not blazing fast.

$ repo init -u https://android.googlesource.com/platform/manifest \
-b android-10.0.0_r40 --depth=1
$ git clone https://github.com/android-rpi/local_manifests \
.repo/local_manifests -b arpi-10
$ repo sync -j1 --verbose

Note: The sync takes a good while even on faster connections.

Prepare

The android-rpi image uses Android TV as a base image, which provides a good starting point for a non-mobile device. Therefore, by default the image contains the TvSettings app, which is handy for connecting your Raspberry Pi to a WiFi, so that you will be able to connect to it with ADB. In order to be able to press enter in the WiFi password dialog, however, a simple change must be applied to packages/apps/TvSettings:

diff --git a/Settings/res/layout/setup_password_item.xml b/Settings/res/layout/setup_password_item.xml
index 6495148..75270cc 100644
--- a/Settings/res/layout/setup_password_item.xml
+++ b/Settings/res/layout/setup_password_item.xml
@@ -32,7 +32,7 @@
android:paddingEnd="@dimen/setup_list_item_padding"
android:paddingStart="@dimen/setup_list_item_padding">
- <EditText
+ <androidx.leanback.widget.GuidedActionEditText
android:id="@+id/guidedactions_item_title"
style="@style/Setup.Action.TextInput"
android:layout_width="match_parent"
@@ -40,8 +40,7 @@
android:focusable="true"
android:gravity="center_vertical"
android:imeOptions="actionNext|flagNoExtractUi"
- android:inputType="text">
- </EditText>
+ android:inputType="text" />
</FrameLayout>
<CheckBox

P.S. If you need video decoding, apply also the other patch at android-rpi wiki.

Before we rush to build the image, it is worth noting that at this point you could tweak many settings in device/arpi/rpi4/rpi4.mk. For example, the screen resolution is set to 1280x720 by default, whereas I have a screen with a resolution of 1024x600, so I changed:

diff --git a/rpi4.mk b/rpi4.mk
index 8b22b39..93f5e37 100644
--- a/rpi4.mk
+++ b/rpi4.mk
@@ -26,7 +26,7 @@ PRODUCT_MODEL := Raspberry Pi 4
include frameworks/native/build/tablet-7in-hdpi-1024-dalvik-heap.mk
PRODUCT_PROPERTY_OVERRIDES += \
- debug.drm.mode.force=1280x720 \
+ debug.drm.mode.force=1024x600 \
gralloc.drm.device=/dev/dri/card0 \
gralloc.drm.kms=/dev/dri/card1 \
ro.opengles.version=196609 \

In the same file, you can also add additional application packages to be built and installed on the image. rpi4.mk lists these:

# application packages
PRODUCT_PACKAGES += \
DeskClock \
RpLauncher

The RpLauncher application is a simplified version of the AOSP Launcher and looks like this:

RpLauncher

The rest, such as the TV Settings application, come from the base image (device/google/atv/products/atv_base.mk).

Build

A non-exhaustive list off development packages required for the build:

sudo apt install gcc-arm-linux-gnueabihf libssl-dev \
python3 make bison flex

Build Kernel:

$ cd kernel/arpi
$ ARCH=arm scripts/kconfig/merge_config.sh \
arch/arm/configs/bcm2711_defconfig \
kernel/configs/android-base.config \
kernel/configs/android-recommended.config
$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make zImage
$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make dtbs
$ cd -

Build Android (adjust -j8 for the amount of parallel jobs):

$ source build/envsetup.sh
$ lunch rpi4-eng
$ make -j8 ramdisk systemimage vendorimage

Flash

Once the build finishes, the last remaining step is to prepare the SD card and flash the images. The partitions (device/arpi/rpi4/BoardConfig.mk) should be:

  • p1: 128MB for boot (fat32, boot & lba)
  • p2: 768MB for /system
  • p3: 128MB for /vendor
  • p4: remainings for /data (ext4)

You can use fdisk or parted from command line, or GParted if you prefer a GUI. Nevertheless, the result should look something like:

SD card partitions

The file system type of partitions p2 and p3 doesn’t matter, as the partitions will be overwritten by the following commands:

$ cd out/target/product/rpi4
$ sudo dd if=system.img of=/dev/mmcblk0p2 bs=1M
$ sudo dd if=vendor.img of=/dev/mmcblk0p3 bs=1M
$ cd -

Notice that the exact output path is system specific. You can use lsblkto find out yours.

Finally, we need to populate the boot partition. While you have the SD card inserted, you could, for example, open the boot partition in a file manager to (presumably) auto-mount it. Mine got mounted as /media/jpnurmi/BOOT, so I populated the boot partition with the following commands:

cp device/arpi/rpi4/boot/* \
kernel/arpi/arch/arm/boot/zImage \
kernel/arpi/arch/arm/boot/dts/bcm2711-rpi-4-b.dtb \
out/target/product/rpi4/ramdisk.img /media/jpnurmi/BOOT
mkdir /media/jpnurmi/BOOT/overlayscp kernel/arpi/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4.dtbo \
/media/jpnurmi/BOOT/overlays/

That’s it! Remember to hit the eject button, insert the SD card into your Raspberry Pi, and power it up!

Android 10 on Raspberry Pi 4

--

--