Skip to content

Android 16 Developer Guide

Introduction

This page describes how to build and deploy Android 16 on the VAR-SOM-AM62P. It is based on TI's Android 16 SDK 11.00.01 release.

For additional details about this release, refer to the Release Notes.

For TI's reference documentation, see TI's Processor SDK Android 11.00.01.

Overview

The objective of this document is to guide VAR-SOM-AM62P Android developers to obtain the Android sources, set up the host environment, build, and deploy.

This document contains instructions for:

  • Hardware and software requirements.
  • Setting up the toolchain.
  • Downloading & building the sources.
  • Installing the binaries on the VAR-SOM-AM62P SOM and variants.
  • Making changes to the kernel/configuration and updating the VAR-SOM-AM62P SOM and variants.

Hardware Requirements

You will need the Variscite VAR-SOM-AM62P based evaluation kit.

Host (PC) Setup Requirements

The host development environment for Android is based on Ubuntu, please install one of the following Ubuntu versions:

If you are running Linux in a virtual machine you need at least 16 GB of RAM and 32 GB of swap. The build process requires ~250 GB of free SSD storage. Before starting a build, make sure you have adequate free space available.

NOTE: Avoid using Ubuntu releases other than those recommended above.

Variscite offers Docker containers as an alternative for a development environment, which can be used instead of a virtual machine or a dedicated computer. To learn more, see Variscite's Docker Build Environment guide. Windows with WSL/WSL2 is not supported for Android BSP.

Install required packages on the host PC

Follow the package list from Google's Establishing a Build Environment. In addition, install the packages required by Variscite's helper scripts and the TI build:

sudo apt -y install gnupg flex bison gperf build-essential gcc-multilib g++-multilib
sudo apt -y install python3-pyelftools python3-dev python-is-python3
sudo apt -y install libc6-dev-i386 libncurses5-dev lib32z-dev libz-dev liblz-dev liblzo2-2 liblzo2-dev lzop lz4 cpio
sudo apt -y install libgl1-mesa-dev libxml2-utils xsltproc unzip bc libssl-dev ccache curl
sudo apt -y install git zip swig mtools uuid uuid-dev zlib1g-dev u-boot-tools lib32z1-dev fontconfig
sudo apt -y install mtd-utils device-tree-compiler gdisk m4 dwarves libgnutls28-dev libelf-dev x11proto-core-dev libx11-dev
sudo apt -y install android-sdk-libsparse-utils

Install additional bootloader and OP-TEE build dependencies

Bootloader build pulls in a few host packages and Python modules beyond the AOSP set above:

sudo apt -y install python3-pip wget
pip3 install pycryptodome shyaml --user

For OP-TEE OS, install the host prerequisites listed upstream at OP-TEE Prerequisites.

Configure Git

git config --global user.name "Your Name"
git config --global user.email "Your Email"

Obtain Source Code

Variscite's Linux kernel and U-Boot are available through GitHub. Required patches for the Android file system are pre-installed.

Download Google Repo Tool

mkdir -p ~/bin
curl -o ~/bin/repo https://commondatastorage.googleapis.com/git-repo-downloads/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH

Clone Variscite's Bootloader, Kernel and AOSP Sources

mkdir ~/var_aosp_ti-16_11_00_01 && cd $_
export YOUR_PATH=$PWD
mkdir -p ${YOUR_PATH}/ti-bootloader-aosp/ && cd $_
repo init -u https://github.com/varigit/variscite-bsp-platform.git -b refs/tags/am62p-android-16_11.00.01-v1.0 -m releases/var_RLS_11_00_01_Bootloader.xml
repo sync -j$(nproc)
mkdir -p ${YOUR_PATH}/ti-kernel-aosp/ && cd $_
repo init -u https://github.com/varigit/variscite-bsp-platform.git -b refs/tags/am62p-android-16_11.00.01-v1.0 -m releases/var_RLS_11_00_01_Kernel.xml
repo sync -j$(nproc)
mkdir -p ${YOUR_PATH}/ti-aosp-16 && cd $_
repo init -u https://github.com/varigit/variscite-bsp-platform.git -b refs/tags/am62p-android-16_11.00.01-v1.0 -m releases/var_RLS_11_00_01.xml
repo sync -j$(nproc)

