This page provides instructions how to install Fedora 40 (or newer) on StarFive VisionFive 2 (JH7110) SBC. The instructions assume that main partitions will be on M.2 NVMe. microSD card is not required, but can be used to flash SPI-NOR firmware with a new U-Boot and OpenSBI.
You can place the main partitions on microSD card instead of M.2 NVMe if you don't have one.
This guide assumes that your host system is running Fedora 40 (or newer).
Default accounts:
root
:linux
riscv
:fedora_rocks!
(groups:wheel
andmock
)
Web console (cockpit) should be available at 9090 port (exact link will be printed on the serial console and SSH login).
root
account will not work with SSH and web console. Use riscv
account.
You can find initial VisionFive 2 Fedora 40 disk images here: https://dl.fedoraproject.org/pub/alt/risc-v/disk_images/Fedora-40/VisionFive2/
Installing SPI-NOR firmware via UART boot mode
This method allows to boot upstream U-Boot SPL (XMODEM) and U-Boot proper (YMODEM) using your serial console. This is especially helpful is SPI-NOR content is damaged and the board no longer boots. Once booted you can flash SPI-NOR with a new firmware images.
SPI-NOR partitions:
# cat /proc/mtd dev: size erasesize name mtd0: 00080000 00010000 "spl" mtd1: 00010000 00010000 "uboot-env" mtd2: 00400000 00010000 "uboot" mtd3: 00a00000 00010000 "reserved-data"
[..] partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; spl@0 { reg = <0x0 0x80000>; }; uboot-env@f0000 { reg = <0xf0000 0x10000>; }; uboot@100000 { reg = <0x100000 0x400000>; }; reserved-data@600000 { reg = <0x600000 0xa00000>; }; }; [..]
Make sure your board is powered down.
Connect UART-Serial to USB dongle to VF2 using GPIO headers (3V3):
- PIN 6: GND
- PIN 8: UART-TX
- PIN 10: UART-RX
More details here: https://doc-en.rvspace.org/VisionFive2/Quick_Start_Guide/VisionFive2_SDK_QSG/recovering_bootloader%20-%20vf2.html
Check dmesg
or usb-devices
output for a new device (could be written as "UART", "Serial", etc.).
Your USB serial port adapter will be /dev/ttyUSB<NUMBER>
and /dev/serial/by-id/<NAME>
. The latter name is generated base d on vendor, product name, serial code of your USB serial port adapter.
These devices are in dialout
group. If you don't want to use sudo
and your user to this group:
usermod -aG dialout <USERNAME>
We will use minicom
for serial console. Let's launch it with minicom -s
for setup:
+-----[configuration]------+ | Filenames and paths | | File transfer protocols | | Serial port setup | | Modem and dialing | | Screen and keyboard | | Save setup as dfl | | Save setup as.. | | Exit | | Exit from Minicom | +--------------------------+
Select Serial port setup
. Press A
and modify the path for your USB serial port adapter. Hit ENTER
until you return to the original menu. Then choose Exit
to start.
Switch the board to UART boot mode:
1 (High) 0 (Low) ┌───────┐ ┌───────┐ │XXXXXXX│ │ │ RGPIO_1: 1 (H) └───────┘ └───────┘ ┌───────┐ ┌───────┐ │XXXXXXX│ │ │ RGPIO_0: 1 (H) └───────┘ └───────┘
More details here: https://doc-en.rvspace.org/VisionFive2/Boot_UG/VisionFive2_SDK_QSG/boot_mode_settings.html?hl=uart
Let's use microSD card with FAT or ext4 partition to store new firmware files:
u-boot-spl.bin.normal.out
(U-Boot SPL) [REQUIRED]u-boot.itb
(U-Boot, OpenSBI, DTB) [REQUIRED]uboot-env.bin
(default U-Boot environment in binary format) [OPTIONAL]
All required files can be found in uboot-images-riscv64
(noarch) package. It's also installed in the disk image.
Remove M.2 NVMe if installed. We don't want to have bootable media in any form otherwise Linux will boot before you can get to U-Boot prompt.
Insert the card to the board, and power it on.
You should see similar output:
(C)StarFive CCCCCCCCCCCCCCCCCCCCC
It will constantly write C
.
Press CTRL-A S
. You will see upload menu:
+-[Upload]--+ | zmodem | | ymodem | | xmodem | | kermit | | ascii | +-----------+
Select xmodem
, then [Goto]
button at the bottom. Enter directory were you have downloaded your U-Boot firmware files. Select u-boot-spl.bin.normal.out
using SPACE
and then active [Okay]
button. It will start uploading the first binary:
+----------------[xmodem upload - Press CTRL-C to quit]----------------+ |Sending u-boot-spl.bin.normal.out, 1142 blocks: Give your local XMODEM| | receive command now. | |Xmodem sectors/kbytes sent: 414/51k | | | | | | | | | +----------------------------------------------------------------------+
Press any key once it's uploaded. Now you should see U-Boot SPL booted and C
will continue to be printed out:
U-Boot SPL 2024.10-rc2 (Aug 22 2024 - 00:00:00 +0000) DDR version: dc2e84f0. Trying to boot from UART CCCCCCCCC
Now press CTRL-A S
and select ymodem
. This time we want to send u-boot.itb
file. This file is large and thus will take a bit longer to upload.
+----------------[ymodem upload - Press CTRL-C to quit]----------------+ |Sending: u-boot.itb | |Bytes Sent:1151104 BPS:8710 | |Sending: | |Ymodem sectors/kbytes sent: 0/ 0k | |Transfer complete | | | | READY: press any key to continue... | +----------------------------------------------------------------------+
U-Boot will not find any bootable media and will drop you into the prompt.
Loading Boot0000 'mmc 1' failed Loading from BootNext failed, falling back to BootOrder Loading Boot0000 'mmc 1' failed EFI boot manager: Cannot load any image StarFive #
Check the content of microSD card:
StarFive # ls mmc 1:1 <DIR> 4096 . <DIR> 4096 .. <DIR> 16384 lost+found 1151019 u-boot.itb 146178 u-boot-spl.bin.normal.out 65536 uboot-env.bin
Update U-Boot SPL and U-Boot data:
sf probe load mmc 1:1 ${loadaddr} u-boot-spl.bin.normal.out setenv ldsize ${filesize} sf update ${loadaddr} 0x0 ${ldsize} load mmc 1:1 ${loadaddr} u-boot.itb setenv ldsize ${filesize} sf update ${loadaddr} 0x100000 ${ldsize}
We booted using UART mode with the same files thus we can update default U-Boot environment too:
# env default -a -f; env save ## Resetting to default environment Saving Environment to SPIFlash... Erasing SPI flash...Writing to SPI flash...done OK
Alternative would be to load uboot-env.bin
from microSD card and write it out:
load mmc 1:1 ${loadaddr} uboot-env.bin setenv ldsize ${filesize} sf update ${loadaddr} 0xf0000 ${ldsize}
Let's shutdown the system for now with poweroff
command.
Remove power cable.
Remove the microSD card.
Switch to SPI-NOR boot mode:
1 (High) 0 (Low) ┌───────┐ ┌───────┐ │ │ │XXXXXXX│ RGPIO_1: 1 (H) └───────┘ └───────┘ ┌───────┐ ┌───────┐ │ │ │XXXXXXX│ RGPIO_0: 1 (H) └───────┘ └───────┘
Prepare main system drive (M.2 NVMe or microSD)
Download the latest Fedora 40 disk image. There are multiple way to write RAW disk image to a drive. One of them is using dd
tool:
sudo dd if=./Fedora.riscv64-Rawhide_server_20240826.n.0.raw of=/dev/<YOUR_DRIVE> bs=512K iflag=fullblock oflag=direct conv=fsync status=progress
It's highly import to ensure that a proper of=
device is used otherwise you could damage your host system and loose all the data.
You can also use GNOME Disks application. It has "Restore Disk Image.." once a drive is selected.
This image can be flashed to microSD or M.2 NVMe, and it will work the same way.
Post Install
At this stage you should be able to boot Fedora 40 with firmware on SPI-NOR flash and NVMe for the system partitions.
Our filesystem is not using a full drive capacity:
[root@localhost ~]# btrfs filesystem usage -T / Overall: Device size: 3.53GiB Device allocated: 2.68GiB Device unallocated: 874.98MiB Device missing: 0.00B Device slack: 3.50KiB Used: 1.67GiB Free (estimated): 1.49GiB (min: 1.06GiB) Free (statfs, df): 1.49GiB Data ratio: 1.00 Metadata ratio: 2.00 Global reserve: 5.50MiB (used: 0.00B) Multiple profiles: no Data Metadata System Id Path single DUP DUP Unallocated Total Slack -- -------------- ------- --------- -------- ----------- ------- ------- 1 /dev/nvme0n1p3 2.16GiB 512.00MiB 16.00MiB 874.98MiB 3.53GiB 3.50KiB -- -------------- ------- --------- -------- ----------- ------- ------- Total 2.16GiB 256.00MiB 8.00MiB 874.98MiB 3.53GiB 3.50KiB Used 1.53GiB 73.53MiB 16.00KiB
Expand it to full disk capacity:
[root@localhost ~]# growpart /dev/nvme0n1 3 CHANGED: partition=3 start=3074048 old: size=7411679 end=10485726 new: size=1950451087 end=1953525134 [root@localhost ~]# btrfs filesystem resize max / Resize device id 1 (/dev/nvme0n1p3) from 3.53GiB to max [ 554.546967] BTRFS info (device nvme0n1p3): resize device /dev/nvme0n1p3 (devid 1) from 3794776064 to 998630952960 [root@localhost ~]# btrfs filesystem usage -T / Overall: Device size: 930.05GiB Device allocated: 2.68GiB Device unallocated: 927.37GiB Device missing: 0.00B Device slack: 3.50KiB Used: 1.67GiB Free (estimated): 928.00GiB (min: 464.32GiB) Free (statfs, df): 928.00GiB Data ratio: 1.00 Metadata ratio: 2.00 Global reserve: 5.50MiB (used: 0.00B) Multiple profiles: no Data Metadata System Id Path single DUP DUP Unallocated Total Slack -- -------------- ------- --------- -------- ----------- --------- ------- 1 /dev/nvme0n1p3 2.16GiB 512.00MiB 16.00MiB 927.37GiB 930.05GiB 3.50KiB -- -------------- ------- --------- -------- ----------- --------- ------- Total 2.16GiB 256.00MiB 8.00MiB 927.37GiB 930.05GiB 3.50KiB Used 1.53GiB 73.53MiB 16.00KiB
Change default passwords for root
and riscv
users using passwd
command.
You can access U-Boot default environment from Linux by creating a file /etc/fw_env.config
with:
/dev/mtd1 0x0 0x10000
Command fw_printenv
will print full environment, and fw_setenv
will allow you to modify it without booting into U-Boot.
Change default hostname:
hostnamectl set-hostname <HOSTNAME>
Next time you want to update firmware you can do that from Linux user space. Check SPI-NOR partitioning:
[root@fedora-riscv ~]# cat /proc/mtd dev: size erasesize name mtd0: 00080000 00010000 "spl" mtd1: 00010000 00010000 "uboot-env" mtd2: 00400000 00010000 "uboot" mtd3: 00a00000 00010000 "reserved-data"
Use flashcp
command:
flashcp -v u-boot-spl.bin.normal.out /dev/mtd0 flashcp -v u-boot.itb /dev/mtd2
Boot into U-Boot, load default environment and write it out to SPI-NOR flash.
You can find firmware files on your disk image:
# rpm -ql uboot-images-riscv64 [..] /usr/share/uboot/starfive_visionfive2 [..] /usr/share/uboot/starfive_visionfive2/spl/u-boot-spl.bin.normal.out [..] /usr/share/uboot/starfive_visionfive2/u-boot.itb
Configurating for highest performance
By default CPU scaling governor is schedutil
which close to highest performance while scaling frequency. To achieve the best performance from JH7110 boards you might want to switch to performace
governor.
Get information about the current default kernel:
# grubby --info=DEFAULT index=0 kernel="/boot/vmlinuz-6.10.6-200.1.riscv64.fc40.riscv64" args="ro rootflags=subvol=root earlycon rootflags=subvol=root cpufreq.default_governor=performance" root="UUID=9bde1c01-47d0-43bb-bcdd-4aa90ffec397" initrd="/boot/initramfs-6.10.6-200.1.riscv64.fc40.riscv64.img" title="Fedora Linux (6.10.6-200.1.riscv64.fc40.riscv64) 40 (Server Edition)" id="e97ec9d687994be78cf0a91cc5e7633e-6.10.6-200.1.riscv64.fc40.riscv64"
Modify the current default kernel to user performance
governor:
grubby --update-kernel=DEFAULT --args="cpufreq.default_governor=performance"
To modify the current default kernel and future kernels too to use performance
governor:
grubby --update-kernel=ALL --args="cpufreq.default_governor=performance"
Reboot the system. You can get more information from running system:
# cpupower frequency-info analyzing CPU 1: driver: cpufreq-dt CPUs which run at the same hardware frequency: 0 1 2 3 CPUs which need to have their frequency coordinated by software: 0 1 2 3 maximum transition latency: Cannot determine or is not supported. hardware limits: 375 MHz - 1.50 GHz available frequency steps: 375 MHz, 500 MHz, 750 MHz, 1.50 GHz available cpufreq governors: conservative ondemand userspace powersave performance schedutil current policy: frequency should be within 375 MHz and 1.50 GHz. The governor "performance" may decide which speed to use within this range. current CPU frequency: 1.50 GHz (asserted by call to hardware) # cpupower frequency-info -s analyzing CPU 3: 375000:0, 500000:0, 750000:0, 1500000:268990 (1)