Skip to content

Instantly share code, notes, and snippets.

@Kabouik
Last active April 20, 2024 15:14
Show Gist options
  • Save Kabouik/94e9e60d84c0eeae9d48e18c11ed419e to your computer and use it in GitHub Desktop.
Save Kabouik/94e9e60d84c0eeae9d48e18c11ed419e to your computer and use it in GitHub Desktop.
Dual-booting Droidian and SailfishOS on the F(x)tec Pro1

Dual-booting Droidian and SailfishOS on the F(x)tec Pro1

Author: kabouik but all credits to g7


Known issues related to dual-booting, as of 2023-09-10:

  • Switching from Droidian to SailfishOS can be done directly on the phone, but from SailfishOS to Droidian requires a computer.
  • Nothing else so far, yay.

Foreword

The passphrase for Droidian decryption may stop working after step 2, making the whole OS unbootable. To avoid this issue, it is recommended to start this how-to from a device running stock Android without any form of encryption or locking set (at the initial Android boot, just say "Not now" when prompted to set a lock or pin code). Therefore, you may want first reflash stock Android on the phone before step A below, see how to here. Else, just keep the Droidian partition unencrypted (i.e., skip step A-5, but read it still because you will need to alter other commands slightly).

A. Flash Droidian

  1. Download the Droidian image for your device from here.

  2. Unzip it to some directory with unzip /path/to/droidian-OFFICIAL-phosh-phone-*.zip.

  3. Reboot your phone in bootloader mode (hold Volume down + Power), connect it to USB, and make sure you can see it with fastboot devices (you may need to prepend sudo depending on your system).

  4. Flash Droidian with ./flash_all.sh (use sudo if your system requires it). The device should boot automatically at the end of the process. The lock code is "1234".

  5. (Optional) Start "Device encryption" from the application launcher and follow instructions, if you want to encrypt Droidian. Note that if you do not enable encryption, you will have to replace droidian_encrypted by droidian--droidian-rootfs in all corresponding steps below.

B. Prepare the storage for a second OS

  1. Reboot the phone in bootloader mode, then connect it to USB again.

  2. Go back to the folder where you extracted the Droidian image on your computer, then cd data/ && fastboot flash boot recovery.img. Again, remember that fastboot may require sudo on some systems.

  3. Select "Recovery" in the bootloader using the volume buttons, then confirm with the Power button. The screen will stay black, this is expected.

  4. (Optional and not documented yet, can be done at a later stage anyway) Add the two Android system partitions to the LVM Volume Group (VG) if you want a couple extra GB to be used in the Sailfish root partitions.

  5. Resize the Droidian rootfs:

ssh [email protected] # If your computer already knew a host with that IP, you may have to delete the corresponding line in ~/.ssh/known_hosts
umount /android-rootfs
umount /android-system
umount /halium-system
e2fsck -f /dev/mapper/droidian_encrypted
  1. Decide which size you want your Droidian partition to be. The below example is for 50GB:
resize2fs /dev/mapper/droidian_encrypted 50G
cryptsetup resize /dev/mapper/droidian_encrypted
lvm lvreduce -L 50G droidian/droidian-rootfs
  1. Confirm in the prompt, then run:
lvm lvcreate -L 10G -n root droidian
lvm lvcreate -l 100%FREE -n home droidian
sync
poweroff
  1. Exit SSH with Ctrl+d, reboot into bootloader mode, plug the USB cable, then run fastboot flash boot boot.img (from the same folder as recovery.img we used above). Then select "Start" and confirm with the Power button.

  2. Cross fingers, in hope it still boots. If it doesn't because you enabled encryption and the device now says that your passphrase is incorrect, make sure that you started from stock Android without any form of encryption or locking. If that was already the case, then maybe consider restarting from scratch without encrypting the Droidian partition (see step A).

