GitLab CI builds for devices based on halium_arm64 (Halium 9) - ubports/porting-notes GitHub Wiki

Introduction

This page attempts to gather information about one approach for integrating Halium 9+ device ports capable of using generic halium_arm64 systemimage builds with UBports infrastructure for support of OTA updates and UBports Installer.

The process attempts to make builds of the device-specific parts we need to modify, such as kernel/bootimage, in an automated way (by CI) in a Docker container, without relying on the Android/Halium build system. This minimizes the device-specific building work that needs to be done by the porter/infrastructure, but currently requires some manual configuration to produce working images and makes implementation details different from "classical" Halium-based ports.

Difference from GSI builds

See Generic system image (GSI) page for more details of what GSI is in the context of Halium/UBports, as the definition we use is different from Android. The approach described here is based on a similar idea of parts that can be generic and do not need to be compiled per device, which are mainly the base UBports rootfs and the LXC container image stored at /var/lib/lxc/android-rootfs.img (or /userdata/android-rootfs.img). However, as opposed to "pure" GSI builds, it provides a way to include device-specific parts that have to be maintained separately from base images, such as kernel and device-specific configuration overlays. This allows for the devices to be integrated with System-Image server and UBports Installer in a similar way to earlier type of ports.

Adding new devices

Use one of the existing device repos as reference (for example, xiaomi-beryllium) and adapt it to produce device-specific tarball for your device. TODO: create a common repository that can be used as template.

deviceinfo

The format of this file is inspired by the deviceinfo configuration file used by postmarketOS device packages, but does not strictly follow it. It is used to compile the device kernel from source code and produce the bootimage. The bootimage format differs from device to device, so getting correct values requires analyzing the existing boot.img of the stock ROM for a device or checking the values in BoardConfig(Common).mk if device has TWRP or LineageOS ports with publicly available device trees.

Jobs defined in .gitlab-ci.yml

build

This job fetches sources, compiles kernel, assembles boot.img and packs it together with configuration files overlay into device-specific tarball as output. This tarball is supposed to be fetched by System-Image server and provides device-specific parts during OTA update installation by recovery.

The toolchain that will be used to compile kernel is currently hardcoded in build.sh and defaults to GCC 4.9 from AOSP 9.0. It is possible to compile kernel with Clang instead by defining deviceinfo_kernel_clang_compile="true" in deviceinfo file. The compiler and toolchain version that works with particular kernel source code dump from the device vendor or repository of custom ROM developer differs and sometimes has to be guessed experimentally. If the port is based on LineageOS sources, grep for TARGET_KERNEL_CLANG_COMPILE in BoardConfig.mk/BoardConfigCommon.mk in the device/device-common tree to see if it needs to be compiled with Clang.

flashable

This job fetches OTA update files from UBPorts System-image server, and simulates on CI OTA update installation procedure done by UBPorts recovery on device. It generates combined system.img containing UBPorts rootfs, Halium's android-rootfs.img and device overlay that is ready to be flashed to device system partition with fastboot tool. It is inspired by how factory images for PinePhone and Volla Phone are generated so they can receive OTA updates.

Note: as this requires device tarball to be processed by System-image server, it will not work until device is added there, and it may take up to one day for results of "build" stage to end up in devel OTA channel of System-image server, so this stage has to be triggered manually at a later point.

devel-flashable

This job generates flashable images in a similar way to flashable job, but does not depend on OTA server. Instead, it tries to fetch latest android9 rootfs and halium_arm64 systemimage from UBPorts CI, then combines it with result of build job to produce fake OTA package and generate system.img that can be flashed to system partition of device. Compared to result of flashable job, the generated image does not correspond to any OTA channel and is not versioned, so OTA updates may not work properly on it, but it is useful for testing during port development.