Skip to content

Android OTA

This chapter describes the compilation and upgrade methods for OTA update packages on the Allwinner platform. A133 (ceres-c3), A733 (demo_aiot), and T527 (demo) all use the Allwinner Update app for local upgrades, with the underlying support for both traditional Recovery upgrades and A/B partition upgrades.

Motherboard SoC Product OTA Output Path
K9 T527 t527_demo_arm64 out/target/product/t527-demo/t527_demo_arm64-full_ota.zip
K10B A733 a733_demo_aiot_arm64 out/target/product/a733-demo-aiot/a733_demo_aiot_arm64-full_ota.zip
A133 A133 ceres_c3 out/target/product/ceres-c3/ceres_c3-full_ota-eng_*.zip

Compiling OTA Packages

Compilation methods for full OTA packages on each platform.

A133 (ceres-c3)

The SDK does not support ./build.sh ota directly. You need to manually add the pack4dist patch in build.sh:

      echo "Start pack image"
      cd android
      pack
+    rm out/target/product/ceres-c3/ceres_c3-full_ota*.zip
+    pack4dist
+    mv out/target/product/ceres-c3/ceres_c3-full_ota-eng.*.zip out/target/product/ceres-c3/ceres_c3-full_ota-eng_$(date +%Y%m%d)_$(date +%H%M).zip
      cd -

Note

After running ./build.sh to complete the build, the OTA package is generated automatically.

A733 (demo_aiot)

The SDK has built-in OTA compilation commands:

./build.sh ota

After compilation, the full OTA package is generated at:

out/target/product/a733-demo-aiot/a733_demo_aiot_arm64-full_ota.zip

Note

1. TARGET_PRODUCT is a733_demo_aiot_arm64, and PRODUCT_DEVICE is a733-demo-aiot.
2. The Android compilation configuration path is device/softwinner/jupiter/a733-demo-aiot/device-common.mk.
3. The A733 SDK already includes the pack4dist command, so no manual patching is required.

make installclean

Before compilation, ensure make installclean has been executed to guarantee that the property information is updated correctly.

A133 (ceres-c3)build.sh includes make installclean by default:

# make installclean is already built into build.sh

A733 (demo_aiot) — Controlled by the ANDROID_INSTALLCLEAN variable in build.sh:

# Set at the top of build.sh
ANDROID_INSTALLCLEAN=true
Value Behavior Use Case
true Executes make installclean, cleans intermediate files and performs a full rebuild Modifying BoardConfig / partition sizes / system props, etc.
false Incremental build, compiles only changed files Modifying only DTS / kernel config / small Java changes

OTA Signature Description

The payload metadata of the OTA package must be signed. The device verifies the signature using the public key in /system/etc/security/otacerts.zip.

Component A133 A733
OTA compilation signing key $keys_dir/releasekey vendor/security/app_keys/releasekey
Device otacerts.zip testkey.x509.pem testkey.x509.pem

Verifying Signature Matching

# Check the certificate trusted by the device
adb shell unzip -l /system/etc/security/otacerts.zip

# Check OTA package signature information
unzip -p ota-full_ota.zip payload_properties.txt | grep -i hash
# If the METADATA_SIGNATURE line is missing, the signature or signing key does not match

Fixing Signature Mismatches

When the OTA compilation signing key does not match the public key in the device's otacerts.zip, modify device/softwinner/common/vendorsetup.sh:

- ota_gen_param+=" -k $keys_dir/releasekey"
+ ota_gen_param+=" -k build/make/target/product/security/testkey"

Then re-run the OTA compilation.

