Ubuntu Touch for Treble devices with AIDL-era vendor stacks (Android 12+), redesigned to keep stock boot components untouched.
Build and release images from vendor-version branches (android-12.0 … android-16.0). The main branch is documentation-only.
| Branch | Target vendor Android | TrebleDroid release | PHH variant |
|---|---|---|---|
android-12.0 |
12 | v416 (phhusson) |
squeak-arm64-ab-vanilla |
android-13.0 |
13 | ci-20230905 |
td-arm64-ab-vanilla |
android-14.0 |
14 | ci-20240508 |
td-arm64-ab-vanilla |
android-15.0 |
15 | ci-20250415 |
td-arm64-ab-vanilla |
android-16.0 |
16 | ci-20250617 |
td-arm64-vanilla |
For HEADWOLF F8 (MT6897), try android-15.0 first if the device was upgraded from Android 15→16 and Android 16 GSI bootloops. Use android-16.0 when vendor/GSI major versions match cleanly.
TrebleDroid references: treble_experimentations releases, device_phh_treble.
- Keep stock
boot.imguntouched. - Keep stock kernel untouched.
- Flash only:
android-XX_system.img(versioned system image)vbmeta-disabled.imguserdata.img(seeds/data/ubuntu-gsi/rootfs.erofs)
- Do not flash
boot,vendor_boot,dtbo, orvendor.
Android boots normally, then launches Ubuntu userspace late in boot:
- Stock bootloader + stock kernel + stock ramdisk init (PID 1)
- PHH-based
/systemboots Android framework + vendor HAL services /system/etc/init/ubuntu-gsi.rcstartsubuntu-gsi-launcher- Launcher mounts
rootfs.erofs, builds overlay on/data/uhl_overlay, thenchroots into Ubuntu systemd - Lomiri/Mir starts from inside the Ubuntu chroot
Authoritative design doc: docs/halium-architecture.md
halium/etc/init/ubuntu-gsi.rcAndroid init service definitionsbin/ubuntu-gsi-launcherchroot pivot driverbin/ubuntu-gsi-stop-android-uiSurfaceFlinger hand-off helpercompat/PHH/TrebleDroid-style compatibility enginelomiri/start-lomiri.shLomiri startup (indicators, secrets, app-net watchdog)
scripts/fetch_phh_gsi.shPHH base download/preparebuild_rootfs.shUbuntu chroot rootfs buildbuild_rootfs_erofs.shrootfs -> erofs packbuild_vbmeta_disabled.shdisabled vbmeta buildbuild_system_img.shPHH base + Halium overlay mergebuild_userdata_img.shuserdata seed (/data/ubuntu-gsi/rootfs.erofs)fetch_openstore_clicks.shCore Apps click download (rootfs/clicks.core-apps.list)flash.shflashessystem + vbmeta + userdata(selective flags available)
rootfs/overlay/usr/lib/ubuntu-gsi/- WiFi reclaim / app DNS+routing (
wifi-bringup.sh,halium-app-net.sh) - HAL / display bring-up helpers
- WiFi reclaim / app DNS+routing (
deprecated/- legacy pre-Halium components kept for reference
sudo apt install \
debootstrap qemu-user-static e2fsprogs erofs-utils f2fs-tools jq wget unzip \
android-sdk-libsparse-utils android-tools-fastboot python3avbtool is recommended for production vbmeta-disabled.img generation.
git clone --recursive https://github.com/zerofrip/Ubuntu_Touch_AIDL_GSI.git
cd Ubuntu_Touch_AIDL_GSI
git checkout android-16.0 # pick branch matching your vendor Android version
make build-minimalPipeline:
- device_phh sync -> PHH fetch -> rootfs build -> erofs pack -> vbmeta-disabled -> system image compose -> userdata -> release packaging
Release artifacts under builder/out/:
android-XX_system.img(e.g.android-16.0_system.img)userdata.imgvbmeta-disabled.imglinux_rootfs.erofs(intermediate)
main is documentation-first for day-to-day commits, but Actions → Build Ubuntu GSI → Run workflow on main builds all vendor majors:
android-12.0_system.img…android-16.0_system.img(PHH/TrebleDroid base differs per version)userdata.imgandvbmeta-disabled.imgonce each (shared; not vendor-specific)- Optional release tag input attaches those assets to a GitHub Release as
android-XX_system.img.xz(xz-compressed; decompress before flash) plus shareduserdata.img/vbmeta-disabled.img. Raw uncompressed system images remain on the workflow artifacts tab.
For a single-version local/CI build, checkout the matching android-* branch instead.
make flashor manually (local builder/out/ images):
fastboot flash vbmeta_a builder/out/vbmeta-disabled.img
fastboot flash vbmeta_system_a builder/out/vbmeta-disabled.img
fastboot flash vbmeta_vendor_a builder/out/vbmeta-disabled.img
fastboot reboot fastboot
fastboot flash system_a builder/out/android-16.0_system.img
fastboot flash userdata builder/out/userdata.img
fastboot rebootGitHub Release assets ship android-XX_system.img.xz — decompress first:
xz -dk android-16.0_system.img.xz
fastboot flash system_a android-16.0_system.imgDo not pass --disable-verity / --disable-verification to fastboot when flashing
standalone vbmeta*.img files. On fastboot 34+, that flag path fails with
Failed to find AVB_MAGIC at offset: 0. Verity is disabled by baking flags=3
into vbmeta-disabled.img at build time.
make flash includes userdata (wipes /data). Use that on first install.
For everyday system updates that keep existing /data/ubuntu-gsi, skip userdata:
make flash-system
make flash-vbmeta
bash scripts/flash.sh --no-userdataFull flash guide: docs/flash_quickstart.md.
Enable Ubuntu launcher (default is auto-on from init rules):
adb shell setprop persist.ubuntu_gsi.enable 1Disable launcher and boot Android-only userspace:
adb shell setprop persist.ubuntu_gsi.enable 0
adb rebootThe compatibility layer is inspired by:
Main files:
halium/compat/quirks.jsonhalium/compat/compat-engine.shhalium/compat/prop-handler.shhalium/compat/lib/detect-platform.sh
Engine supports mode-aware execution (android, linux, both) for per-action filtering.
Per-branch settings live in vendor/android-XX.Y.env and are loaded automatically from the git branch name (or VENDOR_ANDROID_VERSION).
Example (vendor/android-16.0.env):
PHH_GSI_REPO=TrebleDroid/treble_experimentationsPHH_GSI_VERSION=ci-20250617PHH_GSI_VARIANT=td-arm64-vanillaRELEASE_SYSTEM_IMG=android-16.0_system.img
Supported PHH variants: arm64-ab*, td-arm64-ab-vanilla, and td-arm64-vanilla (Android 16).
Override in vendor/*.env or via environment variables if your target requires a different base.
Local source build mode:
- Set
PHH_GSI_SOURCE=custom - Set
TREBLE_EXP_PATHto your localtreble_experimentationscheckout - Optionally set
PHH_CUSTOM_TARGETandPHH_CUSTOM_VARIANT - Run
make phh-custom(ormake build)
Smaller preset shortcut:
make phh-custom-minimal- Equivalent to
PHH_CUSTOM_TARGET=android-15.0+PHH_CUSTOM_VARIANT=td-arm64-ab-vanilla
Ultra-light rootfs preset:
make build-minimal- Uses
GSI_ROOTFS_PROFILE=minimalandrootfs/packages.minimal.list - Also applies aggressive rootfs pruning by default in minimal mode
Core Apps (OpenStore clicks):
- Listed in
rootfs/clicks.core-apps.list - Fetched during
build_rootfsintobuilder/cache/openstore-clicks/(ormake fetch-clicks) - Unpacked into rootfs at
/opt/click.ubuntu.com/with.desktopentries for the Lomiri app drawer - Skip network fetch with
GSI_SKIP_CLICK_FETCH=1(uses existing cache only)
Rootfs persistence/self-heal:
- Launcher keeps runtime rootfs in
/data/ubuntu-gsi/rootfs.erofs - Backup copy is kept at
/data/ubuntu-gsi/rootfs.erofs.bak - SHA-256 is verified at boot; missing/corrupt data copy is auto-restored
- Restore source is system seed
/system/usr/share/ubuntu-gsi/rootfs.erofs ROOTFS_SEED_IN_SYSTEM=0keepssystem.imgsmaller, but removes reset-time seed restore
From the Actions tab, run Build Ubuntu GSI on branch main (workflow_dispatch).
That produces every android-XX_system.img plus one shared userdata.img and
vbmeta-disabled.img. Set the optional tag input to publish a GitHub Release
(*.img.xz for system images so all majors fit under the 2GB asset limit).
docs/halium-architecture.md— authoritative Halium designdocs/flash_quickstart.md— flash / userdata policydocs/boot_flow.md/docs/system_layout.md— boot and layoutdocs/hal-bridge-matrix.md— HAL bring-up matrixdocs/lower-layer-display.md— lower-layer / DRM display mode
- Legacy docs/scripts that mention
linux_rootfs.squashfs, squashfs userdata pivot, or binder bridge daemons are historical. Currentuserdata.imgonly seeds/data/ubuntu-gsi/rootfs.erofs. - See
docs/halium-architecture.mdfor current behavior.