SailfishOS Porting for Xperia XZ

This is a draft

Official vs Community

Official Sailfish X builds use a different structure. We will focus on community adaptations.

First of, the setup is a bit unintuitive to understand: Sailfish relies on a ready-made AOSP or LineageOS port on the system partition. Then Sailfish provides its own boot image named hybris-boot.img. It contains a single init script in its ramdisk that loads the Sailfish root filesystem from /data/.stowaways/sailfishos and chroots to it early in the boot sequence. (The Sailfish root file system gets built using misc.)

Focus here on procedure for community builds


Use the following settings in your ~/.hadk.env:

export PLATFORM_SDK_ROOT="/srv/mer"
export ANDROID_ROOT="$HOME/hadk"

export VENDOR="sony"
export DEVICE="f8331"
export FAMILY="tone"
export HABUILD_DEVICE="kagura"

# ARCH conflicts with kernel build
# Need to use armv7hl instead of aarch64 until the SDK target becomes available
export PORT_ARCH="armv7hl"

export USE_CCACHE=1

# Extra options for building with mic
export RELEASE=
# Increment version to match your SDK/target/tooling
export EXTRA_NAME=-kagura

You can also put your Android tree somewhere else, just remember to update $ANDROID_ROOT accordingly.

Android parts

First, build an AOSP or LineageOS system.img using the regular android build system: make systemimage. Flash that image to your device’s system partition.

To sync the regular AOSP build env: Comment out the following lines from .repo/local_manifests/sailfish-aosp.xml: android parts. Then run repo sync and Enter the Android build environment and run make systemimage.

Save the image somewhere and then run make installclean in your Android tree.

Then, swap in the patched bionic, frameworks/base, system/core repos by un-commenting the lines in the manifest again, run repo sync - this time without afterwards - and build the needed hybris parts using make hybris-hal.

It is important that you do not mix these steps up!

mer/Sailfish parts

Use the provided script from droid-hal-device.

Build droid-hal-device, droid-configs, all needed middleware packages, and, finally, droid-hal-version.

It is smarter to run the individual stages of manually:

  • --droid-hal for droid-hal-device

  • --configs for droid-configs

  • --mw for all middleware packages

  • --version for droid-hal-version

This way, you will know which part exactly failed and do not have to rebuild everything after you have fixed a component.

The middleware packages will get cloned to hybris/mw/*. The built package .rpm files will go into $LOCAL_REPO (droid-local-repo/$DEVICE/).

You need to build audioflingerglue and droidmedia manually for tone devices. Refer to the HADK and follow the steps.

Then, you must run to populate the pattern db for mic. If you do not run this(or let --configs will run it for you), mic will fail to find your Jolla Config $DEVICE pattern and exit prematurely.

Image building

Create the kickstart file as instructed in the HADK and run mic create ....


The generated .zip file will not be ready to be flashed because the current build system produces an update-script that contains a set_metadata() instruction, which Android Oreo’s updater binary does not understand.

So, manually unzip the file, flash hybris-boot.img to the boot partition and system.img to the system partition via fastboot. Then push the .bz2 file to /sdcard/ on the device and run these commands manually in the device’s recovery, e.g. TWRP:

rm -rf /data/.stowaways/sailfishos/
mkdir -p /data/.stowaways/sailfishos
tar --numeric-owner \
    -xvjf /sdcard/sailfishos-$DEVICE-$RELEASE-$EXTRA_NAME.tar.bz2 \
    -C /data/.stowaways/sailfishos
rm /sdcard/sailfishos-$DEVICE-$RELEASE-$EXTRA_NAME.tar.bz2

(Subsitute $DEVICE etc. for the actual file name)