NixOS on the Pinephone Pro
Table of Contents
1. NixOS on the Pinephone Pro
1.1. What is this about
This is my personal log of experience with my work on NixOS on the Pinephone Pro. Since i am both a beginner when it comes to NixOS or hardware tinkering (besides some ESP32 stuff) this will document the failures as much as the sucecss stories. I think there are many out there like me, so maybe that helps.
I plan to keep this site evolving over the next months, so make sure you come back at times. You could also subscribe to the RSS feed of the git repo this is generated from.
If this project reaches a state from where readers can build and maintain their system, i plan to move a (corrected and formatted) version to the official nixos-mobile documentation.
If you should be interested in anything regarding mobile nixos on the PPP, let me know by opening an Issue here.
1.2. Disclaimer
As usual, when it comes to such a blog i will warn you, that since i do not 100% know what i am doing, things can break. Follow the guides at your own risk. For safety, i am not writing to the internak eMMC but rather use a SD card, which should not brick the phone when things go sideways.
2. Contact
You can contact me via
- message on Matrix @chfkch:matrix.org
- message in the fediverse (Mastodon) chfkch@ruhr.social
- Follow me on Mastodon!
- Codeberg issue in my repo
3. Blog
3.1. Day 1 - Building an SD card image
The procedure i went with was cloning the git repo from samuel https://github.com/samueldr-wip/mobile-nixos-wip and adding a custom local.nix file on root level of the repo. This file is not tracked since it is listed in the .gitignore. The following chapters describe how and why i added things.
3.1.1. Initialization of local.nix
{ config, libs, pkgs, ... }:
3.1.2. Declaration of variables
let user = "linux"; # Put your desired name here password = "123123"; # numeric password so the login manager from phosh/plasma/mobile can handle in {
3.1.3. Imports
We do not have anything to import so far
# imports = [];
3.1.4. Configuration
- Users
users = { mutableUsers = true; # take username from variables users."${user}" = { isNormalUser = true; password = password; # take password from variables extraGroups = [ "wheel" # for sudo "users" # for login manager "dialout" "feedbackd" "networkmanager" "video" ]; }; };
- System Packages
environment.systemPackages = with pkgs; [ # Default stuff you need vim helix git curl fish # may be redundant with programs.fish.enable exa bat htop # GNOME suite chatty gnome-console megapixels epiphany # fractal #commenting this out because it did not build on my phone portfolio-filemanager ];
programs.fish.enable = true; users.defaultUserShell = pkgs.fish;
- Desktop Environments
- Services
- Calls
I think this is for GNOME
programs.calls.enable = true;
3.1.5. Cleanup
We wilalso include a default version here, since we need it later on the global config.
system.stateVersion = "22.05"; }
3.1.6. Full local.nix
1: { config, libs, pkgs, ... }: 2: 3: let 4: user = "linux"; # Put your desired name here 5: password = 6: "123123"; # numeric password so the login manager from phosh/plasma/mobile can handle 7: in { 8: 9: # imports = []; 10: 11: users = { 12: mutableUsers = true; 13: # take username from variables 14: users."${user}" = { 15: isNormalUser = true; 16: password = password; # take password from variables 17: extraGroups = [ 18: "wheel" # for sudo 19: "users" # for login manager 20: "dialout" 21: "feedbackd" 22: "networkmanager" 23: "video" 24: ]; 25: }; 26: }; 27: 28: environment.systemPackages = with pkgs; [ 29: # Default stuff you need 30: vim 31: helix 32: git 33: curl 34: fish # may be redundant with programs.fish.enable 35: exa 36: bat 37: htop 38: 39: # GNOME suite 40: chatty 41: gnome-console 42: megapixels 43: epiphany 44: # fractal #commenting this out because it did not build on my phone 45: portfolio-filemanager 46: ]; 47: 48: programs.fish.enable = true; 49: users.defaultUserShell = pkgs.fish; 50: 51: services.xserver.desktopManager.phosh = { 52: enable = true; 53: user = user; # from variables 54: group = "users"; 55: }; 56: 57: services.openssh.enable = true; 58: 59: programs.calls.enable = true; 60: 61: system.stateVersion = "22.05"; 62: }
3.1.7. Building the image
In the repos root folder execute the following command. This can take minutes or even hours depending on your bandwidth and hardware specs.
I am building it on a Raspberry Pi4 8GB and it took around 2-3 hours on the first run. Former runs (when i changed config) took about 10-30 minutes or less.
nix-build --argstr device pine64-pinephonepro -A build.disk-image
This will take the hardware specs from the devices/pine64-pinephonepro folder (default.nix) and use them as additional inputs. Note The local.nix we built before will also be used.
The image is located in the result folder. This should also be displayed at the end of the build process.
3.1.8. Writing the SD card
With an image built, write the contents to an SD card. You can use "dd" for that or something else, i used "popsicle" on my main machine. Note The produced images had a very small size for the main partition. I resized it after flashing with "gparted". If needed, i can put a tutorial in here, but i will skip it for now.
3.1.9. Conclusion
Well, the system is bootable, the login manager logs me into phosh. Apps can be started etc. But some things are off. For example i use Nheko as my matrix client, which does not start due to some QT dependencies. That needs to be investigated. Another point is installing new apps. Since we do not have a global /etc/nixos/configuration.nix (more on that later) we can still use nix-env. But it seems some of these apps cannot access the internet, while others installed in the image seem to be able to. For this example i used bitwarden-cli and fractal. On a sidenote: i think the github branch which i based off my work is far behind the official nixos-mobile repo, so e.g. phosh is a little outdated. Maybe i will try to find the definition of the source and adjust it.
3.2. Day 2 - Open questions and where do we go from here
3.2.1. TODO Topics from the previous day
- QT apps on GNOME/phosh
Since this may not occur to many persons, this topic is rather low priority and will be resolved later.
- TODO Apps installed via nix-env
- TODO Uisng a newer version of the package index
In the root folder, there is a file called pkgs.nix which is included in the default.nix to build the image. Switching the "rev" and "sha" variable should already do the trick. To find suitable revisions, check the nixpkgs git repo.
3.2.2. New/Future Topics
- Using global config on the system
Since we are using the prebuilt image only right now, i would like to go for the classic approach of using the
configuration.nix
to change the system later on. NixOS mobile provides way similar to "classic" NixOS to rollback to or boot into older generations. I have seen it on my Oneplus 6T (R.I.P. i bricked it somehow) but i read on mobile there is only one generation instead of multiple. Got to research this topic further. Tomorrow i will try creating theconfiguration.nix
andhardware-configuration.nix
from ourlocal.nix
anddevices/pine64-pinephonepro/default.nix
. - Using the Nix-Installer instead of a prebuilt image
The installer is not included in the WIP git repo yet, so i will either migrate it or move to the main branch completely while locally maintaining the PPP device files, which might be the correct call anyway.
3.3. Day 3 - Global configuration
Let's go and create a static configuration.nix
to maintain the system after starting the prebuilt image. This should be the desired workflow anyway.
Since we already have some chunks of code from day 1, let us use them. Of course there is a little more stuff to do, maybe we can scrap it together from the mobile-nixos repos (at lest the hardware part).
So what do we need? Usually i try to separate my config in parts which can be saved in different files, so they can easily be imported (and thus can be commented out if we don't want to import them). This comes in handy if we want to switch out a desktop environment for another. Of course this could be controlled by variables but let us keep it that way for now.
3.3.1. Prerequisites
The imports for the built image and the global config differ, so we are using this block of code.
imports = [ ./hardware-configuration.nix ];
3.3.2. FInal Files
configuration.nix
1: { config, libs, pkgs, ... }: 2: let 3: user = "linux"; # Put your desired name here 4: password = "123123"; # numeric password so the login manager from phosh/plasma/mobile can handle 5: in 6: { 7: 8: imports = [ 9: ./hardware-configuration.nix 10: ]; 11: 12: users = { 13: mutableUsers = true; 14: # take username from variables 15: users."${user}" = { 16: isNormalUser = true; 17: password = password; # take password from variables 18: extraGroups = [ 19: "wheel" # for sudo 20: "users" # for login manager 21: "dialout" 22: "feedbackd" 23: "networkmanager" 24: "video" 25: ]; 26: }; 27: }; 28: 29: environment.systemPackages = with pkgs; [ 30: # Default stuff you need 31: vim 32: helix 33: git 34: curl 35: fish # may be redundant with programs.fish.enable 36: exa 37: bat 38: htop 39: 40: # GNOME suite 41: chatty 42: gnome-console 43: megapixels 44: epiphany 45: # fractal #commenting this out because it did not build on my phone 46: portfolio-filemanager 47: ]; 48: 49: programs.fish.enable = true; 50: users.defaultUserShell = pkgs.fish; 51: 52: services.xserver.desktopManager.phosh = { 53: enable = true; 54: user = user; # from variables 55: group = "users"; 56: }; 57: 58: services.openssh.enable = true; 59: 60: programs.calls.enable = true; 61: 62: system.stateVersion = "22.05"; 63: }
For the next step to work i cloned the WIP repo to my /etc/nixos
. Other strategies will also work as long as you can link the device specific nix files from here.
hardware-configuration.nix
let mobile-nixos = builtins.fetchGit { # This combination led to us having to downgrade to 22.05 #url = "https://github.com/samueldr-wip/mobile-nixos-wip.git"; #ref = "wip/pinephone-pro"; #rev = "e8ffe9b29c74e27c25f55161c6e952ef97870c3e"; # Old commit (outdated) #rev = "22891f1742a49b87611ba79c4a89d8ac85e2d7b1"; # This combination should be run on 22.11 channel url = "https://codeberg.org/Chfkch/mobile-nixos-ppp"; ref = "master"; #rev = "60251e09b121e60e5b6121b09c9099c54ca77a92"; }; #mobile-nixos = ./mobile-nixos-wip; in { imports = [ (import (mobile-nixos + "/lib/configuration.nix") { device = "pine64-pinephonepro"; }) ]; }
3.3.3. Deploying the configuration
Make sure the final files are in the /etc/nixos
folder.
Since the wip repo uses some old syntax/methods in its packages, we need to make sure, we are running our nix channel on the 22.05 branch. To do this use the following command as root.
nix-channel --add https://nixos.org/channels/nixos-22.05 nixos
First we need to make sure the nix channels are up to date. For this we run the following as root:
nix-channel --update
Then deploy/rebuild the system. Again run the following command as root:
nixos-rebuild switch
This will take some time since it is copying alot of stuff from the nix store to your device. NOTE In my case it will also compile some stuff from source, e.g. Fractal. If you desire a quicker setup process, remove fractal from the sytem packages. NOTE It may also be that some packages will not even build at all. So start small and build up, otherwise you might waste 3 hours compiling stuff that fails in the end…
3.4. Day 4 - Feedback from the pros / Update to a newer state
I had some interesting talks with some people in the nixos on ARM matrix channel. They pointed out that some of my earlier issues originated in me using and old system state (22.05
base). I think it will be a good idea to pump up the versions sooner or later anyway, so why not take a cut here from the previous tasks and focus on that first. Since we generated a bootable global config in day 3 already, i think that is a good level to stop the first take on this topic. If you are interested in fiddling from there on, i think it should work for everyone - if not, let me know.
Since i do not know how much time i will have due to some RL stuff, i will try to gather the pieces we need in the meantime. That would mean:
- Creating a fork of the main branch from the nixos-mobile repo. Wether this will be on GitHub or on Codeberg.org will have to be decided. Advantage of GH would be the "real" forking, the advantage of CB is well, not being owned by M$.
- Migrate the pinephone pro specific device configuration to that new repo
- Build a new system configuration off of that - either via a new SD card or via the already existing installation
Benefits from this operation should be:
- Less things breaking on config level because upstream has figured it
out already, for example the xorg stuff which made me switch to
22.05
state. - More up to date packages (duh!), in this case newer DE version (phosh gestures i think) and some kernel stuff (maybe we get to use the PPP keyboard drivers here, for those who have such a keyboard)
So why build a fork of the main repo here? Well the PPP specific config is not merged into the main yet. There is an open pull request, which is not complete yet. As soon as this is done i think it would be best to switch to the main again, just to get a more recent nixpkgs index etc.
I built a custom Codeberg Fork to test things out. You may use this to get things started, but i advise to fork an own repo off the main repo if you really want to test things out, since i may experiment a bit there or discontinue it altogether if the device will be merged into the original repo.
Since we are using the 22.11
release now, make sure to switch/overwrite the existing channel to the correct one
# run as root nixos-channel --add https://nixos.org/channels/nixos-22.11 nixos
Sadly i cannot go more into detail about switching here, since it is just a minor change in the hardware-configuration.nix
.
So building a new system off of this configuration does work, but somehow some apps (some which were working previously) now seem to stop working due to a GTK/Wayland (GTK Error 71) issue. Even gnome-control-center
and such will not start. I think i do not have time to figure this out on my own, so help is appreciated.
Things that do work are for example the newer phosh version with gestures etc.
On a sidenote i got to test out the NixOS rollback functionality. This
happened when i borked my config my some plasma mobile fiddling. Since
the system did not boot completely but got to early stage 2 i think, i remembered to have seem the generations recovery some other time on my OP6T. On the Pinephone pro you can reach the recovery menu by holding the volume down
button during the Pre-Init stage. And what can i say besides it is a life saver. How many times did i bork my system to an unbootable state when i experimented with Arch Linux on the Pinephone Pro - which is still a great distribution - due to mostly me lacking knowledge, but also bad updates/bad states.