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:
- Ubuntu 22.04/24.04 64-bit LTS http://www.ubuntu.com/download/desktop
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:
For OP-TEE OS, install the host prerequisites listed upstream at OP-TEE Prerequisites.
Configure Git¶
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 -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¶
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 SoCtispl-<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 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¶
or
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):
- For SD boot:
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/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-sideflashall.shfastboot installer, and the SPDXsbom.spdx.jsonSoftware Bill of Materials.scripts/holds the on-target installeram6_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.
- 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
- Extract it:
tar --use-compress-program=unzstd -xf android-artifacts-am62p-var-som-symphony-userdebug.tar.zst
cd android-artifacts
- Run the installer:
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:
- U-Boot boots from the on-SOM eMMC.
- 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¶
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:
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:
Power the board, interrupt U-Boot, and enter fastboot:
Run the installer from the product output:
Flags:
--bootloader— flash onlytiboot3+bootloader(tispl + u-boot).--disable-avb— flashvbmeta*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.binandpayload_properties.txtfrom the OTA zip file. - Push
payload.binto the board's/data/ota_package/directory:
- Open
payload_properties.txtin 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:
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
Menu Config¶
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:
- Source — add the in-tree driver under
ti-linux-kernel/. - Kconfig — set
CONFIG_*=minprivate/devices/ti/am6x/ti.fragment. - 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 inTI_VENDOR_BOOT_MODULES(vendor_boot ramdisk, first-stage) orTI_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.
- In-tree: full kernel-root path in
No BoardConfig.mk change is needed — the Android build picks up the kernel's
variscite_am62p_dist output automatically.