Orange Pi 5 NVMe/SATA SSD Boot Guide

Orange Pi 5 with Heat Sinks
Orange Pi 5 NVMe / SSD Boot Guide

The Orange Pi 5 has a nice M.2 NVMe slot but unfortunately most of the official images will not boot if you try to directly image a NVMe drive. Fortunately there is an easy way to get this working that people who frequent the blog will almost certainly have seen before.

We are going to bootstrap the boot process using a SD card and then clone that SD card to our SSD to be used as the root partition. This essentially will let us have our system’s root partition on the SSD (much faster).

Let’s get started!

Hardware Used

Orange Pi 5 - Top View
Orange Pi 5

The Orange Pi 5 the latest release from Orange Pi and is the most powerful model yet. It has a 6 core CPU and options from 4GB of RAM all the way up to 32GB of RAM!

Links:*, AliExpress*,*,*,*,*,*,*,*,*

Kioxia 2230 M2 NVMe Drive
Kioxia 2230 M.2 NVMe Drive

The Kioxia (Toshiba) 128GB M.2 2230 PCIe NVMe drive is much shorter than most NVMe drives (full size is 2280). It fits great with single board computers / tablets / other smaller form factors.


Geekworm Copper Heat Sink Set
Geekworm Copper Heat Sink Set

The Geekworm copper heat sink set is designed to fit many different single board computers. It uses thermal conductive adhesive which many “cheap” heat sink kits for SBCs don’t have. Eliminates hot spots and reduces throttling. Can be further enhanced by powered cooling over the heat sinks.


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

The StarTech USB 3.1 to 2.5″ SATA adapter is one I have recommended for many years for use with all kinds of devices including the Raspberry Pi, Orange Pi, ODROID, Libre “Renegade” and Tinker Board. It’s widely compatible and works with gaming consoles as well.


Note for USB Booting

Important: Only the top blue port of the Orange Pi 5 is fast for using USB storage. You can use a USB-connected SSD.

The bottom port, despite being blue, is USB 2.1.

Keep in mind that if you are using a USB SSD then in the instructions anywhere it says /dev/nvme0n1 you will need to use /dev/sda or whatever drive was assigned when you plug in your drive via USB.

Note for Official Debian / Ubuntu Images (Updated 1/10/2023)

Orange Pi has updated their official images to support directly booting from NVMe. This means that if you are using the official Ubuntu or Debian from then you can actually write the image directly to the SSD. This is the easiest way to get it going.

You first need to write the image to a SD card and then run:

sudo orangepi-config

Then choose System->Install->Boot from SPI and install the new updated boot loader to the SPI flash.

This did not work at launch but is working now. It is now possible to simply write the official images directly to NVMe and boot with it after updating the boot loader! The following instructions will still be useful for other operating systems or operating systems that do not support booting directly from NVMe.

Note for Armbian (Added 1/20/2023)

Armbian has a similar install utility as orangepi-config. For Armbian you will use:

sudo armbian-config

Then choose System->Install->Boot from eMMC and install the new updated boot loader to the SPI flash.

You should also install the system to Armbian using this method. The instructions in the rest of the article are meant for operating systems that will not boot natively from NVMe. It uses a SD card as the boot loader to essentially let you boot anything (even ones not designed to boot directly from NVMe).

Supported SSD Sizes (Updated 1/26/2023)

Important: There is also a type of M.2 drive called a M.2 SATA drive. This is an older type of drive that most of you won’t have but some of you will. This type of drive is supported by the Orange Pi 5 but you have to add a special overlay (overlays=ssd-sata). If your NVMe drive shows up as /dev/sda instead of /dev/nvme0n1 then you have a M.2 SATA SSD. If you have a M.2 SATA drive follow this excellent guide by u/jng98908 on reddit.

You can use either a 2230 or a 2242 size NVMe drive.

There are actually holes for mounting hardware at both places.

Using a 2230 size NVMe drive looks like this:

Orange Pi 5 with 2230 NVMe drive mounted
Orange Pi 5 with 2230 NVMe drive mounted

It’s totally fine to use a larger one but they will be hanging off the edge of the board. As you can see I do not have the mounts installed on my board. I just leave the 2230 drive in the port like this but it is on my to-do list to find some mounts for the M.2 drive for this board.

