Slackware runs riscv64 port by slarm64 team

Title. I’m very experienced with my favourite distro and can only say that their builds are quite generic, RV64GC centered and with very generic default cflags which produce compatible but slow-ish binaries (up to 10x slower than built for JH7110 with clang). So, one might require complete rebuild, which I’m tasked with now on my brand new VF2 V1.3B.

Also, they provide(d) quite “dirty” bootstrap images, I run into one when I booted it on VF1 and it contained two versions of package descriptors in /var/log/packages. Their kernel idk for which target (qemu?) but never ran on any VF for me, I had to cross-compile with StarFive config in the beginning.

There is no easy installation method because official Slackware installer requires you to boot from something first but currently there is no boot media to start with for riscv64.

Today my own Slackware on my board is fully self-hosting, I built everything on it, from U-Boot to X11. It just takes some patience.

Index of /slarm64 package tree
Index of /slackware/rootfs bootstrap minimal rootfs
Official Slackware source tree is taken verbatim, then patches (if needed) are applied from Index of /slarm64/slarm64-current. Patches just fix SlackBuilds to be riscv64 compatible, they don’t add anything beyond that which is good.
As for kernel, I would suggest going with plain Debian one taken verbatim for first time, and rebuild if needed. If you ever ran Slackware, you know how to do this.

As for SBo (, largest repository of all third party software build scripts outside of Slackware scope, think like Arch’s AUR), often it is required to run autoreconf -fvi or replace config.sub and config.guess prior to any ./configure in packages with autotools to update architecture detection. Otherwise they mostly fail because riscv64-slackware-linux is not known to them.
I made a hack around: because patching every SlackBuild is PITA (because they’re all different), I just found a common command which occurs in every SlackBuild: chown -R root:root ., created /usr/src/bin/chown with content like:

# chown -R root:root .
# fix autolulz stupidity
if [ "`/bin/basename ${0}`" = "chown" -a "${1}" = "-R" -a "${2}" = "root:root" -a "${3}" = "." ]; then
        if ! pwd | egrep -q '^/tmp'; then exec /bin/chown "${@}"; fi
        /usr/bin/find -type f -name config.sub -exec /bin/cp -a /usr/share/autoconf/build-aux/config.sub '{}' ';'
        /usr/bin/find -type f -name config.guess -exec /bin/cp -a /usr/share/autoconf/build-aux/config.guess '{}' ';'
exec /bin/chown "${@}"

and placed /usr/src/bin ontop of $PATH. Works flawlessly!


Having just returned to Slackware 15.0 after a years hiatus from Slack, also my very favorite distro, while they sorted out 15.0 and got the repos updated for it, I’m very excited for this post. I’ll definitely be following suit. All my systems, except my wife’s, run Slackware today. I’ll probably grab an eMMC module and target that so I can still boot into debian for debug from SD card.

Thank you so much for posting this. I was looking into it a bit already, but was confused on where to begin. This will help me get started! The slackbuilds workaround is brilliant, I wouldn’t have thought of that ever.

Much Obliged,
Magus Mycelius


My first Slackware was 3.1 I think, circa '96. Boot and root floppies!

I’m tempted to give this riscv64 port a go on my VF2. Have you had any success in booting Slack directly off NVMe? If so, could you provide instructions please?

Have you uploaded any optimized rootfs images?

Praise “Bob”!

1 Like

Yeah, I do run it on my daily basis. Unfortunately I dare to say their builds are highly “generic”, thus, slow-ish on this CPU. So I went to rebuild the whole system myself, with Clang/LLVM when possible, with appropriate CFLAGS for this CPU.

As of running it off NVMe it’s fairly simple. First, make sure you have latest U-Boot in your board. Then, just grab their rootfs thing, partition your NVMe under, say, Debian-minimal, then mke2fs there, mount and untar rootfs onto it. It shall be ready for an initial kickstart. It might be messy, but it shall work. (for example, a package can be marked as installed multiple times with different versions, at least that’s what I’ve got six months ago)
They don’t offer a conventional setup procedure like it’s done on x86 yet, so you’re really have to go back to floppy times :smile:

