You normally start a Raspberry Pi from a (micro) SD card. But sometimes that is not so convenient. Recently, the developers of the family of minicomputers have added two new boot modes: USB and Network. With USB mode, you can start the Raspberry Pi from an operating system on a USB stick or hard drive that you connect via USB.
With network mode, you don't even need a local storage device: the Raspberry Pi downloads its operating system over the network from another computer. In this way you can also easily have multiple Raspberry Pis booted via an operating system on a central computer. If you update that central operating system, all your Raspberry Pis will automatically run the latest version.
01 Experimental Boot Modes
The new boot modes are experimental and developed for the Raspberry Pi 3. The boot code that is needed for this is in the BCM2837: the processor of the Raspberry Pi 3. If you have a Raspberry Pi 1, 2 or Zero, you can also use the use new boot modes, but in a roundabout way: format an sd card with fat32, copy the file bootcode.bin to the card and boot your Pi from this card. That may not be complete without an SD card, but you can boot your Pi from USB or the network.
02 Possible problems with USB
Booting from USB doesn't always work. For example, some USB sticks switch on too slowly. External hard drives also do not always respond within two seconds, the time the boot code waits by default. You can increase that timeout to five seconds, but some drives aren't even ready yet. Other USB sticks have very specific requirements for the communication protocol, which the Raspberry Pi 3 boot code (limited to 32 kB ROM) does not meet. So you may have to try out some discs.
03 Firmware Upgrade
We assume you are running Raspbian on your Raspberry Pi. If not, download an image and put it on an SD card with the program Win32DiskImager and boot the Pi from it. First, refresh all repositories with sudo apt-get update. If you are running Raspbian Lite (the version without graphical interface), first run sudo apt-get install rpi update because that minimal version of Raspbian does not have the rpi-update package. Then update the firmware from the 'next' branch with sudo BRANCH=next rpi-update.
04 Enable USB Mode
Open the boot configuration file with sudo nano /boot/config.txt and add the command program_usb_boot_mode=1 to the end. Save the file with Ctrl+O and exit nano with Ctrl+X. Restart your Pi with sudo reboot, and after the reboot, make sure the USB mode is enabled. You do that with the command vcgencmd otp_dump | grep 17:, which should return a number ending in 0x3020000a. Then open the boot configuration file again and delete the command program_usb_boot_mode=1, so you don't accidentally enable USB boot mode on another Pi you insert this SD card into.
05 Partitioning USB Storage
Now connect your USB storage device to your Pi. Partition this device with sudo parted /dev/sda. Create a new partition table with mktable msdos and confirm with yes that you want to destroy all data on the disk. Then create a 100 megabyte fat32 partition with mkpart primary fat32 0% 100M and an ext4 partition that occupies the rest of the drive with mkpart primary ext4 100M 100%. View the changes with print and close parted with quit. Then create the boot file system with sudo mkfs.vfat -n BOOT -F 32 /dev/sda1 and the root filesystem with sudo mkfs.ext4 /dev/sda2.
06 Raspbian copy
Install the program rsync with sudo apt-get install rsync. Then create a new directory with sudo mkdir /mnt/usb and mount the ext4 file system of the usb storage on it with sudo mount /dev/sda2 /mnt/usb/. Then create a boot directory with sudo mkdir /mnt/usb/boot and mount the boot filesystem on it with sudo mount /dev/sda1 /mnt/usb/boot/. Now copy the Raspbian system you are running from the SD card to the file system on your USB storage. You do that with the command sudo rsync -ax --progress / /boot /mnt/usb. Please be patient as it may take a while.
The USB storage now contains a copy of your running Raspbian, but not everything should be identical. For example, the new system needs different ssh keys. Therefore, go to the USB storage with cd /mnt/usb and mount some special filesystems with sudo mount --bind /dev dev, sudo mount --bind /sys sys and sudo mount --bind /proc proc. Then enter a chrome (change root) out with sudo chroot .. All commands you execute now are executed in the system on the USB storage, no longer in the system on the SD card.
08 New ssh keys
You are now root user in the chroot. First, delete the existing ssh keys as those are the ones we copied from the sd card's system. You do that with rm /etc/ssh/ssh_host*. Then generate new ssh keys by reconfiguring the OpenSSH server with dpkg-reconfigure openssh-server. Then exit the chroot with exit. All commands you perform now will be executed again in the system on the SD card. Then unmount the special filesystems with sudo umount dev, sudo umount sys and sudo umount proc.
09 Modify Root File System
Now make sure the Pi is using the root file system on the USB storage instead of the one on the SD card. For that you modify the file /boot/cmdline.txt on with sudo sed -i "s,root=/dev/mmcblk0p2,root=/dev/sda2," /mnt/usb/boot/cmdline.txt. Do the same in the file /etc/fstab: sudo sed -i "s,/dev/mmcblk0p,/dev/sda," /mnt/usb/etc/fstab. Then go to your home directory with cd, unmount the filesystems from the usb storage with sudo umount /mnt/usb/boot and sudo umount /mnt/usb and turn off the Pi with sudo poweroff. Unplug the power cable, remove the SD card and plug the power cable back in. If all goes well, your Pi will now boot from your USB storage.