2 releases
Uses new Rust 2024
| 0.1.1 | Dec 26, 2025 |
|---|---|
| 0.1.0 | May 17, 2025 |
#13 in Android
54KB
1K
SLoC
payload_packer
A standalone tool for generating full and incremental Android OTA payloads for A/B devices.
Disclaimer
This is an experimental tool. The official Google delta generator may use different methods and optimisations. Use this tool at your own risk for development and testing purposes.The payloads generated by this tool have not yet been tested on real devices. However, third-party payload dumpers are able to correctly interpret and extract payloads created by this tool.
For an end-to-end proof of concept and validation tests for both full and incremental OTAs, see the tests/ directory.
Features
- Generate full OTA payloads from partition images
- Generate incremental (delta) OTA payloads between two versions
Installation
You can install it using one of the following methods:
- Via Cargo:
cargo install payload_packer
-
From prebuilt binaries: Download the appropriate binary for your platform from the Releases page
-
Build from source:
git clone https://github.com/rhythmcache/payload_packer.git
cd payload_packer
cargo build --release
Usage
Generating a Full Payload
A full payload contains complete partition data and can be installed on any device running the same Android version.
./payload_packer --target-dir /path/to/new/images --output payload.bin
Example with specific partitions:
./payload_packer \
--target-dir /path/to/new/images \
--partitions system,vendor,boot \
--method xz \
--level 5 \
--output payload.bin
Generating an Incremental (Delta) Payload
An incremental payload contains only the differences between two versions, resulting in smaller file sizes.
./payload_packer \
--delta \
--source-dir /path/to/old/images \
--target-dir /path/to/new/images \
--output delta_payload.bin
Example with compression settings:
./payload_packer \
--delta \
--source-dir /path/to/old/images \
--target-dir /path/to/new/images \
--partitions system,vendor,product \
--method xz \
--level 9 \
--chunk-size 4194304 \
--output incremental_payload.bin
Using Individual Image Files
Instead of specifying directories, you can provide individual image files:
./payload_packer \
--target-image /path/to/system.img \
--target-image /path/to/vendor.img \
--target-image /path/to/boot.img \
--output payload.bin
Payload generation is a CPU- and I/O-intensive process.
For large partition images (multiple gigabytes), generating full or incremental payloads can take a significant amount of time depending on image size, storage speed, compression method, and system resources.
Please be patient while the payload is being generated, especially when using high compression levels or processing large images.
Command Line Options
| Option | Description |
|---|---|
-o, --output |
Path to output payload.bin file (default: output/payload.bin) |
-t, --target-dir |
Directory containing target (new) .img files |
--target-image |
Individual target image file (can be used multiple times) |
--delta |
Generate incremental payload instead of full payload |
-s, --source-dir |
Directory containing source (old) .img files (required for delta) |
--source-image |
Individual source image file (can be used multiple times) |
-p, --partitions |
Comma-separated list of partitions to include |
-m, --method |
Compression method: xz, zstd, or bz2 (default: xz) |
-l, --level |
Compression level (xz: 0-9, zstd: 1-22, bz2: 1-9) |
--threads |
Number of threads for parallel processing |
-b, --block-size |
Block size in bytes (default: 4096) |
-c, --chunk-size |
Target chunk size per operation in bytes (default: 2097152) |
--skip-properties |
Skip creation of payload_properties.txt file |
--mmap-threshold |
File size threshold for using memory mapping (default: 400MB) |
How It Works
Full Payload Generation
Full payloads contain complete partition data:
- Each partition image is divided into chunks based on the specified chunk size
- Each chunk is compressed using the selected compression algorithm (XZ, Zstandard, or Bzip2)
- Compressed chunks are written sequentially to the payload file
- A manifest is created containing metadata about all operations, block sizes, and partition information
- The final payload consists of: header + manifest + compressed data blobs
Incremental Payload Generation
Incremental payloads contain only the differences between source and target versions:
- Source and target partition images are compared chunk by chunk
- For each chunk, the tool determines the most efficient operation:
- ZERO: If the target chunk contains only zeros, no data is stored
- SOURCE_COPY: If source and target chunks are identical, only a reference is stored
- SOURCE_BSDIFF: If chunks differ slightly, a binary diff patch is generated using bsdiff
- REPLACE: If chunks differ significantly, the target chunk is compressed and stored
- The tool automatically selects between bsdiff and replace based on which produces smaller output
- Bsdiff operations use Bzip2 compression internally
- Replace operations use the user-specified compression method (XZ, Zstandard, or Bzip2)
The incremental approach significantly reduces payload size for updates where most partitions remain unchanged or have minor modifications.
Output Files
payload.bin: The main OTA payload filepayload_properties.txt: Contains metadata including file hash, size, and manifest hash (unless--skip-propertiesis used)
Limitations
- Does not support signing payloads (signatures must be added separately)
- Experimental tool, may not match official Google OTA payload behaviour exactly
- Does not validate partition compatibility or Android version requirements
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Contributing
Contributions are welcome.
Dependencies
~30–40MB
~837K SLoC