How MagiskBoot Unpacks and Repacks Android Boot Images with Multi-Format Compression Support
MagiskBoot automatically detects compression formats by inspecting magic bytes and uses Rust-based streaming encoders/decoders to transparently handle gzip, lz4, lzma, xz, bzip2, and lzop during boot image extraction and reconstruction.
The magiskboot binary serves as the core boot image manipulation engine in the topjohnwu/Magisk repository. Written primarily in Rust with a thin C++ shim interface, the tool processes raw Android and ChromeOS boot images to extract and reconstruct kernel, ramdisk, and device tree components regardless of their underlying compression scheme.
Magic Byte Detection in bootimg.cpp
When reading a boot image or individual section, magiskboot identifies compression formats through the check_fmt() function defined in [native/src/boot/bootimg.cpp](https://github.com/topjohnwu/Magisk/blob/master/native/src/boot/bootimg.cpp#L69-L102). This utility examines the first few bytes of the data buffer to recognize magic signatures for gzip, lz4 (including legacy and LG variants), lzma, xz, bzip2, lzop, as well as raw Android/AOSP and ChromeOS boot image headers.
The detection mechanism maps these magic bytes to the FileFormat enum, enabling the rest of the pipeline to select appropriate handlers without user intervention.
Streaming Decompression via compress.rs
Once a format is identified, the C++ helper decompress() forwards raw bytes to the Rust function decompress_bytes() implemented in [native/src/boot/compress.rs](https://github.com/topjohnwu/Magisk/blob/master/native/src/boot/compress.rs#L90-L98). This function retrieves a streaming decoder via get_decoder(), which maps each FileFormat to its corresponding implementation—such as GzDecoder, LZ4FrameDecoder, or XzDecoder.
The architecture copies data directly to the output file descriptor in a streaming fashion, writing each component (kernel, ramdisk, dtb) in its original uncompressed form unless the user passes the -n flag to skip decompression entirely.
Unpacking Boot Images with magiskboot unpack
When invoked as magiskboot unpack <bootimg>, the command-line driver in [native/src/boot/cli.rs](https://github.com/topjohnwu/Magisk/blob/master/native/src/boot/cli.rs) parses the boot header using the dyn_img_hdr structure. The tool extracts each section according to offsets stored in the dynamic header and invokes decompress() for any compressed segments.
Files are written to the current directory with canonical names: kernel, ramdisk.cpio, second, dtb, and others. This standardization allows shell scripts like boot_patch.sh to locate and modify specific components predictably.
Repacking and Compression Restoration
The repack command accepts the original boot image path to reuse its header metadata and size constraints. During reconstruction, magiskboot examines each component file in the working directory to determine if compression is required (unless -n is specified).
The Rust function compress_bytes() in [native/src/boot/compress.rs](https://github.com/topjohnwu/Magisk/blob/master/native/src/boot/compress.rs#L79-L87) handles encoding via get_encoder(), selecting implementations like GzEncoder, LZ4FrameEncoder, or XzEncoder to stream data into the output file. The dyn_img_hdr struct tracks size changes, and the updated header is written to the final boot image (new-boot.img by default).
Header Management and Architecture
The dyn_img_hdr struct in [bootimg.cpp](https://github.com/topjohnwu/Magisk/blob/master/native/src/boot/bootimg.cpp) encapsulates all boot image metadata including kernel size, ramdisk size, and version fields. During repack, dyn_img_hdr::print() and dump_hdr_file() generate a temporary header file for user editing. After all sections are processed, header values reflect the new compressed sizes.
The overall architecture separates concerns between a C++ front-end handling command-line parsing and file I/O, and a Rust core library implementing format detection and streaming compression. Shell wrappers like scripts/boot_patch.sh orchestrate these binaries for installation workflows.
Practical Command Examples
Unpack a boot image with automatic format detection:
./magiskboot unpack boot.img
# Generates: kernel, ramdisk.cpio, second, dtb, ...
Repack after modifying components:
./magiskboot repack boot.img
# Produces new-boot.img with compression types restored
Skip all compression handling to preserve raw blobs:
./magiskboot unpack -n boot.img
./magiskboot repack -n boot.img
Force specific compression for a component:
./magiskboot compress=xz ramdisk.cpio
./magiskboot repack boot.img
Summary
- Magic byte inspection via
check_fmt()inbootimg.cppautomatically identifies gzip, lz4, lzma, xz, bzip2, and lzop formats without user flags. - Streaming decompression occurs through
decompress_bytes()incompress.rs, mapping formats to Rust decoders likeGzDecoderandXzDecoder. - The
magiskboot unpackcommand extracts components to canonical filenames using header offsets fromdyn_img_hdr. - Repacking reuses original headers and calls
compress_bytes()to restore compression viaget_encoder(), updating size metadata in the boot image header. - A hybrid C++/Rust architecture separates CLI handling from core compression logic, exposed through FFI in
lib.rs.
Frequently Asked Questions
What compression formats does MagiskBoot support?
MagiskBoot supports gzip, lz4 (including legacy and LG variants), lzma, xz, bzip2, and lzop, as well as raw uncompressed data. The check_fmt() function in native/src/boot/bootimg.cpp recognizes each format by inspecting magic bytes at the start of the data stream.
How does MagiskBoot detect compression formats automatically?
The tool inspects the first few bytes of any section using check_fmt() to match against known magic numbers. This detection happens transparently during both unpacking and repacking, eliminating the need for users to specify format flags manually.
Can I prevent MagiskBoot from decompressing files during unpack?
Yes. Passing the -n flag to the unpack command skips decompression entirely, preserving sections exactly as stored in the original image. This is useful when working with proprietary or non-standard compression schemes.
How does repack preserve the original compression format?
During repack, magiskboot references the original boot image header to determine the previous compression state. It then uses compress_bytes() in compress.rs to apply the appropriate encoder via get_encoder(), ensuring the reconstructed image matches the original format specification unless explicitly overridden.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →