VIM3/VIM3L AOSP Android 16 Baklava

Android 16 is internally codenamed “Baklava”.This naming choice marks a departure from the traditional alphabetical order of dessert-themed codenames which had been a hallmark of earlier Android versions. “Baklava” is the sixteenth and latest major release of Android, the mobile operating system developed by the Open Handset and led by Google. The first developer preview was released on November 19, 2024. The first beta was released on January 23, 2025.Google released the final version on June 10, 2025.

Now, we can enjoy the latest “Baklava” on VIM3/VIM3L.

Code Download and Compilation

Obtaining the Code

mkdir khadas-aosp-16 && cd $_
repo init -u https://gitlab.baylibre.com/baylibre/amlogic/atv/aosp/manifest.git -b yukawa-android-16
repo sync
./device/amlogic/yukawa/fetch-vendor-package.sh

Compiling the Code

  • VIM3
export TARGET_VIM3=true
export TARGET_USE_TABLET_LAUNCHER=true
source build/envsetup.sh
lunch yukawa-bp2a-userdebug
m
  • VIM3L
export TARGET_VIM3L=true
export TARGET_USE_TABLET_LAUNCHER=true
source build/envsetup.sh
lunch yukawa-bp2a-userdebug
m

Supported Lunch Targets

Android Lunch Android Version
yukawa-bp2a-userdebug TV Debug (VIM3/VIM3L)

