Raspberry Pi 4 Ubuntu 20.04 / 20.10 USB Mass Storage Boot Guide

Ubuntu Server 20.04 + Raspberry Pi
Ubuntu Server 20.04 + Raspberry Pi

*UPDATE 2/16/2021 – BootFix.sh has been fixed to work with the new Ubuntu 20.04.2 images. If you were having trouble grab the latest BootFix.sh from GitHub and try again and you should have success!*

Official support from Canonical for the Raspberry Pi has come a long way. We can now install officially supported Ubuntu on the Pi! In my previous guide for Ubuntu 18.04 on the Pi the Raspberry Pi was not officially supported yet and to be honest the experience was pretty janky.

The previous LTS “unofficial” release had so many problems I actually rolled my own image with dozens of fixes to common ailments before I quickly realized that maintaining a Linux distro, even in such a limited capacity as patching in and distributing fixed binaries, was a monumental undertaking.

Fortunately the current Ubuntu 20.04 LTS release is officially certified for the Raspberry Pi. This combined with Ubuntu’s full 64 bit userland/system environment allows you to take full advantage of the 8 GB Pi’s memory without per-process 3GB memory limits (very useful if you are doing something like running a Minecraft server and want to allocate almost all of the 8 GB to it) means there has never been a better time to give Ubuntu a try on the Pi.

This guide takes it a step further and shows you how to get Ubuntu 20.04 / 20.10 working with a SSD. Let’s get started!

Equipment Used

Kingston A400 SSD
Kingston A400 2.5″ SATA SSD

The Kingston A400 has been a great drive to use with the Pi for years. It’s reliable, widely available around the world, has low power requirements and performs very well. It’s also very affordable. This drive has been benchmarked over 1000 times at pibenchmarks.com and is the #1 most popular SSD among the Pi community!

Links: AliExpress.com*, Amazon.ae*, Amazon.ca*, Amazon.com*, Amazon.com.au*, Amazon.com.mx*, Amazon.co.jp*, Amazon.co.uk*, Amazon.de*, Amazon.es*, Amazon.fr*, Amazon.in*, Amazon.it*, Amazon.se*

StarTech 2.5" SATA to USB 3.0/3.1 Adapter
StarTech 2.5″ SATA to USB 3.0/3.1 Adapter

Both the USB 3.0 and USB 3.1 variants of the StarTech 2.5″ SATA adapter work well with the Pi 4. I’ve used the 3.0 variant with my Pi 4 since launch and it has always worked well. I later bought the 3.1 variant and had the same positive experience. These two adapter variants are my go to adapters for all my Pi related projects that need a fast and easy 2.5″ SATA SSD!

Links: AliExpress.com*, Amazon.ae*, Amazon.ca*, Amazon.cn, Amazon.com*, Amazon.com.au*, Amazon.com.mx*, Amazon.co.uk*, Amazon.de*, Amazon.es*, Amazon.fr*, Amazon.in*, Amazon.se*

NVME Option (powered USB hub required, see “Power Requirements” section in my more generalized Raspberry Pi 4 USB booting guide):

Samsung 970 EVO NVMe SSD
Samsung 970 EVO Plus

The Samsung 970 EVO Plus is a fantastic drive and has fallen in price substantially. It’s widely available around the world. The smaller capacities (such as the 250GB version) of this drive are perfect for the Pi! This is the top performance option without going into the “Pro” series of the lineup which are much more expensive.

Links: AliExpress.com*, Amazon.ae*, Amazon.ca*, Amazon.com*, Amazon.com.au*, Amazon.com.mx*, Amazon.co.jp*, Amazon.co.uk*, Amazon.de*, Amazon.es*, Amazon.fr*, Amazon.in*, Amazon.it*, Amazon.se*

ASUS ROG Strix Enclosure

If you really want to take things over the top the ASUS Rog Strix enclosure uses the latest USB 3.2 Gen2 specification, is RGB capable and works with the Pi. A powered USB hub is also required for this enclosure. Unsurprisingly, adding the extra lighting does take extra power! More widely available than the ICY BOX but tends to be on the expensive side.

Links: AliExpress.com*, Amazon.ca*, Amazon.com*, Amazon.com.au*, Amazon.com.mx*, Amazon.co.jp*, Amazon.co.uk*, Amazon.es*, Amazon.fr*, Amazon.in*, Amazon.it*, Amazon.se*


Verify Power Supply Size (3.5A strongly recommended)

Check your Raspberry Pi’s power supply size and make sure it is delivering at least 3.5A. There are a lot of USB C adapters for the Raspberry Pi that are only 3.0A. These will typically work fine, until you plug in something like a SSD which draws power from the Pi and there is nothing left to give.

Most SSDs are quite power efficient but HDDs draw significantly more. Older generations of SSDs used quite a bit more power than newer ones as well. If you are using an older drive or a drive that you know is power hungry you need to pay extra attention to having a quality power source with plenty of capacity.

A good alternative option to relying on the Pi to power the drive is using a powered USB hub* so your drive doesn’t need to draw power from the Pi’s limited power budget. Make sure you get one that is compatible with the Pi as some powered USB hubs won’t work properly with it so check the reviews and do your research to make sure people are using it successfully with the Pi.

Using a 3.5A power supply* or powered USB hub* will ensure your drive is getting enough power without impacting the Pi’s stability.

Recommended Power Solutions

Sabrent Powered USB Hub
Sabrent Powered USB 3.0 Hub

The Sabrent powered USB hub delivers a whopping 2.5A of dedicated power for your USB attached devices. This is almost as much as the Pi adapter itself is rated for (3.0A). It will easily power the most thirsty of setups such as NVMe enclosures.

Links: Amazon.ca*, Amazon.cn, Amazon.com*, Amazon.com.au*, Amazon.co.uk*, Amazon.es*, Amazon.it*, Amazon.se*

Note: Make sure Amazon doesn’t try to take you to the non-powered version and that it’s the one with the AC adapter that plugs in to provide extra power

CanaKit 3.5A Power Adapter
CanaKit 3.5A Power Adapter

The CanaKit 3.5A adapter has an extra half an amp (500 mA) of capacity to give some breathing room to your accessories. This is bigger than the official Pi power supply which provides 3.0A.

Links: Amazon.ca*, Amazon.com*, Amazon.com.au*, Amazon.com.mx*

Verify Storage Adapter Compatibility

You will need a USB 3.0 storage adapter. See my other article on USB booting not specific to Ubuntu for a lot more details on the storage adapters!

Get Latest Raspbian & Updates

To update your bootloader / firmware you should use Raspbian on a SD card. Right now support in third party operating systems to do anything with the new Raspberry Pi 4’s firmware or bootloader is very limited / nonexistent. You can use a third party operating system later once you set the boot mode, but to actually make these changes we will use official Raspbian.

First make sure that you have the absolute latest updates and firmware for the Pi. To upgrade all your packages and firmware to the latest version use the following command:

sudo apt update && sudo apt full-upgrade -y

Once the update has completed restart your Pi with a sudo reboot command to apply the latest firmware / kernel updates.

Verify EEPROM Bootloader is up to date

We can check if your Pi’s bootloader firmware is up to date with the following command:

sudo rpi-eeprom-update

If your Raspbian is *very* out of date you may not have this utility and can install it using:

sudo apt install rpi-eeprom

The output from rpi-eeprom-update will look like this if you are not up to date:

BCM2711 detected
VL805 firmware in bootloader EEPROM
BOOTLOADER: update available
CURRENT: Thu 3 Sep 12:11:43 UTC 2020 (1599135103)
LATEST: Tue 24 Nov 15:08:04 UTC 2020 (1606230484)
FW DIR: /lib/firmware/raspberrypi/bootloader/beta
VL805: up-to-date
CURRENT: 000138a1
LATEST: 000138a1

If it says any updates are available they be installed manually by adding ‘-a’ to the end of our previous command like this:

sudo rpi-eeprom-update -a

After the updates finish installing restart your Pi as firmware updates will not be applied until after a reboot. Now if you run rpi-eeprom-update to check for updates again it should say you are on the latest and up to date!

Changing rpi-eeprom’s Release Channel

Note: As of February 16th the firmware available in the “critical” branch is new enough to USB boot so I no longer recommend changing this. One reader even let me know in the comments that on the “stable” channel his storage was getting corrupted prompting a full reinstall!

By default you will only receive updates from Raspbian’s “critical” channel. This is a very conservative firmware update channel that will only give you very well tested firmware updates that are considered critical fixes for the device. Another channel that is available is “stable”.

Carlos and other commenters have reported that the current “critical” firmware didn’t work for them and they had to upgrade to the “stable” channel.

To switch to the stable channel we are going to edit the file /etc/default/rpi-eeprom-update:

sudo nano /etc/default/rpi-eeprom-update

Change the line FIRMWARE_RELEASE_STATUS=”critical” to:


Now you can run sudo rpi-eeprom-update and you should see a new update available.

Install Ubuntu on USB Storage Device

The new official Raspberry Pi imaging tool is really good. It’s available on Windows, Linux and MacOS and is a small and fast download. It also works fine on most USB mass storage devices like SSDs. Since Ubuntu is now officially supported the image itself is also available in this tool which saves you the trouble of having to find and download the right image files.

64 bit images are recommended for the Pi 4 for better performance but the 32 bit images work as well.

If you want to do things the traditional way you can download the image from the main Ubuntu site and write it yourself using Etcher / dd / Win32diskimager / your preferred tool and skip to the next section. It’s recommended to create the media with the Raspberry Pi Imager unless you are having problems with that utility or are using this as a troubleshooting step.

Once you’ve downloaded the tool run it as administrator/sudo to avoid permission errors. To run the utility from the command line is usually sudo rpi-imager. You’ll be greeted with this screen:

Raspberry Pi Imager - Main Menu
Raspberry Pi Imager – Main Menu

Next click the “Choose OS” button:

Raspberry Pi Imager - OS Menu
Raspberry Pi Imager – OS Menu

Ahh, the benefits of being officially supported! Ubuntu is right there on the list waiting for us. Select the Ubuntu option and you will get the different choices of flavors/architectures. There’s Ubuntu Desktop, Ubuntu Server, and Ubuntu Core in various forms of 64-bit (arm64) and 32-bit (armhf).

If you want to use the out-of-the-box Ubuntu Desktop edition you need to use the 64 bit Ubuntu 20.10 image as they never made a 20.04 desktop version for some reason. This really isn’t usually a big deal though because you can always choose the “Server” version and install Ubuntu’s desktop environment later with:

sudo apt install ubuntu-desktop

Once you’ve selected the edition you want go ahead and pick the “Choose SD Card” option and write the image. Despite not being a SD card my USB mass storage devices showed up anyway (writing the guide I used a StarTech adapter and a Kingston A400 SSD).

I’m sure some of you will manage to find unusual devices and configurations that may not show up in this tool. It doesn’t appear to show “fixed drives” that are physically installed in your machine. Regardless if it is causing a headache you may need to do it the old fashioned way and download the image from the main Ubuntu site and write the image using your favorite imaging tool instead.

Modifying Ubuntu for USB Booting

We need to make some changes to the Ubuntu drive we just created before we boot from it. Make sure your Pi is powered on and booted into Raspbian then plug in your newly imaged Ubuntu drive. We are going to make the changes using the Pi.

Find and Mount Storage Device

First let’s find your storage device using the command:


This will show you all the storage devices attached to your system:

sda           8:0    0 119.2G  0 disk 
├─sda1        8:1    0   256M  0 part 
└─sda2        8:2    0   2.8G  0 part 
mmcblk0     179:0    0  59.5G  0 disk 
├─mmcblk0p1 179:1    0   256M  0 part /boot
└─mmcblk0p2 179:2    0  59.2G  0 part /

