Moving to USB(SSD) drive on Raspberry Pi 4, with room for future native boot

This has been a hot topic for the past 8+ months now, with many waiting on baited breath for Raspberry Pi foundation to add native functionality to boot directly from USB. This still hasn’t happened, and the stock line on almost all formal communication lines continues to be ‘it will be there when it is done’. Apparently there are rumors of it working in isolated test environments, so perhaps this will be available in the near future.

For now, our options are

  1. Stay booting/running on microSSD. The read and write speeds are very low, and the cards are highly susceptable to corruption.
  2. use the openhabian-config expand to USB script. This will be fairly straight forward and will work, but do not create a boot partiion on the USB SSD drive - something that may be a headache if booting directly from USB drives becomes a possibility in the future - then the boot partition will be needed.
  3. Manually set up the drive to include a boot partition.
    This is the route I took. I already had a working microSD install running on my raspberry pi (openhabian 2.5, although the version shouldn’t make a difference for this method). This should allow me to currently start the boot from the microSD and redirect almost immediately to the SSD (with some critical boot files on the microSD, but not a whole lot of writing to wear it out), and the rest on the SSD where things are faster and more reliable. It will also allow me to have the boot partition on the microSD as well, currently functioning as a backup for the microSD, but in the future allowing for me to relatively seamlessly switch to booting entirely form the SSD.

I am sure there are many potential improvements to be made from this process, and am open to feedback for others’ benefit. If you wish to be really thorough, you can run step 12 (speed test) at the beginning to get a baseline to compare your future speeds against.

As you should always do before any big / brash changes, you should backup your system. There are several good threads on this. If you haven’t done that yet, and you have valuable data/files that aren’t easily recreated, do this now.

How to successful move from microSD card to SSD on Raspberry Pi 4

  1. get an SSD drive. There are many pre-packaged USB3 enclosures with decent SSD drives in them. If getting an off-brand, make sure it will be compatible with raspberry pi (googlable). I used a Samsung Portable SSD T5 500GB USB 3.1 External SSD

  2. Set up your new SSD drive with correct partitions. The best way to do this is with the official openhabian image.
    Use balanetcher / (or other mac/os-friendly approach) to write the openhabian image to the SSD. This will set up the partitions as FAT for the boot partition (currently not used until booting natively from USB is supported on RPi4) and the EXT4 (rootfs). Follow the same procedure as in the new official install guides for writing these images.
    (in my use case to move an existing installation over, these files will be erased anyway)

  3. Expand the rootfs (ext4) partition.

a) This could be done either with a dummy microSD raspbian / openhabian card that points to the usb/SSD in the commandline.txt, then the firstboot scripts will automatically expand the drive. This will be a bit of hassle if you have to get another microSD for this. If starting with a fresh install, you could cheat a bit and edit cmdline.txt (find it on the FAT32 partition (can read in windows/mac), and change the boot parameter to point to /dev/sda2 before your first boot. Note, be sure to set your wifi credentials in openhabian.conf as well, to make your life easier, in this instance.

b) If moving from an existing openhabian setup, though, this may be more hassle. If you have other utilities at your disposal (I used paragon Hard Disk Manager Advanced on windows), you can use those to expand the drive.

c) there are command line methods to do this, and a google search will likely identify them for you.

  1. If starting with a fresh install, then skip to step 7

  2. Take a look at your available drives to know which drives their system address (/dev/xyz)

sudo fdisk -l

See my output below. Note the mmcblk0 is the microSD memory card, and /dev/sda is my SSD drive. It will be more clearly identified in step 7, but you can also see the PARTUUID of the SSD drive represented as the DIsk identifier. You need to ensure your drive/partition is also at /dev/sda2, and not sdb2 or sdc2. If it is ‘b’ or ‘c’, then use those letters in the coming step 5 and 6.

The results of my command on my system:

...
[snip a whole lot of ram information]
...
Disk /dev/mmcblk0: 14.9 GiB, 15931539456 bytes, 31116288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xddd649c3

Device         Boot  Start      End  Sectors  Size Id Type
/dev/mmcblk0p1        8192   532480   524289  256M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      540672 31116287 30575616 14.6G 83 Linux


Disk /dev/sda: 465.8 GiB, 500107862016 bytes, 976773168 sectors
Disk model: Portable SSD T5
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 33553920 bytes
Disklabel type: dos
Disk identifier: 0x17869b7d

Device     Boot  Start       End   Sectors   Size Id Type
/dev/sda1         8192    532480    524289   256M  c W95 FAT32 (LBA)
/dev/sda2       540672 976773119 976232448 465.5G 83 Linux