As of their kernel’s, I’m not sure. I never got any of these prebuilts provided by them to work. They always panicked. At the very beginning I just reused Debian one, built my own and swapped. It was a long time ago, maybe it changed as of now, dunno.

NOTE to this date I never tested X11 or Wayland or any other GUI on it. But I try to keep them installed and updated. Many “heavy” software like Clang/LLVM, GCC/g++, QEMU emulating x86_64 and booting other Linux, some benchmarks, compiling new Slackware on it was tested and proven to work.

If you’re interested more, I can offer some help in form of making initial initramfs with busybox and few fs-related tools ready.


Really? I’ll have to give that a go but I’m surprised beause it seems that the official SF Debian image requires that the user configure U-boot to get NVMe boot to function, in theory at least although I’ve not got it to work yet.

I also doubt booting slack from NVMe will work because it seems the rootfs tarballs don’t include a VF2 kernel so I’d have to use the SF Debian kernel or build my own. I expect I’ll get exactly the same kernel panic if I try to re-use the SF kernel to boot off NVMe.

1 Like

You’re correct, my bad. Actually, you have to tune U-Boot environment to get it boot. At least:

root@serval:~# fw_printenv | fgrep -i nvme
bootcmd=sysboot nvme 0:1 any ${pxefile_addr_r} /extlinux.conf
nvmebootenv=pci enum; nvme scan
preboot=run chipa_set_uboot;run mmcbootenv;run nvmebootenv

That’s what I have in my fwenv. Note that it is ignoring any UEFI stuff, just a simple syslinux compatible text boot menu emulated by U-Boot. But it works.

In case you’ll run into any problems, just let me know.


Which kernel are you using? If you have built your own it would be handy if you could upload it.

Could you please document how to correctly extract the rootfs and a suitable kernel so that booting from NVMe works please? Please also share your extlinux.conf.

Also, which version of u-boot and the firmware are you running? I presume the latest?

It would seem you would’ve had to run these commands to configure u-boot:

setenv bootcmd 'sysboot nvme 0:1 any ${pxefile_addr_r} /extlinux.conf'
setenv nvmebootenv 'pci enum; nvme scan'
setenv preboot 'run chipa_set_uboot;run mmcbootenv;run nvmebootenv'
setenv kernel_comp_addr_r 0x50000000
setenv kernel_comp_size 0x04000000
setenv fdtfile starfive/jh7110-visionfive-v2.dtb

I’m using quite outdated but stable for me 5.15.105 which is StarFive’s 5.15.0 rebased manually ontop of’s 5.15.105 with some custom patches applied to it by me (all completely unrelated to JH7110, proprietary software of mine built as a modules. In past I applied a dirtypipe fix over original SF’s kernel because it’s still vulnerable to it, and my issue opened on their github is ignored). I believe it’s a mess already, so I wouldn’t like to share it, unless you are in absolute need for it.

I can build a pristine rebased 5.15.105 and share my original rebased repo if you want to. But it’ll take some time because I’m not gonna cross-compile the thing. From that point I cannot give you warranty it’ll boot off NVMe just like mine does because I’m not going to mess with my boot partition, but I highly suspect it’ll work anyway.

As of U-Boot and OpenSBI, I had built them myself. Here are git stamps I’m currently running:

U-Boot: commit 688befadf1d337dee3593e6cc0fe1c737cc150bd (HEAD, tag: VF2_v2.11.5, origin/JH7110_VisionFive2_devel, JH7110_VisionFive2_devel)
OpenSBI: commit c6a092cd80112529cb2e92e180767ff5341b22a3 (HEAD, tag: VF2_v2.11.5, origin/master, origin/JH7110_VisionFive2_devel, origin/HEAD, JH7110_VisionFive2_devel)

My extlinux.conf:

menu title Slackware RISCV boot options
timeout 20
default linux64