Your SD card will always start with mmcblk so you can rule that one out. That leaves sda as the only other disk device on the system. This will be the same for most of you but depending on what type of drive and storage adapter you use this can vary. You can substitute whatever yours is in place of /dev/sda in these instructions going forward. If yours is sdb use /dev/sdb. If it’s nvme0 use /dev/nvme0, etc.

In my output under the “MOUNTPOINT” column you can see it is blank. This means the drive isn’t mounted on my system. My mmcblk0p1 mountpoint though is not blank and is “/boot” as an example of a non-blank mountpoint. If you are using the full “Desktop” version of Raspbian it may have automatically mounted your drive and created 2 shortcuts on your desktop that will take you to the files. If your mountpoint is not blank and has something like /media/pi/writable go ahead and unmount them now using the following commands substituting the mountpoint listed for your drive:

sudo umount /media/pi/writable
sudo umount /media/pi/system-boot

Now we are going to create two mountpoints and mount the Ubuntu drive. Use these commands substituting your own drive it is not /dev/sda:

sudo mkdir /mnt/boot
sudo mkdir /mnt/writable
sudo mount /dev/sda1 /mnt/boot
sudo mount /dev/sda2 /mnt/writable

Once you have mounted everything correctly your lsblk command’s output should look like this with the mountpoint field now populated:

sda           8:0    0 119.2G  0 disk 
├─sda1        8:1    0   256M  0 part /mnt/boot
└─sda2        8:2    0   2.8G  0 part /mnt/writable
mmcblk0     179:0    0  59.5G  0 disk 
├─mmcblk0p1 179:1    0   256M  0 part /boot
└─mmcblk0p2 179:2    0  59.2G  0 part /

Modify Mounted Partitions – Option A – Automated Script

If you just want to get your Ubuntu partition bootable I have made an automated script to do this. As long as you have mounted the partitions as /mnt/boot and /mnt/writable the script will make the necessary changes for Ubuntu 20.04 / 20.10 to boot! The source code for the script is available at https://github.com/TheRemote/Ubuntu-Server-raspi4-unofficial/blob/master/BootFix.sh

Here is a one liner to run the script:

sudo curl https://raw.githubusercontent.com/TheRemote/Ubuntu-Server-raspi4-unofficial/master/BootFix.sh | sudo bash

You may also download it for inspection (such as nano BootFix.sh or opening it in the Text Editor if you are using Desktop Raspbian) with:

curl https://raw.githubusercontent.com/TheRemote/Ubuntu-Server-raspi4-unofficial/master/BootFix.sh -O BootFix.sh
chmod +x BootFix.sh
nano BootFix.sh

To execute the script use:

sudo ./BootFix.sh

As long as you mounted your partitions correctly it will modify the partition and tell you that it was successful. Now unmount your partitions with the following commands:

sudo umount /mnt/boot
sudo umount /mnt/writable

You may now shut down your Pi and remove the SD card from the Pi leaving just the USB mass storage device plugged in. Reconnect the power.

Modify Mounted Partitions – Option B – Manual Instructions

See bottom of the article for the manual instructions section

First Boot

If all went well the system should boot up into Ubuntu’s logon screen! The default credentials are:

Username: ubuntu
Password: ubuntu

Before logging in for the first time you will be forced to select a new password. Once you have done that you will be fully logged in!

Important Note: Upon logging in for the first time if the Pi is connected to the internet Ubuntu will immediately/soon start a lengthy update process via snapd and apt.  This can be annoying since you'll be ready to start configuring the system and if you do an apt install it will halt and wait for the updates to finish.  

It may seem like they're stuck, but if you use the 'top' command you will see all sorts of apt/package/update/extraction related activity happening.  Even on my 8 GB Pi and a gigabit fiber connection these took a good 20 minutes or so before my CPU activity went back to 0 and the apt lock released.

I highly recommend letting these finish and not yanking the power on the Pi / forcing a reboot / trying to kill the processes.  It will often cause a ton of very nasty apt and dpkg problems to the point where it's easier to start over from a fresh image than try to fsck and apt install --fix-broken your way out of it  Try to do other necessary configuration that doesn't involve apt in the mean time and let these finish in the background.

Once the patching is finished your shiny new Ubuntu 20.04 system is fully ready to use!

Manual Instructions

These are the manual instructions to recreate what the automated script does. If you used the automated script you don’t need to do anything further in this section unless you want to understand more about how it works or you want to do the process manually.

Decompress the kernel

We need to decompress the kernel as we will be changing the way the Pi is booting. Ubuntu uses u-boot by default and we will be switching away from that. We can do this with the following command:

zcat -qf "/mnt/boot/vmlinuz" > "/mnt/boot/vmlinux"

Update config.txt with correct parameters

Now let’s update /mnt/boot/config.txt with the parameters we need to load the decompressed kernel. Open up config.txt with nano with:

sudo nano /mnt/boot/config.txt

Change the [pi4] section to the following contents:

initramfs initrd.img followkernel

Create script to automatically decompress kernel

We are going to create a script to automatically decompress the kernel. If we don’t do this we have to decompress it every time Ubuntu updates. This particular part of the script was not written by me and was found at the post on the Raspberry Pi forums by egrechko.

First let’s create the decompression script. Open up a new file with nano using:

sudo nano /mnt/boot/auto_decompress_kernel

Paste the following contents:

#!/bin/bash -e
# auto_decompress_kernel script
# 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
      echo -e "\e[31mHash failed, kernel will be compressed\e[0m"
# Backup the old decompressed kernel
if [ ! $? == 0 ]; then
   exit 1
   echo -e "\e[32mDecompressed kernel backup was successful\e[0m"
# Decompress the new kernel
echo "Decompressing kernel: "$CKPATH".............."
zcat -qf $CKPATH > $DKPATH
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"
   echo -e "\e[32mMD5 generated Succesfully\e[0m"
exit 0

Create apt script to call kernel decompression script automatically

This is a one liner to create a script to call the auto_decompress_kernel script:

echo 'DPkg::Post-Invoke {"/bin/bash /boot/firmware/auto_decompress_kernel"; };' | sudo tee /mnt/writable/etc/apt/apt.conf.d/999_decompress_rpi_kernel

Verify Drive Performance

You can make sure everything is running correctly (and as fast as it should be) by running my quick storage benchmark. You can run the benchmark with the following one-liner:

sudo curl https://raw.githubusercontent.com/TheRemote/PiBenchmarks/master/Storage.sh | sudo bash

This will give you a score you can compare to the other Raspberry Pi Storage Benchmark results and make sure that you are getting an equivalent speed to your peers with the same device!

Fix (some) USB Adapter Problems Using Quirks

Some storage adapters don’t work very well with the Raspberry Pi 4. There is an option that can get a lot of them working using quirks. If your Ubuntu is booting to emergency mode but not in normal mode it’s worth giving quirks a try. This lowers performance, but it’s still much faster than a SD card and your adapter won’t go to waste.

To find out the quirks mode string to use we need to find the device ID string for your adapter and then add an entry to cmdline.txt telling the kernel to apply them on boot.

Find Your Adapter

To apply the quirks we first need to get the adapter id. We will use the sudo lsusb command:

$ sudo lsusb
 Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 Bus 002 Device 002: ID 174c:55aa ASMedia Technology Inc. Name: ASM1051E SATA 6Gb/s bridge, ASM1053E SATA 6Gb/s bridge, ASM1153 SATA 3Gb/s bridge, ASM1153E SATA 6Gb/s bridge
 Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
 Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

On line 2 we can see my ASM1051E SATA 6Gb/s bridge adapter (it’s the known working StarTech.com 2.5″ SATA to USB 3.0* adapter). You will see something very similar to mine when you run the command and it shouldn’t be too hard to figure out which device it is. If you need more information add a -v switch to make the command sudo lsusb -v. This can sometimes add some additional details to make it easier to figure out which one is your adapter.

If you’re still not sure, we have another command that between the two that can narrow things down. Type / paste the following:

sudo dmesg | grep usb

 [0.828535] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 4.19
 [0.828568] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
 [0.828597] usb usb3: Product: DWC OTG Controller
 [0.828620] usb usb3: Manufacturer: Linux 4.19.75-v7l+ dwc_otg_hcd
 [0.828644] usb usb3: SerialNumber: fe980000.usb
 [0.830051] usbcore: registered new interface driver uas
 [0.830182] usbcore: registered new interface driver usb-storage
 [0.836488] usbcore: registered new interface driver usbhid
 [0.836511] usbhid: USB HID core driver
 [0.971598] usb 1-1: new high-speed USB device number 2 using xhci_hcd
 [1.154217] usb 1-1: New USB device found, idVendor=2109, idProduct=3431, bcdDevice= 4.20
 [1.154254] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
 [1.154281] usb 1-1: Product: USB2.0 Hub
 [1.301989] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci_hcd
 [1.332965] usb 2-1: New USB device found, idVendor=174c, idProduct=55aa, bcdDevice= 1.00
 [1.332999] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=1
 [1.333026] usb 2-1: Product: ASM105x
 [1.333048] usb 2-1: Manufacturer: ASMT
 [1.333071] usb 2-1: SerialNumber: 123456789B79F

This is the dmesg log showing the hardware detection as hardware is activated on the Pi. If your log is really long you can generate fresh entries by just unplugging a device and plugging it back in and running the command again. Here we can clearly see that the ASM105x is what our StarTech adapter is being detected as.

Now we can go back to our first lsusb command and we want the 8 characters from the ID field that comes right after the Device:

Bus 002 Device 002: ID 174c:55aa ASMedia Technology Inc. Name: ASM1051E SATA 6Gb/s bridge

Our adapter’s ID is: 174c:55aa

Applying Quirks

To apply the quirks to our USB adapter we are going to edit /boot/firmware/cmdline.txt. Type:

sudo nano /boot/firmware/cmdline.txt

We are going to add the following entry into the very front of cmdline.txt:


In place of the X’s above you will put in your adapter’s ID that we got before. With the example commands I gave above mine would look like this: usb-storage.quirks=174c:55aa:u. After this my cmdline.txt looks like this (everything should be one continuous line, no line breaks!):

usb-storage.quirks=174c:55aa:u dwg_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc

Now reboot the Pi. If the Pi fails to boot you can plug the SD card into the computer and go to /boot/cmdline.txt and undo the change we did so you can boot back in with your SD card.

Verifying Quirks

Once you have rebooted after changing cmdline.txt we can verify the quirks have been applied by doing another dmesg | grep usb command:

sudo dmesg | grep usb
 [1.332924] usb 2-1: New USB device found, idVendor=174c, idProduct=55aa, bcdDevice= 1.00
 [1.332957] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=1
 [1.332983] usb 2-1: Product: ASM105x
 [1.333006] usb 2-1: Manufacturer: ASMT
 [1.333028] usb 2-1: SerialNumber: 123456789B79F
 [1.335967] usb 2-1: UAS is blacklisted for this device, using usb-storage instead
 [1.336071] usb 2-1: UAS is blacklisted for this device, using usb-storage instead
 [1.336103] usb-storage 2-1:1.0: USB Mass Storage device detected
 [1.336479] usb-storage 2-1:1.0: Quirks match for vid 174c pid 55aa: c00000
 [1.336611] scsi host0: usb-storage 2-1:1.0

This time we can see in dmesg that UAS was blacklisted for the device and it has loaded with the usb-storage driver instead. This driver tends to be more compatible with the “problematic adapters” but the performance is usually significantly lower. It’s definitely worth a try though as some adapters do better with the quirks performance-wise. The only way to know for sure is to run a benchmark (see “Verify Drive Performance” section).

