Linux OSBN/Ubuntuusers Planet XING / LinkedIn / Amazon

Raspberry Pi 4: Boot Ubuntu 20.04 via USB

For some time, the Raspberry Pi 4 also supports booting via USB to circumvent buggy SD card system media. Back in May, this feature was supplied as beta, since September it is considered as stable functionality.

Booting Raspberry Pi OS (former Raspbian) via USB works out of the box, but additional steps are required for the current Ubuntu LTS version 20.04.

Before booting Ubuntu via USB you will need to update the single-board computer’s EEPROM using a Raspberry Pi OS installation. First, ensure having all available updates installed and reboot the device before altering the configuration file /etc/default/rpi-eeprom-update:

FIRMWARE_RELEASE_STATUS="stable"
The previous setting (critical) won’t install the newest firmware!

Afterwards, update the firmware:

# rpi-eeprom-update -d -f /lib/firmware/raspberrypi/bootloader/stable/pieeprom-2020-09-03.bin
When writing this article, the latest firmware was released on 03.09.2020.

After another reboot the new firmware is enabled.

In the metantime, copy the Ubuntu 20.04 Raspberry Pi image on an USB device, e.g. using balenaEtcher or Win32DiskImager. Before the medium can be bootet, you will need to copy missing bootloader files. This can be done with the following command:

$ wget $( wget -qO - https://github.com/raspberrypi/firmware/tree/master/boot | perl -nE 'chomp; next unless /[.](elf|dat)/; s/.*href="([^"]+)".*/$1/; s/blob/raw/; say qq{https://github.com$_}' )
Kudos to Richard Tirtadji for this one-liner and the following script!

Afterwards, the downloaded *.dat and *.elf files need to be copied to the FAT partition on the USB device (will be mounted below /boot/firmware later).

This is also a good time to unpack the compressed kernel image as the firmware currently only supports booting uncompressed images:

$ cd mountpoint
$ zcat vmlinuz > vmlinux

In the same folder you will also need to alter the file config.txt to ensure that the image can be found. For my installation, the following lines were needed:

[pi4]
kernel=uboot_rpi_4.bin
max_framebuffers=2
dtoverlay=vc4-fkms-v3d
boot_delay
kernel=vmlinux
initramfs initrd.img followkernel

Afterwards, a script (auto_decompress_kernel) is created – it will automatically decompress kernel images:

#!/bin/bash -e

#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

Ensure changing the file permissions to make the script executable:

$ chmod +x auto_decompress_kernel

It is a good idea to link the script after the first boot with apt package management to have it executed after installing kernel updates. For this, create the file  /etc/apt/apt.conf.d/999_decompress_rpi_kernel and make it executbale:

$ cat /etc/apt/apt.conf.d/999_decompress_rpi_kernel
# content 999_decompress_rpi_kernel
DPkg::Post-Invoke {"/bin/bash /boot/firmware/auto_decompress_kernel"; };

$ chmod +x $_

Afterwards, booting should never be a problem again.

Sharing is caring

Leave a Reply

Your email address will not be published. Required fields are marked *