SD card boot loader – Preparing SD Card

First you should have a completely working installation on a SD card of the OS that you would like to use. I used the official Debian desktop image for this guide (recommended) so if your partitions are different it may be your flavor of Linux and need slightly altered instructions.

If you have an already working installation you want to move to your SSD you can use this as well most likely.

Note that some operating systems like Armbian will require you to manually go in and modify files on the “boot” partition. If you stick with the official images you should be able to follow the guide as-is but note that some operating systems may have text files (or even files that need to be recompiled with mkimage like for Armbian) for this method to work.

You should completely update first with:

sudo apt update && sudo apt full-upgrade

Preparing SSD

First we are going to completely remove all partitions from the drive so it’s completely blank. Your drive should typically be /dev/nvme0n1:

sudo gdisk /dev/nvme0n1

Now remove all partitions from the device. If you press “p” it will print out the partitions. You can then use “d” to delete them.

Here’s an example on mine:

root@orangepi5:~# sudo gdisk
GPT fdisk (gdisk) version 1.0.6

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): p
Disk /dev/nvme0n1: 250069680 sectors, 119.2 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): E3017ECA-4571-4F62-A39F-4BA2A4323BD8
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 250069646
Partitions will be aligned on 64-sector boundaries
Total free space is 8350 sectors (4.1 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              64            8063   3.9 MiB     0700  loader1
   2           16384           24575   4.0 MiB     0700  loader2
   3           24576           32767   4.0 MiB     0700  trust
   4           32768         1081343   512.0 MiB   EF00  boot
   5         1081344       250069646   118.7 GiB   8300  rootfs

Command (? for help): d

Keep pressing d until all the partitions are deleted. Once they are gone use the ‘w’ command to write your changes.

Cloning Installation to SSD

We’re now ready to clone your installation to the SSD. We can now copy your drive to the SSD with the following command:

cat /dev/mmcblk1 > /dev/nvme0n1

Wait for the operation to complete (there won’t be any output but you will have a cursor again and be able to type new commands). Remember that you are copying an entire drive from one to another basically with that one command.

Mine took about 30-45 minutes (although I was using a 64GB SD card and the larger SD card you use the longer it will take to copy the whole drive).

If you are having any trouble with permissions try becoming “root” first with:

sudo su

Now try running the command again and as the superuser you should not encounter any permission errors.

Change SD card’s rootfs UUID

We need to change our SD card’s UUID so that it doesn’t try to boot from that partition. We can set it to a random one with the following command:

sudo tune2fs -U random /dev/mmcblk1p2

If you get an error with the previous command regarding csums try the following command instead:

sudo tune2fs -O metadata_csum_seed -U random /dev/mmcblk1p2

We can verify that it has changed with blkid like this:

root@orangepi5:~# sudo blkid
/dev/nvme0n1p1: SEC_TYPE="msdos" LABEL_FATBOOT="opi_boot" LABEL="opi_boot" UUID="0257-2A31" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="bootfs" PARTUUID="0a65713b-d4b4-0642-a3a4-ebc357e507a1"
/dev/nvme0n1p2: LABEL="opi_root" UUID="ae948e48-3646-4f5c-be01-73168e079bc8" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="7490e84a-f585-944e-9ce6-f275f067a023"
/dev/mmcblk1p1: SEC_TYPE="msdos" LABEL_FATBOOT="opi_boot" LABEL="opi_boot" UUID="0257-2A31" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="bootfs" PARTUUID="0a65713b-d4b4-0642-a3a4-ebc357e507a1"
/dev/mmcblk1p2: LABEL="opi_root" UUID="37a6ee0a-e61d-470a-9e53-eaf51726942c" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="4f32d51c-0523-1248-9bc3-092d1f11c594"

Notice that /dev/nvme0n1p2 and /dev/mmcblk1p2 no longer have matching UUIDs. This is exactly what we want.

Change SSD’s boot UUID

Next we are going to change the boot partition’s UUID on the SSD. This will make it so that the mounted /boot folder inside your operating system actually mounts the SD card (which is your actual boot loader in this configuration).

First make sure you have mtools with:

sudo apt install mtools -y

Now we can change the UUID with:

sudo mlabel -N aaaa1111 -i /dev/nvme0n1p1 ::

You can verify these are different using the same sudo blkid command as the previous section.

Run fsck

Before we reboot run fsck on the drive like this:

sudo fsck -yf /dev/nvme0n1p2

This will prevent you from having to run fsck on the CLI the first time you try to boot.

Reboot and Verify

Now reboot the Orange Pi 5 with:

sudo reboot

With any luck you should be booted using your SSD! We can verify this with the mount command like this:

root@orangepi5:~# mount
/dev/nvme0n1p2 on / type ext4 (rw,noatime,errors=remount-ro,commit=600)
/dev/mmcblk1p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=936,iocharset=utf8,shortname=mixed,errors=remount-ro)
/dev/nvme0n1p2 on /var/log.hdd type ext4 (rw,noatime,errors=remount-ro,commit=600)