label linux64
        kernel /linux64.gz
        fdt /vf2.dtb
        append ro console=ttyS0,115200 earlycon=sbi root=/dev/nvme0n1p2 resume=/dev/nvme0n1p4 stmmac.chain_mode=1
        initrd /initramfs.xz

label rescue
        kernel /linux64.gz
        fdt /vf2.dtb
        append ro console=ttyS0,115200 earlycon=sbi root=/dev/nvme0n1p2 resume=/dev/nvme0n1p4 init=/bin/sh stmmac.chain_mode=1
        initrd /initramfs.xz

Add rootwait after root=/dev/nvme0n1p2 if you don’t use initramfs (you can remove initrd line then).

As of rootfs, you have to grab one from here: Index of /slackware/rootfs and use it as initial seed. I grabbed this:

% bsdtar -tvf slarm64-riscv64-current-riscv64-rootfs-20210314.tar.xz | head
drwxr-xr-x  0 root   root        0 мар 14  2021 ./
drwxr-xr-x  0 root   root        0 фев 20  2021 ./var/
drwxr-xr-x  0 root   root        0 фев 20  2021 ./var/lib/
drwxr-xr-x  0 root   root        0 мар 14  2021 ./var/lib/pkgtools/
drwxr-xr-x  0 root   root        0 мар 14  2021 ./var/lib/pkgtools/setup/
drwx------  0 root   root        0 мар 14  2021 ./var/lib/pkgtools/setup/tmp/
-rwxr-xr-x  0 root   root       66 фев 16  2003 ./var/lib/pkgtools/setup/setup.timeconfig
-rwxr-xr-x  0 root   root      283 мая 14  2009 ./var/lib/pkgtools/setup/setup.setconsolefont
-rwxr-xr-x  0 root   root      170 фев 16  2003 ./var/lib/pkgtools/setup/setup.70.install-kernel
-rwxr-xr-x  0 root   root     9164 июн 19  2018 ./var/lib/pkgtools/setup/setup.80.make-bootdisk

Judging by it’s modification date, it’s very outdated. But I guess it might work just to grab current packages from Index of /slackware/slarm64-riscv64-current/slarm64 and upgrade everything. Apparently, rootfs contains slackpkg:

% bsdtar -tvf slarm64-riscv64-current-riscv64-rootfs-20210314.tar.xz | fgrep installpkg
-rwxr-xr-x  0 root       root     27635 дек 29  2020 ./sbin/installpkg

So you might go with smth like (under Debian)

# cd /
# fdisk -u /dev/nvme0n1
# (partition it): 1[boot]:100M 2[rootfs]:40G 3[userdata]:free minus 20G 4[swap]:20G
# mke2fs -t ext4 -LSLRV15 /dev/nvme0n1p2 # rootfs
# mke2fs -t ext4 -Luserdata -m0 /dev/nvme0n1p3 # /home etc.
# mkswap /dev/nvme0n1p4 # swap
# mkdir -p /mnt/slroot
# mount /dev/nvme0n1p2 /mnt/slroot
# cd /mnt/slroot
# tar -xf /path/to/slarm64-riscv64-current-riscv64-rootfs-20210314.tar.xz
# sync
# echo caracal >/mnt/slroot/etc/HOSTNAME # set hostname
# sed -e -i 's@^root:x:@root::@g' /mnt/slroot/etc/passwd # enable initial login for root without any password prompt at all
# cat >/mnt/slroot/etc/fstab <<EOF
/dev/nvme0n1p1     /boot   vfat   ro,nodev,noexec,defaults                          0   0
/dev/nvme0n1p2     /       ext4   defaults                                          1   1
/dev/nvme0n1p3     /home   ext4   nosuid,defaults                                   0   2
/dev/nvme0n1p4     swap    swap   pri=1,defaults                                    0   0
devpts                     /dev/pts      devpts    gid=5,mode=620                   0   0
proc                       /proc         proc      hidepid=2,gid=24,defaults        0   0
tmpfs                      /dev/shm      tmpfs     nosuid,size=50%,defaults         0   0
tmpfs                      /tmp          tmpfs     nosuid,size=100%,defaults        0   0
debugfs                    /sys/kernel/debug   debugfs    defaults                  0   0
configfs                   /sys/kernel/config  configfs   defaults                  0   0
# cd /; umount /mnt/slroot
# mkdosfs -F 32 -n SLRVboot /dev/nvme0n1p1 # you might also use ext2 for it, because U-Boot handles this: mke2fs -m0 -text2 -LSLRVboot /dev/nvme0n1p1
# mount /dev/nvme0n1p1 /mnt/slroot
# cp -a /path/to/prepared/extlinux.conf /mnt/slroot
# mkdir -p /mnt/slroot/extlinux
# cp -a /path/to/prepared/extlinux.conf /mnt/slroot/extlinux # dunno how default U-Boot catches /extlinux.conf, I have symlinks installed all over the place.
# cp -a /path/to/prepared/Image.gz /mnt/slroot/linux64.gz
# cp -a /path/to/prepared/initramfs.xz /mnt/slroot/initramfs.xz # you may omit this if you don't have to setup something before booting rootfs, like, dm-crypt, RAID or pre-loaded drivers stuff
# cp -a /path/to/prepared/jh7110-visionfive-v2.dtb /mnt/slroot/vf2.dtb # just a handy name, you might want to rename it into original and fix extlinux.conf aswell. I have a symlink on that place with ext2 in /boot
# umount /mnt/slroot

