A tool to build a GSI (Generic System Image) from stock Android firmware.
Supported firmware:
- full OTA zips (
payload.bin) - fastboot packages
super.img, sparse imagessystem.new.dat- Samsung tars
- Huawei
UPDATE.APP - Unisoc
.pac - LG
.kdz - Oppo
.ozip - QFIL packages
- Sony
.sin - Pixel factory images
Partitions can be ext4, EROFS or F2FS.
This project requires Python 3.10+.
On macOS, install Homebrew and Xcode Command Line Tools first.
git clone https://github.com/MysticGSI/mysticgsi.git && cd mysticgsi
./setup_host.pyInstall Python 3 and Git if you haven't already. Make sure both are added to PATH. We recommend using WinGet:
winget install --id Python.Python.3.14 --exact --source winget
winget install --id Git.Git --exact --source wingetgit clone https://github.com/MysticGSI/mysticgsi.git && cd mysticgsi
python setup_host.pyOn macOS, Debian/Ubuntu, Arch and Windows, the script installs system packages and
creates .venv. On NixOS, it checks the development shell. Native image
tools and the Apktool JAR are bundled with the repository.
Swap requirements.txt for requirements-dev.txt if you want the dev tools.
The bundled Apktool JAR needs Java; native image tools are under
tools/bin/<platform>/<architecture>.
macOS
xcode-select --install
brew install python@3.13 curl aria2 gpatch openssl@3 openjdk@17
export PATH="$(brew --prefix openjdk@17)/bin:$PATH"
"$(brew --prefix python@3.13)/bin/python3.13" -m venv .venv
.venv/bin/python -m pip install -r requirements.txtUbuntu / Debian
sudo apt-get update
sudo apt-get install -y python3 python3-venv python3-pip curl aria2 \
openssl patch ca-certificates libarchive-tools default-jre-headless
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txtArch
sudo pacman -Syu --needed python python-pip curl aria2 openssl patch \
libarchive jre17-openjdk-headless
python -m venv .venv
.venv/bin/python -m pip install -r requirements.txtNixOS
nix --extra-experimental-features 'nix-command flakes' develop
python3 cli.py build <name> <firmware> --type <type>Windows
winget install --id 7zip.7zip --exact --source winget
winget install --id aria2.aria2 --exact --source winget
winget install --id EclipseAdoptium.Temurin.26.JDK --exact --source winget
python -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txt.venv/bin/python cli.py build <name> <firmware|URL> [--type <type>] [--compress]
.venv/bin/python cli.py rebuild <name> [--compress]
.venv/bin/python cli.py list
.venv/bin/python cli.py cleanOn Windows, run from the repository root:
.venv\Scripts\python.exe cli.py build test D:\path\to\firmware.tarF2FS extraction on Windows needs a local NTFS working directory that allows case sensitivity. Use an up-to-date Python for Windows directory permissions.
build - Build a new ROM image
rebuild - Rebuild an existing ROM image
list - List all builds
clean - Clean up all buildsname - Name of the build
firmware or URL - Path to the firmware or URL to download it from
--type <type> - ROM type; default is auto (use an explicit type if detection fails)
--compress - Compress the output image into a ZIP
--add <tag> - Add a tag to the build name
--no-debloat - Keep the apps the patch set would otherwise remove
--no-merge - Build separate images instead of merging partitions into system
--avb-key /path/to/key.pem - Sign with the specified RSA private keyBy default, an image is signed with AOSP's AVB RSA-2048 test key. You can pass --avb-key /path/to/key.pem to sign with your own RSA private key.
To keep separate system and product partitions:
.venv/bin/python cli.py build lg firmware.kdz --no-merge --compressThis writes *-system.img, *-product.img, and images for any other partitions
normally merged into system. Partitions already inside system stay there.
The ZIP contains each image as <partition>.img; rebuild keeps this layout.
These images require a device that mounts the separate partitions.
Example:
.venv/bin/python cli.py build raven \
https://dl.google.com/dl/android/aosp/raven-up1a.231105.003-factory-76a795d5.zip \
--type pixel --compressSee CONTRIBUTING.md before opening a pull request.
.venv/bin/ruff check .Patch files of 50 MiB or more are stored xz-compressed (<name>.xz) and unpacked during builds. After adding one, run ./tools/assets.py pack and commit the .xz files (or .xz.000, .xz.001, ... for split archives).
./tools/assets.py status shows what's packed.
Apache License 2.0, see LICENSE. Bundled avbtool is MIT-licensed;
see tools/avb/LICENSE. Third-party files under patches/
have separate terms; see NOTICE.