Here we can see that our root partition (/) is indeed on /dev/nvme0n1p2 and not /dev/mmcblk0p2. We can also see that my /boot folder is properly mounted is /dev/mmcblk0p1 (the SD card which is serving as our boot loader). Success!

Resize NVMe Partition (Added 1/24/2023)

You can use Orange Pi’s built in resize application if you are using one of the official operating systems:

sudo /usr/lib/orangepi/orangepi-resize-filesystem start

Testing Performance

For the guide I used a SSSTC 128GB 2230 M.2 NVMe drive. These are available on Amazon for around $10-12 (also see Kioxia 128GB M.2 2230 module*).

You can verify the performance of your drive on Pi Benchmarks using the following command:

sudo curl | sudo bash

Here are the results:

     Category                  Test                      Result     
HDParm                    Disk Read                 375.32 MB/s              
HDParm                    Cached Disk Read          381.15 MB/s              
DD                        Disk Write                234 MB/s                 
FIO                       4k random read            47080 IOPS (188321 KB/s) 
FIO                       4k random write           35128 IOPS (140514 KB/s) 
IOZone                    4k read                   75628 KB/s               
IOZone                    4k write                  67285 KB/s               
IOZone                    4k random read            35874 KB/s               
IOZone                    4k random write           70620 KB/s               

                          Score: 17,718

The full Orange Pi 5 benchmark can be viewed here on Pi Benchmarks.

That is an outstanding score. We are getting NVMe performance. This score actually even beats my ODROID M1 benchmark.

The Orange Pi 5 is without a doubt a very powerful board and is performing exactly where it should be.

Other Resources

If you are looking for alternative WiFi adapters for the Orange Pi 5 see my using E-keyed WiFi adapters with the Orange Pi 5 guide here!

I’ve written a review for the Orange Pi 5 available here

All of my single board computer reviews are available here


Inline Feedbacks
View all comments

Razor Burn
Razor Burn
19 hours ago

Hi James,

So I followed your suggestion and flashed Armbian to the NVMe and its now showing with the different partitions and an unallocated amount totaling 231.33GiBs

I then went to:

sudo armbian-config

Install to/update boot loader OK

5 Install /Update the boot loader on SD/eMMC

I then tried booting from:

4 Boot from MTD Flash – system on SATA, USB or nVME

I then get an error message saying: “There is not enough free capacity on /dev/. Please check your device”

A quick check of GParted shows :

unallocated 16.00MiB
/dev/nvme0n1p1 (key symbol) bootfs
/dev/nvme0n1p2 rootfs

/dev/nvme0n1 (238.47 GiB)

I assume this means that the boot loader has saved to the nvme so I tried starting up without the SD Card and all I get is flashing red light and a black screen with things booting back up when I reinsert the SD Card.

I’m not sure what I’m missing and will probably look to go with one of the official Orange Pi distros instead as your instructions seem clearer and I wasn’t really able to find any answers on the Armbian forum so I don’t want to trouble you by suggesting that you do a separate SSD booting guide just for Armbian as its still fairly new with weekly updates and I’ll give your suggestion trying Debian/Ubuntu a go over the weekend as the instructions look simpler… Thanks again for the support!

Razor Burn
Razor Burn
16 hours ago