BE SURE TO ADAPT THE sd# BELOW IF YOUR TARGET DRIVE ISN’T SDA2 (happens if you have multilple usb drives plugged in)

  1. Reformat the EXT4 partition. This can be done through fdisk, or I used Paragon Hard Disk Manager on windows, choosing ext4. This will remove the fresh install openhabian files on the new drive, to allow you to copy your old ones in. If doing a fresh install, don’t format the partition. For within linux, though, the command is
sudo mkfs.ext4 /dev/sda2
  1. Copy the working files over from your microSD card to the newly formatted partition on your SSD drive. All this is done through a raspberry pi terminal.
    a) make a mount point for the new SSD
sudo mkdir /media/externalSSD

b) mount the drive:

mount /dev/sda2 /media/externalSSD

(note, if your drive isn’t sda2, modify that paramater as needed)
c) copy the files over

rsync -avx / /media/externalSSD

( your SSD 2nd partition now is a mirror copy of your microSD’s 2nd partition )

d) You may wish to take this time to also mirror over the files from your SD card boot directory. This will make it very easy to start USB booting natively in the future. If you make any changes to files in the boot directory in the interim, they will need to be copied/synced over again at that time.

Change the /sda1 as needed. Be aware the sudo rm command removes all the files in the boot directory of the new SSD drive, placed there by the image you flashed near the beginning. If you wish this to be kept as a backup, you can instead move it into a subdirectory.

sudo mkdir /media/externalSSDBoot
mount /dev/sda1 /media/externalSSDBoot
sudo rm /media/externalSSDBoot/* -r
rsync -avx /boot /media/externalSSDBoot

Make your raspberry pi redirect to boot from new SSD drive

7 ) run blkid - to find out what the relevant PARTUUID is for the SSD drive

blkid
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="F661-303B" TYPE="vfat" PARTUUID="ddd649c3-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="8d008fde-f12a-47f7-8519-197ea707d3d4" TYPE="ext4" PARTUUID="ddd649c3-02"
/dev/sda1: LABEL_FATBOOT="boot" LABEL="boot" UUID="F661-303B" TYPE="vfat" PARTUUID="17869b7d-01"
/dev/sda2: UUID="77911dd1-00f2-40bf-82d4-27f212163ad7" TYPE="ext4" PARTUUID="17869b7d-02"

note, if they have the same PARTUUID, which can happen with some ways of creating the drive, you may need to look into using fdisk to change it.

  1. Make a backup of cmdline.txt
sudo cp /boot/cmdline.txt /boot/cmdline.oldSD
  1. Change cmdline.txt to point to the new SSD drive
sudo nano /boot/cmdline.txt

Replace the old PARTUUID to the new PARTUUID.
press x to exit, any enter / y to save.
(note, I prefer using PARTUUID to point to the drive, rather than /dev/sda2, as it will not change. If you used sda2, it may change if you plug different USB storage devices into your pi)

[my working cmdline.txt is below. Replace my PARTUUID with yours. In the past I hadn’t realized the -02 portion refers to the second partition in the given drive - be careful to preserve this correctly]

dwc_otg.lpm_enable=0 console=tty1 root=PARTUUID=17869b7d-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

  1. Reboot your pi.
sudo reboot

I use my nicereboot script, as I don’t yet know when to trust when openhab is shut down nicely before a reboot - you can manually shut down openhab first, if you wish, or simply reboot as there is likely not much to loose with given that you are switching to the SSD drive.

  1. Last step: Update your fstab file.
    Your fstab entry tells linux what drives to mount to given locations. Be careful, you can create a lot of problems for yourself if you mess this file up.
sudo nano /etc/fstab

Change the PARTUUID for the root ‘/’ location to be your new PARTUUID.
control - x to exit, and enter/y to save.

For now, the boot directory should still be the old microSD card (leave it in). In my case, this is ddd649c3-01

FYI, my working final fstab is below, with the only change being on the 3rd line:

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

/usr/share/openhab2          /srv/openhab2-sys           none bind 0 0
/etc/openhab2                /srv/openhab2-conf          none bind 0 0
/var/lib/openhab2            /srv/openhab2-userdata      none bind 0 0
/var/log/openhab2            /srv/openhab2-logs          none bind 0 0
/usr/share/openhab2/addons   /srv/openhab2-addons        none bind 0 0

12)You should be done. To prove it to yourself, you can do some speed tests.

TEST WRITE SPEED. (microSD will have around 30mb/s, SSD should have 50-200+)

dd if=/dev/zero of=temp.txt bs=1M count=1024 oflag=direct

TEST READ SPEED (microsd will have 40 mb/s, SSD should have 180-200+)

dd if=temp.txt of=/dev/null bs=1M count=1024 iflag=direct

My write/read speeds are now 202 and 267 MB/s respectively. Much better than 30/40 previously.

I had a wide variety of sources for this. Most notably,
Rick Makes : https://www.youtube.com/watch?v=KoxVVoV2hRA
Andries Spiess : https://www.youtube.com/watch?v=gp6XW-fGVjo&t=484s
Try At Home : https://www.youtube.com/watch?v=FM9wuFLufyA
and beyond this, there were many individual references I looked up for various commands used.

9 Likes

Nice tutorial! I have a question about this statement:

What’s the advantage of booting from a USB drive over booting from MicroSD and then handing off to the USB drive? I would think that if the MicroSD’s sole purpose was to boot up the Pi, the wear would be very minimal. And if it did ever corrupt, wouldn’t you just have to swap in a new MicroSD card and be on your way, since everything important is on the USB drive?

I’m assuming it’s not that simple in reality.

Hello @bdm,
I JUST stumbled onto this great right up. However, I started out taking the suggestions of some colleagues and writing Raspbian to both the SD and the USB3.0 attached SSD. Minor apt-get updates were just performed. But it seams that my Boot is on the ssd and the / is on the SD…go figure…lol. How can I at least get these swapped. I wouldn’t mind wasting an SD to just boot from. I want the expansion and speed of the SSD. ANY help is much appreciated in advance. See Disk below:
Setup:
RPi 4 - not overclocked…yet
root@lilScrappipi:~# lsblk -l
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 238.5G 0 disk
sda1 8:1 0 256M 0 part /boot
sda2 8:2 0 3.3G 0 part
mmcblk0 179:0 0 59.6G 0 disk
mmcblk0p1 179:1 0 256M 0 part
mmcblk0p2 179:2 0 59.4G 0 part /

pi@lilScrappipi:~ $ sudo -i
root@lilScrappipi:~#
root@lilScrappipi:~# fdisk -l

[snip a whole lot of ram information]

Disk /dev/ram15: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Disk /dev/mmcblk0: 59.6 GiB, 64021856256 bytes, 125042688 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xea7d04d6

Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/mmcblk0p2 532480 125042687 124510208 59.4G 83 Linux

Disk /dev/sda: 238.5 GiB, 256060514304 bytes, 500118192 sectors
Disk model: USB3.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0xea7d04d6

Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/sda2 532480 7397375 6864896 3.3G 83 Linux

Hi Russ,
Some of it may be my OCD kicking in, but I do like being able to backup a single drive, and not rely at all on a micro SD card (I’ve had far too many fail in the past).
The way around re-creating the bood microSD card would require you to save a backup of your config.txt. When your microSD card fails, burn another one with the SAME openhabian version as you had initially. Start to set it up, then replace the fresh config.txt with your backed-up one. Theoretically this should have you off to the races. It never has really worked as easily for me (in part due to inadvertently creating new problems for myself along the way), though, hence my push to get rid of microSD cards.

You’re completely correct that the wear should be minimal on the /boot component.

I suppose another benefit is that it can be a functional backup for future SD cards until the point that it becomes functional, at which the transition is very easy.

1 Like

Hi AZDNice, welcome to the forum.
How to fix this really depends on what OS you are most comfortable using, and what utilities you are comfortable with. Linux parted magic used to be my go-to boot distro for fixing file systems, and fdisk should work as well (although my experience with its’ nuts and bolts is very limited). Off of a windows system you could use paragon hard disk manager advanced.

Essentially what you’d want to do is make sda2 an ext4 partition and copy the files from mmcblk0p2 over to it using rsync as above. At this point you should have a fully functioning hard drive. Now you need to play catchup. If your mmcblk0p1 is a FAT32 partition, you copy the contents of sda1 over to mmcblk0p1.

Make sure the config.txt on your mmcblk0p1 (SD boot partition) points to the hard drive as per my example above.
Finally, you will need to go into fstab on your linux system and change the /boot to point to /dev/mmcblk0p1 and the / to point to /dev/sda2 (although better to use PARTUUID)

I hope that makes sense. Good luck, and google will be your friend to sort out whatever tools you plan to use. It may be possible to do most of it on the pi, if for some reason your ssd mmcblk0p1 actually contains the /boot information and is bootable.

Looks like we are getting closer - there is a official beta to boot from USB

https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=274595

2 Likes

About time!!