- 13 Dec 2024
- 3 Minutes to read
- Print
- DarkLight
- PDF
OTA guide
- Updated on 13 Dec 2024
- 3 Minutes to read
- Print
- DarkLight
- PDF
Over-The-Air (OTA) user guide
Based on android 13 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.
- rename old target files package as OLD-target-file.zip.
- update your code and re-generate new target files package by Section 2.1 command.
- rename new target files package as NEW-target-file.zip
- generate incremental package by ota_from_target_files tool with following command
incremental-ota.zip is the output file as incremental package. It also contains payload.bin and payload_properties.txt that used for incremental update.out/host/linux-x86/bin/ota_from_target_files -i $OLD-target-file.zip $NEW-target-file.zip incremental-ota.zip
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
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).
unzip the package to get payload.bin and payload_properties.txt
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
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
unzip full-ota.zip or incremental-ota.zip to get payload.bin and payload_properties.txt files.
push payload.bin into device storage
adb push payload.bin /sdcard/
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
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.