Ok so I did some googling and saw a post on Reddit “Booting Orange Pi 5 from NVMe SSD”

Use etcher (or your preferred imaging tool) to write the OS image to an SD card

Use etcher again to write the same image to your NVMe SSD

Insert both the SD card and the NVMe SSD into the Orange Pi 5

Power on the Orange Pi (the first time around it will boot from the SD card)

SSH into the Orange Pi 5, and run: orangepi-config (or armbian-install if you’re using armbian)

Select boot options, then select: Install/Update the bootloader on SPI Flash (this might be Install/Update the bootloader on MTD Flash if using armbian)

Once this is complete, you can remove the SD card and the device will now be able to boot directly from NVMe (SD card is no longer needed — this is true even if you decide to re-image your NVMe SSD)

I followed those steps and got an error when selecting to boot from MTD Flash so shut down yet Armbian load screen popped up and I gathered I’d try restarting without the SD Card and eureka my Pi 5 now boots from NVMe so no need for the sd card!

I really appreciate your support James as it takes true dedication and passion to put in the many hours making these informative reviews and guides, not to mention answering the any questions and troubleshooting users problems so thank you!

1 day ago

Hi again,
I still cannot boot directly from ssd. The only difference between your tutorial and other tutorials that can boot from ssd any my case is that in my case the ssd drive is recognized as sda not as nvme. Is that a problem?

1 day ago
Reply to  Mahdi

Here is the output of Debug/UART serial port:

DDR Version V1.08 20220617
LPDDR4X, 2112MHz
channel[0] BW=16 Col=10 Bk=8 CS0 Row=16 CS=1 Die BW=16 Size=1024MB
channel[1] BW=16 Col=10 Bk=8 CS0 Row=16 CS=1 Die BW=16 Size=1024MB
channel[2] BW=16 Col=10 Bk=8 CS0 Row=16 CS=1 Die BW=16 Size=1024MB
channel[3] BW=16 Col=10 Bk=8 CS0 Row=16 CS=1 Die BW=16 Size=1024MB
Manufacturer ID:0x1 Samsung
CH0 RX Vref:34.7%, TX Vref:18.8%,0.0%
CH1 RX Vref:32.7%, TX Vref:18.8%,0.0%
CH2 RX Vref:32.7%, TX Vref:18.8%,0.0%
CH3 RX Vref:31.7%, TX Vref:17.8%,0.0%
change to F1: 528MHz
change to F2: 1068MHz
change to F3: 1560MHz
change to F0: 2112MHz
U-Boot SPL board init
U-Boot SPL 2017.09-orangepi (Jan 06 2023 - 14:00:02)
Trying to boot from MMC2
spl: mmc init failed with error: -123
Trying to boot from MMC1
Card did not respond to voltage select!
spl: mmc init failed with error: -95
Trying to boot from MTD2
Trying fit image at 0x4000 sector
## Verified-boot: 0
## Checking atf-1 0x00040000 ... sha256(806278dba1...) + OK
## Checking uboot 0x00200000 ... sha256(b1fc1e0a9d...) + OK
## Checking fdt 0x0034b500 ... sha256(feafd7cda6...) + OK
## Checking atf-2 0x000f0000 ... sha256(c00c7fd75b...) + OK
## Checking atf-3 0xff100000 ... sha256(71c3a5841b...) + OK
## Checking atf-4 0xff001000 ... sha256(2301cf73be...) + OK
Jumping to U-Boot(0x00200000) via ARM Trusted Firmware(0x00040000)
Total: 505.204 ms

