payload_packer

Crates.iopayload_packer
lib.rspayload_packer
version0.1.1
created_at2025-05-17 03:11:49.182878+00
updated_at2025-12-26 16:30:16.103648+00
descriptionA standalone tool for generating full and incremental Android OTA payloads for A/B devices.
homepagehttps://github.com/rhythmcache/payload_packer
repositoryhttps://github.com/rhythmcache/payload_packer
max_upload_size
id1677624
size143,006
(rhythmcache)

documentation

README

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:

  1. Each partition image is divided into chunks based on the specified chunk size
  2. Each chunk is compressed using the selected compression algorithm (XZ, Zstandard, or Bzip2)
  3. Compressed chunks are written sequentially to the payload file
  4. A manifest is created containing metadata about all operations, block sizes, and partition information
  5. The final payload consists of: header + manifest + compressed data blobs

Incremental Payload Generation

Incremental payloads contain only the differences between source and target versions:

  1. Source and target partition images are compared chunk by chunk
  2. 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
  3. The tool automatically selects between bsdiff and replace based on which produces smaller output
  4. Bsdiff operations use Bzip2 compression internally
  5. 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 file
  • payload_properties.txt: Contains metadata including file hash, size, and manifest hash (unless --skip-properties is 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.

Commit count: 10

cargo fmt