These instructions can be used to upgrade Raspberry Pi OS from Buster to Bullseye with only an SSH connection (no physical access). Some addidional steps are performed to make sure that the Pi automatically joins the WiFi network after upgrading. This is necessary if the Pi is located in a remote or hard to reach location.
Especially on older Pis, the upgrade will take several hours, so plan accordingly.
If you have physical access to the Pi, consider making a backup of the SD card with the SD Card Copier utility (red berry menu in the top left >> Accessories >> SD Card Copier).
If the SD Card Copier is not in the menu, you can install it with sudo apt install piclone
.
-
Make sure Buster is as up to date as possible:
sudo apt update
sudo apt full-upgrade
-
(optional) If you use manually installed Python packages, you can export a list of them, allowing you to quickly reinstall them after upgrading:
- Python 2:
pip freeze > python_2_packages.txt
- Python 3:
pip3 freeze > python_3_packages.txt
- Python 2:
-
IMPORTANT: Prevent the
connman
package from being installed. This package is not needed and prevents the system from automatically connecting to the WiFi after the first reboot:sudo apt-mark hold connman
-
Change the package sources to Bullseye:
sudo sed -i 's/buster/bullseye/g' /etc/apt/sources.list
sudo sed -i 's/buster/bullseye/g' /etc/apt/sources.list.d/raspi.list
-
Update the package sources and upgrade to Bullseye:
sudo apt update
sudo apt install libgcc-8-dev gcc-8-base
- After some time, a message titled
apt-listchanges: News
will pop up. You can close it withq
. - When asked if services can automatically be restarted, use your arrow keys to select
Yes
and confirm with the return key. - When asked about changed configuration files, choose
Y
if you didn't manually change the file. For manually changed files, chooseN
. To see the changes in the file, chooseD
, use the arrow keys to scroll the diff list and close it withq
.
- After some time, a message titled
sudo apt full-upgrade
- Follow the same steps as for the last command.
-
Remove old packages:
sudo apt autoremove
-
Switch to the new GPU driver on the Raspberry Pi 4:
sudo sed -i 's/vc4-fkms-v3d/vc4-kms-v3d/g' /boot/config.txt
-
(optional) If you exported your Python packages in the previous steps, you can reinstall them now:
- If you want to install the latest version of all Python packages (instead of the one that was previously installed), you can run these commands first:
- Python 2:
sudo sed -i 's/==/>=/g' python_2_packages.txt
- Python 2:
sudo sed -i 's/==/>=/g' python_3_packages.txt
- Python 2:
- Install the Python packets:
- Python 2:
sudo pip install -r python_2_packages.txt --upgrade
- Python 3:
sudo pip3 install -r python_3_packages.txt --upgrade
- Note that if pip/pip3 fails to install a package, all subsequent packets will be skipped. If this happens, fix the error and re-run the command.
- Python 2:
- If you want to install the latest version of all Python packages (instead of the one that was previously installed), you can run these commands first:
-
IMPORTANT: The upgrade deleted the WiFi country setting. You have to set up your WiFi country, or the WiFi will be disabled after rebooting:
sudo raspi-config
- Go to
5 Localisation Options
>>L4 WLAN Country
and choose your country.
- Go to
-
Finally reboot the system:
sudo reboot
Thanks for this @Iksas, was very helpful
I know it was probably written a while ago but for some reason when I was running
sudo apt full-upgrade
in step #5 it hung when trying to install conman.I expected that connman should have been skipped as I had run
sudo apt-mark hold connman
from step #3, so yeah not sure what happened that cancelled/prevented the hold on that package...For anyone else with a similar issue, to resolve it I had to get physical access to the Pi (as it wouldn't auto-connect to the wifi), got it to connect and then ran
sudo apt-get remove --purge connman
(after running the auto-suggested commandsudo dpkg --configure -a
to finalise the install of the other pending packages). From there I was able to complete step #5 and continue as normal.Note #2: Python v2 was removed, or unlinked, during the process for me it seems (I have an output in python_2_packages.txt but
pip --version
now points to python 3.9. shrug I wasn't using Python very much so might check on that later.Thanks again @Iksas