C. Flash SailfishOS

  1. Download the latest valid SailfishOS build for the Pro1 from here and extract it. cd into child directories until you see some files.

  2. Connect the phone to your WiFi from the Settings application, then run the following commands on the phone in the default Console (it may be slow, don't worry, you can install better ones later):

sudo apt update
sudo apt install openssh-server hybris-usb rsync android-sdk-libsparse-utils

The password is "1234".

  1. From there, we can transfer the Sailfish image to the phone using, from the computer, rsync -aazvP sailfish.img001 droidian@IP:/home/droidian/Downloads/, where IP is either its WLAN IP (if you know it), or 10.15.19.82 if the phone is still connected through USB.

  2. Now SSH into the device for easier typing: ssh droidian@IP, using the same IP as in the previous step. You may again need to delete the row for that IP in ~/.ssh/known_hosts on your computer if that IP was already known to it.

  3. Now unsparse the image with cd Downloads && simg2img sailfish.img001 sailfish.img.

  4. (If you are currently trying to reflash SailfishOS over a previous flash, but have done all this before, then you need to rename your VG first with sudo vgrename sailfish droidian.)

  5. Run the following commands (preferably one by one):

dd if=/dev/zero of=sailfish.img seek=$(du -b sailfish.img | awk '{print $1}') bs=512 count=1
sudo losetup -f sailfish.img
sudo vgscan
sudo vgchange -ay sailfish
sudo vgs

A new volume group called "sailfish" should now be available.

  1. Flash SailfishOS:
sudo dd if=/dev/mapper/sailfish-root of=/dev/mapper/droidian-root bs=512 status=progress
sudo dd if=/dev/mapper/sailfish-home of=/dev/mapper/droidian-home bs=512 status=progress
  1. Clean up everything:
sudo vgchange -an sailfish
sudo losetup -l
  1. Double check that /dev/loop1 is actually what sailfish.img is attached to, then run:
sudo losetup -d /dev/loop1
sudo vgrename droidian sailfish

D. Force Droidian kernel updates to be always installed on the same slot (a), and flash the SailfishOS boot on the other slot (b):

  1. Run:
sudo su
cat > /etc/flash-bootimage/99-force-slot.conf <<EOF
BOOTIMAGE_SLOT_A="/dev/disk/by-partlabel/boot_a"
BOOTIMAGE_SLOT_B="/dev/disk/by-partlabel/boot_a"
DTBO_SLOT_A="/dev/disk/by-partlabel/dtbo_a"
DTBO_SLOT_B="/dev/disk/by-partlabel/dtbo_a"
VBMETA_SLOT_A="/dev/disk/by-partlabel/vbmeta_a"
VBMETA_SLOT_B="/dev/disk/by-partlabel/vmbeta_a"
DEVICE_IS_AB="no"
EOF
  1. Then reboot into bootloader mode, plug the USB cable, then fastboot set_active b and fastboot flash boot_b hybris-boot.img (which should be in the extracted SailfishOS image, with the file we rsynced to the phone earlier). Select "Start" and confirm with the Power button.

  2. To alternate between Drodian and SailfishOS, you can use fastboot set_active a (Droidian) or fastboot set_active b (SailfishOS) from the bootloader, but this requires a computer. Alternatively, you can switch OS from the phone itself using devel-su /usr/libexec/droid-hybris/system/bin/bootctl set-active-boot-slot 0 (SailfishOS to Droidian) or sudo android_bootctl set-active-boot-slot 1 (Droidian to SailfishOS).

E. Fix SailfishOS home partition if it doesn't unlock at boot with your encryption code

  1. Upon switching to SailfishOS and booting, if your encryption code doesn't seem to unlock the partition (busy icon spinning forever), you may need to check the partition. The easiest way to do that is to reboot into Droidian (see D. 3.), then run:
sudo cryptsetup luksOpen /dev/sailfish/home sfoshome
sudo fsck /dev/mapper/sfoshome
  1. If fsck reports a filesystem size differing from the physical size, then you may try:
sudo resize2fs /dev/mapper/sfoshome
  1. Reboot your phone, and try booting and unlocking SailfishOS again.

Quick demonstration video of some Droidian features


Backing up the whole system (both operating systems)

  1. Reboot the phone in bootloader mode, then connect it to USB.

  2. Go back to the folder where you extracted the Droidian image on your computer, then cd data/ && fastboot flash boot recovery.img. Again, remember that fastboot may require sudo on some systems.

  3. Select "Recovery" in the bootloader using the volume buttons, then confirm with the Power button. The screen will stay black, this is expected.

4, From your computer, run ssh [email protected] "dd if=/dev/disk/by-partlabel/userdata bs=4M | pigz" | dd of=droidian_userdata_backup.img.gz status=progress

  1. (bis) Alternatively, you can run ssh [email protected] "dd if=/dev/disk/by-partlabel/userdata | gzip -c" | dd of=bk.img.gz status=progress, but the above should be faster.

  2. Go brew several coffees, it may take hours.

  3. Exit SSH with Ctrl+d, reboot into bootloader mode, plug the USB cable, then run fastboot flash boot boot.img (from the same folder as recovery.img we used above) to restore the phone in a booting state.

  4. On the phone you want to flash the backup to, do the steps necessary to flash vanilla Droidian on it (see above), then flash the recovery.img boot partition and boot it into recovery mode to it as shown above, then run from your computer zcat bk.img.gz | pv | ssh [email protected] "dd oflag=direct of=/dev/disk/by-partlabel/userdata". You may have to install pv on your computer first, but it will be very handy to report progress on the copy because it can take hours.

  5. Once done, reboot into bootloader mode, plug the USB cable, then run fastboot flash boot boot.img (from the same folder as recovery.img we used above) so that the phone can boot. Hope.


Checking the integrity of a backup

The .img backup can be checked on a computer before doing anything too bold on the phone with the following commands (untested, but suggested by g7):

tar xvzf your_backup.img.gz
sudo losetup your_backup.img
sudo vgscan
sudo vgchange -ay droidian
sudo vgs # Should find your backed up volume groups

Now, you should find the backed-up LVs in /dev/mapper on your system, and you can mount droidian-rootfs if you want as well. If you have encrypted Droidian, you should use the detached header feature:

sudo cryptsetup luksOpen /dev/mapper/sailfish-droidian--rootfs rootfs_unlocked --header /dev/mapper/sailfish-droidian--reserved

You should be able to open the Sailfish /home without using the detached header, the password being the lock code that you set.

To clean up after checking the partitions, unmount what you mounted previously, then:

sudo cryptsetup luksClose /dev/mapper/rootfs_unlocked
sudo vgchange -an droidian
sudo losetup -d /dev/loopX # Where X is the loop device number you got when calling sudo losetup your_backup.img

Reducing the SFOS /home partition to 20G and extending Droidian accordingly:

Make sure you make a backup before following the steps below.

  1. Preparation: flash recovery.img as described above, then boot into recovery mode and run this on the computer:
ssh [email protected] # You may need to remove the line of that IP from ~/.ssh/known_hosts first
umount /android-rootfs
umount /android-system
umount /halium-system
e2fsck -f /dev/mapper/droidian_encrypted
  1. Shrink filesystem -> LUKS -> LV:
cryptsetup luksOpen /dev/sailfish/home sfos_unlocked
e2fsck -f /dev/mapper/sfos_unlocked
resize2fs -f /dev/mapper/sfos_unlocked 20G
cryptsetup resize /dev/sailfish/home
lvm lvreduce -L 20G /dev/sailfish/home
  1. Grow LV -> LUKS -> filesystem:
lvm lvextend -l +100%FREE sailfish/droidian-rootfs
cryptsetup resize /dev/mapper/droidian_encrypted
cryptsetup luksClose /dev/mapper/droidian_encrypted
cryptsetup luksOpen /dev/mapper/sailfish-droidian--rootfs --header /dev/mapper/sailfish-droidian--reserved droidian_encrypted
resize2fs /dev/mapper/droidian_encrypted
  1. Wrap everything up:
sync
poweroff # Did not have any effect so I had to hard reboot, but never know.
  1. Flash boot.img again as described above, reboot, and cross fingers.

It has not been tested, but it should be possible to reduce the size of the Sailfish partition by a given amount instead of stating a final size. To do this, instead of 20G in the commands above, use -20G.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment