Skip to main content

OTA guide

Over-The-Air (OTA) user guide​

Based on android 13 and later platform.

1. Build images​

Ideally, compile all images, but at least ensure that the u-boot and kernel are compiled.
For partial build, please refer here

2. Build OTA update package​

2.1 Build target files​

Generate partition target files with following command:

make  target-files-package -j4

You can find the target files in the following path:

out/target/product/$product/obj/PACKAGING/target_files_intermediates/$<product>-target_files-**

It also generate target files package.

out/target/product/$product/obj/PACKAGING/target_files_intermediates/$<product>-target_files-**.zip

2.2 Build full update package​

Based on target files to pack full OTA package with following command:

make otapackage -j4

You can find the full OTA package in the following path:

out/target/product/$product/$product-ota-**.zip

$product-ota-**.zip includes payload.bin and payload_properties.txt, which used for full OTA update.

Rename as full-ota.zip

2.3 Build incremental update package​

Generate diff package between old and new full package.

  1. rename old target files package as OLD-target-file.zip.
  2. update your code and re-generate new target files package by Section 2.1 command.
  3. rename new target files package as NEW-target-file.zip
  4. generate incremental package by ota_from_target_files tool with following command
    out/host/linux-x86/bin/ota_from_target_files -i $OLD-target-file.zip $NEW-target-file.zip incremental-ota.zip
    incremental-ota.zip is the output file as incremental package. It also contains payload.bin and payload_properties.txt that used for incremental update.

3. Implement OTA update​

Using update_engine_client tool​

update_engine_client is a prebuilt tool that supports A/B system updates. It can support updates from a remote server or from internal storage on the device.

3.1 Update system from remote server​

  1. copy full-ota.zip or incremental-ota.zip (generate on Section 2.2 and 2.3) to the HTTP server (for example, 192.168.1.1).

  2. unzip the package to get payload.bin and payload_properties.txt

  3. get contain of payload_properties.txt

    cat payload_properties.txt

    Example:

    FILE_HASH=5towPrI4BlB//hhmBldF6kfV71zG5FNV70NX0O1xqvs=
    FILE_SIZE=46961
    METADATA_HASH=MFQnSQkvFpRRCqP+heWUSOby0E2ie0Ou8v+Nc07oy44=
    METADATA_SIZE=43765
  4. In console mode, type following command

    update_engine_client --payload=http://192.168.1.1:10888/payload.bin --update --headers="FILE_HASH=5towPrI4BlB//hhmBldF6kfV71zG5FNV70NX0O1xqvs=
    FILE_SIZE=46961
    METADATA_HASH=MFQnSQkvFpRRCqP+heWUSOby0E2ie0Ou8v+Nc07oy44=
    METADATA_SIZE=43765"
    Notes:

    The content of the --headers parameter must be exactly the same as payload_properties.txt, without adding any spaces or return character.


3.2 Update system from board's storage​

  1. unzip full-ota.zip or incremental-ota.zip to get payload.bin and payload_properties.txt files.

  2. push payload.bin into device storage

    adb push payload.bin /sdcard/
  3. get contain of payload_properties.txt

    cat payload_properties.txt

    Example:

    FILE_HASH=5towPrI4BlB//hhmBldF6kfV71zG5FNV70NX0O1xqvs=
    FILE_SIZE=46961
    METADATA_HASH=MFQnSQkvFpRRCqP+heWUSOby0E2ie0Ou8v+Nc07oy44=
    METADATA_SIZE=43765
  4. In console mode, type following command

    update_engine_client --payload=file:///sdcard/payload.bin --update --headers="FILE_HASH=5towPrI4BlB//hhmBldF6kfV71zG5FNV70NX0O1xqvs=
    FILE_SIZE=46961
    METADATA_HASH=MFQnSQkvFpRRCqP+heWUSOby0E2ie0Ou8v+Nc07oy44=
    METADATA_SIZE=43765"
    Notes:

    The content of the --headers parameter must be exactly the same as payload_properties.txt, without adding any spaces or return character.


4. Check OTA update​

After run update_engine_client, system will update automatically in the background.
When it finishes, it show "Update successfully applied, waiting to reboot" in the logcat.
Example:

I update_engine: [INFO:postinstall_runner_action.cc(454)] Unmapped all partitions.
I update_engine: [INFO:postinstall_runner_action.cc(470)] All post-install commands succeeded
I update_engine: [INFO:action_processor.cc(116)] ActionProcessor: finished last action PostinstallRunnerAction with code ErrorCode::kSuccess
I update_engine: [INFO:update_attempter_android.cc(565)] Processing Done.
I update_engine: [INFO:update_attempter_android.cc(810)] Writing update complete marker.
I update_engine: [INFO:update_attempter_android.cc(580)] Update successfully applied, waiting to reboot.
I update_engine: Successfully unmapped snapshot product_a
I update_engine: Successfully unmapped snapshot system_a
I update_engine: Successfully unmapped snapshot vendor_dlkm_a
I update_engine: Successfully unmapped snapshot system_ext_a
I update_engine: Successfully unmapped snapshot vendor_a
I update_engine: [INFO:metrics_reporter_android.cc(159)] Current update attempt downloads 0 bytes data

And then device need to reboot to apply OTA update patches.

5. Trouble shooting​

5.1 update_engine error​

error log:

E update_engine: [ERROR:file_stream.cc(-1)] unknown(...): Domain=system, Code=EACCES, Message=Permission denied
E update_engine: [ERROR:file_fetcher.cc(87)] Couldn't open /sdcard/payload.bin


Solution:

setenforce 0

5.2 full ota package update fail​

Please make sure the base version is the same between device ROM and package.

5.3 incremental ota package updata fail​

Before implement incremental OTA update, please make sure previous OTA update had applied in your device.
You may need to run full OTA update at beginning.

5.4 timestamp issue​

error log:

I update_engine: [INFO:delta_performer.cc(922)] Detected a 'full' payload.
E update_engine: [ERROR:delta_performer.cc(1046)] The current OS build timestamp (1726482761) is newer than the maximum timestamp in the manifest (1722397232)
E update_engine: [ERROR:download_action.cc(227)] Error ErrorCode::kPayloadTimestampError (51) in DeltaPerformer's Write method when processing the received payload -- Terminating processing


Solution:
The base timestamp is not the same between device and OTA package. The image in device and OTA package need to generate on the same build server.