Apply Variscite's platform patches and install toolchains

cd ${YOUR_PATH}/ti-aosp-16/device
variscite/scripts/install.sh

Build Bootloader Components

TI's Android 11.00.01 SDK consolidates the bootloader build (ATF, OP-TEE, R5 SPL, A53 U-Boot) into helper scripts under ti-bootloader-aosp/build/. Each board is described by a YAML config in build/config/boards/. Create build/config/boards/am62p-var-som-symphony.yaml with the following contents, which select the Variscite defconfigs:

plat: k3

tiboot3:
  defconfig: am62px_var_som_r5_defconfig
  soc: am62px-var-som

tispl:
  defconfig: am62px_var_som_a53_defconfig
  defconfig_fragments: am62px_a53_android.config
  soc: am62px

spd: opteed

target_board: lite

ti_lpm: true

optee:
  flags: CFG_ARM64_core=y
  optee_ta_path: vendor/ti/am62x/optee/ta
  plat: k3-am62x
  rpmb: false

android:
  binaries_path: vendor/variscite/am62x/bootloader/2025.01/am62p-var-som-symphony

secure:
  gp: false
  hsfs: true

Build and stage the bootloader prebuilts

The recommended flow is release_android.sh, which builds every board config (or a single one with --config), produces both the debug and release mode artifacts, and copies them into the AOSP tree at the android.binaries_path from the YAML. This directory is not present in a fresh checkout — create it before the first build.

mkdir -p ${YOUR_PATH}/ti-aosp-16/vendor/variscite/am62x/bootloader/2025.01/am62p-var-som-symphony
cd ${YOUR_PATH}/ti-bootloader-aosp/
./build/release_android.sh \
    --aosp=${YOUR_PATH}/ti-aosp-16 \
    --config=build/config/boards/am62p-var-som-symphony.yaml

This stages the following files into ti-aosp-16/vendor/variscite/am62x/bootloader/2025.01/am62p-var-som-symphony/, keeping the mode suffix in the filename (the AOSP BoardConfig.mk picks the right mode based on the Android build variant — debug for userdebug, release for user):

  • tiboot3-<mode>-hsfs.bin — R5 SPL for HS-FS SoC
  • tispl-<mode>.bin — A53 SPL (TF-A + OP-TEE + U-Boot SPL)
  • u-boot-<mode>.img — A53 U-Boot proper

To build the artifacts only — without staging them into AOSP — run build_all.sh directly. It writes to out/am62p-var-som-symphony/<mode>/ (default release):

./build/build_all.sh --config=build/config/boards/am62p-var-som-symphony.yaml --mode=debug

Build the Kernel

The kernel follows the GKI model and is built with Bazel, separately from AOSP. The compiled artefacts are deposited in the AOSP tree under device/variscite/am62p-var-som-kernel/kernel/6.12.23, where the AOSP build picks them up. This directory is not present in a fresh checkout — create it before the first build.

mkdir -p ${YOUR_PATH}/ti-aosp-16/device/variscite/am62p-var-som-kernel/kernel/6.12.23
cd ${YOUR_PATH}/ti-kernel-aosp/
export DIST_DIR=${YOUR_PATH}/ti-aosp-16/device/variscite/am62p-var-som-kernel/kernel/6.12.23
./tools/bazel run --config=ti //private/devices/ti/am6x:ti_dist -- --destdir=$DIST_DIR

If your home directory is on Btrfs, append --workaround_btrfs_b292212788 to the Bazel command.

Note: the Bazel-driven build is not a standard kernel build. Refer to Google's Generic Kernel Image documentation for details.

Re-build the kernel quickly after small changes

./tools/bazel run --config=ti --config=fast //private/devices/ti/am6x:ti_dist -- --destdir=$DIST_DIR

Build the Android Images

cd ${YOUR_PATH}/ti-aosp-16
source build/envsetup.sh
lunch am62p_var_som-bp2a-userdebug