INFO: Preloader serial: 2
NOTICE: BL31: v2.3():v2.3-405-gb52c2eadd:derrick.huang
NOTICE: BL31: Built : 11:23:47, Aug 15 2022
INFO: spec: 0x13
INFO: ext 32k is valid
INFO: GICv3 without legacy support detected.
INFO: ARM GICv3 driver initialized in EL3
INFO: system boots from cpu-hwid-0
INFO: idle_st=0x21fff, pd_st=0x11fff9, repair_st=0xfff70001
INFO: dfs DDR fsp_params[0].freq_mhz= 2112MHz
INFO: dfs DDR fsp_params[1].freq_mhz= 528MHz
INFO: dfs DDR fsp_params[2].freq_mhz= 1068MHz
INFO: dfs DDR fsp_params[3].freq_mhz= 1560MHz
INFO: BL31: Initialising Exception Handling Framework
INFO: BL31: Initializing runtime services
WARNING: No OPTEE provided by BL2 boot loader, Booting device without OPTEE init ialization. SMC`s destined for OPTEE will return SMC_UNK
ERROR: Error initializing runtime service opteed_fast
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x200000
INFO: SPSR = 0x3c9

U-Boot 2017.09-orangepi (Jan 06 2023 - 14:00:02 +0800)

Model: Orange Pi 5
PreSerial: 2, raw, 0xfeb50000
DRAM: 3.7 GiB
Sysmem: init
Relocation Offset: eda2b000
Relocation fdt: eb9f91c8 - eb9fecc8
Using default environment

SF: Detected sfc_nor with page size 256 Bytes, erase size 4 KiB, total 16 MiB
Bootdev(atags): mtd 2
PartType: EFI
DM: v1
boot mode: None
Model: Orange Pi 5
CLK: (sync kernel. arm: enter 1008000 KHz, init 1008000 KHz, kernel 0N/A)
b0pll 24000 KHz
b1pll 24000 KHz
lpll 24000 KHz
v0pll 24000 KHz
aupll 24000 KHz
cpll 1500000 KHz
gpll 1188000 KHz
npll 24000 KHz
ppll 1100000 KHz
aclk_center_root 702000 KHz
pclk_center_root 100000 KHz
hclk_center_root 396000 KHz
aclk_center_low_root 500000 KHz
aclk_top_root 750000 KHz
pclk_top_root 100000 KHz
aclk_low_top_root 396000 KHz
Net: No ethernet found.
Hit key to stop autoboot('CTRL+C'): 0
mmc@fe2c0000: 1
mmc@fe2e0000: 0
PCIe-0 Link Fail

Device 0: unknown device
scanning bus for devices...

Device 0: unknown device

Device 2: Vendor: 0x2207 Rev: V1.00 Prod: sfc_nor
Type: Hard Disk
Capacity: 16.0 MB = 0.0 GB (32768 x 512)
... is now current device
Failed to mount ext2 filesystem...
** Unrecognized filesystem type **

Device 1:
Device 0: unknown device
starting USB...
Bus usb@fc000000: usb maximum-speed not found
Register 2000140 NbrPorts 2
Starting the controller
Bus usb@fc800000: USB EHCI 1.00
Bus usb@fc840000: failed to get usb phy
Port not available.
Bus usb@fc880000: USB EHCI 1.00
Bus usb@fc8c0000: USB OHCI 1.0
Bus usb@fcd00000: usb maximum-speed not found
Register 2000140 NbrPorts 2
Starting the controller
scanning bus usb@fc000000 for devices... 1 USB Device(s) found
scanning bus usb@fc800000 for devices... 1 USB Device(s) found
scanning bus usb@fc880000 for devices... 1 USB Device(s) found
scanning bus usb@fc8c0000 for devices... 1 USB Device(s) found
scanning bus usb@fcd00000 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found

Device 0: unknown device
failed to find reset-gpios property
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/000
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/00
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/0
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm-rockchip
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default-arm
No ethernet found.
missing environment variable: bootfile
Retrieving file: pxelinux.cfg/default
No ethernet found.
Config file not found
failed to find reset-gpios property
No ethernet found.
Could not get mtd 0
## Booting FIT Image FIT: No fit blob
FIT: No FIT image
Unknown command 'bootrkp' - try 'help'
opi# dir
Unknown command 'dir' - try 'help'

1 day ago
Reply to  Mahdi

here is what I did:

1- Flashed a SD card with latest orange pi image version jammy 1.1.0.
2- Flashed a SSD with the same image
3- Plugged both SD and SSD
4- Logged in and Install/Update the bootloader on SPI flash
5- Unplugged the SD card.

Unfortunately it does not boot from SSD.

1 day ago

I really thank you. I tried over 50 times with this M.2 SATA. I even did not know there are different M.2 drive. I really thank you again.