I have built a Gentoo prefix for SailfishOS on my Sony Xperia XA2. A prefix allows you to use Gentoo's package manager Portage to install software which you can use from within the hosting operating system. If you are not familiar with the concept, have a look at the project website.
Building a prefix takes a long time and is very compute intensive. It is also a very error prone process. Once installed however, the prefix is really rather stable. This is why I make my prefix available for download here.
When using my prefix, here are a couple of things you should know:
72aa9d75199c92c3f12e3850fa095b3a5f9391ec938c3474c8a5b46b6996a440
./opt/gentoo
./opt/gentoo/startprefix
.emerge-webrsync
.
Here are two possible ways to install the prefix. For SailfishOS devices with small internal storage and / or a small /opt
I strongly suggest the second option. No matter which way you choose, remember to always run the post-installation steps.
/opt
All commands in this chapter should be run as user root
.
You can install the prefix directly to /opt
. First, you need to verify that there is enough free storage in the target location though:
df --human-readable /opt
The output will look something like this
Filesystem Size Used Avail Use% Mounted on /dev/mmcblk0p71 821M 271M 526M 34% /opt
In the example output above there is definitely not enough space. You will need at least 1.5 GB of free space. More if you plan on actually installing any applications.
Assuming there is enough free space, proceed as follows.
cd /opt # Download the archive wget https://vimja.website/prefix/gentoo.tar.xz # Or, if you don't have wget installed curl https://vimja.website/prefix/gentoo.tar.xz --output gentoo.tar.xz # Verify the checksum cat << EOF | sha256sum --check - 72aa9d75199c92c3f12e3850fa095b3a5f9391ec938c3474c8a5b46b6996a440 gentoo.tar.xz EOF
The output of this last command should look like this, otherwise something went wrong during the download.
gentoo.tar.xz: OK
Continue with the installation
# Extract the archive unxz --to-stdout gentoo.tar.xz | tar --extract --file - # Change the permissions chown --recursive nemo:nemo gentoo
Now, continue on with the post-installation steps below.
All commands in this chapter should be run as user root
.
Here we will install the prefix to an SD card and then bind-mount it to the target location. See the section "bind-mounting the prefix" below for more details. This example uses the SD card name 656748eb-61db-4360-96fc-fed41fef0f98
. Your SD card will almost certainly have a different name so you will need to replace it in the commands below.
cd /media/sdcard/656748eb-61db-4360-96fc-fed41fef0f98/ # Create a directory to protect the prefix from system indexers mkdir --mode=0700 gentoo cd gentoo # Download the archive wget https://vimja.website/prefix/gentoo.tar.xz # Or, if you don't have wget installed curl https://vimja.website/prefix/gentoo.tar.xz --output gentoo.tar.xz # Verify the checksum cat << EOF | sha256sum --check - 72aa9d75199c92c3f12e3850fa095b3a5f9391ec938c3474c8a5b46b6996a440 gentoo.tar.xz EOF
The output of this last command should look like this, otherwise something went wrong during the download.
gentoo.tar.xz: OK
Continue with the installation
# Extract the archive unxz --to-stdout gentoo.tar.xz | tar --extract --file - # Change the permissions chown --recursive nemo:nemo gentoo # Create a target directory for the bind-mount mkdir --mode=0755 /opt/gentoo # Bind-mount the prefix to /opt mount --options=bind gentoo /opt/gentoo
Now, continue on with the post-installation steps below.
All commands in this chapter should be run as user nemo
.
Start the prefix:
/opt/gentoo/startprefix
If the prefix is started successfully, the output will say Entering Gentoo Prefix /opt/gentoo
and also your prompt will now look different.
Run this command to verify basic functionality of the package manager:
emerge --info
At the top of the output, some warnings will be printed. You can ignore those. Further down, inforamtion on the installed repositories and Portage's variables will be shown.
Before you can start using the prefix, you need to download a current copy of the Portage tree. The download is up to 1 GB in size and extracting it, especially to a slow SD card, can take a long time.
emerge-webrsync
Instead of Downloading my pre built prefix, you can always build your own. This way you can choose yourself where the prefix should be located. More importantly it also means you don't have to trust me.
I had to patch the bootstrap-prefix.sh
in order to make it work on SailfishOS. You can download my patched version of the script directly from my website here or find it in my for of the Gentoo prefix Git repository here
As explained below, even with my patches, I was only ever able to build a 32bit userspace. If you succeed in building a 64bit userspace, please let me know. Unfortunately, by default the script will try to build a 64bit environment, so you need to explicitly force 32bit.
export CHOST=armv7l-pc-linux-gnu ./bootstrap-prefix.sh
Bootstrapping took between 24 and 48 hours on the XA2. You may be able to bootstrap on a different device and copy over the finished prefix. For more details, see the section on device compatibility.
You will need a number of development tools installed on the device. I forget which ones they are. gcc
is certainly one of them ;) However, they should all be available from the default repositories.
You will also need the kernel headers to be installed. Unfortunately the kernel-headers
package provided by Jolla in the default repositories contains the headers for some device other than the XA2. I downloaded the source archive from Sony and manually copied the headers into place.
The prefix is 32bit only. The XA2's kernel is 64bit but the compiler available from Jolla is 32bit. I tried to build a 64bit prefix but failed. Unfortunately, having a 64bit kernel and 32bit userspace can result in problems in some cases. For example FFmpeg
wants to compile the 64bit assembler which will fail. In the case of FFmpeg
this can be worked around by adding EXTRA_FFMPEG_CONF="--arch=arm"
to the make.conf
at /opt/gentoo/etc/portage/make.conf
.
I have removed Python 2 from the prefix before uploading it. Unless you have custom code or specific packages absolutely requiring it, there is no need to put Python 2 back in. Unfortunately the changes I have made will also prevent the system from upgrading to Python 3.7 in the future. To change this, modify or remove the variable PYTHON_TARGETS
in the make.conf
file at /opt/gentoo/etc/portage/make.conf
.
Placing the prefix in /opt
keeps the indexers from attempting to index it. At first I had it living in /home/nemo
. However, the system load generated by various indexers attempting to index the entire portage tree made the device largely unusable and killed the battery. The SailfishOS system indexer can easily be kept from indexing a directory by putting a file called .nomedia
in the folder. Other indexers, for example from the GhostCloud app, are not.
Having the prefix in /opt
you may eventually run out of available storage space. My solution for this is to keep the prefix on my sdcard and then bind-mounting it to the final target. To keep the indexers from indexing the prefix on the sdcard, I place it into a separate folder which is owned by root
and inaccessible to the user nemo
.
Here is my setup in detail: /media/sdcard/<card-id>/gentoo
is 0700
and owned by root:root
. Inside this folder there is another folder gentoo32
which is owned by nemo
, containing the prefix. After booting, I run this as root:
mount --options bind /media/sdcard/<card-id>/gentoo/gentoo32 /opt/gentoo
Starting the prefix using the supplied startprefix
script will remove (some) variables from your env
. Particularly if you want to run Wayland applications, here are some variables you need to set. To find the correct value, have a look at env
before starting the prefix.
XDG_RUNTIME_DIR
QT_QPA_PLATFORM
DBUS_SESSION_BUS_ADDRESS
Other than the environment variables, some applications also need xkb
to be present. I did this by soft-linking the SailfishOS xkb
into the prefix like so:
ln --symbolic /usr/share/X11/xkb /opt/gentoo/usr/share/X11/xkb
Here is a set of use flags advisable for using on SailfishOS:
USE="-X wayland pulseaudio dbus"
It turns out that during bootstrapping, the Gentoo prefix script does not apply aggressive CPU optimization. Most importantly, many Gentoo users use -march=native
or a similar option for their personal machine, resulting in code that is highly optimized for their target CPU but unlikely to run on anything other. Since this is not the case on a freshly bootstrapped prefix, the chances are pretty good that it will run on other devices, too.
The prefix was bootstrapped on a Sony Xperia XA2. I have also successfully tested it on my Jolla 1.
@Kabouik over at together.jolla.com has successfully tested the prefix on a Jolla C.
I have also copied the prefix to a RaspberryPi (a RaspberryPi 2, I think) where it works just fine. Building binary packages using the --buildpkg
Portage option on the RaspberryPi and then installing the package on a SailfishOS device works too. This is especially important since it allows to offload considerable CPU power to an external device.
This suggests to me that one could probably build the prefix on a RaspberryPi in the first place and then copy it over to a smartphone once it is complete. I have not tested this though.
If you test the prefix on a different device, please let me know how it goes by sending an E-Mail to gentoo-prefix@vimja.email.
SD cards and the flash storage used in smartphones are not typically well suited for the kind of IO created by syncing the portage tree or compiling software. Thus running a Gentoo prefix on such a storage device could significantly shorten the lifetime of your storage.
Compiling large packages has led to my XA2 running out of memory. In one case the Out-of-memory killer killed important system processes. The next time I tried to answer a call, there was no audio. The Jolla 1 crashed and rebooted when I tried to build a new GCC. So be careful when compiling software on your smartphone. Keep an eye on dmesg
and system logs and maybe reboot the device when you are done.