Upgrade Prerequisites

  1. When a battery is connected, ensure the battery level is sufficient before upgrading. When no battery is connected, battery power supply must be disabled in the device tree.
                                 battery_power_supply: battery-power-supply {
                                         compatible = "x-powers,axp803-battery-power-supply";
-                                        status = "okay";
+                                        status = "disabled";

                                         pmu_chg_ic_temp = <0>;
                                         pmu_battery_rdc= <93>;

Warning

1. This option is enabled by default to support both battery and battery-less boot scenarios.
2. When no battery is connected, this option must be disabled to support OTA upgrades; otherwise, the OTA upgrade will fail due to the system detecting low battery.

2. Ensure the image date in the OTA package is newer than the image date on the board.

Tip

./build.sh ota automatically executes make installclean during compilation, so you don't need to run it manually.

Upgrade Procedure

1. First, ensure that both the OTA package and the board meet the upgrade prerequisites.

2. Place the OTA package in /sdcard/.

Method Command
ADB adb push <ota_zip> /sdcard/
USB Drive cp /mnt/udisk/*.zip /sdcard/

3. Open Settings -> System -> Advanced -> Local Update.

adb shell am start -n com.softwinner.update/com.softwinner.update.MainActivity

A133 (ceres-c3)

A133_OTA_ENTER

4. Select OTA System Update.

image-20250916171506303

5. Select the corresponding OTA package and wait for verification.

image-20250916171547458

6. Click Start install.

image-20250916171617182

7. Click OK and wait for the upgrade to complete.

image-20250916171709862

A733 (demo_aiot)

4. Select OTA System Update (left panel).

5. Click the text "Please select update package!" — the system will open the DocumentsUI file picker.

6. In the file picker, navigate to /sdcard/ (Internal Storage), select the corresponding OTA package, and wait for verification.

7. When the confirmation dialog appears, click "I got it".

Verification

8. Wait for the upgrade to complete (A/B upgrade or Recovery mode will automatically reboot).

9. After the upgrade is complete, verify the changes by checking for new features or system build properties.

$ getprop ro.build.date
 [Tue Sep 16 16:44:38 CST 2025]

Upgrade Principles

The underlying working principles of OTA upgrades, including both traditional Recovery and A/B partition modes.

Traditional Recovery Upgrade

The OTA package is copied to /cache/update.zip, and then RecoverySystem.installPackage() is called to reboot into Recovery mode and install the package.

Key source code:

  • OtaUpgradeUtils.javaDEFAULT_PACKAGE_NAME = "update.zip", CHCHE_PARTITION = "/cache/"
  • VerifyPackage.java — Verifies OTA package integrity

A/B Partition Upgrade

The payload of the OTA package is written directly to the inactive slot (slot B) via update_engine_client. After the upgrade is complete, the system switches slots and reboots.

Key source code:

  • AbUpdate.java — A/B upgrade UI and logic
  • UpdateService.javaupdate_engine_client --update --payload=file://<path>
  • FileSearch.java — Scans all mounted partitions for .zip files

Debugging Methods

Log capture, key markers, and common troubleshooting methods for OTA upgrades.

1. Capturing Upgrade Logs

# Clear old logs
adb logcat -c

# Perform the upgrade operation...

# Export all logs
adb logcat -v threadtime -d > ota_log.txt

2. Key Log Markers

Log Tag Description
AbSelectPackage File selection callback, includes the selected file path
AbUpdate A/B upgrade, parses OTA package (size/name)
update_engine Underlying OTA engine (signature verification / partition writing)

3. Common Errors and Analysis

3.1. Signature Mismatch

kDownloadMetadataSignatureMismatch

AbUpdate: size: 1063382761
AbUpdate: name: META-INF/com/android/metadata
update_engine: InstallPlan: source_slot: A, target_slot: B
update_engine: [ERROR:payload_verifier.cc(137)] None of the 1 signatures is correct
update_engine: [ERROR:delta_performer.cc(372)] Mandatory metadata signature validation failed
update_engine: [ERROR:download_action.cc(227)] Error ErrorCode::kDownloadMetadataSignatureMismatch (26)

Cause: The OTA compilation signing key does not match the public key in the device's otacerts.zip.

Troubleshooting:

# Check the certificate trusted by the device
adb shell unzip -l /system/etc/security/otacerts.zip

# Check the signing key configured for OTA compilation
grep 'ota_gen_param.*-k' device/softwinner/common/vendorsetup.sh

# Compare the fingerprints of both certificates
openssl x509 -in build/make/target/product/security/testkey.x509.pem \
  -noout -fingerprint -sha256

3.2. File Path is Null

W AbSelectPackage: File is null, Please retry!

Cause: The DocumentsUI file picker did not return a valid file URI.

Solution: Simply retry the operation.

3.3. File Path is a content URI

W AbSelectPackage: file path is: content://com.android.externalstorage.documents/...
W AbSelectPackage: INDEX_FILE_CHECK

This is normal. The Update app handles content URIs and then begins parsing the OTA package.

3.4. Battery Detection Failure

The upgrade interface shows an error related to low battery.

Troubleshooting: Verify that the battery-power-supply status in the device tree has been disabled as required (see the "Upgrade Prerequisites" section).

3.5. SELinux Permission Denied

I ftwinner.update: type=1400 audit: avc: denied { open } for path="/dev/__properties__/...vendor_default_prop..."

Troubleshooting: Ensure SELinux is in permissive mode or that the appropriate sepolicy rules have been added.

4. Viewing Recovery Logs

# Device must be rooted
adb shell "su 0 ls -la /cache/recovery/"
adb shell "su 0 cat /cache/recovery/last_log"
adb shell "su 0 cat /cache/recovery/last_install"

Frequently Asked Questions

  • OTA upgrade fails?

1. Verify that all upgrade prerequisites are met.

2. Check the upgrade logs (last_log) for clues:

$ ls /cache/recovery/
block.map    last_kmsg.1 last_kmsg.4 last_log   last_log.3 uncrypt_file
last_install last_kmsg.2 last_kmsg.5 last_log.1 last_log.4
last_kmsg    last_kmsg.3 last_locale last_log.2 last_log.5

3. For more issues, refer to the documentation:

Android_10_OTA_Development_Guide.pdf
Component Path
Update App vendor/aw/public/package/apk/Update/app/src/main/java/com/softwinner/update/
ABUpdater vendor/aw/public/package/apk/ABUpdater/
OTA Compilation Script device/softwinner/common/vendorsetup.sh (pack4dist)
Update Configuration device/softwinner/jupiter/a733-demo-aiot/ (A733)
kernel DTS longan/device/config/chips/a733/configs/demo_aiot/board.dts (A733)