Booting Raspberry Pi 4 From USB

・3 min read

I recently purchased another Raspberry Pi 4 but this time I wanted to use Ubuntu 20.04 and I wanted to use a USB 3 1TB external hard drive as the boot disk. The reason for using a large boot disk is mainly to avoid SD card corruptions in future as all read/writes (once booted) will be on the external USB drive not on the SD card.

The first step is install Ubuntu 20.04 onto an SD card. Connect the USB hard drive to the Raspberry Pi 4 into one of the USB 3 ports and boot the Pi.

On first login on Ubuntu 20.04 the username is ubuntu and the password is ubuntu. You will be prompted to change the password the first time you boot.

SSH in to the Pi (after discovering its IP address via DHCP) and run the following command:

sudo fdisk -l

You will be shown a list of all partitions. As this is a standard Pi install with an SD card and an additional USB device, my partitions are as follows:

/dev/mmcblk0p2  =  SD Card
/dev/sda        =  External USB Drive

We need to set the partition table structure on the external drive /dev/sda.

sudo fdisk /dev/sda

Type p to see a list of partitions.

Then type d to delete the primary partition.

Now we need to create a new partition. Type n to create the partition, followed by p to set the new partition as primary and then choose 1 as the partition number.

You can press Enter twice to accept the suggested parition start and end blocks.

Finally, type w to write the changes to the disk.

Now the USB drive has the correct partition structure we need to format the new partition that we just created at /dev/sda1.

sudo mkfs.ext4 /dev/sda1

This may take a while, but no more than a couple of minutes if this is a fresh installation and the drive is smaller than 2TB (which it should be otherwise we need a different partition setup).

We need to make a directory where we will mount this USB drive to.

sudo mkdir /media/externalbootUSB

The directory name can be anything you want. Next we need to mount the partition to this new directory.

sudo mount /dev/sda1 /media/externalbootUSB

Now that the partition is mounted to our new directory, we can copy all of the SD card files to the USB drive partition.

sudo rsync -avx / /media/externalbootUSB

This took me around 3 minutes from a 32GB SD card to a 1TB USB 3 external drive.

Now we need to set the SD card to boot to the USB drive rather than itself.

As far as I know, on everything other than Ubuntu 20.04 and Raspberry Pi 4 this should be done in /boot/cmdlinetxt. On Ubuntu 20.04 and a Raspberry Pi 4 I had to do the following:

sudo nano /boot/firmare/cmdline.txt

Paste the following line (commenting out the existing line):

net.ifnames=0 dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc root=/dev/sda1 rootfstype=ext4 rootwait

Remember to change the root=/dev/sda1 to whatever your partition is.

sudo reboot now

Once the Raspberry Pi 4 reboot you should be able to login, run df -h and the USB drive should show as being mounted on / with a capacity of however many MB/GB/TB the external drive is.

ubuntu@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           380M  3.9M  376M   2% /run
/dev/sda1       916G  2.2G  868G   1% /
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/loop0       49M   49M     0 100% /snap/core18/1708
/dev/loop1       62M   62M     0 100% /snap/lxd/14808
/dev/loop2       24M   24M     0 100% /snap/snapd/7267
/dev/mmcblk0p1  253M   61M  192M  25% /boot/firmware
tmpfs           380M     0  380M   0% /run/user/1000

In my case, my external drive has 868G remaining and is only 1% used. The important value here is the Mounted on point. It must be /.

You can now customise the installation as much as you want as you’re booting from the external USB drive.