Fake Treble for Xperia XZ

How to build GSI support on tone devices.

This guide should help you create builds that can run Generic System Images (GSIs) for the Xperia XZ, even though it was never shipped with a /vendor partition.

We will move the “Software Binaries”, as Sony calls them, from the /odm mountpoint to /vendor/odm and move the vendor part from the system partition (/system/vendor) to the oem partition.


Partition   Mountpoint
system      /system
oem         /odm


Partition   Mountpoint
system      /system
oem         /vendor

Most steps in the regular Android build guide and the official Sony build guide apply here as well.


Clone my own local_manifests instead of Sony’s:

git clone https://git.ix5.org/felix/local-manifests-ix5 \
  local_manifests -b 'ix5-customizations-10'


After you run repo_update.sh, also run q_repo_update.sh. Then, run treble_repo_update.sh. These scripts will fetch all the relevant patches you need to create a fake treble build.

You will also need to download the Android 9, Kernel 4.9 Software Binaries. Do not use the Kernel 4.14 binaries!


Then, create the folder device/sony/customization inside your build environment.

It needs to contain two files:

Customization.mk: (note the uppercase C!)

# Include buildvar whether to build a fake treble build or not
include device/sony/customization/customization-noproduct.mk


# Fake treble builds for kagura

If you want to build a vendor-only OTA package, add this to customization-noproduct.mk:

# Skip adding system to ota


Clone https://git.ix5.org/felix/device-sony-odm into device/sony/odm.

Then, you need to extract the “Software Binaries” - “blobs” for short - from the official images.

When you download an image from the Software Binaries page, you will receive a .zip archive, which contains a .img file. This .img file is a sparse android image1:

$ file SW_binaries_for_Xperia_Android_10.0.7.1_r1_v2a_tama.img
 ↳ SW_binaries_for_Xperia_Android_10.0.7.1_r1_v2a_tama.img: \
   Android sparse image, version: 1.0, [...]

Sparse Images & Loop Mount

You can un-sparse the image using the simg2img2 tool. Run /path/to/simg2img SW_<name>.img swbins-unsparse.img and you will receive a regular loop image of an ext4 file system.

$ file swbins-unsparse.img
 ↳ swbins-unsparse.img: Linux rev 1.0 ext4 filesystem data, \
   [..] volume name "odm" (extents) (large files) (huge files)

You can then mount that image using loop3:

sudo mount -o loop swbins-unsparse.img /mnt/

Create device/sony/odm/blobs/ and copy the contents of the mounted image there:

cd device/sony/odm
mkdir blobs
sudo cp -r /mnt/* blobs/
# Delete ext4 metadata
sudo rm -rf blobs/lost+found/
# Don't forget the colon
sudo chown -R $(whoami): blobs/

Build it!

First, because building the kernel on Android Q from inside the Android tree is quite complicated, we use a script to build them instead.

cd kernel/sony/msm-4.9/common-kernel

Edit build-kernels-gcc.sh and uncomment/edit the Override lines so the section looks like this

# Override:

This will save you from building the kernel for all Sony devices and only build for the Xperia XZ (“kagura”).

Then, build the kernel with patched dtb:

bash build-kernels-gcc.sh

After this has finished, you should have a file named kernel-dtb-kagura in your kernel/sony/msm-4.9/common-kernel folder.

Now, go back to your Android root dir and run the build commands:

source build/envsetup.sh && lunch aosp_f8331-userdebug
make bootimage systemimage vendorimage

In case your build stops at about 90% with this error, just re-start the build4.

[ 93% 12745/13686] //frameworks/base:hiddenapi-lists-docs Metalava [common]
FAILED: out/soong/[...]hiddenapi-lists-docs-stubs.srcjar

Flash the resulting files in out/target/product/kagura/:

fastboot flash boot boot.img
fastboot flash oem vendor.img
Do not flash Sony’s software binary image again now, all the needed blobs are already included in vendor.img for you!


To create a flashable zip file, use make otapackage. You can install the resulting zip file in out/target/product/kagura via TWRP or any other recovery.

adb push out/target/product/kagura/aosp_f8331-ota-eng*.zip /sdcard/

Compatible GSIs

You need to use system-as-root, arm64_ab GSIs since this is now the default for Android 10.

Use fastboot flash system <my-gsi.img>.

Since SELinux is in enforcing mode, badly-built GSIs will fail to run. You can set it to permissive by changing the commandline:

BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive

or set BOARD_USE_ENFORCING_SELINUX := false in Customization.mk.

Going back to regular builds

You need to:

  • Unset PRODUCT_FAKE_TREBLE_BUILD in customization-noproduct.mk
  • Unset PRODUCT_BUILD_SYSTEM_IMAGE in customization-noproduct.mk
  • Undo dtsi: tone: conjure oem into /vendor in kernel/sony/msm-4.9/kernel in case you want to build non-treble tone builds again
After you've flashed your fake treble build, you need to re-flash the regular Software Binaries to the oem partition if you want to return to regular builds.

Not a Lawyer

You should decide for youself whether this approach falls within the purview of the blobs EULA. In the EU, you might have some more rights than in other areas so some passages of the following might be void, but I’ve highlighted the relevant parts of the EULA below:


Sony Mobile grants You non-exclusive, non-transferable end-user copyright rights to download the Software on the local hard disk(s) or other permanent storage media of one computer and install the Software, by using the Fastboot Protocol, on a single Sony Mobile device with an unlocked boot loader at a time. Except as provided by any Open Source License Terms, You may use the Software only for the sole purpose of testing and validating Your own applications and/or content (“Purpose”). […]


a) You may not use (other than as expressly permitted for the Purpose), modify, translate, reproduce, or transfer the right to use the Software or copy the Software. You may not use the Software for any reason other than the Purpose.

  1. For more info, see source.android.com or search for “Sparse Image”. ↩︎

  2. You should already have the tool in out/host/linux-x86/bin/simg2img as well. ↩︎

  3. You also use udisksctl to mount the image: udisksctl loop-setup -r -f swbins-unsparse.img ↩︎

  4. Android’s metalava takes up enormous amounts of RAM. It attempts to verify the whole Android API at once and is badly designed. ↩︎

Edit source on Github