newline

Table of Contents

  1. Preparing before the update
  2. Updating
    1. Updating firmware
    2. Updating recovery
    3. Updating the whole system
  3. Post-update

Upgrading LineageOS 20 to 21 on a Samsung Galaxy S10

Guide, Mobile

July 20, 2024

Thanks to Linux4’s work and that of the LineageOS team, we have another major upgrade for Samsung Galaxy S10. Because it’s a major version change, this upgrade is a manual process. This time with the additional caveat that you have to wipe your data to upgrade. I was done in around half an hour, but then it took several hours to restore all my data.

The LineageOS wiki doesn’t emphasize this enough, so let me restate: you need to wipe your data to do this upgrade. Once more, you have to erase and factory reset your device to upgrade from version 20 to 21. I know, it’s annoying, it sucks, but it’s the only way. Apparently because of some repartitioning, but I’m not sure about the details, and I don’t know enough to disregard the warning with confidence that I won’t brick my phone. Hence, I’ll break down this post into 3 parts: preparing, updating, and post-update. I basically followed the guide here.

Preparing before the update

The first step is to back up everything you want to keep. Seedvault takes care of a lot of this, but in my case, I had to also manually copy some things (Signal backup, any files in the internal memory, any work profile data, two-factor auth database from Aegis, etc.). If it can’t back up something, Seedvault will tell you. Word of caution – I also had the additional problem that after updating, Seedvault didn’t restore the backup fully. It restored some apps, then started restoring Google Play Services, and then went back to the ‘select a backup to restore’ screen (seemingly having failed, but without a message). So, you might want to use additional backup solutions (you’re on your own there, I haven’t searched for any other ones yet).

Much of my data is copied with Syncthing, so that saves a bit of backing up too. Make sure any backups are stored on the SD card, and/or copy them to your computer (I used OpenMTP to transfer them to my computer), and make sure you have access to your Seedvault restore key.

Then, gather the files you need:

You will also need a computer with:

Once everything was backed up, I removed the SD card from my phone to avoid erasing it by accident. It shouldn’t happen, I don’t even think it’s possible through the interface, but I’m paranoid like that – I’d rather be sure the SD card filesystem isn’t even physically present when I erase data.

Updating

There were three parts to this: updating the firmware, updating the recovery, and finally updating the whole system. You need to have USB debugging enabled on your phone (go to Settings and About phone, tap the build number a bunch of times, then go back to the main Settings menu, search for USB debugging, and enable it).

Updating firmware

  1. Connect your phone to your computer, run adb -d reboot bootloader
  2. Follow the instructions here

Updating recovery

  1. Connect your phone to your computer, run adb -d reboot bootloader
  2. Follow the instructions here (no need to reboot into download mode, you’re already there): https://wiki.lineageos.org/devices/beyond1lte/install/#installing-lineage-recovery-using-heimdall

Updating the whole system

Follow the instructions here: https://wiki.lineageos.org/devices/beyond1lte/upgrade/

Post-update

Re-insert the SD card, boot up the phone, and go through the setup process, cancelling any google crap along the way. At some point it’ll ask you if you want to restore your Seedvault backup, and then tell you which apps it couldn’t restore.

There were a bunch of customization settings that didn’t get restored, which I had to change manually. Also, I had to restore some things from the Seedvault backup manually. I used this Seedvault extractor to decrypt the backup. Inside the backup, some files are TAR archives, and some are sqlite3 databases. For the sqlite3 databases, some had tables with the column kv_entry, where the key was a string and the value was a blob. To dump that, you can use the sqlite3 CLI tool and run a query like select writefile('/tmp/object', column_name) from kv_entry where key = 'whatever', and then analyze the dumped file further.