234 thoughts on “Raspberry Pi 4 Ubuntu 20.04 / 20.10 USB Mass Storage Boot Guide”

  1. Avatar for Chad Corbin

    Thanks so much for this tutorial! Confirmed that Ubuntu MATE 20.10 also boots from USB natively (maybe not surprising to many). Also, may be obvious to others, but I still had to:

    > sudo nano /etc/default/rpi-eeprom-update
    > sudo rpi-eeprom-update -a
    > sudo -E rpi-eeprom-config –edit
    > BOOT_ORDER=0xf41

    under Raspberry Pi OS before the Pi would boot to USB. The “rpi-eeprom-config” change was mentioned in the previous tutorial, but missing from this one.

    Now booting successfully using the Argon One M.2 case and Samsung 860 EVO M.2 SSD.

    One issue I’ve encountered (may be specific to the Argon One or may be common to USB boot in general) is that the Pi will freeze whenever it is put into suspend (automatically through power management, or manually from a menu), requiring a hard reset. I haven’t confirmed if this is the case with USB boot generally.

  2. Avatar for minnix

    Hey James thanks for this. One issue I’m having is when imaging ubuntu 64bit 20.04 server to a 4tb ssd with the raspberry pi imager, ubuntu is only using 1.7tb (about half the drive). lsblk shows the disk as being 3.7tb though but root partition is only 1.7tb. Is there a way to use the entire drive? Everything boots fine it’s just that one issue.

    1. Avatar for RobBohn

      Check if it is using LVM – my Ubuntu 20.10 server installation used LVM and only setup about 200GB on a 1TB drive. Here’s what I did:

      # View the current logical disk space
      sudo df -h /home/
      # **Avail** column is disk space remaining on this logical disk

      # View the disk’s LVM disk space
      sudo pvs
      # **PFree** column is remaining disk available to you

      # See Logical Volume info
      sudo lvdisplay

      # To extend your logical disk to use all available space do the following…….

      # Extend your logical volume – the last arg is the Filesystem in df -h command
      sudo lvextend -l +100%FREE /dev/mapper/ubuntu–vg-ubuntu–lv

      # Resize the Filesystem to match – the last arg is the Filesystem in df -h command
      sudo resize2fs -p /dev/mapper/ubuntu–vg-ubuntu–lv

      # see that it worked – **Size** should now be larger
      sudo df -h /home/

      Some of this info I got from: https://askubuntu.com/questions/1279912/install-encrypted-ubuntu-server-20-04-on-proxmox

      1. Avatar for jamesachambers

        Wow, very interesting!

        So traditionally Ubuntu has performed resize2fs as part of the initial setup. I wonder if this step isn’t happening for some reason or is picking wrong values for larger drives. Maybe it’s expecting a SD card and isn’t properly resizing a SSD since you two seem to have widely varying sizes of hard drives and both did not use the full space.

        It must be performing some sort of resize step since you both ended up with different size partitions. Maybe the LVM partitions are based on values that don’t make sense outside of SD cards or with very large sizes?

        Thanks for posting these steps, these look pretty painless!

        1. Avatar for minnix

          Ok I figured out the issue. The rpi ubuntu images use MBR instead of GPT disk partition tables, and MBR only supports 2tb or smaller drives. As far as I can tell there is no way to boot from larger than a 2tb disk with ubuntu rpi image. Raspberry pi os does support GPT but ubuntu rpi images do not. That is a shame. If you want to use ubuntu on a 4tb disk you will still need an sd card to boot from and move root to the usb disk, same as the old way.

          1. Avatar for jamesachambers

            Great discovery minnix!

            I actually had not tried this on a > 2 TB drive. This is a little disappointing for sure (it never feels good to have unprovisioned disk space or to not take full advantage of hardware due to technical limitations) and hopefully this will get addressed now that USB booting is officially released.

            They definitely need to fix that and update the base images to not require so many tweaks/modifications to get them to boot in the first place! If I were to guess we will probably see changes like this for the first time in whatever comes after 20.10 with 20.10 itself being the second most likely place for them to show up first.

            Historically the changes haven’t been backported to other versions but technically other versions weren’t “officially supported” at the time so I would love to see all these things fixed in the images and backported all the way back to LTS!

            1. Avatar for minnix

              There is an alternative if you’d like to use a 64bit OS with a disk over 2tb. Akeo (the creator of the Rufus disk imager) has laid out a method to install Debian bullseye using the netinstall iso directly to USB drive. Basically you format the drive with gpt partition table and create about a 350mb bootable partition (esp fat32, or in fdisk just use option 1 which is EFI partition which is what I did), then copy over the contents of the latest RPI EFI firmware and the contents of the debian netinstall iso into the new partition as well. Plug in the drive and turn on the Rpi 4 and you will be greeted by the debian installer, no SD card needed. Worked fine for me. He laid it out on the rpi forums: https://www.raspberrypi.org/forums/viewtopic.php?t=282839

              I kind of prefer this to ubuntu as I don’t need a desktop (even though you can install one if you’d like) and wanted something light and fast for server usage.

              1. Avatar for jamesachambers

                That’s a very clever trick by Akeo. I’m definitely familiar with Rufus and have used it countless times over the years!

                Thanks for sharing this. I have actually had fantastic experiences with Debian on the Pi. It was even a fantastic experience back on Debian Jessie! I’m sure it’s in part because Raspberry Pi OS / Raspbian is a derivative of Debian and is basically downstream from it but it’s a fantastic experience and I could see why you’re possibly even beginning to prefer it now!

      2. Avatar for RobBohn

        I did a default 64-bit Ubuntu Server install, and it must be doing this as some sort of almost thin provisioning, allowing me to choose later if I want to expand the same volume or alternatively make a separate/additional volume. But it seems backwards from previous experience. I had this just happen on five X64 systems with 3 different disk sizes – all made a single 200GB volume, leaving the rest unallocated. Weird.

  3. Avatar for Andres Torres

    Hi James! Thank you very much for the guide, it is really helpful.
    Just somethings i’d like to add hoping they can help others to overcome any issues with the installation process. I followed the guide using a Raspberry 4b 8Gb, using both scenarios, meaning flashing a USB 3 stick with Ubuntu Server 20.04 with Etcher and Raspberry imager, i had a boot issue in the last step where the PI complained about the SSD not being inserted, to fix this i was missing to set the option “Boot with USB if SSD is not present or has a problem” under the Advanced menu in raspi-config. Enabling this allowed the boot from the USB as expected. There is some UDEV issue on boot where some process gets stuck and it takes around 3mins for it to resume loading Ubuntu, more about it here: https://github.com/AdnanHodzic/displaylink-debian/issues/331 the solution was to run systemctl mask systemd-udev-settle . After the system boots there is no ETH0 connection, the ethernet card simply won’t work but what i did is connect my raspberry to my wifi and run a distro-upgrade, after upgrading the system it seems that netplan gets fixed and automatically you get ethernet working along with wifi.

    1. Avatar for jamesachambers

      Hey Andres,

      Thanks for the great tips! I think the reason that is fixing your ethernet is that it’s upgrading the firmware. Whatever firmware is shipping on Ubuntu 20.04 64-bit (funny enough the 32 bit one works) is way too old to USB boot Ubuntu and have networking. Again.

      I say again because I’ve had to fix their images for years to be bootable with all accessories working and unfortunately it looks like 20.04 isn’t going to change that. See my Raspberry Pi 18.04 precompiled image to see the lengths I had to go to previously to get everything to work! 20.10 is a much better experience and doesn’t need any of this.

      I’d rate LTS support (especially 64-bit) as EXTREMELY poor on the Pi (not even USB bootable with ethernet still in 2021) but people need to use it for a bunch of various reasons so I’ll provide a fix here. It’s definitely not the “LTS” experience of desktop. The newer one you use the better your Pi will work at the moment (which is pretty much the exact opposite of x86_64 Ubuntu). You’ve done very well getting all those fixes in there!

      I’m going to make the script update the firmware for 20.04 64 bit here but it’s definitely pretty janky compared to if Ubuntu would just update their base images. It’s basically a hack, where I copy the 20.10 firmware over the top of the 20.04 firmware. It would be better for everyone if they would update it themselves but it doesn’t look like it’s happening any time soon! They *never* updated 18.04 or any of those images but now that they’re officially supported maybe they’ll recompile a new base 6 months to a year from now.

      That is a really interesting solution with masking systemd-udev-settle, thank you for sharing! I have not seen that fix before and it will definitely help a lot of people out!

  4. Avatar for Stigh

    Hi James,

    I followed your example using an RPi4 8Gb, installing rOS first and ran the RPi Imager choosing 20.04 LTS Server 64bit, installed it on myUSB3 SSD. Success. Then I did the manual steps regarding lsblk and finally ran the script. Success. Removed SD for booting Ubuntu…
    It stop with a “Kernel Panic – Not syncing! : Can not allocate SWIOTLB buffer earlier and can’t now provide you with the DMA bounce buffer”

    Any suggestions?

    1. Avatar for jamesachambers

      Hey Stigh,

      I think someone else was recently having trouble with the 64 bit Ubuntu 20.04 image as well. I need to get it fired up on one of my Pis and see what has changed. It could also be your storage adapter. Which one are you using?

      Just for a test can you try with the 20.10 image? If that works then the script must need some changes here for whatever they did with the 64 bit Ubuntu 20.04 image!

      1. Avatar for Stigh

        Hey James,

        Currently writing to 20.10 Server 64-bit to the SSD for testing….

        Question; when I run the script and files are downloaded and written to ‘a’ partition – is this to the SD or SSD?
        As I retried the 20.04, I suddenly realized looking further up in the process there is insufficient space, probably causing the issue.

        Quite a noob still, espcially on linux partitions structure. Sorry for my dumb question.

      2. Avatar for Stigh

        Resolving deltas: 100% (3641/3641), done.
        error: unable to write file modules/5.10.6+/kernel/net/netfilter/nf_conntrack_sip.ko
        …and a bunch more ‘unable to write…’

        PS; I am running rOS from a regular thumbdrive and a SSD from another USB but this shouldn’t matter?

        1. Avatar for jamesachambers

          Hey Stigh,

          It sounds like either that disk/drive may be failing or the partition table is corrupt on it. Can you try running fsck against both partitions?

          Are you booting with them both plugged in at the same time? The output you posted said it’s unable to write to the drive. If both are plugged in it may be selecting the wrong drive.

          There’s also differences between how Ubuntu and Raspbian boot that could complicate things. Ubuntu always uses the root label partition of “writable” and doesn’t use partition IDs like Raspbian as well as some other subtle differences in how they boot. The official Ubuntu images usually boot using u-boot for example which is a totally different process altogether. The drive being full/out of space is another possibility but I really doubt it in this case.

          Theoretically it should work, but this type of boot support is brand new and so when troubleshooting this I would stick with the standard configuration for testing and to narrow this down. I’d try only with one plugged in if you aren’t doing this already just to rule out anything crazy like that!

          The partition might also be in “read-only” mode because it detected an issue with the partition table and won’t mount it in write mode until you run fsck on it. This happened to me once or twice during testing where my partitions were being mounted as “read-only” like this due to an error requiring fsck to correct. The other possibility is that the disk/drive is physically failing and that’s why it can’t write to those sectors/areas of the drive.

          I encountered partitions that needed an fsck a few times when I was preparing and testing this article originally. It definitely happens! Let’s start there and see what you’re getting.

          1. Avatar for Stigh

            Hey James,

            I will try fsck tomorrow.

            I booted with the USB thumbdrive inserted only, then I inserted the SSD.
            After that I ran the PRi Imager and wrote the image to the SSD.
            From there, I start with your guide.

            I’m using the new Argon ONE M.2 case so I’m not sure what “adapter” it uses.

            1. Avatar for jamesachambers

              Hey Stigh,

              Thanks for the additional info. I think fsck is for sure the place to start.

              I’d definitely try with Ubuntu 20.10 just in case as a test even if you 100% intend to stay on LTS. It has newer firmware and has solved issues in the past with certain drives/configurations. I may be able to fix the firmware issues as well if the newer image is working. I’m getting my Ubuntu imaging test station set back up here to give this one a try since this is the second issue with the 64 bit 20.04 image specifically that has come up recently.

              Another person was having an issue until they enabled “quirks” mode from this guide. I don’t have the Argon One case specifically but let’s see what you find out during your testing because that will narrow things down significantly!

              1. Avatar for Stigh

                Hey James, then I got everything working – the fault was using the ‘base’ rOS on a thunbdrive, even if I installed without connecting the SSD, where connecting the SSD after booted into rOS on the thumbrive. So a suggested addon in the guide, do NOT try to install and run rOS onto a thumbdrive, then inserting the SSD and continue. It will fail.

                Using a SD card, it worked straight forward, testing both 20.04 LTS Server 64 bit and 20.10 Desktop 64 bit.

                A final question; do you recommend running 20.04 or 20.10 on the RPi ?

                1. Avatar for jamesachambers

                  Hey Stigh,

                  That’s excellent news! That’s a great find. I’ll get that added in the guide here.

                  It makes sense on some level since they are both USB mass storage devices. When we change it to boot from USB mass storage there’s nowhere we really specify which mass storage device to use (yet that I know of). I’m guessing this will get fixed over time as more people try this!

                  At the moment I recommend 20.10 even though I’m a hardcore LTS fan usually. The reason is that LTS gets a really long time to get the firmware updates. Usually this is good because it ensures you have a nice stable experience.

                  Right now though with all these new features coming to the Pi I would set it up with 20.10 so you can take advantage of them without waiting for them to go through the long testing process to make it into LTS. I think a year from now my recommendation will be LTS again once all the firmware supporting the new features makes it’s way through the process! If you are trying to USB boot you will definitely have an easier time. The eth0 port seems to be missing on the 20.04 64 bit server version right now (which I’m in the process of investigating from other comments here) for example but works fine in 20.10.

                  In the past I have compiled images with newer firmware but I may update the BootFix script to give it a copy of 20.10’s firmware or something like that to fix the eth0 issue. But for the easiest/least frustration definitely 20.10 for the moment!

                  Hopefully that helps!

                  1. Avatar for Stigh

                    Hey James,

                    Thank you for replying and for pointing me to test the SD card rather than thumbdrive 🙂 This was actually a quite ‘natural’ thought as when the Argon One-case are assembled, you can’t access the SD card slot. So, when using this case, keep it open until scripts are open and you can remove the SD card before finally rebooting to start Ubuntu.

                    1. Avatar for jamesachambers

                      Hey Stigh,

                      No problem at all! I haven’t tried that case yet (link if people are wondering what we’re talking about) but I can see the appeal. I like my setups to be clean and streamlined. Having a giant long M.2 stick dangling loose off a cable definitely does not meet that goal.

                      The enclosures would be a second place. They’re not nearly as “messy” and are designed to lay flat and stay still and can be tucked out of the way but they still add an extra cable and external “piece” basically.

                      This type of setup is definitely first place for being clean and streamlined. You have M.2 solid state storage right underneath the Pi with a little USB connector connecting the M.2 board with one the Pi’s USB 3.0 ports. No extra cables!

                      I’m sure I’ll get one eventually but I just got the “Icy Box” recently and realized all my NVMe drives are in use for other projects! It’s probably time to upgrade one of the 256GB drives in my main tower now that solid state prices for large sizes have dropped significantly which will give me another project NVMe drive!

                      Thanks for leaving the tip for others. I know I’ve heard of this case before and I think I’ve seen it appear in some of the storage benchmarks so there are definitely other people who will be setting it up like this!

                  2. Avatar for Stigh

                    Hi James, regarding the Argon case, I think I read somewhere that is doesn’t support NVMe M.2’s – if this casing are to be considered, please check this thoroughly.

  5. Avatar for Ben

    A note for overclocking:

    It is still possible to overclock your pi in ubuntu by changing arm_freq in config.txt BUT the boot partition isnt necessarily in /boot. For me (by running mount | grep boot) my boot partition is in /boot/firmware, which is where i found config.txt.

    Im a noob and it took me 3 hours to figure this out

  6. Avatar for Ben

    Bought an ROG STRIX Arion and Crucial P1 for a minecraft server.
    I followed all the instructions and after rebooting i was met with ‘no sd card, please insert’. Had this issue for 3 hours while i messed around trying to get it working. eeprom was up to date, tried 20.10/04 and 18, manually doing the script steps, the img straight from the website, different ports, different cables, nothing worked.

    Finally to test if my firmware was correct i grabbed a thumb drive and followed the steps. Rebooted straight into ubuntu and it worked first time. Shutdown, removed the thumb drive and inserted the external enclosure (which had a clean flash of 20.04.1 and script run from my earlier tests), rebooted and it booted into ubuntu with no issues.

    I have absolutely no idea why this worked but here i am.

    Thank you for the fantastic walkthrough!

    1. Avatar for jamesachambers

      Hey Ben,

      I think you’re on to something here. I think some people may have recovery.bin on their main SD card’s boot partition and it is booting from that instead of the old version.

      You broke the cycle by not booting with the SD card so it booted off your “real” firmware instead of the recovery.bin on the SD card. Check out the documentation here for a source and some more background (the recovery.bin section): https://www.raspberrypi.org/documentation/hardware/raspberrypi/booteeprom.md


      At power on, the BCM2711 ROM looks for a file called recovery.bin in the root directory of the boot partition on the sd-card. If a valid recovery.bin is found then the ROM executes this instead of the SPI EEPROM image. This mechanism ensures that the bootloader SPI EEPROM can always be reset to a valid image with factory default settings.

      Can you check your SD card for recovery.bin? I’m curious if you will have it. I have a hunch that some of the people encountering this have something like this file on their SD card. Apparently when you have it it boots using that image and ignores your real one!

  7. Avatar for Carlos

    I was able to get 20.10 server 64bit working but not 20.04 64bit server. The network device is not recognized. I was not able to get ethernet or wireless enabled. dmesg did not have any mention of bcmgenet in it.

    BTW not sure if it is necessary for this to work but might be good to add instructions to change the eeprom release from critical to stable before running the rpi-eeprom-update command.

    1. Avatar for jamesachambers

      Hey Carlos,

      Thanks for the info and the steps you took here. I’ve added an entire new section called “Changing rpi-eeprom’s Release Channel” based on your feedback as I think it will help a lot of others as well. It actually explains why we had to fight with the firmware so much with some of the previous commenters.

      I think I’m up to speed! Are your cloud-init steps finishing on 20.04? This can take a long time, but it’s not recommended to log in until it has finished. I did this a few times during testing and sometimes it would give me weird errors like the ‘ubuntu’ user doesn’t exist since cloud-init was still in the setup steps and had not created it yet. I did not observe this behavior on 20.10 although cloud-init will sometimes still write text over the top of you when you think it’s already finished (and it still takes forever to do it’s initial ‘snap’ update before you can start using apt).

      If you’re trying to log in and cloud-init text/other text is displaying over the top of you it isn’t finished yet and interfering with this can break networking. The important one to not interfere with is the one time setup the very first time you boot it. After the first boot interfering with cloud-init is harmless, but the Pi specifically has special steps like expanding your partition to use all the free space on the drive, creating the “ubuntu” user, etc. on the very first startup.

      If you do a dmesg | grep firmware does it say anything anywhere about firmware files unable to load/not found? I have seen this kind of thing before when I did my old Ubuntu 18.04 image. That image had like 20-30 fixes like this from before it had official support. When preparing that image to fix issues like this I would copy the latest firmware from /lib/firmware on Raspbian into Ubuntu’s /lib/firmware directory over the top of it.

      Whether dmesg is complaining about firmware or not, this is what I would try: copy all of the contents of an up to date Raspbian/Ubuntu 20.10 /lib/firmware folder over the top of your existing Ubuntu 20.04 /lib/firmware folder replacing any files that have a conflict with your newer more updated source. You could also use one of your Ubuntu 20.10 /lib/firmware folders as a source as well. Anything that is newer than the 20.04 firmware or is actually able to boot with all components available to the OS and functioning properly.

      Make sure you are matching 64 bit to 64 bit and not trying to copy 32 bit firmware to a 64 bit distro or vice versa. If you don’t have the 64 bit Raspbian beta version then use Ubuntu 20.10 64 bit as the source instead. After this reboot Ubuntu and see if it recognizes your networking.

      I went as far as rebuilding the kernel in 18.04 to get all the hardware accessories working but I really don’t think that should be necessary for 20.04 64 bit. Can you give copying the firmware over the top of your old firmware a try? If it still isn’t working I can look at the script this week here and see if I can reproduce it myself as well! If it does work maybe I need to add firmware updating into the BootFix.sh script.

      1. Avatar for Carlos

        Thanks for the detailed reply. I think you are right about the likely cause. I used the RPi Imager tool and it only has the 32bit versions of the Raspberry OS which is what I ran your script from. Odd thing is I used the exact same sd card for running your script to ‘fix’ USB sticks with 20.04 and 20.10. I’ll install the Ubuntu 64bit on an sd card and try with that instead in the next couple days. Cheers!

      2. Avatar for Carlos

        Couldn’t help myself I did some tests that didn’t require much active time…. here are some updates.

        Using an SD Card with Ubuntu 20.94 64bit Server.
        – fresh install of same ubuntu on USB stick
        – SD and USB in at power on, rpi boots from the USB and everything works fine without having to run your script. I believe this is expected given the SD was in.
        – Decided to run your script after it booted and cloud-init completed (rebooted with SD first and inserted USB after). Ethernet did not work after booting without SD card installed.
        – Repeated with another fresh install on the USB, this time inserted it after SD booted and ran your script. Still did not work.

        I fetched the 8/20 beta 64bit release of raspberry os and will try that next on an SD card. If it does not work I will try the steps you described above to copy the firmware.

        1. Avatar for jamesachambers

          Hey Carlos,

          Those were all great steps to do. You covered a lot of bases and confirmed some things. I think we’re on the right track here. I think that the /lib/firmware/* files may need an update for 20.04 64 bit.

          It’s interesting that the 32 bit works as I’d just tested this with another commenter earlier but that the 64 bit seems to not have new enough firmware. It has been a little bit since I tested the 64 bit 20.04 one so I will give that one another try. It sounds like you’ve tried enough times that it can’t just be a one-off and it should happen to me as well. I should be able to be of more assistance when I take a closer look!

          1. Avatar for Andrey

            I’ve just tried both steps and yep – ethernet doesn’t work. There were no eth0 at all. When I tried to load manually bcmgenet module, it wasn’t there in the ubuntu image. For some reason, wifi didn’t work either – so I can’t get out to the network from that ubuntu 20.04

            1. Avatar for jamesachambers

              Hey Andrey,

              Thanks for confirming! My tentative plan is to have BootFix.sh update the firmware on the 20.04 image so it can recognize the eth0 adapter.

              I’m planning on firing this up today and getting it working!

              1. Avatar for Zirowe

                Hi, thank you for your work and detailed description.
                I also have the no ethernet/wifi connection after booting without sd from ssd with ubuntu 20.04.01 64bit.
                Cant even use ifconfig, since its not installed, and wont install without connection.
                Is there a workaround?

                1. Avatar for jamesachambers

                  Hey Zirowe,

                  It looks like Andres was able to get his firmware updated to do it. I’m sure you can just copy newer firmware over the top of your /lib/firmware from a Ubuntu 20.10 image or an updated 20.04 image as I’d been doing this for years to fix 18.04.

                  I am going to go down to my Pi lab in the basement here after I finish eating and see if I can get this added in here today. This has been on my to-do list pretty much all week but it has been a crazy week. Today is the day! It should be a relatively simple change but will require a couple hundred MB update for Ubuntu 20.04 64 bit LTS. I’m only going to target that version and not touch the firmware on any 32 bit or the working 20.10 64 bit.

                  You could absolutely check back here a little later today if you didn’t want to fight with manually updating the firmware (understandable)!

                  1. Avatar for jamesachambers

                    Ok I think I found the problem. It turns out that 64 bit Ubuntu 20.04.1 actually *can’t* take the new DTBs. That is actually the problem. The firmware is too old to even load them.

                    This means that the solution was easier than I thought. If it is Ubuntu Server 64 bit 20.04.1 it now skips updating the DTBs for that version and continues to update the DTBs for the other versions.

                    I’m finishing final testing on this now but I wanted to let you know it was ready to try when you checked back! It is available on GitHub. Make sure you delete your old BootFix.sh script and download the latest one and it should be ready to try again! You will want to start with a fresh image, the old DTBs that it is going to leave in place have already got overwritten in the drive you prepared earlier.

                    When you run a sudo apt-get update && sudo apt dist-upgrade -y you will get the latest firmware/updates that fix this issue. This fix will just help it have ethernet when it boots the first time before updating!

                    1. Avatar for Carlos

                      Hi James. Just to followup on this. I had been running with the RPI image in the SD card to allow it to boot from the USB. Based on the above I decided to do the the apt upgrade and that took care of it for me. I was able to remove the SD card and happily boot ubuntu 20.04 from USB now. Thank you!

  8. Avatar for Mike Carillon

    as long as your eeprom bootloader is up to date, the latest ubuntu-20.10-preinstalled-server-arm64+raspi.img image from ubuntu will boot with out any changes.

    1. Avatar for jamesachambers

      Hey Mike,

      That’s great! I wish I could say I was positive they were going to fix all of them eventually here but I’m not.

      We waited so long for fixes on 18.04 and they literally never came. I had to roll an alternative image to fix the dozens of issues with it. All the fixes for 18.04 ended up coming out in 19.10 and 20.04.

      Let’s hope that the new “officially supported” status of these new images means these fixes/updates will be backported to the current branch this time rather than making everyone wait until the next version of Ubuntu.

      Thanks for letting us know this. It’s useful to know the server image will work on an updated one without changes if your firmware is up to date.

      Updating firmware is unfortunately where most problems have been but after a few tries with the recovery image most people have been getting through it!

    2. Avatar for Steve

      That worked for me where anything less than 20.10 did not. I am using a UGREEN M.2 NVMe enclosure with a Samsung 970 Evo 512GB SSD.

      I just set the boot loader to stable and updated to latest (December 11 2020 as of today). Then flashed the Ubuntu 20.10 image referenced above to the SSD. Turned off RPi4; Removed SD Card; Plugged in enclosure (Used blue port) and turned the Pi on. Booted just fine.

      One caveat: Do not assume the Pi will be allocated the same DHCP IP address every time it starts. With the SD card it got one address from the router but with the SSD it was given a different IP address. My experience has always been that a devices MAC address was used to allocate DHCP addresses from the router but this time that assumption tripped me up.

      1. Avatar for jamesachambers

        Yeah this absolutely appears to be necessary. I do a ton of crazy testing with my Pis and undoubtedly had much newer firmware than most users on all my Pis!

        I added it in the guide directly after my conversation with Carlos in the comments here to hopefully save others some time and frustration.

  9. Avatar for Wally

    Hello Got the SSD to boot but cannot get the WiFi to work? Only the ethernet works. How to get WiFi to work?
    I tried netplan to set wifi but still won’t work. When type hostname -I will get blank line only? So unable to get WiFi to output a IP address so I can ssh from my laptop? Please advise how to fix this WiFi issue and no IP address for it ? Thanks. Wally

    1. Avatar for jamesachambers

      Hey Wally,

      It’s extremely tricky to configure netplan unfortunately. If there’s a single wrong space/tab out of place in the YAML config file it will basically stop reading your changes from that point.

      Is this a version with a GUI or is this command line only? Getting the GUI version is the easiest answer, but if you have a use case or need to use the CLI version here’s what I would do:


      I would try to configure your Pi using the wpa_supplicant.conf method like you do using the CLI on Raspbian. It should work the same on Ubuntu. This method doesn’t apply itself every time you reboot and there’s more configuration to make the changes stick permanently, this is more just for a test to see if it’s just netplan choking on the config file and if your WiFi is actually functioning.

      Do you see the WiFi card? If you do a:

      ifconfig -a

      If you don’t have net-tools yet (very handy for CLI) you can install them with:

      sudo apt install net-tools -y

      I think we need some more information here. The hostname -l says a blank line only. It may be as simple as your WiFi interface isn’t enabled and just needs to be turned on with a:

      sudo ifconfig wlan0 up

      Let us know what you see!

  10. Avatar for Joel

    Hi James,

    I followed your steps but during the first boot, I get a

    Failed to start journal service
    Failed to load Kernel Modules
    Failed to apply Kernel Variables

    Any advice is appreciated.

    1. Avatar for jamesachambers

      Hey Joel,

      It looks like it’s not finding the kernel modules in the /boot partition. Can you try running a fsck on the boot and root partitions? I know it isn’t booting but if you have another PC you can check it from there. If you look in your “boot” folder/partition does it look like all the files are there?

      It may have also just been a bad image. It may be worth it to try one more time. Sometimes if something goes wrong and it needs an fsck it’s faster to just start over!

      Which version and flavor of Ubuntu are you trying to set up?

  11. Avatar for Paolo

    Hi James!
    Wonderful work!
    This procedure can help people a lot!!!

    But I’m not able to use the same to make “LXD Ubuntu Appliance for Raspberry Pi” USB bootable, because seems bootable only from a SD card.
    Here the link: https://ubuntu.com/appliance/lxd/raspberry-pi
    As far as I was able to understand, content of this “appliance” is a (deeply?) modified Ubuntu server, so boot files are different.

    I understand that is another and less interesting service, even, if working as expected, may be able to run a good number of OS container on a RPi 4 8G (as mine).
    Moreover, one the same ESXi for Arm work very well, but I like to do something similar but with a open source solution without tile limits.

    Coud you help me?

    Thanks in advance!!!

  12. Avatar for Victor

    Hello James,
    I’ve set up my system to use an SSD, according to your previous method of booting from the flash drive and then transferring control to the SSD which contains the Raspbian system. It works fine, but now that it’s possible to boot directly from the SSD, I’d like to do that. I don’t want to do a new installation if possible. I suspect this should be easy, but I’m a newbie and don’t want to mess it up. Can you help?

    1. Avatar for jamesachambers

      Hey Victor,

      I think I can help! First you’ll need to update your Pi’s bootloader firmware. To do that I would prepare a Raspbian installation temporarily on a spare SD card/drive and then do a:

      sudo apt full-upgrade -y

      After it finishes reboot your Pi with:

      sudo reboot

      After it reboots you can verify it updated the firmware with the command:

      sudo rpi-eeprom-update

      The reason this is necessary is that if you have been USB booting Ubuntu it doesn’t have any mechanism to update your Pi’s onboard bootloader firmware so it is almost certainly too old to natively USB boot yet.

      After you’ve ran full-upgrade and rebooted the first thing I would try is to actually shut your Pi down and remove your SD card leaving only the SSD plugged in. See if it will boot from it with the new bootloader firmware without making any other changes and just taking the SD card out. If it doesn’t, then here’s what I would do:

      From this point on is theoretically the danger zone where we will start making changes. I’m also assuming that the drive you are trying to convert is running Ubuntu 20.04 or 20.10. If it’s running an older version let me know first before trying these instructions as they are designed for 20.04 and 20.10.

      I know your goal is to not lose everything and have to start over but definitely just in case back up anything that is important as it would be irresponsible for me to tell you nothing could go wrong or there’s no risk. Let’s boot back into the Raspbian installation we used earlier to update your Pi’s firmware and connect your SSD.

      From here you’ll follow this guide but you will skip to the “Modifying Ubuntu for USB Booting” section as you already have an imaged drive. You’ll run the BootFix.sh script which will update the firmware on the boot partition (files like start4.elf, etc) and decompress the kernel which will allow it to natively USB boot without having to use a SD card anymore! Again, make sure you’re running 20.04 or 20.10 or let me know first as I have no idea what this would do to 18.04 but if you are on a newer one I have thoroughly tested all of those!

      This will reset any custom changes you have made to /boot/firmware/config.txt so if you have anything set up in there you’ll need to redo it as this file gets tweaked to allow the Pi to natively USB boot. That should be it. It’s pretty much the same process as if you did a fresh image other than the losing custom config.txt changes!

      1. Avatar for Victor

        The drive I am using now is running Raspbian, not Ubuntu. All I did was to copy the Raspbian SD card to the SSD, change the partuuid of the drive and then change cmdline.txt on the flashcard to point to the SSD. I am happy with Raspbian, so there should be little that I have to do. I have run sudo apt full-upgrade -y and also sudo rpi-eeprom-update -a, but there is still something that needs to change in order for it to boot from the SSD. When I remove the flashcard and power up the LED on the SSD flashes, but it does not boot.

        1. Avatar for jamesachambers

          Hey Victor,

          Perfect, that helps. It sounds like you’ve already taken care of the firmware and the upgrades. I think in your case you may just need to do a:

          sudo -E rpi-eeprom-config --edit

          and change the BOOT_ORDER line to:


          Then a Ctrl+X and then a y to save. I have some better instructions on modifying the bootloader configuration in my New Raspberry Pi 4 Bootloader USB Boot Guide in the “Editing Bootloader Configuration” section that goes through this step by step.

          This will change the bootloader to try booting from the SSD first and then it will fall back to the SD card if the SSD boot fails. I have a feeling your BOOT_ORDER is going to be something like 0x1, which just means try booting from the SD card and don’t do anything else.

          Can you try making that change and rebooting without the SD card in? The other possibility is that the /boot partition on your SSD’s partition need to be updated as well as apt usually only gets one or the other during upgrades and one of them ends up behind/out of sync.

      2. Avatar for Victor

        I’m thinking that what I need to do is update /etc/fstab and then rerun all the updates, because apt has been updating the flashcard’s boot partition.
        But I am afraid to do it! Here is what it looks like now:

        proc /proc proc defaults 0 0
        PARTUUID=97709164-01 /boot vfat defaults,noatime 0 2
        PARTUUID=d34db33f-02 / ext4 defaults,noatime 0 1
        # a swapfile is not a swap partition, no line here
        # use dphys-swapfile swap[on|off] for that

        So should I change the first line to look like the second?

        1. Avatar for jamesachambers

          Hey Victor,

          Yes I definitely saw that coming too in my other reply here as well. I do think you’ll need to modify that partition label in /etc/fstab to match your SSD or it isn’t going to find it when you remove the SD card.

          Between that and making the change from my other reply you should be covered because as you said it’s a relatively small amount of changes we made in the first place and you’re taking them all into account here!

            1. Avatar for jamesachambers

              Yes it will still be vfat and will be completely identical other than the partition label. You could generally just copy the files from the SD card’s /boot folder over the top to update them which will save a little bit of time over going the apt route but both would work.

              Apt might not realize that those files aren’t up to date since the package manager doesn’t store that info on the boot partition and I don’t think it actively scans them for changes but you could force a reinstall or some other apt tricks to get it to do it.

              The very last numbers there are the order that fsck is supposed to check them for errors at boot time. You can generally leave these the same.

              1. Avatar for Victor

                The dates on the files in the boot partition on the ssd are recent so I think they have been updated. So I think I am safe to go ahead and change fstab and then the boot order and try it.

                1. Avatar for jamesachambers

                  I think so too but I have a feeling your bootloader needs the recovery image flash before it’s going to go. It’s missing too many options here and looks like a config from before native USB booting was possible.

                1. Avatar for jamesachambers

                  Gotcha. We’ve seen this before in the comments of the New Raspberry USB boot guide as well.

                  The only fix so far has been to create a SD card with the “Raspberry Pi 4 EEPROM boot recovery” image from the Pi Imager tool. This image is located in the “Misc utility images” section of the Pi Imager utility.

                  It’s super simple to run, you just basically plug it in and let it boot and it will start blinking. At that point it’s done. If you boot back into Raspbian you should have all the options available to you! I do have a step by step guide available in Raspberry Pi 4 Bootloader Firmware Updating / Recovery Guide as well.

                  1. Avatar for victor

                    Well, I’ve downloaded it for my Windows computer. Unfortunately when I insert my only spare SD card (which was fine the last time I used it) I get a “blue screen of death.” I will have to get another SD card. Anyway it is past midnight here so I will hit the sack now. Hopefully I have all the information needed to continue once I have a new card. Thank you for your help!

                  2. Avatar for Victor

                    Good Morning!
                    I purchased another SD card, and created the bootloader image refresh easily. I put it into the pi (model 4, 4 GB) and it blinked a few times and then blinked rapidly as it was supposed to. Then I rebooted, but I still do not see a BOOT_ORDER line, just the same three as before.

                    1. Avatar for jamesachambers

                      Hey Victor,

                      It’s worth a try, but everyone else who has tried that got a timeout error when they tried to save it. Here are the options it’s supposed to have:


                      Take a look at the dates and versions the options were added. You don’t have a single option added in 2020. Your last option is POWER_OFF_ON_HALT=0 which was added all the way back on 2019-05-10. So just to understand why I’m concerned, you aren’t missing one option. You’re missing at least 7 options. Anything that was added in 2020 is missing from your config. I bet if you try to add them it won’t let you and will give you a timeout error.

                      You’re the first person that the recovery image hasn’t fixed. Check out what happened with Frank Meyer, who had the EXACT same broken config as you did: https://jamesachambers.com/new-raspberry-pi-4-bootloader-usb-network-boot-guide/comment-page-1/#comment-7811

                      Maris also tried to do this in https://jamesachambers.com/new-raspberry-pi-4-bootloader-usb-network-boot-guide/comment-page-1/#comment-7752 and wasn’t able to do it. He ended up using a different storage adapter or even an external drive to update it it looks like.

                      I would say go ahead and add the line but it looks exactly like these other two that they were eventually able to fix using the recovery image and it sounds like possibly a different storage device/adapter. Let’s see if you get this same timeout error.

                      We had someone new stop by and say they actually fixed their USB booting by reverting to an older version here: https://jamesachambers.com/raspberry-pi-4-bootloader-firmware-updating-recovery-guide/comment-page-1/#comment-8319.

                      We’re in uncharted territory with yours though. Everyone else so far has eventually got it using the recovery image. Maybe it’s going to take more than one try or fiddling with different storage devices too like Maris!

                    2. Avatar for Victor

                      Hi James,
                      Well, I’m making progress. I ran the bootloader refresh two more times and now I have all the options. The BOOT_ORDER was already 0xf41, so I didn’t change anything there. I changed the PARTUIID in fstab to the SSD.
                      Now it still boots with the SD card inserted (it transfers control to the SSD), but when I take it out, it appears to by trying to boot from the hard drive but doesn’t succeed. The green led flickers a few times, as does the led on the SSD, but nothing happens. Then it tries again, etc.
                      Something is missing somewhere.

                    3. Avatar for victor

                      Here is the output from df when it boots with the card inserted. You can see that it is using the boot partition of the SD card:

                      Filesystem 1K-blocks Used Available Use% Mounted on
                      /dev/root 240067368 7900424 222327108 4% /
                      devtmpfs 1827800 0 1827800 0% /dev
                      tmpfs 1959896 0 1959896 0% /dev/shm
                      tmpfs 1959896 16916 1942980 1% /run
                      tmpfs 5120 4 5116 1% /run/lock
                      tmpfs 1959896 0 1959896 0% /sys/fs/cgroup
                      /dev/sda1 258095 53463 204633 21% /boot
                      tmpfs 391976 0 391976 0% /run/user/1000
                      tmpfs 391976 0 391976 0% /run/user/1001

                    4. Avatar for jamesachambers

                      Hey Victor,

                      That is excellent progress! That’s perfect that it defaulted to 0xf41 since they changed that to be the default a few months ago and it’s another good sign that the bootloader firmware recovery actually worked!

                      We may need to check your partition labels here. What does your /etc/fstab look like right now?

                      In the df output you posted it looks like it actually is using the SSD for your boot partition even when you’re booted in on the SD card:

                      /dev/sda1 258095 53463 204633 21% /boot

                      /dev/sda1 should be the SSD. The SD card should be something like /dev/mmcblk0p1. Very interesting. This would suggest that your /etc/fstab is correct and that it is mounting the SSD for the /boot partition. Will it still not boot if you take the SD card out completely and then connect the power?

                      How did you end up transferring the files from your SD card’s boot partition to the SSD? You can connect it on a Windows or Linux computer and drag and drop them from the SD card’s “boot” to the SSD’s “boot” with just a normal file explorer window choosing to replace anything that has a conflict with the newer more updated version from the SD card.

                      In a configuration like you had typically the files in “boot” on the SSD will be the stock ones from when you imaged it (never updated) since that partition has never been mounted by the OS before until you modified the /etc/fstab file to tell it to mount that one instead of the SD card’s.

                      Another thing to double check is your config.txt and cmdline.txt files. I know you made some changes to them, but when you copied these files did they get overwritten? It may be worth double checking these config files on the SSD’s boot partition. It looks like that is what is mounted from what you posted.

                      cmdline.txt will have a line like:

                      console=serial0,115200 console=tty1 root=PARTUUID=XXXXX-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh

                      and just make sure that’s pointing to the SSD’s root partition (02) as well!

                      There’s one more possibility. It’s possible that your fstab was pointing at the SSD this entire time and that you copied old firmware from the SD card that had never been updated over the top of newer firmware that was getting put on the SSD.

                      It’s a little hard to wrap your head around, but there’s a difference between what the Pi booted off of and what your OS mounts as the “boot” folder when the system loads. This could result in your updates going to the SSD (and basically not being used) but the firmware on the SD card was fine for getting through the boot process so it never really mattered. Some people using this method changed /etc/fstab to point toward the SD card for the boot partition and others toward the SSD.

                      If you think your firmware on the SSD’s “boot” partition may have been overwritten or compromised, we can clone the latest firmware branch with git and manually update it like this (WARNING: You really don’t want to do this unless you know/suspect your firmware files in the /boot folder are damaged and as a last resort “Hail Mary” to avoid having to reimage and start over. This syntax is also for Raspberry Pi OS/Raspbian. For Ubuntu the folder where these files are is /boot/firmware instead of just /boot like Raspbian so you’d need to change the end of the sudo cp lines to /boot/firmware instead of just /boot. This also won’t work unless the SSD’s boot partition is the one mounted which in this case it is):

                      git clone https://github.com/Hexxeh/rpi-firmware.git --depth 1
                      sudo cp rpi-firmware/*.dat /boot
                      sudo cp rpi-firmware/*.elf /boot
                      sudo cp rpi-firmware/*.bin /boot
                      sudo cp rpi-firmware/*.dtb /boot

                      Those commands clone the latest Raspberry Pi firmware branch and copy the latest elf, dat, dtb and bin files into the boot folder replacing the existing ones. After this shut down your Pi and remove the SD card completely. Have your SSD remain plugged in and connect the power.

                      Typically you’ll see a little Raspberry Pi BIOS-looking startup screen with some text telling you what is going on (just like a PC has) as it goes through the boot process. This is provided you have a screen connected. I’m not sure how exactly how long they’ve had this type of a startup screen but if you see it it’s a good sign that you’re dealing with modern firmware!

                    5. Avatar for victor

                      Hello James,

                      I found that /boot/cmdline.txt still had the partition ID from the SD card so I changed it to match the SSD. But when I remove the card it still does not boot, although it accesses the SSD.
                      Here is my present fstab:

                      PARTUUID=d34db33f-01 /boot vfat defaults,noatime 0 2
                      PARTUUID=d34db33f-02 / ext4 defaults,noatime 0 1

                      I set this up several months ago by copying everything from the SD to the disk and then changing several files, precisely which I don’t remember, but I followed your instructions.

                      I do know that I changed fstab so that the boot partition ID was that of the SD card. Since then I have run apt upgrade all several times but the dates on the files in the boot directory of the SSD are still from January and February 2020. When I look at the files on the SD, they are much newer. So I think this is the problem.

                      Can I just copy files from the SD to the disk? Both directories are accessible when it is running.

                      I am running headless, but I can access the GUI with a remote desktop program if this will make it easier.

                      Which files do I need to copy?

                    6. Avatar for jamesachambers

                      Hey Victor,

                      Perfect. Fixing cmdline.txt is part of the problem for sure.

                      You can absolutely just copy the files from the SD to the disk. You can do this remotely through a program like WinSCP or another file transfer program, through remote desktop, directly on the command line or through SSH, or however it is easiest for you with your setup to get both the disk and the SD card in the same place and replace the older files with the newer ones.

                      If the files on the SD are newer those are the ones that need to be on the SSD. Without these newer files on the SSD on it won’t know how to USB boot.

                      The partitions are supposed to be identical basically. You want to “catch up” the SSD’s boot partition so the file dates match up with the SD card. The important ones are all the files that end in .elf, .dat, .bin and .dtb. This will be basically everything except cmdline.txt and config.txt.

                      You already have your bootloader firmware covered from earlier, so once those files on the SSD are caught up it should have everything it needs to USB boot on it’s own!

                    7. Avatar for Victor

                      Hello again James,
                      Success at last!
                      What I did was mount mmcblk0p1, which is the boot partition on the SD card. Then I copied all the dtb, dat, img, elf, and bin files from there to /boot on the SSD. Then I shut down, unplugged the power, pulled the SD out, and reconnected the power. And it worked!
                      Thank you for all your help. I couldn’t have done it otherwise.

                    8. Avatar for jamesachambers

                      Hey Victor,

                      Congratulations! The help is no problem at all, I’m glad you had the patience and persistence to see it through to the end without giving up!

                      I honestly think I learned enough from us going through the process together that it warrants writing an article specifically about migrating a SD-based USB boot to a full blown USB booting one. Thanks for working through it with me and being patient, I think all the steps that we’ve gone through here will help some others that are going through something similar!

  13. Avatar for Joe

    Hi, thanks for guide. Unfortunately, I’m unable to get Ubuntu Server to boot after using your automatic script, it just shows a black screen, which doesn’t seem to load anything. I have used RpiOS desktop on an sdcard, and a flashed Ubuntu Server on the SSD, but it still requires the microsd to be started.

    Any ideas would be appreciated, thanks

    1. Avatar for jamesachambers

      Hey Joe,

      Which adapter are you using? Have you used it before to USB boot with another OS other than Ubuntu or is this the first time you’ve tried to USB boot with it? I’m just wondering if it’s one of the ones that has trouble.

      1. Avatar for Joe

        Thanks for your reply, I’m using the Sabrent EC-UK30 enclosure, I have tested it with Windows as an external device, but first time using it with the Rpi4 with Ubuntu as USB boot. I was thinking the same thing as you, with the adaptor being troublesome, as it seems to boot into ssd on boot fine, but just hangs on a black screen unfortunately. It seems to load fine with the microsd card in however via ssh.

        1. Avatar for Joe

          Just an update, I’ve managed to boot in Ubuntu, however every time I start, it boots into ‘Emergency mode’, I can’t find the root cause unfortunatly.

          1. Avatar for jamesachambers

            Hey Joe,

            That’s a really interesting result here. I have a crazy idea, which is that if you’re able to get into emergency mode can you edit the /boot/firmware/cmdline.txt file and enable quirks mode? There’s a “Fix (some) USB Adapter Problems Using Quirks” section in my New Raspberry Pi 4 USB Guide that runs through how to enable it. I’ll also add those sections to this post as they may help people with this in the future.

            I have a feeling it is a chipset incompatibility that quirks mode may correct and let you boot into regular Ubuntu. I think it’s able to boot into “emergency mode” using some sort of fallback compatibility mode. It’s worth a try at least!

            1. Avatar for Joe

              Bro, I’m not sure how I missed your Quirks fix, but I applied the fix and I’m happy to say everything is booting correctly now!

              Thank you so much, you made my day! Happy Holidays 🙂

              1. Avatar for jamesachambers

                Very glad to hear it Joe! Don’t sweat it about missing anything, I actually added some more information in this article after your comment when I realized it could be of assistance. Happy Holidays to you as well!

  14. Avatar for Ada


    First off, great tutorial and script c: much appreciated.

    I’m having some trouble with this on a fresh RaspiOS minimal image to setup ubuntu server 20.10.

    I flashed a wd green 128gb with the ubuntu-20.10-preinstalled-server-arm64+raspi.img image from ubuntu, and an old noob sd with 2020-08-20-raspios-buster-arm64-lite.img

    I have the same problem as Lucien with vmlinuz “not being in gzip format”

    makes mount points
    mkdir: cannot create directory '/mnt/boot': File exists
    mkdir: cannot create directory '/mnt/writable': File exists
    Mount which device? enter /dev/sdX# and partitions #s
    (first one will be interpreted as boot, second one system)
    sda 8:0 0 111.8G 0 disk
    |-sda1 8:1 0 256M 0 part
    `-sda2 8:2 0 2.9G 0 part
    mmcblk0 179:0 0 7.3G 0 disk
    |-mmcblk0p1 179:1 0 256M 0 part /boot
    `-mmcblk0p2 179:2 0 7G 0 part /
    device X?
    # corresponding to boot
    # corresponding to system
    confirm that the partitions have been mounted correct
    sda 8:0 0 111.8G 0 disk
    |-sda1 8:1 0 256M 0 part /mnt/boot
    `-sda2 8:2 0 2.9G 0 part /mnt/writable
    mmcblk0 179:0 0 7.3G 0 disk
    |-mmcblk0p1 179:1 0 256M 0 part /boot
    `-mmcblk0p2 179:2 0 7G 0 part /
    now run BootFix.sh!
    pi@raspberrypi:~ $ sudo ./BootFix.sh
    Found writable partition at /mnt/writable
    Found boot partition at /mnt/boot
    Decompressing kernel from vmlinuz to vmlinux...

    gzip: /mnt/boot/vmlinuz: not in gzip format
    Kernel decompressed
    Updating config.txt with correct parameters...
    Creating script to automatically decompress kernel...
    Creating apt script to automatically decompress kernel...
    Updating Ubuntu partition was successful! Shut down your Pi, remove the SD card then reconnect the power.

    I manged to get it booting once by following instructions on https://superuser.com/questions/298826/how-do-i-uncompress-vmlinuz-to-vmlinux

    pi@raspberrypi:/mnt/boot $ od -A d -t x1 vmlinuz | grep '1f 8b 08 00'
    pi@raspberrypi:/mnt/boot $ od -A d -t x1 vmlinuz | grep 'fd 37 7a 58 5a 00'
    16826032 78 7a 5f 64 65 63 00 00 fd 37 7a 58 5a 00 00 00
    pi@raspberrypi:/mnt/boot $ od -A d -t x1 vmlinuz | grep '42 5a 68 39'
    pi@raspberrypi:/mnt/boot $ su
    root@raspberrypi:/mnt/boot/extr# sudo dd if=vmlinuz bs=1 skip=16826040 | unxz > vmlinux
    unxz: (stdin): Compressed data is corrupt

    But now I run into this problem… would be weird that different mirrors have different compression types, so probably something else spooky.

    Why I tried from scratch again was because the standard ubuntu login wouldn’t work despite internet connection and letting it sit overnight to finish background updates. I also chrooted into it and made a new user which didn’t work either.. something seems weird with these ubuntu images :’C

    I also found some info about using extract-vmlinux from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/extract-vmlinux
    or from /usr/src/linux-headers on ubuntu but keep running into problems with this as well.. I’ll keep trying I guess but if you have any clues that would be greatly appreciated, at least I get to learn about all these different tools in the process ^^)

    1. Avatar for jamesachambers

      Hey Ada,

      I think I’ve found the problem. Were you using a 32 bit image? It looks like the script was leaving in arm_64bit=1 in the config.txt on 32 bit images. This has been fixed.

      Can you give it another try?

    2. Avatar for Mike Carillon

      ubuntu-20.10-preinstalled-server-arm64+raspi.img image from ubuntu is already able to boot from usb storage without any changes as long as you have the updated bootloader.

  15. Avatar for dzm

    Your decompress kernel script (as copy/pasted to this page) contains escaped characters that, if directly copied to a local script, will fail.

    echo -e “\e[31mMD5 GENERATION FAILED!\e[0m”
    echo -e “\e[32mMD5 generated Succesfully\e[0m”

    Note that each open- and close-quote contains escape sequences.

    Regarding at least one person above having a problem with the file system going bad/becoming locked. I tried migrating my SD card to a Samsung 256G (MZ – 5PA256A) SSD connected via some no-name USB3SATA JMicron (JMS579) adapter (quirks mode enabled). I used a Mac with ddrescue to completely copy the SD to the SSD (I copied at the block device level, not at the partition level):

    ddrescue –force /dev/disk7 /dev/disk8

    The Pi4 booted with this drive with no problem, but after about 1 minute of running would start to throw inode write errors (I seem to have lost them in my scrollback). After a short period of this Raspian would complain that I was using a read-only drive, and then would refuse to execute any executables (“ls not found” etc). Multiple fdisk-at-startup runs, etc made no difference. I then replaced the Samsung SSD with an old “OCZ 60Gb” I happen to have lying around. Using the exact same steps as above (ddrescue, fdisk at startup, raspi-config to resize the primary partition), this drive has been working flawlessly.

    I’ve connected the Samsung back to the Mac to do more testing against it. So far a DiskUtil secure erase (7 writes over the entirety of the storage area), plus multiple abuse-runs with dd:

    dd if=/dev/zero of=/Volumes/Untitled/foo bs=1m count=256k
    dd of=/dev/zero if=/Volumes/Untitled/foo bs=1m count=256k

    have not produced any errors or warnings, so my best conclusion is that Raspbian (or the JMicron chip) somehow chokes on this SSD. I’d extrapolate from this that it may have problems with other SSDs and that in certain situations the symptoms of this choking will be “read only” or worse.

    I guess that’s a whole bunch of words for “some drives won’t work; buy from the ‘known working’ list.” 🙂

    1. Avatar for jamesachambers

      Ugh, my web site formatting must be mangling that. Let me see what I can do. Thanks for the heads up!

      Those are pretty interesting results for the Samsung. I’m pulling that up as a 470 series which is not one that I’ve encountered before. I do see it’s a SATA II drive instead of a SATA III drive. I wonder if that has something to do with it possibly? Most adapters I’ve seen are meant for SATA III and the standards themselves are backwards compatible but that assumes the adapter (mostly) and probably to some extent the Pi can work with it.

      Theoretically it would max out at 3 GB / sec instead of 6 GB / sec but you’ll hit other bottlenecks on the Pi before reaching anywhere near either of those speeds.

  16. Avatar for Lodewijk


    I used your automatic script and now every apt-command ends with the follwing error:

    flash-kernel: installing version 5.4.0-1025-raspi
    Taking backup of vmlinuz.
    mv: cannot move ‘/boot/firmware/vmlinuz’ to ‘/boot/firmware/vmlinuz.bak’: Read-only file system
    run-parts: /etc/initramfs/post-update.d//flash-kernel exited with return code 1
    dpkg: error processing package initramfs-tools (–configure):
    installed initramfs-tools package post-installation script subprocess returned error exit status 1
    Errors were encountered while processing:
    Files have not changed, Decompression not needed
    E: Sub-process /usr/bin/dpkg returned an error code (1)

    Everything seems to work, but I’m afraid this will bite me in the future..

    1. Avatar for jamesachambers

      Uh oh! Your boot partition is read-only. Usually this is due to a corrupt partition. It needs an fsck on /dev/sda1. It probably needs an fsck on /dev/sda2 as well.

      Did you happen to run your imager tool to create the Ubuntu media on Mint Linux? I was able to find someone else who had this issue here: https://www.raspberrypi.org/forums/viewtopic.php?t=289035. If you weren’t on Mint I would still suspect that perhaps automounting interfered.

      run-parts: /etc/initramfs/post-update.d//flash-kernel exited with return code 1 – I see a double forward slash here that I bolded too. The path to this file is not something the script would have any effect on and your OS seems to be getting it wrong here.

      Failing storage device / missing damaged /etc/fstab are also a possibility: https://raspberrypi.stackexchange.com/questions/76254/pi-boots-with-read-only-filesystem but it’s probably a bad/corrupt image. I doubt there’s anything wrong with the drive itself but it’s possible.

      You’re right to be concerned. This needs to be corrected. You could try remounting your boot partition as rw but honestly if a fsck on /dev/sda1 doesn’t fix it I would try reimaging it! The Mint Linux guy from my first link ended up writing the image the old school way using dd. This might be worth a try for you too!

      One more thing to check. When you are creating the image and you plug in your SSD drive before you run the script if your operating system has a GUI it will usually try to automount the image and create 2 shortcuts on your desktop. If you don’t remove these automounts and then you mount them again they will be double mounted. This was the Mint Linux guy’s issue most likely, and if you aren’t absolutely positive you didn’t unmount the automounts it could have something to do with this as well!

  17. Avatar for lucian

    Thank you for the tutorial! But I have a problem. The default 20.04.1 LTS installation comes with kernel version 5.4.0-1023. At first boot the unattended upgrade procedure updates the kernel with version 1025 and after rebooting the kernel version is still 1023. I tried manually running the script but it says nothing has changed. I believe something fails inside the unattended upgrade but the hashes are still preserved so running the script manually doesn’t help. I deleted the hash file but still no change, after reboot the version still stands as 1023. I know it’s hard to debug on someone else’s machine but I can help with all the info needed. Thank you again!

    1. Avatar for jamesachambers

      Hey lucian,

      Thanks for letting me know! It definitely is hard to debug other people’s machines but you gave me enough to investigate.

      I wonder if this is just with the unattended upgrade. What happens if you do a:

      sudo apt update && sudo apt dist-upgrade -y

      I used the desktop 20.10 version to test and here’s what you should see (just with the 5.4.x kernel instead of 5.8.0). Here was my starting kernel:

      rpi@rpi:/boot/firmware$ uname -a
      Linux rpi 5.8.0-1008-raspi #11-Ubuntu SMP PREEMPT Thu Nov 12 15:49:32 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux

      Now let’s do the dist-upgrade:

      Setting up linux-image-5.8.0-1010-raspi (5.8.0-1010.13) ...
      I: /boot/vmlinuz.old is now a symlink to vmlinuz-5.8.0-1008-raspi
      I: /boot/initrd.img.old is now a symlink to initrd.img-5.8.0-1008-raspi
      I: /boot/vmlinuz is now a symlink to vmlinuz-5.8.0-1010-raspi
      I: /boot/initrd.img is now a symlink to initrd.img-5.8.0-1010-raspi
      Setting up linux-image-raspi ( ...

      This is where the links to the kernel are actually updated so you should see this in here. After a few more steps the system will update the ramdisk which will look like this:

      update-initramfs: Generating /boot/initrd.img-5.8.0-1008-raspi
      Using DTB: bcm2711-rpi-4-b.dtb
      Installing /lib/firmware/5.8.0-1008-raspi/device-tree/broadcom/bcm2711-rpi-4-b.dtb into /boot/dtbs/5.8.0-1008-raspi/./bcm2711-rpi-4-b.dtb
      Taking backup of bcm2711-rpi-4-b.dtb.
      Installing new bcm2711-rpi-4-b.dtb.
      Ignoring old or unknown version 5.8.0-1008-raspi (latest is 5.8.0-1010-raspi)

      Here you can see it ignore the old kernel. After a reboot I ended up with:

      Linux rpi 5.8.0-1010-raspi #13-Ubuntu SMP PREEMPT Wed Dec 9 17:14:07 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux

      Can you follow my steps and see what you get and how it compares to these? My initial suspicion is that unattended-upgrade might not be triggering the apt script.

      One more command we can have you try that just updates the ramdisk (the last step):

      sudo update-initramfs -u

      1. Avatar for Lucian


        I didn’t try the steps above yet but I’m able to see an error inside the logs and I have some proper steps to reproduce.

        1. So after booting from the SSD the unattended upgrade installs the new kernel (1025), I could see that in htop when it was generating the initramfs. I let it run for about 30mins to finish everything.
        2. Rebooted as ubuntu asks, and the kernel is still 1023. The contents of the boot partition:
        lrwxrwxrwx 1 root root 43 Dec 13 09:53 dtb -> dtbs/5.4.0-1025-raspi/./bcm2711-rpi-4-b.dtb
        lrwxrwxrwx 1 root root 43 Dec 13 09:51 dtb-5.4.0-1015-raspi -> dtbs/5.4.0-1015-raspi/./bcm2711-rpi-4-b.dtb
        lrwxrwxrwx 1 root root 43 Dec 13 09:53 dtb-5.4.0-1025-raspi -> dtbs/5.4.0-1025-raspi/./bcm2711-rpi-4-b.dtb
        drwxr-xr-x 4 root root 4096 Dec 13 09:51 dtbs
        drwxr-xr-x 5 root root 4608 Jan 1 1970 firmware
        lrwxrwxrwx 1 root root 27 Dec 13 09:10 initrd.img -> initrd.img-5.4.0-1025-raspi
        -rw-r–r– 1 root root 13818442 Dec 13 09:51 initrd.img-5.4.0-1015-raspi
        -rw-r–r– 1 root root 13818499 Dec 13 09:53 initrd.img-5.4.0-1025-raspi
        lrwxrwxrwx 1 root root 27 Jul 31 16:44 initrd.img.old -> initrd.img-5.4.0-1015-raspi
        lrwxrwxrwx 1 root root 24 Dec 13 09:10 vmlinuz -> vmlinuz-5.4.0-1025-raspi
        -rw——- 1 root root 8390521 Jul 10 05:18 vmlinuz-5.4.0-1015-raspi
        -rw——- 1 root root 8340400 Dec 9 11:55 vmlinuz-5.4.0-1025-raspi
        lrwxrwxrwx 1 root root 24 Jul 31 16:44 vmlinuz.old -> vmlinuz-5.4.0-1015-raspi
        3. uname -r outputs 5.4.0-1023-raspi
        4. sudo apt update
        5. sudo apt upgrade to install the remaining updates and some errors show up:
        update-initramfs: Generating /boot/initrd.img-5.4.0-1015-raspi
        W: missing /lib/modules/5.4.0-1015-raspi
        W: Ensure all necessary drivers are built into the linux image!
        depmod: ERROR: could not open directory /lib/modules/5.4.0-1015-raspi: No such file or directory
        depmod: FATAL: could not search modules: No such file or directory
        cat: /var/tmp/mkinitramfs_wMsnnn/lib/modules/5.4.0-1015-raspi/modules.builtin: No

        update-initramfs: Generating /boot/initrd.img-5.4.0-1025-raspi
        W: missing /lib/modules/5.4.0-1025-raspi
        W: Ensure all necessary drivers are built into the linux image!
        depmod: ERROR: could not open directory /lib/modules/5.4.0-1025-raspi: No such file or directory
        depmod: FATAL: could not search modules: No such file or directory
        cat: /var/tmp/mkinitramfs_mPYMrl/lib/modules/5.4.0-1025-raspi/modules.builtin: No such file or directory
        find: ‘/var/tmp/mkinitramfs_mPYMrl/lib/modules/5.4.0-1025-raspi/kernel’: No such file or directory

        5. The auto update script says nothing has changed when the package installation ends

        So it still doesn’t boot the newly installed kernel. I could try a dist-upgrade to upgrade to 20.10 but I would like to use 20.04 for a while now 🙂

      2. Avatar for Lucian

        The contents of the firmware folder is:
        -rwxr-xr-x 1 root root 23824896 Dec 13 09:11 vmlinux
        -rwxr-xr-x 1 root root 25907712 Dec 13 09:02 vmlinux.bak
        -rwxr-xr-x 1 root root 8340400 Dec 13 10:13 vmlinuz
        -rwxr-xr-x 1 root root 8340400 Dec 13 09:53 vmlinuz.bak

        and the check.md5 file is there. So I think the script runs when the unattended upgrade updates the kernel to 1025

        Then I manually ran:
        ubuntu@ubuntu:/boot/firmware$ sudo update-initramfs -u
        update-initramfs: Generating /boot/initrd.img-5.4.0-1025-raspi
        W: missing /lib/modules/5.4.0-1025-raspi
        W: Ensure all necessary drivers are built into the linux image!
        depmod: ERROR: could not open directory /lib/modules/5.4.0-1025-raspi: No such file or directory
        depmod: FATAL: could not search modules: No such file or directory
        cat: /var/tmp/mkinitramfs_Jz538Z/lib/modules/5.4.0-1025-raspi/modules.builtin: No such file or directory
        find: ‘/var/tmp/mkinitramfs_Jz538Z/lib/modules/5.4.0-1025-raspi/kernel’: No such file or directory

        1. Avatar for jamesachambers

          Hey Lucian,

          It looks like you’re missing the entire kernel modules directory. I take it /lib/modules/5.4.0-1025-raspi doesn’t actually exist?

          The script doesn’t do anything with the kernel modules. I’m really perplexed what you are seeing. I guess I need to fire up the old one again and make sure I don’t see this at all on there.

          This is a separate package called linux-modules-5.x. You can see all the ones you have with:

          sudo apt search linux | grep modules

          The script is pretty simple. There’s basically nothing to it except decompressing the kernel. If the kernel isn’t decompressed, your Pi literally can’t boot and won’t get past a black screen. Without a kernel there is nothing to boot to, so I think something else is going on here.

          Did you use the Raspberry Pi imaging tool to create these or are you downloading images off Ubuntu’s web site? I have only done it using the images that the Raspberry Pi imaging tool creates.

      3. Avatar for Lucian

        I’m trying with Ubuntu 20.10 now and I get a weird error:
        ound writable partition at /mnt/writable
        Found boot partition at /mnt/boot
        Decompressing kernel from vmlinuz to vmlinux…

        gzip: /mnt/boot/vmlinuz: not in gzip format
        Kernel decompressed
        Updating config.txt with correct parameters…
        Creating script to automatically decompress kernel…
        Creating apt script to automatically decompress kernel…
        Updating Ubuntu partition was successful! Shut down your Pi, remove the SD card then reconnect the power.

        And vmlinux has 0 bytes

      4. Avatar for Lucian

        It worked, finally. It was my mistake. I switched to using Raspian to do the initial setup scripts and I actually removed the microSD card when booting, although it looked like it worked normally and USB has higher boot priority. Thank you for taking the time to help!

        1. Avatar for jamesachambers

          Oh wow, that is a great find Lucian, I’m glad you followed up because I should have asked those questions right off the bat!

          Thanks for following through and posting the results. It’s going to help a lot of people. I’m also going to update the guide a little bit to help others avoid going down this path.

          There’s some things I can do to help with this too. I can add some better safety checks in the script to make sure it’s running on a compatible version of Raspbian that it has all the files it needs.

          Basically Raspbian is used as the “source” for the script, or Raspbian’s /boot folder specifically. This is used to update the .elf and .bat firmware files on the Ubuntu device as the ones it ships with won’t boot. If exactly the right things aren’t in there you’re going to see some very perplexing behavior like you have. I’ll get that added in there.


  18. Avatar for Bastian

    My script that was installed using the automated script is missing some parameters, I think that is the reason:

    #!/bin/bash -e
    # auto_decompress_kernel script
    # Check if compression needs to be done.
    if [ -e /check.md5 ]; then
    if md5sum –status –ignore-missing -c /check.md5; then
    echo -e “\e[32mFiles have not changed, Decompression not needed\e[0m”
    exit 0
    echo -e “\e[31mHash failed, kernel will be compressed\e[0m”
    # Backup the old decompressed kernel
    mv .bak
    if [ ! 0 == 0 ]; then
    exit 1
    echo -e “\e[32mDecompressed kernel backup was successful\e[0m”
    # Decompress the new kernel
    echo “Decompressing kernel: “”…………..”
    zcat >
    if [ ! 0 == 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 > /check.md5
    if [ ! 0 == 0 ]; then
    echo -e “\e[31mMD5 GENERATION FAILED!\e[0m”
    echo -e “\e[32mMD5 generated Succesfully\e[0m”
    exit 0

  19. Avatar for Bastian

    Thank you for the information, it helps a lot, however when I do:

    sudo apt-get install –reinstall linux-image-5.4.0-1023-raspi

    It stops with:

    mv: missing destination file operand after ‘.bak’
    Try ‘mv –help’ for more information.
    Decompressed kernel backup was successful
    Decompressing kernel: …………..
    /boot/firmware/auto_decompress_kernel: line 25: syntax error near unexpected token `newline’
    /boot/firmware/auto_decompress_kernel: line 25: `zcat > ‘
    E: Problem executing scripts DPkg::Post-Invoke ‘/bin/bash /boot/firmware/auto_decompress_kernel’
    E: Sub-process returned an error code

    If I reboot it no longer boots.

    1. Avatar for jamesachambers

      Hey Bastian,

      You’re right. It looks like the way I am creating the automated script has a mistake. The EOF in the script probably needs a backslash in front of it to escape it. After the “zcat” in what you posted there are no variables because they were not escaped properly. I did test it, and the scripts work in the non-automated form, but I did not test reinstalling the kernel with the automated version so I missed it, whoops!

      I’ll get a fix up shortly, thanks for letting me know!

      1. Avatar for jamesachambers

        This fix is up. The problem was:

        echo "Creating script to automatically decompress kernel..."
        cat << EOF | sudo tee "$mntBoot/auto_decompress_kernel">/dev/null

        needed to be

        echo "Creating script to automatically decompress kernel..."
        cat << \EOF | sudo tee "$mntBoot/auto_decompress_kernel">/dev/null

        I’ve committed this fix to GitHub. Can you give it another go here? I just tested and was able to dist-upgrade an entire 20.10 desktop installation and successfully patch my kernel as well as reboot with this fix added.

        Hopefully you were the first one who tried it but if anyone else out there had this problem and didn’t comment go ahead and run the new automated script here with this fix!

Leave a Comment

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

Type here..