Make Ubuntu server 20.04 boot from an SSD on Raspberry Pi 4
It has been a while since I’m interested in Raspberry Pi, the reason why I’ve 6 Raspberry Pi at home 😝; however, I prefer Ubuntu Server rather than Raspberry Pi OS (ex-Raspbian), and it’s totally a subjective opinion (I’m using Ubuntu since version 08.04. 12 years ago; I’m feeling too old!).
Say Goodbye to your SD-Card
Since last May 2020, Raspberry Pi Foundation has announced its big show “the arrival of USB boot on Raspberry Pi 4 in a beta version”, and since I’m holding this kind of Raspberry Pi, I was looking for how to make it possible with Ubuntu Server for RPi.
I’m using my 6 Raspberry Pi as a Kubernetes Cluster, and I have a lot of I/O operations, so using an SD-Card is not enough for me (an SSD Hard Disk is more suitable for I/O operations rather than an SD-Card). After a lot of googling, I didn’t find a complete way to make my Raspberry Pi 4 boot Ubuntu Server from USB (whether USB key or SSD external) [With 0 errors], that’s why I’ve decided to write this post to explain how to make it possible with easy steps, so I hope it will help you.
To achieve this operation we need:
- Raspberry Pi 4b (at least 4 GBytes RAM).
- SD-Card (at least 8 GBytes disk space).
- USB key (or external SSD disk I’m using an SSD Disk with 256 GBytes space).
- BalenaEtcher installed to flash the SD-Card and the SSD disk → https://www.balena.io/etcher/.
- Raspberry Pi OS image → https://www.raspberrypi.org/downloads/raspberry-pi-os/ I’m using the lite version.
- Ubuntu Server 20.04 64 bits for Raspberry Pi → https://ubuntu.com/download/raspberry-pi
Let’s dive into it
First, let me say that this procedure can be applied to any ARM OS and not just Ubuntu Server.
1- Burn the Raspberry OS on the SD-card using BalenaEtcher.
2- Burn the Ubuntu Server on the SSD Disk using BalenaEtcher.
3- Boot your Raspberry Pi with the SD-Card (for the moment don’t plug the USB disk). If you want to access your Raspberry Pi from ssh, don’t forget to add the ‘ssh’ file to the boot partition.
4- In my case, I’m accessing my Raspberry Pi via ssh (default username: pi and password: raspberry, don’t forget to change them after login 😛).192.168.0.4 is the address of my raspberry.
$ ssh pi@192.168.0.4
5- Now let’s upgrade the system:
$ sudo apt update && sudo apt full-upgrade -y
This operation will upgrade the system and all the installed applications.
6- Edit the rpi-eeprom-update file and replace firmware release status by ‘beta’ value:
$ sudo nano /etc/default/rpi-eeprom-update
7- Install the latest bootloader beta update by executing the next commands: (2020–07–31 is the date of the recent beta bootloader in my case).
# cd /lib/firmware/raspberrypi/bootloader/beta/
# rpi-eeprom-update -d -f pieeprom-2020-07-31.bin
Once the rpi-eeprom-update command finishes reboot the raspberry.
8- After rebooting, you can verify that the eeprom has been updated successfully by executing this command and verify that you have the last version:
$ vcgencmd bootloader_version
9- Now, plug the SSD disk to the Raspberry Pi and mount its partitions.
a- let’s find the name of the disk by executing
$ lsblk
- /dev/sda1: the boot partition on the SSD.
- /dev/sda2: the principal partition on the SSD.
b- let’s mount them on /mnt/boot (the boot partition) and /mnt/principal (the principal partition)
$ sudo mkdir /mnt/boot && sudo mount /dev/sda1 /mnt/boot
$ sudo mkdir /mnt/principal && sudo mount /dev/sda2 /mnt/principal
10- Now we’ll copy the content (*.dat & *.elf files) of /boot partition to /mnt/boot.
$ cd /mnt/boot
$ sudo cp /boot/*.elf /mnt/boot/
$ sudo sudo cp /boot/*.dat /mnt/boot/
11- let’s extract the vmlinuz file on the boot partition https://en.wikipedia.org/wiki/Vmlinux .
$ cd /mnt/boot
# zcat vmlinuz > vmlinux
12- Update the section [pi4] on config.txt file (located on /mnt/boot) as follow:
# nano /mnt/boot/config.txt
Add the next lines and save the file.
dtoverlay=vc4-fkms-v3d
boot_delay
kernel=vmlinux
initramfs initrd.img followkernel
13- Now we’ll add a script for auto decompression of the Kernel in boot partition (/mnt/boot/) let’s name it auto_decompress_kernel.
#!/bin/bash -e# auto_decompress_kernel script#Set Variables
BTPATH=/boot/firmware
CKPATH=$BTPATH/vmlinuz
DKPATH=$BTPATH/vmlinux #Check if compression needs to be done.
if [ -e $BTPATH/check.md5 ]; then
if md5sum --status --ignore-missing -c $BTPATH/check.md5; then
echo -e "\e[32mFiles have not changed, Decompression not needed\e[0m"
exit 0
else
echo -e "\e[31mHash failed, kernel will be compressed\e[0m"
fi
fi#Backup the old decompressed kernel
mv $DKPATH $DKPATH.bak
if [ ! $? == 0 ]; then
echo -e "\e[31mDECOMPRESSED KERNEL BACKUP FAILED!\e[0m"
exit 1
else
echo -e "\e[32mDecompressed kernel backup was successful\e[0m"
fi #Decompress the new kernel
echo "Decompressing kernel: "$CKPATH".............." zcat $CKPATH > $DKPATH if [ ! $? == 0 ]; then
echo -e "\e[31mKERNEL FAILED TO DECOMPRESS!\e[0m"
exit 1
else
echo -e "\e[32mKernel Decompressed Succesfully\e[0m"
fi #Hash the new kernel for checking
md5sum $CKPATH $DKPATH > $BTPATH/check.md5 if [ ! $? == 0 ]; then
echo -e "\e[31mMD5 GENERATION FAILED!\e[0m"
else
echo -e "\e[32mMD5 generated Succesfully\e[0m"
fi #Exit
exit 0
make it executable:
# chmod +x auto_decompress_kernel
14- Now, we’ll add a script 999_decompress_rpi_kernel in /mnt/principal/etc/apt/apt.conf.d/ folder to decompress the rpi kernel , it’s content is:
DPkg::Post-Invoke {"/bin/bash /boot/firmware/auto_decompress_kernel"; };
make it executable:
# chmod +x /mnt/principal/etc/apt/apt.conf.d/999_decompress_rpi_kernel
Here is a link for further reading https://debian-handbook.info/browse/wheezy/sect.apt-get.html#sidebar.directory.d
15- At this step, our journey is over, switch off the Raspberry Pi and unplug the SD-Card, switch it on then and enjoy booting from SSD disk. I’ll access my Raspberry Pi now via ssh but with ubuntu this time (default user and password are ubuntu/ubuntu).
$ ssh ubuntu@192.168.0.4
After first login using ubuntu default credentials, the OS asks you to change the default password:
let’s check for the last time, by executing lsblk command:
Raspberry Pi is booting now from USB disk so enjoy it 😃.
N.B.: Since the bootloader is in the beta version you should repeat these steps in case of upgrading the boot.
I hope you enjoyed this small tutorial and now go enjoy your RPi Projects.