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"
Afterwards, update the firmware:
# rpi-eeprom-update -d -f /lib/firmware/raspberrypi/bootloader/stable/pieeprom-2020-09-03.bin
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$_}' )
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.
My MicroSD contains Ubuntu 20.04 right now. So I need to go back to RasperryPi OS first?
Hi Harry,
Maybe this could help you updating the EEPROM under Ubuntu: https://askubuntu.com/questions/1253070/raspberry-pi-4-firmware-upgrade-eeprom-over-ubuntu-20-04
I haven’t tried it cause I had a spare SD card with Raspbian around.
Merry christmas!
Best wishes,
Christian.