, and then try to reboot. If something goes wrong, use rescue boot target to drop into shell.


Thanks Strlcat

Is it necessary to rebuild the kernel, U-boot and OpenSBI to get NVMe boot working?

As of kernel I cannot tell you much. You might want to try luck with building your own, or grabbing a recent one from one of the distributions.

As of U-Boot, I don’t see CONFIG_PCIE_STARFIVE=y in their so I’m not sure about upstream NVMe functionality.

OpenSBI is pretty generic, you might try just to append U-Boot payload to it’s fw_payload.bin, but I would prefer to build it properly. Gladly it’s very easy to build OpenSBI.

If you’ll require instructions on how to build U-Boot and OpenSBI, then let me know. I also can give you configs for all three items so you might try your luck.

EDIT CONFIG_PCIE_STARFIVE is enabled by default according to their drivers/pci/Kconfig, so prebuilts provided by SF not older than 2.11.5 tag shall work. You don’t need to rebuild.

1 Like

Slackware sounds like a lot of effort to set up.

The Debian sid image is working well for me and I can directly boot it off NVMe using these u-boot commands:

nvme scan
fatload nvme 0:3 ${kernel_addr_r} vmlinuz-5.15.0-vf2-104+
fatload nvme 0:3 ${ramdisk_addr_r} initrd.img-5.15.0-vf2-104+
fatload nvme 0:3 ${fdt_addr_r} dtb-5.15.0-vf2-104+/starfive/jh7110-visionfive-v2.dtb
setenv bootargs 'root=/dev/nvme0n1p4 rw console=tty0 console=ttyS0,115200 earlycon rootwait'
setenv kernel_comp_addr_r 0x50000000
setenv kernel_comp_size 0x04000000
booti $kernel_addr_r $ramdisk_addr_r:$filesize $fdt_addr_r

How do I configure u-boot to do the equivalent of what that booti command does? I’ve been trying things like this (the commands below don’t work):

setenv boot_targets 'nvme0'
setenv preboot 'run chipa_set_uboot;pci enum;nvme scan'
setenv fdtfile dtb-5.15.0-vf2-104+/starfive/jh7110-visionfive-v2.dtb
setenv kernel_comp_addr_r 0x50000000
setenv kernel_comp_size 0x04000000
setenv bootcmd_nvme0 'sysboot nvme 0:3 any ${pxefile_addr_r} extlinux.conf'

I keep on seeing the following errors:

In:    serial
Out:   serial
Err:   serial
Model: StarFive VisionFive V2
Net:   eth0: ethernet@16030000, eth1: ethernet@16040000
starfive_pcie pcie@2C000000: Starfive PCIe bus probed.
PCI: Failed autoconfig bar 10
Hit any key to stop autoboot:  0 
Card did not respond to voltage select! : -110
Couldn't find partition mmc 0:3
Can't set block device
Importing environment from mmc1 ...
## Warning: Input data exceeds 1048576 bytes - truncated
## Info: input data size = 1048578 = 0x100002
## Error: "boot2" not defined
Card did not respond to voltage select! : -110
Couldn't find partition mmc 1:3
Can't set block device
## Warning: defaulting to text format
Retrieving file: extlinux.conf
Failed to load 'extlinux.conf'
Error reading config file

I think I need to know (how to find out) what order the uboot commands are run in. What is the “master script/process” here? Pretend I know nothing about u-boot because thats pretty much true.

First command run by U-Boot from environ is content of preboot envvar. Once preboot complete, you face opportunity to get U-Boot shell. At this time you see typical Hit any key to stop autoboot:. If you don’t, U-Boot continues running contents held in bootcmd envvar. This is normal boot process, and pretty common among typical U-Boot setups.

This board however is quite special: it has two U-Boot stages. The first one, SPL, is run directly by SoC’s BootROM and runs from L2 cache aka 2MB SRAM at 0x08000000 with most privileges (default PMPcfg, highest M-Mode, full access to everything). It’s role is solely to setup DRAM and load second stage there. Second stage right now is OpenSBI, which drops privileges to S-Mode, leaving itself resident in protected enclave by PMU and retains M-Mode when it’s code is invoked. This is where U-Boot main, and later, Linux kernel runs.

sysboot shall invoke anything required, skipping fatload, and setenv bootargs. It also shall invoke right boot handler like booti or bootelf for the file type provided, in theory.
Try fiddling with it: sysboot nvme 0:1 any ${pxefile_addr_r} /extlinux.conf. It’s just an example, examine your ssd layout with nvme part. Try to get into fs contents: ls nvme 0:1 / Be sure to provide right device:partno numbers (you’ll get them from nvme part).

Tbh, current U-Boot scripting done by SF is quite messy and confusing. But you shall dig out the right path once you start understanding what’s going on.

Also, try to copy Debian’s behavior first. IIRC current Debian still uses sysboot instead of clumsy UEFI, like Fedora did. At least Image-69 is done this way. The easiest way would be save your current envvar progress to a free QSPI space somewhere in the middle of huge 16MB area:

cp.b 210f0000 a0000000 10000 # read environ
sf probe
sf update a0000000 800000 10000 # <-- write to QSPI at 8MB offset
# do a reset after this, because 0x21000000 gets unmapped after `sf probe`

Then reset envvars to factory defaults:

env default -a
env save

and continue experimenting. Don’t worry, your backup is at 0x21800000, and restoring it is simple:

cp.b 21800000 a0000000 10000
sf probe
sf update a0000000 f0000 10000
# reset board to get 0x21000000 mapping back and load new environ



Also, if it will help, here is my complete fwenv dump from a working Slackware board:

boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_efi_binary=load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootriscv64.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi
boot_efi_bootmgr=if fdt addr ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr;fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
boot_prefixes=/ /boot/
boot_scripts=boot.scr.uimg boot.scr
boot_targets=mmc0 dhcp 
bootargs=ro quiet console=ttyS0,115200 earlycon=sbi stmmac.chain_mode=1
bootcmd=run bootcmd_b
bootcmd_a=load nvme 0:1 ${kernel_addr_r} /linux64.gz; load nvme 0:1 ${ramdisk_addr_r} /initramfs.xz; setenv ramdisk_size ${filesize}; load nvme 0:1 ${fdt_addr_r} /vf2.dtb; booti ${kernel_addr_r} ${ramdisk_addr_r}:${ramdisk_size} ${fdt_addr_r}
bootcmd_b=sysboot nvme 0:1 any ${pxefile_addr_r} /extlinux.conf
bootcmd_dhcp=devtype=dhcp; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00027:UNDI:003000;setenv bootp_arch 0x1b;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci;
bootcmd_mmc0=devnum=0; run mmc_boot
chipa_gmac_set=fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_10 <0x0>;fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_100 <0x0>;fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_1000 <0x0>;fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_delay_sel <0x9>;fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_10 <0x0>;fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_100 <0x0>;fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_1000 <0x0>;fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_delay_sel <0x9> 
chipa_set=if test ${chip_vision} = A; then run chipa_gmac_set;fi; 
chipa_set_linux=fdt addr ${fdt_addr_r};run visionfive2_mem_set;run chipa_set;
chipa_set_linux_force=fdt addr ${fdt_addr_r};run visionfive2_mem_set;run chipa_gmac_set; 
chipa_set_uboot=fdt addr ${uboot_fdt_addr};run chipa_set;
chipa_set_uboot_force=fdt addr ${uboot_fdt_addr};run chipa_gmac_set; 
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
efi_dtb_prefixes=/ /dtb/ /dtb/current/
ext4bootenv=ext4load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootenv}
importbootenv=echo Importing environment from mmc${devnum} ...; env import -t ${loadaddr} ${filesize}
load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
load_vf2_env=fatload mmc ${bootpart} ${loadaddr} ${testenv}
loadbootenv=fatload mmc ${bootpart} ${loadaddr} ${bootenv}
mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
mmcbootenv=run scan_mmc_dev; setenv bootpart ${devnum}:${mmcpart}; if mmc rescan; then run loadbootenv && run importbootenv; run ext4bootenv && run importbootenv; if test -n $uenvcmd; then echo Running uenvcmd ...; run uenvcmd; fi; fi
nvmebootenv=pci enum; nvme scan
preboot=run chipa_set_uboot;run mmcbootenv;run nvmebootenv
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done; setenv devplist
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;run boot_efi_bootmgr;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootriscv64.efi; then echo Found EFI removable media binary efi/boot/bootriscv64.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scan_mmc_dev=if test ${bootmode} = flash; then if mmc dev ${devnum}; then echo found device ${devnum};else setenv devnum 0;mmc dev 0;fi; fi; echo bootmode ${bootmode} device ${devnum};
scan_sf_for_scripts=${devtype} read ${scriptaddr} ${script_offset_f} ${script_size_f}; source ${scriptaddr}; echo SCRIPT FAILED: continuing...
sf_boot=if sf probe ${busnum}; then devtype=sf; run scan_sf_for_scripts; fi
testmemrate=timer start; mw.q 100000000 a55a5aa5aa555aaa 28000000; timer get
ver=U-Boot 2021.10_serval (Mar 26 2023 - 15:39:38 +0200)
visionfive2_mem_set=fdt memory ${memory_addr} ${memory_size};

I removed some items related to serial numbers or mac addresses only. Because I left it almost unaltered, here are some commands which are never called - I used to run smth like env set bootcmd_a $bootcmd to do backups.

It is designed to load things from ext2 fs on /dev/nvme0n1p1, with following layout:

/extlinux/extlinux.conf -> /extlinux.conf (symlink)
/vf2.dtb (might be a symlink)

and with following /extlinux.conf:

menu title Slackware RISCV boot options
timeout 20
default linux64

label linux64
        kernel /linux64.gz
        fdt /vf2.dtb
        append ro console=ttyS0,115200 earlycon=sbi root=/dev/nvme0n1p2 resume=/dev/nvme0n1p4 stmmac.chain_mode=1
        initrd /initramfs.xz

label rescue
        kernel /linux64.gz
        fdt /vf2.dtb
        append ro console=ttyS0,115200 earlycon=sbi root=/dev/nvme0n1p2 resume=/dev/nvme0n1p4 init=/bin/sh stmmac.chain_mode=1
        initrd /initramfs.xz



Thanks for the tips strlcat!

