StarFive VisionFive 2 Official Debian SSD Boot Guide

StarFive VisionFive 2 SSD Boot Guide
StarFive VisionFive 2 SSD Boot Guide

The StarFive VisionFive 2 comes with a M.2 M-key PCIe 2.0 slot that we can use with a 2280 NVMe drive. Unfortunately at release it’s not possible to boot from the NVMe drive but this is expected to be added to the device through some combination of SPI+NVMe booting.

In the meantime 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

StarFive VisionFive 2
StarFive VisionFive 2

The StarFive VisionFive 2 is a quad-core high performance single board computer that runs the RISC-V open-hardware architecture. It also has a dedicated GPU making it suitable for desktop use!

Links:*, AliExpress*

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.


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@starfive:/# sudo gdisk /dev/nvme0n1
sudo: unable to resolve host starfive: Temporary failure in name resolution
GPT fdisk (gdisk) version 1.0.9

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

Found invalid GPT and valid MBR; converting MBR to GPT format
typing 'q' if you don't want to convert your MBR partitions
to GPT format!

Command (? for help): p
Disk /dev/nvme0n1: 1953525168 sectors, 931.5 GiB
Model: Samsung SSD 960 EVO 1TB                 
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 8ACF6B0D-D7EC-48A0-955B-93AD7C6B53FE
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 1953525134
Partitions will be aligned on 2048-sector boundaries
Total free space is 1922993516 sectors (917.0 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          264191   128.0 MiB   0700  Microsoft basic data
   2          264192        30533632   14.4 GiB    8300  Linux filesystem

Command (? for help): d
Partition number (1-2): 1

Command (? for help): d
Using 2

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/nvme0n1.
The operation has completed successfully.

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:


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/mmcblk1p3

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/mmcblk1p3

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

root@starfive:/boot# sudo blkid
sudo: unable to resolve host starfive: Temporary failure in name resolution
/dev/nvme0n1p3: LABEL="root" UUID="8260c14e-8ec8-406a-ae74-4ae0465376cf" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="3d4c02eb-9c28-46a1-a86b-71666ef51cdb"
/dev/nvme0n1p2: SEC_TYPE="msdos" UUID="49C6-F38E" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="bdc51e7d-66f3-4ba4-ac93-adf2e8850928"
/dev/mmcblk1p3: LABEL="root" UUID="2e441104-607f-4f13-ada2-09d2ef0e03fd" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="3d4c02eb-9c28-46a1-a86b-71666ef51cdb"
/dev/mmcblk1p2: SEC_TYPE="msdos" UUID="49C6-F38E" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="bdc51e7d-66f3-4ba4-ac93-adf2e8850928"
/dev/nvme0n1p1: PARTUUID="5f7fd372-5546-44df-b018-a077758cee2f"
/dev/mmcblk1p1: PARTUUID="5f7fd372-5546-44df-b018-a077758cee2f"

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

Fix extlinux.conf

Use this one-liner to update /boot/extlinux/extlinux.conf:

sudo sed -i 's/mmcblk1p3/nvme0n1p3/g' /boot/extlinux/extlinux.conf

EDIT 4/1/2023: Some builds use the path /boot/boot:

sudo sed -i 's/mmcblk1p3/nvme0n1p3/g' /boot/boot/extlinux/extlinux.conf

Run fsck

Before we reboot run fsck on the drive like this:

sudo fsck -yf /dev/nvme0n1p3

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 VisionFive 2 with:

sudo reboot

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

root@starfive:/home/user# sudo mount
/dev/nvme0n1p3 on / type ext4 (rw,relatime)

Here we can see that our root partition (/) is indeed on /dev/nvme0n1p3 and not /dev/mmcblk0p3. Success!

Benchmarking Performance

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                 181.92 MB/s              
HDParm                    Cached Disk Read          181.63 MB/s              
DD                        Disk Write                107 MB/s                 
FIO                       4k random read            44425 IOPS (177700 KB/s) 
FIO                       4k random write           9006 IOPS (36024 KB/s)   
IOZone                    4k read                   64462 KB/s               
IOZone                    4k write                  43701 KB/s               
IOZone                    4k random read            35419 KB/s               
IOZone                    4k random write           75853 KB/s               

                          Score: 13,856

The full StarFive VisionFive 2 benchmark can be viewed here on Pi Benchmarks.

This is actually a great performance score. It’s much higher than anything the Raspberry Pi 4 can do thanks to the PCIe interface (while the Raspberry Pi 4 has to use USB).

It’s also below competing ARM boards such as the Orange Pi 5, ODROID M1 and the Raspberry Pi CM4 that have PCIe 2.0 interfaces. The latest generation of alternative ARM boards are faster than this board but they also have a lot more CPU cores.

It’s pretty impressive performance considering this is RISC-V and not an ARM device. This is by far the highest score I’ve *ever* seen on any RISC-V device. It’s not even close. RISC-V is still a rapidly developing technology while ARM processors (while still having technological improvements) are unquestionably a much further developed technology. RISC-V is catching up very quickly though!

Other Resources

I’ve written a review for the StarFive VisionFive 2 available here

Don’t miss my guide on how to update the StarFive VisionFive 2’s firmware here

You can see all of my RISC-V articles here

All of my single board computer reviews are available here

Notify of

Inline Feedbacks
View all comments
Jackson Lancaster
Jackson Lancaster
2 months ago

When I run the command
sudo tune2fs -U random /dev/mmcblk1p3
I get errors because the file system is vfat and this command only works on ext fs.
How could I make this work?

4 months ago

could you do update since firmware is supposedly allowing native booting on Starfive 2 board?

11 months ago

A few other notes I forgot to mention in my last comment.
I didn’t bother with changing the UUID, I just took out the sdcard once I was done. No more conflicting uuids.
In u-boot you will need to change the default bootcmd using:
editenv bootcmd
At the edit prompt type “run bootcmd_mmc0” (assuming you are using the emmc)
You should then be able to continue booting by just typing “boot” or “reset”

11 months ago

If you’re cloning the sdcard to nvme or emmc you can greatly simplify this process by just using dd, no need to partition the nvme/emmc because dd is just going to overwrite it. Using your guide I was able to clone my sdcard to emmc by using the following steps:
sudo dd if=/dev/mmcblk1 of=/dev/mmcblk0 conv=fsync
sudo fsck -yf /dev/mmcblk0p3
sudo fsck -yf /dev/mmcblk0p4
modify extlinux.conf on /dev/mmcblk0p3 as required. i ended up just mounting it and using vim because that’s what i’m more comfortable with.
modify fstab on /dev/mmcblk0p4 and update root and boot to point to the emmc (or nvme)
expand /dev/mmcblk0p4 partition (steps in visionfive 2 getting started guide or google)

Sergey Khabarov
Sergey Khabarov
1 year ago

With my cheap Crucial P3 ssd 256 gb I have a bit higher results:
Category Test Result
HDParm Disk Read 201.50 MB/s
HDParm Cached Disk Read 195.87 MB/s
DD Disk Write 91.8 MB/s
FIO 4k random read 44618 IOPS (178474 KB/s)
FIO 4k random write 8939 IOPS (35757 KB/s)
IOZone 4k read 80756 KB/s
IOZone 4k write 47042 KB/s
IOZone 4k random read 36373 KB/s
IOZone 4k random write 87858 KB/s

Score: 15137

Aleksander Alekseev
Aleksander Alekseev
1 year ago

Thanks for sharing! But shouldn’t you also change the partition sizes after cloning the image of the SD card?

1 year ago

@james, there have been a couple of releases since this guide was written, it might be worth a refresh. For instance the /boot/boot path is now just /boot again.

Aleksander Alekseev
Aleksander Alekseev
1 year ago

Thanks! Interestingly what the Quick Start Guide suggests seems to be as safe as doing the same from another Linux PC. The idea is that fdisk modifies only the partition table, not the partitions per se. So if you drop a partition and create a new one starting from the same block no data will be lost (fdisk doesn’t touch the filesystem on the partition, etc). On top of that ext4 supports on-line resizing, which is used by resize2fs.

1 year ago

I like the trick of just using ‘cat’ to clone the SD card : I used dd if=/dev/mmcblk1 bs=8M status=progress of=/dev/nvme0n1 which seemed to run somewhat faster, Not sure what the optimal blocksize is for the NVMe but 8M is usual for the SD card, the slower of the two.

1 year ago

You can use -ibs and -obs to specify them appropriately for each device. The dd default is 512K.

The big impact that I am aware of is that if the blocksize is lower than the device blocksize it will need to make multiple reads or writes for that physical block.. but writes are usually the bottleneck. 8M is the usual blocksize for SD cards afik, but trying to find the NVMe blocksize ended in google-hell so I assumed (as you point out) that I should increase it, but rely on it’s caching too.