We also support the following build flags to enable optional features:

  • TARGET_KERNEL_USE=6.12|mainline : Select Kernel version (default is 6.12)
  • TARGET_VIM3=true : Build for VIM3 Board
  • TARGET_VIM3=true`: Build for VIM3 board
  • TARGET_VIM3L=true : Build for VIM3L Board (Default target)
  • TARGET_BUILTIN_EDID=true : This option allows to preload 1920x1080 EDID structure
  • TARGET_USE_TABLET_LAUNCHER=true : Use tablet launcher instead of Android TV launcher

Extension

Building the Android Kernel

Android is built around the Linux kernel. By default, the boot.img for Android is constructed from the binary kernel image located in the following directory:

~/src/khadas-aosp-16/device/amlogic/yukawa-kernel/6.12

Below are instructions for rebuilding and customizing the Linux kernel for Android.

Android 16 supports two kernel versions:

  • 6.12 (default): Stable Android kernel 6.12
  • mainline: Latest mainline kernel for development

Fetching the kernel code

For kernel 6.12 (default):

mkdir ~/src/khadas-kernel-6.12/ && cd $_
repo init -u https://gitlab.baylibre.com/baylibre/amlogic/atv/aosp/kernel/manifest.git -b yukawa-android16-6.12
repo sync

For kernel mainline:

mkdir ~/src/khadas-kernel-mainline/ && cd $_
repo init -u https://gitlab.baylibre.com/baylibre/amlogic/atv/aosp/kernel/manifest.git -b yukawa-mainline
repo sync

Building the Kernel

In this section, we assume that we already have a fully built Android source code tree located at:

~/src/khadas-aosp-16/

Building Everything from Scratch

For the 6.12 kernel (default):

cd ~/src/khadas-kernel-6.12/
export destdir=~/src/khadas-aosp-16/device/amlogic/yukawa-kernel/6.12
tools/bazel run //yukawa-device:yukawa_dist -- --destdir=$destdir

For the mainline kernel:

cd ~/src/khadas-kernel-mainline/
export destdir=~/src/khadas-aosp-16/device/amlogic/yukawa-kernel/mainline
tools/bazel run //yukawa-device:yukawa_dist -- --destdir=$destdir

Rerun this command for incremental rebuilding.

Defconfig/menuconfig Changes

To configure the kernel using menuconfig:

tools/bazel run --config=local //common:yukawa_with_kgdb_config -- menuconfig

Alternatively, you can manually edit the arch/arm64/configs/amlogic_gki.fragment file.

Rebuilding All Associated Android Images

To test the changes made to the kernel, we must rebuild the relevant Android images:

boot.img: Contains the kernel binary file and the main device tree

vendor.img: Contains the kernel modules

To rebuild the Android images, perform the following:

cd ~/src/khadas-aosp-16/
source build/envsetup.sh 
lunch yukawa-bp2a-userdebug
m bootimage vendorimage

Flashing the kernel

With GKI and Android 16, flashing only the kernel is not sufficient. You need to reflash the entire device using the flash script:

cd $ANDROID_PRODUCT_OUT
adb reboot fastboot
./flash.sh

Bootloader

Obtaining Code

git clone https://gitlab.baylibre.com/baylibre/amlogic/atv/u-boot.git -b u-boot/v2026.01-rc1/integ bootloaders

Building

Install build dependencies:

sudo apt install gcc-aarch64-linux-gnu bc bison build-essential curl u-boot-tools flex git libssl-dev python3 python3-pip wget -y
pip3 install pyamlboot --user

Download the FIP package and generate the script:

cd bootloaders/
wget <package_file>
wget https://gitlab.baylibre.com/baylibre/amlogic/atv/aosp/device/amlogic/yukawa/-/raw/master/bootloader/scripts/generate-bins-new.sh

Unpack the FIP package:

tar xvf <package_file>

Generate the U-Boot image with the following command:

export CROSS_COMPILE=aarch64-linux-gnu-
make khadas-vim3_android_ab_defconfig|khadas-vim3l_android_ab_defconfig
make -j"$(nproc)"

Generate the FIP binary file:

chmod +x generate-bins-new.sh
./generate-bins-new.sh <fip-directory> u-boot.bin

Flashing Bootloader

Flash the result:

fastboot flash bootloader uboot-bins/u-boot.bin
fastboot erase bootenv
fastboot reboot bootloader

If partition table update is required after reboot:

fastboot oem format

Firmware Download

For this purpose, we will provide firmware for each version. If you wish to skip the compilation, you can click the links below to download the images directly.

20251218:

Flashing Method

For optimal results, the VIM3/VIM3L should be directly connected to the host PC. Avoid using USB hubs, as they often do not provide enough power to the board. Below, I will demonstrate the flashing process using VIM3.

After downloading the firmware and extracting it.if the image file is obtained from the compiled code, it will be located in the khadas-aosp-16\out\target\product\yukawa directory.

First time flashing method:

The flashing will be done using the pre-built pyamlboot tool, which requires a Ubuntu system for flashing.

  • Install pyamlboot via pip
pip3 install pyamlboot

Alternatively, refer to pyamlboot for other methods.

  • Set the board to USB upgrade mode:

1- Power up the VIM3
2- Press the F button quickly 3 times within 2 seconds, then release the button
The power LED (blue) will flash for about 3 seconds. After the power LED (blue) goes out, the board will enter upgrade mode.

  • Flash Android Bootloader
# For VIM3
export BOOTLOADER_NAME=u-boot_kvim3_ab.bin
# For VIM3L
export BOOTLOADER_NAME=u-boot_kvim3l_ab.bin

cd ~/src/khadas-aosp-16/out/target/product/yukawa/
boot-g12.py ${BOOTLOADER_NAME}

The bin file path is: khadas-aosp-16\out\target\product\yukawa

  • Start U-Boot and run fastboot
    After the board resets, interrupt U-Boot again and enter fastboot mode:
=> fastboot 0

U-Boot should run fastboot, then

fastboot oem format
fastboot flash bootloader ${BOOTLOADER_NAME}
fastboot erase bootenv
  • Flash Android Images

Flash Android Images using the automated script:

cd ~/src/khadas-aosp-16/out/target/product/yukawa
./flash.sh

After executing the ./flash command, the device will reboot. Press the R (reset) button to continue flash.

  • Reset U-Boot environment to default values

Interrupt the U-Boot autoboot by pressing any key, then run the following commands to reset the environment:

=> env default -a
=> saveenv
=> reset



4 Likes

So Cool!
:clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap: :clap:

The font is too blurry; could you please help fix it?

I flashed https://dl.khadas.com/products/vim3/firmware/android/vim3-aosp-android-16-20251218.tar.gz (both u-boot and Android images) on my VIM3.

It booted successfully twice, but then it gets stuck in u-boot always


[2025-12-30 09:26:50.116] U-Boot 2026.01-rc4-00040-g1c915a322670 (Dec 18 2025 - 10:51:13 +0100) khadas-vim3
[2025-12-30 09:26:50.118] 
[2025-12-30 09:26:50.118] Model: Khadas VIM3
[2025-12-30 09:26:50.119] SoC:   Amlogic Meson G12B (A311D) Revision 29:b (10:2)
[2025-12-30 09:26:50.312] DRAM:  2 GiB (total 3.8 GiB)
[2025-12-30 09:26:50.315] Core:  407 devices, 36 uclasses, devicetree: separate
[2025-12-30 09:26:50.487] MMC:   mmc@ffe03000: 0, mmc@ffe05000: 1, mmc@ffe07000: 2
[2025-12-30 09:26:50.535] Loading Environment from MMC... Reading from MMC(2)... OK
[2025-12-30 09:26:50.649] In:    usbkbd,serial
[2025-12-30 09:26:51.137] Out:   vidconsole,serial
[2025-12-30 09:26:51.137] Err:   vidconsole,serial
[2025-12-30 09:26:51.137] Net:   eth0: ethernet@ff3f0000
[2025-12-30 09:26:51.167] 
[2025-12-30 09:26:51.167] Hit any key to stop autoboot:  2 
Hit any key to stop autoboot: 1
Hit any key to stop autoboot: 0
[2025-12-30 09:26:53.194] Card did not respond to voltage select! : -110
[2025-12-30 09:26:53.195] Card did not respond to voltage select! : -110
[2025-12-30 09:26:53.196] meson_pcie_wait_link_up: error: wait linkup timeout
[2025-12-30 09:26:54.263] PCIE-0: Link up (Gen1-x1, Bus0)
[2025-12-30 09:26:54.264] Starting the controller
[2025-12-30 09:26:54.564] USB XHCI 1.10
[2025-12-30 09:26:54.564] Bus usb@ff500000: 2 USB Device(s) found
[2025-12-30 09:26:56.052] => 

When it still booted, u-boot logs looks like this:

[2025-12-30 09:22:45.477] U-Boot 2026.01-rc4-00040-g1c915a322670 (Dec 18 2025 - 10:51:13 +0100) khadas-vim3
[2025-12-30 09:22:45.479]
[2025-12-30 09:22:45.479] Model: Khadas VIM3
[2025-12-30 09:22:45.479] SoC: Amlogic Meson G12B (A311D) Revision 29:b (10:2)
[2025-12-30 09:22:45.661] DRAM: 2 GiB (total 3.8 GiB)
[2025-12-30 09:22:45.676] Core: 407 devices, 36 uclasses, devicetree: separate
[2025-12-30 09:22:45.847] MMC: mmc@ffe03000: 0, mmc@ffe05000: 1, mmc@ffe07000: 2
[2025-12-30 09:22:45.866] Loading Environment from MMC… Reading from MMC(2)… OK
[2025-12-30 09:22:46.214] In: usbkbd,serial
[2025-12-30 09:22:46.686] Out: vidconsole,serial
[2025-12-30 09:22:46.686] Err: vidconsole,serial
[2025-12-30 09:22:46.687] Net: eth0: ethernet@ff3f0000
[2025-12-30 09:22:46.735]
[2025-12-30 09:22:46.735] Hit any key to stop autoboot: 2
Hit any key to stop autoboot: 1
Hit any key to stop autoboot: 0
[2025-12-30 09:22:48.755] Card did not respond to voltage select! : -110
[2025-12-30 09:22:48.756] Card did not respond to voltage select! : -110
[2025-12-30 09:22:48.757] ** Booting bootflow ‘mmc@ffe07000.bootdev.whole’ with android
[2025-12-30 09:22:48.799] ## Booting Android Image at 0x01080000 …
[2025-12-30 09:22:55.799] Kernel load addr 0x11080000 size 19288 KiB
[2025-12-30 09:22:55.800] Kernel extra command line: no_console_suspend console=ttyAML0,115200 earlycon printk.devkmsg=on init=/init firmware_class.path=/vendor/firmware log_buf_len=1M brcmfmac.feature_disable=0x82000 cma=576M bootconfig
[2025-12-30 09:22:55.805] RAM disk load addr 0x14000000 size 14994 KiB
[2025-12-30 09:22:55.806] Working FDT set to 39eb8ee1
[2025-12-30 09:22:55.807] Uncompressing Kernel Image to 11080000
[2025-12-30 09:22:55.808] Loading Ramdisk to 7f15b000, end 7ffff725 … OK
[2025-12-30 09:22:56.636] Loading Device Tree to 000000007f144000, end 000000007f15a4c8 … OK
[2025-12-30 09:22:56.638] Working FDT set to 7f144000
[2025-12-30 09:22:56.638]
[2025-12-30 09:22:56.651] Starting kernel …
[2025-12-30 09:22:56.652]
[2025-12-30 09:22:56.652] [ 0.000000][ T0] Booting Linux on physical CPU 0x0000000000 [0x410fd034]

@zoulou
Please follow the video instructions and try again.

I did all this from the video and Android booted twice without any issues right after flashing. But since the 3rd attempt, u-boot stops. Unclear to me why it does not try the Booting bootflow mmc@ffe07000.bootdev.whole with android.

I am sorry @william.lin … I found out what causes the bootloader to get stuck.
It happens when I follow the “Tap to fix” from SystemUI Silent notification “Issue with SD card”.


It then brings a dialog that will attempt to format a (not existing) SD card and will stuck at 20%.
Next boot after this (unnecessary) step ends with the fact that u-boot does not find the Android images anymore. I am really sorry… a simple “fastboot oem format” and Android boots up again

I’ve built successfully and my VIM3 now is able to run AOSP 16. However I encounter an issue when I would like to do ‘adb root && adb remount’ for the purpose to access system and vendor partitions. The adb tool said it was done successfully, but after ‘adb reboot’, the system stuck in u-boot, and it said fail to boot because of vbmeta image got hash mismatch. This issue could be resolved by re-flashing vbmeta image to vbmeta_a. But I still not able to access vendor partition. Any suggestion?

Thanks!

@hoffman ,
We will check this issue, but a potential fix might require the next maintenance update to be released.

Hi Khadas team. I flashed the Android 16 image following the instructions in this thread. The system boots successfully and works fine over HDMI, but my TS050 display does not turn on at all, no backlight, completely black.

  1. Is the TS050 supported in this AOSP Android 16 build?
  2. If not enabled by default, is there a device tree overlay that needs to be applied?
  3. Is there a way to enable it via U-Boot environment variables or fastboot?

@Thibaut ,
The current version only supports HDMI output, and we will further improve the system’s functionality in the future.