Considering how slow the VF2 SD card is and its USB ports don’t provide enough power to use a bus powered SSD, I’m surprised there isn’t more interest in getting this working, especally after I proved this is almost working with a currently available image.

I’m a bit puzzled by this suggestion:

" Also, try to copy Debian’s behavior first. IIRC current Debian still uses sysboot instead of clumsy UEFI, like Fedora did. At least Image-69 is done this way. The easiest way would be save your current envvar progress to a free QSPI space somewhere in the middle of huge 16MB area…"

You then give what appear to be a few u-boot commands but what presumptions are you making here, if any? I have reset my u-boot EVs several times since I last boot Debian sid off an SD card.

U-boot can’t be accessed via UART post boot as far as I’m aware and currently I can only boot the Debian 69, Debian sid or Arch from SD card in an automated manner so where and when should I run cp.b; sf probe and sf update?

Are you implying that booting some VF2 distros will make adjustments to U-boot?

I’ve got direct nvme boot working with Debian sid now but not using extlinux.conf, just using the booti command.

Thanks for your help @strlcat !


I’ve seen you say elsewhere on the forum that you get ~280 MB/s read speeds from your SSD? Thats about as high as I’ve heard anyone get on the VF2. I only get ~155 MB/s out of my Samsung 980 PRO and I’ve used lspci to check its running at PCIe 2x.

Have you read about anyone getting a higher speed on their VF2 using a different disk?

What make and model is your VF2 SSD?


Well if something is not going to work but there’s a working sample lying around I would try copy it’s behavior first, that’s what I meant by “trying to get Debian working first”. I might be wrong tho cause I never tried to run Debian in the first place off SSD, but I guess modern Debian supports SSD. Correct me if I’m wrong.

1 Like

Times changed. I tried it now again and I’ve got only around 255MB/s. Probably change of power supply.
Funny thing: I get this number only with optimized build of my encryption tool. With stock coreutils’ cat or dd, I get around 200MB/s. But I don’t care about both since dm-crypt encryption layer is much slower (even if using ARX block cipher) and floats at around 60MB/s for me.

I’m using Apacer M.2 2280 SSD.

1 Like

Once, loong before the NVM stuff went in, at around 2.8.0 I used to boot kernel off… QSPI itself. I flashed a heavily compressed and packed into FIT format kernel+ramdisk blob produced by script like this:


/ {
        description = "Linux FIT image for JH7110 VisionFive2";
        #address-cells = <2>;

        images {
                kernel {
                        description = "Kernel";
                        data = /incbin/("linux64.lzma");
                        type = "kernel";
                        arch = "riscv";
                        os = "linux";
                        compression = "lzma";
                        load = <0x0 0x40200000>;
                        entry = <0x0 0x40200000>;
                fdt {
                        description = "DTB";
                        data = /incbin/("vf2.dtb");
                        type = "flat_dt";
                        arch = "riscv";
                        compression = "none";
                        load = <0x0 0x46000000>;
                        entry = <0x0 0x46000000>;
                initrd {
                        description = "Initrd";
                        data = /incbin/("initramfs.xz");
                        type = "ramdisk";
                        arch = "riscv";
                        os = "linux";
                        compression = "none";
                        load = <0x0 0x46100000>;
                        entry = <0x0 0x46100000>;

        configurations {
                default = "config";
                config {
                        kernel = "kernel";
                        fdt = "fdt";
                        ramdisk = "initrd";

built with this command: mkimage -f linux64.its linux64.itb (mkimage is part of u-boot-tools package which comes preinstalled with slarm64-riscv64 rootfs), and then flashed to QSPI at 0x21500000. Then I used bootm 21500000 from U-Boot prompt to boot it (and set it as default bootcmd). It worked well well before NVM stuff went in.
I did not want to waste sdcard for this purpose that time cause I had no any of small size.

The reason I dropped this is because it was quite not portable and limited size of kernel (I had to aggressively compress it with lzma -9 so it would fit into remaining 11MB space in QSPI flash). Fun times.

1 Like