Loyal readers may know that I've been using a Samsung Galaxy S5 as my main phone since the post Rooting and installing LineageOS on a Samsung Galaxy S5. What was then an old phone is now practically ancient – the S5 was released in 2014. As a result I've been unable to upgrade beyond LineageOS 16.0, meaning it is stuck on Android 9. This means many apps have stopped receiving updates, which is annoying. The CPU is also underpowered for modern needs. OpenStreetMap (OsmAnd~) has gotten particularly slow, which has been somewhat of a hindrance in my daily life. I've been putting up with these issues because the phone still worked, even if shittily.
This situation changed recently, due to the S5 randomly rebooting when making phone calls. I suspect it has to do with bad solder joints. It has gotten to the point where I can barely call people unless I have the phone tethered to a USB charger, and even when I do tether it, phone calls are not reliable. The issue came to a point last autumn when I fractured my right fibula and the phone rebooted in the middle of talking to medical personnel. So yeah, the S5 is finally too broken and it needs to be replaced.
"Why do all my 30 year old electronics keep breaking on me?" - Strong Bad, sbemail #137, The Paper.
GrapheneOS
An acquaintance of mine recently showed me his Google Pixel with GrapheneOS installed, and I asked him some questions about it and it seemed like a good fit for my needs. GrapheneOS is a security focused operating system that allows sandboxing Android apps to a degree that is to my tastes. In particular, it allows running BankID in a sandbox, which is essential in Sweden to do things like paying one's taxes, contacting the healthcare system and so on. Proving one's identity to Swedish authorities currently depends on a handful of proprietary vendors, particularly BankID. I have tried many things to try and run BankID in other ways, but the only thing that has worked so far is an actual phone. There is also the option to run BankID on a Windows computer. Unfortunately, doing this requires already having a phone that BankID can run on. Note that the S5 can not run BankID. I had another phone, a Galaxy A5, for that. But BankID recently dropped support for such old Android versions, so that's another reason to upgrade.
Installing using the CLI method
There are two methods for installing GrapheneOS: via WebUSB or via CLI tools. Because I think giving the web browser access to the USB bus is a profoundly terrible idea, even if using Firefox, I decided to go the CLI route. Here is the guide I used: CLI install guide on grapheneos.org (fetched 2026-08-16).
I was initially unsure whether to even boot into the stock OS on the phone, but the installation guide states the following:
It's best practice to update the device before installing GrapheneOS to have the latest firmware for connecting the device to the computer and performing the early flashing process. Either way, GrapheneOS flashes the latest firmware early in the installation process.
I therefore decided to set the phone up normally and get it fully upgraded before proceeding. I used "English (Sweden)" as the language option to make searching the web for any issues easier. I skip account setup and skip setting up any SIM card. I set up a PIN but do not set up fingerprint or face unlock. For Google services I disallow GPS position, disable phone number verification and sending usage and diagnostic data. I pick Firefox as my web browser and DuckDuckGo as my search engine. I decline to install any default Google apps. I am finally let into the phone proper, and am immediately asked again to set up a SIM card, which I decline. I allow the phone to sit and charge for a while, and for Android to install any updates in the background. After about an hour there are no more background updates. I go into settings and start a system update to from Android 16 to Android 17. I reboot the phone when the update to Android 17 is finished downloading. A security update also needs to be installed, which entails a second reboot.
At this point I am ready to continue with the actual install. The guide says to enable OEM unlocking, but no such option exists on my device. I figure this is probably because the device is not locked to any particular carrier. 🐦⬛ Caw! Huh, that's strange. How did a crow get in here? Shoo!
Next I install fastboot. Debian stable uses version 1:34.0.5-12, which is too old.
Testing has 1:34.0.5-13, which is also too old.
I follow the guide's instructions to install an up-to-date version of fastboot.
The following packages were installed as root:
$ apt install libarchive-tools android-sdk-platform-tools-common openssh-client
Next I download and extract platform-tools under ~/local.
dtrx is a handy tool that can extract any compressed archive, without the need to faff around with any flags.
I use the -n flag to ensure a directory is always created.
$ cd ~/local
$ curl -O https://dl.google.com/android/repository/platform-tools_r35.0.2-linux.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 7297k 100 7297k 0 0 2148k 0 0:00:03 0:00:03 --:--:-- 2148k
$ echo 'acfdcccb123a8718c46c46c059b2f621140194e5ec1ac9d81715be3d6ab6cd0a platform-tools_r35.0.2-linux.zip' | sha256sum -c
platform-tools_r35.0.2-linux.zip: OK
$ dtrx -n platform-tools_r35.0.2-linux.zip
Next I add the following line to the end of ~/.bashrc:
export PATH=$PATH:$HOME/local/platform-tools_r35.0.2-linux/platform-tools
I open a new terminal and verify that the correct fastboot is reachable via $PATH:
$ fastboot --version
fastboot version 35.0.2-12147458
Installed as /home/thardin/local/platform-tools_r35.0.2-linux/platform-tools/fastboot
I stop the fwupd service as root:
$ systemctl stop fwupd.service
At this point I'm ready to install GrapheneOS.
I shutdown the device, then start it while holding the volume down button.
I see the red "Fastboot Mode" text.
I connect the device to my laptop.
I attempt to unlock flashing using fastboot:
$ fastboot flashing unlock
FAILED (remote: 'flashing unlock is not allowed')
fastboot: error: Command failed
The first hit on this error is "Flashing Unlock is Not Allowed: How to Fix" on droidwin.com.
I try the get_unlock_ability command in fastboot:
$ fastboot flashing get_unlock_ability
< waiting for any device >
fastboot never gets past this waiting, so the process appears to have hanged.
I boot back into Android to check the OEM Unlock Toggle again, but see nothing.
At this point I realize I didn't actually unlock the developer options, which is why OEM unlock was not visible.
🐦⬛ Caw! Caw!
Yes yes, you were right.
Stupid crows.
I enable developer options by tapping the build number in "About phone" seven times. I then see "OEM unlocking" in the developer options, and enable it. I take the opportunity to download and check the factory images in advance of rebooting the device, which are available here: Pixel 10a (stallion) images on grapheneos.org. I pick the "stable" image, and its signature. I download the public key that the image is signed with, and verify that it matches what is said in the guide, and the same key listed in their github repository:
$ curl -O https://releases.grapheneos.org/allowed_signers
$ cat allowed_signers
contact@grapheneos.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIUg/m5CoP83b0rfSCzYSVA4cw4ir49io5GPoxbgxdJE
I check the factory image once it has finished downloading and unzip it:
$ ssh-keygen -Y verify -f allowed_signers -I contact@grapheneos.org -n "factory images" -s stallion-install-2026081300.zip.sig < stallion-install-2026081300.zip
Good "factory images" signature for contact@grapheneos.org with ED25519 key SHA256:AhgHif0mei+9aNyKLfMZBh2yptHdw/aN7Tlh/j2eFwM
$ dtrx -n stallion-install-2026081300.zip
I check the contents of flash-all.sh for any suspicious commands, but see nothing I wouldn't expect.
I notice the section in the guide on /tmp sometimes being too small, but mine is just under 8 GiB which I presume to be enough.
🐦⬛ Caw!
Quiet you, I can see that the install consists of multiple sub-images, none of which are even close to that large.
I reboot the device into fastboot mode once more.
This time I see that the device state is "locked (unlockable)".
It would have been nice if it had previously stated "locked (not unlockable)" instead of just "locked".
I again attempt to unlock the device using the fastboot command.
$ fastboot flashing unlock
< waiting for any device >
The command remains stuck here.
I notice that fwupd.service is active, and stop it once more.
I attempt to unlock once again, and fail once more.
Disconnecting and reconnecting the device makes it work.
I hit the volume down key to select "Unlock the bootloader" and proceed with the unlock.
The device state changes to "unlocked".
I make flash-all.sh executable and run it:
$ chmod +x flash-all.sh
$ ./flash-all.sh
[snip]
Warning: skip copying radio_a image avb footer (radio_a partition size: 0, radio_a image size: 191479948).
Sending 'radio_a' (186992 KB) FAILED (Write to device failed in SendBuffer() (Success))
After a bit of reading and tinkering I realized the error is probably due to using a USB hub.
I move the USB table to a USB port on the laptop instead.
I then re-run flash-all.sh but it hangs.
After fiddling with the script for a while I notice that it hangs on fastboot getvar product.
I verify this in a separate terminal.
fastboot getvar slot-count also hangs.
I disconnect and reconnect the USB cable, and verify that fastboot getvar slot-count works.
I re-run flash-all.sh and this time it works!
[snip]
Sending 'super' (30384 KB) OKAY [ 0.963s]
Writing 'super' OKAY [ 0.075s]
Finished. Total time: 1.041s
Once the script is done running, I re-lock the bootloader:
$ fastboot flashing lock
OKAY [ 0.180s]
Finished. Total time: 0.180s
I verify that the bootloader is now locked, and boot into GrapheneOS. Success! I set things up and disable OEM unlocking.
The two issues I had above were both mentioned in the guide, so I only have myself to blame for not reading it twice. Luckily no harm came from my bungling.
Initial impressions
The first thing that strikes me is that the default app store has almost no apps. What one needs to do is install another app store like F-Droid. From F-Droid one can install Aurora Store, which is a free software reimplementation of Google Play. It allows installing Android apps without having a Google account, which I think is very neat. It's possible to install BankID from Aurora, but it seems one still needs to have Google Play Services installed to use it.
I tried installing Mad Skills Motorcross 3 since a friend of mine works at Turborilla, just to see if it works on Graphene. I'm able to get into the menus, and after enabling Internet access I'm allowed to start the game. The game unfortunately seems to hang on the loading screen. Oh well.
F-Droid apps work as one would expect. For example NewPipe still works well as a YouTube frontend. OsmAnd~ unsurprisingly works much faster than before!
The main issue so far is getting files off my old phone and onto the new phone. For some reason it is not possible to just share files over Bluetooth, at least not in Lineage 16. Android Beam is a thing in 16, but it was removed by Google back in 2023 so it appears to not be an option. Warpinator looks promising for this task.
I have yet to move my SIM card to the new phone, so there's no telling yet how well that will work. The documentation suggests disabling everything except 4G (LTE) to reduce the attack surface. This seems prudent.