F(x)tec Pro¹ with SailfishOS 3.2 community build
Table of Contents
I finally received my F(x)tec Pro¹.
After checking with the shipped Android that the device was not DOA and applying all updates, I reflashed it with SailfishOS
These are my notes on installing Sailfish OS 3.2.1.20 community build.
When I did the flashing, sailfishos-t5-release-3.2.1.20-devel-20200122.zip
was the current version.
Obviously check the linked post and here
for most recent image available if flashing at a later date.
What this post is about
- Getting Sailfish OS on the F(x)tec Pro¹
- allowing me to use Ansible with the Pro¹ being a host (the playbooks are run from one of my Fedora x86_64 machines)
- grabbing some info from the device to compare to my previous SFOS devices
- doing some well documented adjustements that were not yet part of the build
I am fine with using a community build that can not include some bits, hopefully Jolla will eventually make one available which, like all previous SFOS releases, I’ll most definitely will purchase to support the company.
Pages to Read
Check these three pages for updated information before flashing!
- together.jolla.com Fxtec Pro1 - Sailfish OS tips and tricks
- maemo.org SFOS on F(x)tec Pro¹…
- F(x)tec Community Sailfish OS for Fxtec Pro1
- The SFOS part of the Guide: Sailfish X on Xperias
- Sailfish OS Cheat Sheet
While I love SFOS and greatly appreciate the community efforts, information is spread all over the place. maemo.org is always my primary source, followed by together.jolla.com
Install Sailfish OS
Just follow the instructions, I am not going to needlessly duplicate them here. To be safe against future data loss, I have just pointed the Wayback Machine at the URL.
Command Log
These are the commands I used. You MUST read the guide linked above, the commands are just for my records and do not include steps done interactively on the phone.
µSD Card Preparation
Since tyhe instructions insist on a card no larger than 32GB and me not having any idea what filesystems besides vfat that TWRP build supports, I started with a vfat formatted SD card since I expect TWRP to read vfat.
If the SIM / µSD card tray was not so flimsy on the Pro¹ I would have done a few tests, but I am not willing to riosk breaking it on this new toy.
[root@workstation ~]# grep 3EA0-15EE /proc/mounts
/dev/sdd1 /run/media/pcfe/3EA0-15EE vfat rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,showexec,utf8,flush,errors=remount-ro 0 0
[root@workstation ~]# fdisk -l /dev/sdd
Disk /dev/sdd: 29.83 GiB, 32010928128 bytes, 62521344 sectors
Disk model: SD Transcend
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x80200802
Device Boot Start End Sectors Size Id Type
/dev/sdd1 2048 62521310 62519263 29.8G c W95 FAT32 (LBA)
Install Needed Tools on Workstation
I use Fedora on my workstation, the needed tools are available in the standard repos.
[root@workstation ~]# dnf install android-tools
Expect to find them in any modern distro, the packe name might differ though. If you use Windows or MacOS, then you are on your own.
Unlock Bootloader
Remember to first allow this and USB debugging under Android’s developer settings, as desribed in the instructions.
[root@workstation ~]# fastboot devices
8911ce70 fastboot
[root@workstation ~]# fastboot flashing unlock
OKAY [ 0.044s]
Finished. Total time: 0.044s
Flash TWRP
[root@workstation ~]# fastboot devices
8911ce70 fastboot
[root@workstation ~]# fastboot set_active a
Setting current slot to 'a' OKAY [ 0.009s]
Finished. Total time: 0.010s
[root@workstation tmp]# fastboot flash boot twrp-3.3.1-qx1000.img
Sending 'boot_a' (31768 KB) OKAY [ 0.797s]
Writing 'boot_a' OKAY [ 0.144s]
Finished. Total time: 0.943s
Flash SFOS via TWRP
Again, just follow the linked guide.
At the end of TWRP flashing, I got a ‘No OS installed warning’ warning which I ignored. Only ignore such warnings if, like me, you are comfortable reviving a dead phone as long as you manage to control the bootloader.
Sailfish booted up fine, but could not set the clock.
So I skipped Jolla account creation, compleetd the tutorial and set the clock to automatic in SFOS settings.
Use SailfishOS
From here on, it should behavelike any SFOS device. Obviously the commercial Jolla bits are not in the community build. e.g. the Android compatibility layer.
Only mind kernel updates for now! Check if the OTA you plan to install still needs you to
dd the boot image to boot_a
.
With 20191218 and later images that should no longer be necessary
TODO: verify and update both here and at TJC after I applied my first new kernel via OTA.
Complete the Tutorial
It seems you can not skip the tutorial on first boot, complete it to gain control of you device. But, I find the version in 3.2.1.20 shorter than on older builds. Let’s see how I feel when I see it for the Nth time ;-)
Enable Developer Mode
Follow Jolla’s instructions
Copy SSH Pubkey to Phone
user@workstation ~ $ ssh-copy-id -f -i ~/.ssh/id_USBkey.pub nemo@pro1
Enable ssh Access for root
I’ll ssh in directly as root. This saves me from having to make devel-su
a valid
become_method
docs.
To be able to ssh in as root, you need to
- enable developer mode in Jolla Settings
- enable remote access in Jolla Settings
- put your ssh pubkey in
/root/.ssh/authorized_keys
chmod 0700 /root/.ssh/
chmod 0600 /root/.ssh/authorized_keys
user@workstation ~ $ ssh nemo@pro1
Last login: Sat Feb 1 11:38:40 2020
,---
| Sailfish OS 3.2.1.20 (Nuuksio)
'---
[nemo@Pro1 ~]$ devel-su
Password:
[root@Pro1 ~]# cd
[root@Pro1 ~]# mkdir .ssh
[root@Pro1 ~]# chmod 700 .ssh
[root@Pro1 ~]# cd .ssh
[root@Pro1 .ssh]# cp /home/nemo/.ssh/authorized_keys .
[root@Pro1 .ssh]# ll
total 4
-rw------- 1 root root 773 Feb 1 14:31 authorized_keys
Ansible
You may not need this, but like to control my gizmos with Ansible.
These steps should apply to any SFOS device, I have successfully used them with a previous one.
Install Python on SFOS
For Ansible to be able to control your Sailfish X device, you will need to install python
.
user@workstation ~ $ ssh nemo@pro1
Last login: Sat Feb 1 14:31:46 2020 from 192.168.50.40
,---
| Sailfish OS 3.2.1.20 (Nuuksio)
'---
[root@Pro1 ~]# pkcon refresh
Refreshing cache
Refreshing software list
Finished
[root@Pro1 ~]# pkcon install python
Resolving
Querying
Testing changes
Finished [ ] (0%)
The following packages have to be installed:
python-2.7.15+git5-1.6.3.jolla.armv7hl An interpreted, interactive, object-oriented programming language
python-libs-2.7.15+git5-1.6.3.jolla.armv7hl Runtime libraries for Python
Proceed with changes? [N/y] y
Installing
Querying
Downloading packages
Installing packages
Finished
[root@Pro1 ~]#
Add Sailfish OS Device to Inventory
Obviously you will have to ensure that your phone is always reachable as pro1
, do this via your network infrastructure.
pro1 ansible_user=root
Test Ansible Connectivity
user@workstation ~ $ ansible pro1 -m ping
[WARNING]: Platform linux on host pro1 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
pro1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
View Ansible Facts
user@workstation ~ $ ansible -m setup pro1
[WARNING]: Platform linux on host pro1 is using the discovered Python interpreter at /usr/bin/python, but future
installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
pro1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
[...]
Silence the Warning
For now I want Ansible to explicitly use Python 2.7 in the Pro1, so
I added the following in host_vars/pro1.yml
.
ansible_python_interpreter: /usr/bin/python2.7
Do not blindly add this, RTFM first
and decide which behaviour you want for your use case. auto
or auto_silent
may better suit your use case.
Use The Right Ansible Modules and Roles
Note that you should enable/disable repos with ssu
. e.g.:
ssu --help
ssu lr #list repo
ssu ar #add repo
Software should be installed with pkcon
.
pkcon install <PackageName>
Neither of these seem to have corresponding ansible modules.
My Generic SFOS Playbook
Is still quite short at the moment (only nails down ssh access), I expect this to grow when doing a step manually starts to annoy me.
For now I simply added the new host to my old play sailfish.yml
, it now reads as follows
- name: SailfishOS config
hosts:
- gemini
- pro1
- Xperia10II-DualSIM
become: no # we ssh in directly as root with ssh key, to avoid dealing with devel-su
handlers:
- name: restart systemd-journald
systemd:
name: systemd-journald.service
state: restarted
- name: restart sshd
systemd:
name: sshd.service
state: restarted
tasks:
# Ensure sshd config is set up to my liking, the disconnect after 15 mins is simply because I tend to forget for hours that I ssh-ed in and this will have a battery hit
- name: SSHD | ensure AuthorizedKeysFile is configured
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^AuthorizedKeysFile'
insertbefore: '^#AuthorizedPrincipalsFile none'
line: 'AuthorizedKeysFile .ssh/authorized_keys'
notify: restart sshd
- name: SSHD | ensure PasswordAuthentication is off
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PasswordAuthentication'
insertafter: '^#PasswordAuthentication'
line: 'PasswordAuthentication no'
notify: restart sshd
- name: SSHD | ensure that a response is requested from the client after 1 minute of inactivity
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^ClientAliveInterval'
insertafter: '^#ClientAliveInterval'
line: 'ClientAliveInterval 1m'
notify: restart sshd
- name: SSHD | ensure that a client is disconnected after 3 missed response requests
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^ClientAliveCountMax'
insertafter: '^#ClientAliveCountMax'
line: 'ClientAliveCountMax 3'
notify: restart sshd
# set either 'volatile' or 'persistent'
# if you enable the use of persistent journal, then also see
# https://together.jolla.com/question/4842/how-to-enable-more-detailed-and-persistent-logs-on-jolla-device/
- name: Ensure journald.conf is NOT set to save to persistent storage
ini_file:
path: /etc/systemd/journald.conf
section: Journal
option: Storage
value: volatile
no_extra_spaces: True
backup: False
notify: restart systemd-journald
- name: Ensure journald.conf has a more reasonable setting than the default RuntimeMaxUse=1M
ini_file:
path: /etc/systemd/journald.conf
section: Journal
option: RuntimeMaxUse
value: 10M
no_extra_spaces: True
backup: False
notify: restart systemd-journald
# While with the ini file entry Storage=persistent, systemd should create the target dir, ensure it is there like the above URL suggests
# bounce the journald if the directory was changed
- name: Ensure /var/log/journal is present
file:
path: /var/log/journal
state: directory
owner: root
group: systemd-journal
notify: restart systemd-journald
and then ran it;
pcfe@workstation pcfe.net (master) $ ansible-playbook -l pro1 sailfish.yml
PLAY [SailfishOS config] *****************************************************************************************
TASK [Gathering Facts] *******************************************************************************************
ok: [pro1]
TASK [SSHD | ensure AuthorizedKeysFile is configured] ************************************************************
ok: [pro1]
TASK [SSHD | ensure PasswordAuthentication is off] ***************************************************************
changed: [pro1]
PLAY RECAP *******************************************************************************************************
pro1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Collect Info on the Pro1
Storage
Sadly the installed build does not use LVM. Shame I find having it greatly increases my flexibility in dealing with storage.
But at least /
and /home/
being on the same partition and large means I do not
need to resize as I did on my Gemini PDA and my Xperia SFOS devices.
[root@Pro1 ~]# df -h /home/nemo/
Filesystem Size Used Avail Use% Mounted on
/dev/sda8 106G 1.2G 104G 2% /
[root@Pro1 ~]# df -h -x tmpfs -x devtmpfs
Filesystem Size Used Avail Use% Mounted on
/dev/sda8 106G 1.2G 104G 2% /
/dev/sda8 106G 1.2G 104G 2% /data
/dev/sda6 3.0G 2.5G 490M 84% /system_root
/dev/sda2 27M 4.1M 22M 16% /mnt/vendor/persist
/dev/sde18 992M 548M 429M 57% /vendor
/dev/sde6 64M 368K 64M 1% /vendor/bt_firmware
/dev/sda6 106G 1.2G 104G 2% /system
/dev/sde9 12M 11M 1.4M 88% /vendor/dsp
/dev/sde5 110M 103M 7.1M 94% /vendor/firmware_mnt
overlay 106G 1.2G 104G 2% /system
overlay 106G 1.2G 104G 2% /system_root/system
/dev/sda8 106G 1.2G 104G 2% /vendor/lib64/librecovery_updater_msm.so
/dev/sda8 106G 1.2G 104G 2% /vendor/bin/netmgrd
While I did not quite expect to see this many block devices, I will not override the vendor’s setup.
[root@Pro1 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 113.6G 0 disk
|-sda1 8:1 0 8K 0 part
|-sda2 8:2 0 32M 0 part /mnt/vendor/persist
|-sda3 8:3 0 1M 0 part
|-sda4 8:4 0 512K 0 part
|-sda5 8:5 0 512K 0 part
|-sda6 8:6 0 3G 0 part /system_root
|-sda7 8:7 0 3G 0 part
`-sda8 8:8 0 107.5G 0 part /data
sdb 8:16 0 4M 0 disk
`-sdb1 8:17 0 4M 0 part
sdc 8:32 0 4M 0 disk
`-sdc1 8:33 0 4M 0 part
sdd 8:48 0 128M 0 disk
|-sdd1 8:49 0 4K 0 part
`-sdd2 8:50 0 1M 0 part
sde 8:64 0 4G 0 disk
|-sde1 8:65 0 512K 0 part
|-sde2 8:66 0 2M 0 part
|-sde3 8:67 0 512K 0 part
|-sde4 8:68 0 512K 0 part
|-sde5 8:69 0 110M 0 part /vendor/firmware_mnt
|-sde6 8:70 0 1M 0 part /vendor/bt_firmware
|-sde7 8:71 0 4M 0 part
|-sde8 8:72 0 32M 0 part
|-sde9 8:73 0 16M 0 part /vendor/dsp
|-sde10 8:74 0 1M 0 part
|-sde11 8:75 0 512K 0 part
|-sde12 8:76 0 64M 0 part
|-sde13 8:77 0 8M 0 part
|-sde14 8:78 0 64K 0 part
|-sde15 8:79 0 512K 0 part
|-sde16 259:0 0 512K 0 part
|-sde17 259:1 0 128K 0 part
|-sde18 259:2 0 1G 0 part /vendor
|-sde19 259:3 0 512K 0 part
|-sde20 259:4 0 2M 0 part
|-sde21 259:5 0 512K 0 part
|-sde22 259:6 0 512K 0 part
|-sde23 259:7 0 110M 0 part
|-sde24 259:8 0 1M 0 part
|-sde25 259:9 0 4M 0 part
|-sde26 259:10 0 32M 0 part
|-sde27 259:11 0 16M 0 part
|-sde28 259:12 0 1M 0 part
|-sde29 259:13 0 512K 0 part
|-sde30 259:14 0 64M 0 part
|-sde31 259:15 0 8M 0 part
|-sde32 259:16 0 64K 0 part
|-sde33 259:17 0 512K 0 part
|-sde34 259:18 0 512K 0 part
|-sde35 259:19 0 128K 0 part
|-sde36 259:20 0 1G 0 part
|-sde37 259:21 0 16K 0 part
|-sde38 259:22 0 4K 0 part
|-sde39 259:23 0 1M 0 part
|-sde40 259:24 0 256K 0 part
|-sde41 259:25 0 256K 0 part
|-sde42 259:26 0 4K 0 part
|-sde43 259:27 0 32.7M 0 part
|-sde44 259:28 0 4K 0 part
|-sde45 259:29 0 1M 0 part
|-sde46 259:30 0 8M 0 part
|-sde47 259:31 0 2M 0 part
|-sde48 259:32 0 64M 0 part
`-sde49 259:33 0 128K 0 part
sdf 8:80 0 1.5G 0 disk
|-sdf1 8:81 0 2M 0 part
|-sdf2 8:82 0 2M 0 part
|-sdf3 8:83 0 2M 0 part
`-sdf4 8:84 0 4K 0 part
mmcblk0 179:0 0 29.8G 0 disk
`-mmcblk0p1 179:1 0 29.8G 0 part
zram0 253:0 0 1G 0 disk [SWAP]
RAM Available to SFOS
[root@Pro1 ~]# free -h
total used free shared buff/cache available
Mem: 5.6Gi 1.4Gi 3.3Gi 23Mi 895Mi 4.1Gi
Swap: 1.0Gi 0B 1.0Gi
CPU
[root@Pro1 ~]# lscpu
Architecture: aarch64
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 2
Vendor ID: Qualcomm
Model: 4
Model name: Kryo V2
Stepping: 0xa
CPU max MHz: 2457.6001
CPU min MHz: 300.0000
BogoMIPS: 38.40
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32
Kernel
[root@Pro1 ~]# uname -a
Linux Pro1 4.4.153-perf+ #12 SMP PREEMPT Mon Jan 20 11:37:27 CET 2020 aarch64 aarch64 aarch64 GNU/Linux
OS Customisations
Since I expect these to be part of the build soon, not in Ansible for now.
Replace Boot Splash
Done as per this tjc post.
Not planned to add in Ansible playbook unless I find a module that handles writing to a raw device, but even then doubtful.
I will mosty certainly not do dd
with the command
or shell
module.
HW Keyboard US-international
Done as per this tjc post I chose US, intl., with AltGr dead keys (custom version with extra characters).
Automatic Keyboard Backlight (automatic using mce)
I chose the automatic using mce mode as per this tjc post.
Hardware decoding of h.264 and h.265 (hevc) videos in native SFOS applications
As per this tjc post.
Left Unchanged
- I did not enable off-mode-charge.
Using OpenRepos.net
First install File Browser, then Storeman. Simply follow the Guide: Sailfish X on Xperias. Thanks olf!
Install Patchmanager 3.0
As per Guide: Sailfish X on Xperias.
Patches Installed
- Lockscreen Analog Clock by Ancelad
- Ultimate statusbar patch by Anceland
The Analog Clock one allows for lock screen customisation, including a digital clock. The statusbar patch is installed but not enabled for now.
Test Results
The following functionality has been tested so far. I’ll amend the list as I use the device.
- incoming call answered on handset, no issue, good audio quality (2020-02-01)
- outgoing call initiated on handset, also fine
- inbound SMS, no issue
- GPS, got a fix after the expected while (I did expect first fix to take a whiel) and was able to navigate with Pure Maps
- calDAV and cardDAV sync, no issues doing an initial sync with Kolab Now
Tests to run
- phone calls with Bluetooth headset
Adaptations repo to contribute to
https://gitlab.com/sailfishos-porters-ci/t5-ci/