or

lunch am62p_var_som-bp2a-user

A userdebug build creates a debuggable version of Android. A user build creates a production version of Android.

Switching between eMMC and SD card builds

  • For eMMC boot (the default):
m -j$(nproc) 2>&1 | tee build-emmc.log
  • For SD boot:
m TARGET_SDCARD_BOOT=true -j$(nproc) 2>&1 | tee build-sd.log

Images created by the Android build

The resulting images are located in out/target/product/am62p_var_som.

Image Description
tiboot3-am62p-var-som-symphony-hsfs.bin
tispl-am62p-var-som-symphony.bin
u-boot-am62p-var-som-symphony.img
Bootloader stages (R5 SPL, A53 SPL, U-Boot).
bootloader-am62p-var-som-symphony.img tispl.bin + u-boot.img, generated by the flash scripts.
boot.img GKI kernel image. Since Android 13 the generic ramdisk lives in init_boot.img, not here.
init_boot.img Generic ramdisk (separated from boot.img since Android 13).
vendor_boot.img Vendor modules and vendor ramdisk.
dtb.img Device-tree blobs.
dtbo.img Device-tree overlays (dtbo-unsigned.img when AVB is disabled).
vbmeta.img AVB metadata.
vbmeta_vendor_dlkm.img AVB info for vendor_dlkm.
vbmeta_system_dlkm.img AVB info for system_dlkm.
super.img Super image (system, vendor, product, system_dlkm, vendor_dlkm).
metadata.img Metadata partition.
persist.img Used for OP-TEE secure storage.
userdata.img Empty userdata filesystem image.

Download the release package

The Variscite Android release package:

What is inside the release package

Extracting the .tar.zst gives an android-artifacts/ folder:

android-artifacts/
├── android/
└── scripts/
  • android/ holds the flashable images (boot.img, vendor_boot.img, init_boot.img, super.img, vbmeta*.img, dtbo.img, bootloader-am62p-var-som-symphony.img, ...), the host-side flashall.sh fastboot installer, and the SPDX sbom.spdx.json Software Bill of Materials.
  • scripts/ holds the on-target installer am6_install_android.sh.

super.img is staged in raw (non-sparse) form so it can be written directly to the eMMC super partition.

Install Android

With the SOM booted into a Linux shell, download the release package, extract it, and run the installer to flash the eMMC.

  1. Download the release package on the SOM:
wget https://variscite-public.nyc3.cdn.digitaloceanspaces.com/VAR-SOM-AM62P/Software/android/am62p-android-16_11.00.01-v1.0.tar.zst
  1. Extract it:
tar --use-compress-program=unzstd -xf android-artifacts-am62p-var-som-symphony-userdebug.tar.zst
cd android-artifacts
  1. Run the installer:
./scripts/am6_install_android.sh

am6_install_android.sh detects the bundled android/ directory next to scripts/ and flashes those images directly. Add -u when AVB was disabled at build time, so the installer flashes dtbo-unsigned.img.

Boot options

Boot options for Android:

  1. U-Boot boots from the on-SOM eMMC.
  2. Directly from SD card (requires a separate AOSP build with TARGET_SDCARD_BOOT=true).

Flash and boot Android from SD card

Create a bootable SD card

cd ${YOUR_PATH}/ti-aosp-16
sudo ./device/variscite/scripts/sh/var-mksdcard.sh /dev/sdX; sync

Replace /dev/sdX with your actual device. You can identify it with dmesg.

Boot from SD card

Make sure the BOOT SELECT DIP switch on the carrier board is set correctly before powering the board:

SW3
0 : Boot from SD card
1 : Boot from eMMC

Flash and boot Android from eMMC

Use the Variscite flashall.sh. Do not use stock fastboot flashall — U-Boot fastbootd leaves the super sub-partitions (vendor_dlkm, system_dlkm) zero-length and the board fails to boot.

Install host tools:

sudo apt-get install android-tools-adb android-tools-fastboot

Power the board, interrupt U-Boot, and enter fastboot:

=> fastboot usb 0

Run the installer from the product output:

cd ${YOUR_PATH}/ti-aosp-16/out/target/product/am62p_var_som
sudo ./flashall.sh
sudo fastboot reboot

Flags:

  • --bootloader — flash only tiboot3 + bootloader (tispl + u-boot).
  • --disable-avb — flash vbmeta* with verity/verification disabled.
  • --sdcard /dev/sdX — write a bootstrap SD card (tiboot3 + tispl + u-boot) for a SOM that cannot reach fastboot from eMMC; the script then prints the U-Boot commands to prepare eMMC and continues with fastboot once you confirm.

Update Android firmware

Generate OTA packages
cd ${YOUR_PATH}/ti-aosp-16
source build/envsetup.sh
lunch am62p_var_som-bp2a-userdebug
m -j$(nproc) otapackage
Install OTA package on the device
  • Extract payload.bin and payload_properties.txt from the OTA zip file.
  • Push payload.bin to the board's /data/ota_package/ directory:
adb push payload.bin /data/ota_package/
  • Open payload_properties.txt in an editor and copy its content. For example:
FILE_HASH=wuBhu49k3pCmQmMl8S/n2NRm1he3A+IHshcQiOfCKc4=
FILE_SIZE=501067958
METADATA_HASH=qPWe72T37KgJtyJhuKSlNkFm1NflKFnLy+An4GnoXyA=
METADATA_SIZE=31967
  • On the board's console, run:
su
setenforce 0
update_engine_client --payload=file:///data/ota_package/payload.bin --update --headers="FILE_HASH=wuBhu49k3pCmQmMl8S/n2NRm1he3A+IHshcQiOfCKc4=
FILE_SIZE=501067958
METADATA_HASH=qPWe72T37KgJtyJhuKSlNkFm1NflKFnLy+An4GnoXyA=
METADATA_SIZE=31967"

The --headers value must match the exact contents of payload_properties.txt without trailing spaces or carriage returns.

After issuing the command, the device shows no immediate output. Monitor progress via logcat:

logcat | grep update_engine

After a successful update, reboot into the updated _a/_b slot.

Manual operations

Build boot.img

When you change the kernel, you may build boot.img alone instead of rebuilding the whole Android tree.

cd ${YOUR_PATH}/ti-kernel-aosp/
export DIST_DIR=${YOUR_PATH}/ti-aosp-16/device/variscite/am62p-var-som-kernel/kernel/6.12.23
./tools/bazel run --config=ti --lto=full //private/devices/ti/am6x:ti_dist -- --destdir=$DIST_DIR
cd ${YOUR_PATH}/ti-aosp-16
lunch am62p_var_som-bp2a-userdebug
m bootimage
cd ${YOUR_PATH}/ti-kernel-aosp/
./tools/bazel run --config=ti //private/devices/ti/am6x:ti_config -- menuconfig

Porting Drivers Notes

The TI K3 kernel uses the GKI model with two trees under ${YOUR_PATH}/ti-kernel-aosp/: common/ (Google's GKI base — do not modify) and ti-linux-kernel/ (the TI device kernel — add drivers here). private/devices/ti/am6x/BUILD.bazel builds ti-linux-kernel/ on top of common/, using gki_defconfig plus ti.fragment.

To add a driver:

  1. Source — add the in-tree driver under ti-linux-kernel/.
  2. Kconfig — set CONFIG_*=m in private/devices/ti/am6x/ti.fragment.
  3. Register it in private/devices/ti/am6x/BUILD.bazel (keep lists sorted):
    • In-tree: full kernel-root path in TI_IN_TREE_MODULES, plus the filename in TI_VENDOR_BOOT_MODULES (vendor_boot ramdisk, first-stage) or TI_VENDOR_DLKM_MODULES (vendor_dlkm, second-stage).
    • Out-of-tree / DDK: Bazel label in TI_EXTERNAL_MODULES_TARGETS, plus the filename appended directly to the placement rules.

No BoardConfig.mk change is needed — the Android build picks up the kernel's variscite_am62p_dist output automatically.