Claremont, Cape Town, 7708
+27 87 265 9183

Boot Ubuntu server from USB on Raspberry Pi 4

Boot Ubuntu server from USB on Raspberry Pi 4

First download Ubuntu 20.04 server LTS 64bit:
Download the Ubuntu image for Raspberry Pi 4 from the Official Ubuntu website.

Image used:

NB: Tested on RPi4 1GB version with latest Firmware.

Flash the image to a USB drive (USB 3 SSD or USB flash drive). Use Raspberry Pi Imager, Select “CHOOSE OS”, scroll down to “Use custom” browse to the downloaded Ubuntu image, select it, now select your USB Drive or USB Key and write it.

Once done remove the USB Key or USB Drive and plug it back in to your PC/MAC or Linux PC and wait for it to mount the disk (or you need to manually mount it), once mounted browse to the system-boot partition.

Open up a terminal and browse to “system-boot” partition.
on macOS it will mount to:
cd /Volumes/system-boot/
On Windows it mounts as an External Drive called system-boot :
i.e. F:/system-boot (your drive letter may differ)

Update the config.txt as follows for the [pi4] section:

On Linux or macOS you can use Nano editor:
$ nano -w config.txt
On windows just use Notepad or your favourite editor i.e. Sublime or Notepad++

Remove the [pi2] and [pi3] sections.

Update the [pi4] section to match below Example:

initramfs initrd.img followkernel

Now Extract the Kernel:
$ sudo dd if=vmlinuz bs=1 | zcat > vmlinux

You can play with enabling/disabling “dtoverlay=vc4-fkms-v3d” comment it # or un comment it, I left mine commented out as per the Example.

Unmount the USB Key / USB Drive and plug into RPi4 and boot.

Wait at-least 5 minutes for the system to settle, SSH keys etc need to generate.

Default login is:
Username: ubuntu
Password: ubuntu

After first login it will ask you to change the password, use a secure password

Reboot once to be sure that everything is working:
$ sudo reboot
log back in with your new password!

To get your IP type:
$ ip address

Boot script for auto Kernel decompression:

In the Boot folder:
on macOS: “/Volumes/system-boot/”
on Windows: YOUR_DRIVE_LETTER_HERE:/system-boot/
i.e. F:/system-boot (your drive letter may differ)
Add a new script to the boot partition called auto_decompress_kernel:
$ sudo nano -w auto_decompress_kernel

add the below:

#!/bin/bash -e
#Set Variables
#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"
#Backup the old decompressed kernel
if [ ! $? == 0 ]; then
exit 1
else echo -e "\e[32mDecompressed kernel backup was successful\e[0m"
#Decompress the new kernel
echo "Decompressing kernel: "$CKPATH".............."
if [ ! $? == 0 ]; then
echo -e "\e[31mKERNEL FAILED TO DECOMPRESS!\e[0m"
exit 1
echo -e "\e[32mKernel Decompressed Succesfully\e[0m"
#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"
exit 0

Now make it executable:
$ sudo chmod +x auto_decompress_kernel

Now boot up your Pi as the next steps will need to be done on the Pi to access the folder: $ /etc/apt/apt.conf.d/

I suggest SSH to your Pi and run the commands via remote terminal to make life easier:
$ cd /etc/apt/apt.conf.d/

Create a script called: 999_decompress_rpi_kernel
$ sudo nano -w 999_decompress_rpi_kernel

Now add to it:

DPkg::Post-Invoke {"/bin/bash /boot/firmware/auto_decompress_kernel"; };

Make it executable:
$ sudo chmod +x 999_decompress_rpi_kernel
$ sudo reboot

Now do a full upgrade, reboot a couple of times to be sure that it is working and that the Kernel is being decompresses as expected:
$ sudo apt-get update && sudo apt-get dist-upgrade -y
$ sudo apt full-upgrade

$ sudo reboot

We have a bunch of tutorials for various Ubuntu server installs, check them out for cool things you can now do with your Raspberry Pi 4 running Ubuntu server!!
You can find them here.

Configure the Firewall:
First check status:
$ sudo ufw status

Add default rules:
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing

Allow SSH:
$ sudo ufw allow ssh
Or if you changed your ssh server port you can specify it like this:
$ sudo ufw allow 22

Allow SSH only from trusted IP:
$ sudo ufw allow from YOUR_TRUSTED_IP_HERE to any port 22
$ sudo ufw allow from to any port 22

Enable the firewall:
$ sudo ufw enable

Adding other services:
$ sudo ufw allow http
$ sudo ufw allow https

Add custom ports:
$ sudo ufw allow YOUR_CUSTOM_PORT_HERE
$ sudo ufw allow 123

And finally you can check all your rules:
$ sudo ufw status numbered

To delete a rule by its number:
$ sudo ufw delete 2

To disable the firewall:
$ sudo ufw disable

To reset the firewall settings:
$ sudo ufw reset

More options:
Allow only specific IP on all ports:
$ sudo ufw allow from YOUR_TRUSTED_IP_HERE

Entire network/subnet on all ports:
$ sudo ufw allow from YOUR_TRUSTED_SUBNET_HERE.0/24

Also look at our how-to on generating SSH keys for password-less logins, then copy your SSH key across for password-less logins:
$ ssh-copy-id ubuntu@YOUR_RPI_IP.

Check out our simple howto on this here.


Leave a Reply