DebianOn is an effort to document how to install, configure and use Debian on some specific hardware. Therefore potential buyers would know if that hardware is supported and owners would know how get the best out of that hardware. The purpose is not to duplicate the Debian Official Documentation, but to document how to install Debian on some specific hardware. If you need help to get Debian running on your hardware, please have a look at our user support channels where you may find specific channels (mailing list, IRC channel) dedicated to certain types of hardware. |
Translation(s): none
Contents
Models covered
?StarFive ?VisionFiveV1
?StarFive VisionFive V1, ?StarFive JH7100 (Dual-core 64-bit ?SiFive U74) + Embedded 32-bit ?SiFive E24 Core, 8 GB 64-bit LPDDR4, Gigabit Ethernet, microSD Card.
Overall Status
Core Components |
||
Boot Standard Kernel: |
{?} |
|
LAN network card (): |
|
|
Detect hard drives (microSD/NVMe): |
|
|
Xorg |
[?] |
|
Extra Features |
||
CPU Frequency Scaling |
[?] |
|
Hibernation |
[?] |
|
Sleep / Suspend |
[?] |
|
Power Off / Reboot |
|
Legend :
= OK ; Unsupported(No Driver) ; = Error (Couldn't get it working); [?] Unknown, Not Test ; [-] Not-applicable
= Configuration Required; = Only works with a non-free driver and or firmware
Important Note
There are no official Debian images available yet.
Boot process overview
The full boot process is documented in the official documentation. This guide is focused on getting u-boot to boot the Linux kernel.
The board comes with the u-boot bootloader flashed on the internal SPI flash. This u-boot first tries to load the file /boot/uEnv.txt from the third partition of the SD card, allowing to customize the boot process. It then implements the "generic distro" concept of u-boot.
Unfortunately, as of May 2022 (U-Boot 2022.04-rc2-?VisionFive built on Mar 07 2022 - 21:12:22 +0800), the bundled u-boot on the board doesn't do anything except loading the uEnv.txt file, because it's missing a built-in definition of "bootcmd". That is, the uEnv.txt file is currently mandatory and needs to specify how to boot. It also needs to define load addresses for the kernel, FDT, and/or EFI image. See https://github.com/starfive-tech/u-boot/pull/31 and https://github.com/starfive-tech/u-boot/pull/32 for patches fixing these issues.
In any case, u-boot can boot Linux using two main methods:
either it can load an extlinux.conf file describing which kernel/FDT/initrd images to boot, load all three images, and boot the kernel directly. This fits the "generic distro" model.
- or it can load an EFI image, typically grub, and delegate the boot process to this second bootloader. Like in the previous case, u-boot will scan partitions to find an EFI image at a specific location (/efi/boot/bootriscv64.efi).
In the long term, using EFI is the preferred and more standard way. However, Debian currently lacks the tooling to make this a straightforward option. The other option, the "legacy" extlinux.conf method, is well integrated in Debian, so it is currently easier to setup. Both options are documented below.
Installing Debian on VisionFive V1
As described above, two boot options are presented in this guide: either using u-boot directly or using a Grub EFI image.
Most of the steps are common for the two options.
Build the kernel
# Install prerequisites on the host machine sudo apt install libncurses-dev libssl-dev bc flex bison make gcc gcc-riscv64-linux-gnu # Download and extract latest StarFive JH7100 sources wget https://github.com/starfive-tech/linux/archive/refs/heads/visionfive.tar.gz tar xf visionfive.tar.gz # build the kernel cd linux-visionfive/ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- starfive_jh7100_fedora_defconfig nice make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc) bindeb-pkg LOCALVERSION=-starfive
While the kernel is compiling, you can proceed with the next steps.
Bootstrap the root filesystem
This step will bootstrap a minimal RISC-V root filesystem in /tmp/riscv-chroot, which can later be copied to the SD card. This is much faster than bootstrapping directly on the SD card.
# Install prerequisites on host: sudo apt install qemu-user-static binfmt-support debootstrap debian-ports-archive-keyring systemd-container rsync wget # The command below will bootstrap debian sudo debootstrap --arch=riscv64 unstable /tmp/riscv-chroot https://deb.debian.org/debian # If you get an error "Unable to execute target architecture", try the following process instead: sudo debootstrap --foreign --arch=riscv64 unstable /tmp/riscv-chroot http://deb.debian.org/debian sudo mkdir -p /tmp/riscv-chroot/usr/bin/ sudo cp "$(which qemu-riscv64-static)" /tmp/riscv-chroot/usr/bin/ sudo chroot /tmp/riscv-chroot/ /debootstrap/debootstrap --second-stage
While debootstrap is working, you can proceed with the next step.
Create partitions and filesystems
We need to create several partitions on the SD card:
- partition 1 is unused
- partition 2 is the EFI System Partition (used for boot option 2)
- partition 3 is the root filesystem, which also includes the kernel, initramfs, and boot configuration
If you want to use a separate boot partition, be aware that it's possible but not straightforward. See "Tips to handle a separate /boot partition" at the end of this page.
We use a GPT partition table to be future-proof, but it could work with a DOS partition table.
# These instructions assume that your microSD card is at /dev/mmcblk0 # The following command will automatically setup all partitions. # Be careful, it doesn't ask any confirmation! sudo sgdisk -g --clear --new=1:0:+16M: --new=2:0:+100M: -t 2:EF00 --new=3:0:-1M: --attributes 3:set:2 -d 1 /dev/mmcblk0 # If you choose to create the partitions manually with gdisk, don't # forget to set the "legacy BIOS bootable" flag on partition 3 # (go to advanced menu, then "set attributes", select partition, and set flag 2) # You can double check your work with: fdisk -l /dev/mmcblk0 # Next, prepare the filesystems sudo mkfs.vfat /dev/mmcblk0p2 sudo mkfs.ext4 -m 0 -L root /dev/mmcblk0p3 # Prepare mountpoint for EFI filesystem in the temporary debian rootfs sudo mkdir -p /tmp/riscv-chroot/boot/efi
Copy kernel packages
Once the kernel has finished compiling, you need to copy the resulting packages in the chroot:
# Run this from the directory where you compiled the kernel sudo cp ../*.deb /tmp/riscv-chroot/root/
Configure Debian
At this point, you must wait for debootstrap to finish bootstrapping the Debian root filesystem. Then you can enter the chroot and configure the system:
# Now enter the chroot and ensure that the package db is up to date sudo systemd-nspawn -D /tmp/riscv-chroot/ -M debian --bind-ro=/etc/resolv.conf apt update apt upgrade # Install initramfs tools, SSH server, NTP client, and various utils apt install initramfs-tools openssh-server systemd-timesyncd rsync bash-completion # Clean downloaded packages apt clean # Install kernel packages apt install ./linux-*.deb # Configure u-boot # This should eventually become unnecessary, see: # https://github.com/starfive-tech/u-boot/pull/31 # https://github.com/starfive-tech/u-boot/pull/32 cat <<EOF > /boot/uEnv.txt fdt_high=0xffffffffffffffff initrd_high=0xffffffffffffffff kernel_addr_r=0x84000000 kernel_comp_addr_r=0x90000000 kernel_comp_size=0x10000000 fdt_addr_r=0x88000000 ramdisk_addr_r=0x88300000 # Move DHCP after MMC to speed up booting boot_targets=mmc0 dhcp # Fix wrong fdtfile name fdtfile=starfive/jh7100-starfive-visionfive-v1.dtb # Fix missing bootcmd bootcmd=run distro_bootcmd EOF # Configure fstab cat <<EOF > /etc/fstab /dev/mmcblk0p2 /boot/efi vfat umask=0077 0 1 EOF # Configure network cat <<EOF >> /etc/network/interfaces allow-hotplug eth0 iface eth0 inet dhcp EOF # Set root password passwd # Change hostname echo visionfive > /etc/hostname # sync disks sync # exit chroot exit
Option 1: legacy u-boot through extlinux.conf
With this method, we need to create an extlinux configuration file that will be parsed by u-boot.
During normal operation, the configuration is generated automatically by u-boot-menu. But it doesn't work correctly in a chroot, so we need to fix it manually.
# Enter chroot again sudo systemd-nspawn -D /tmp/riscv-chroot/ -M debian --bind-ro=/etc/resolv.conf # Install u-boot-menu apt install u-boot-menu # Uncomment U_BOOT_PARAMETERS in /etc/default/u-boot and set it to the following: # U_BOOT_PARAMETERS="rw console=tty0 console=ttyS0,115200 earlycon rootwait stmmaceth=chain_mode:1 selinux=0" vi /etc/default/u-boot # Re-run kernel postinstall hooks dpkg-reconfigure linux-image-5.18.0-starfive # Verify extlinux configuration was generated cat /boot/extlinux/extlinux.conf # Fix root parameter in extlinux configuration sed -i -e 's|root=[^ ]*|root=/dev/mmcblk0p3|' /boot/extlinux/extlinux.conf # exit chroot exit
Finishing steps on the host:
# Copy the content of the chroot to the SD card sudo mkdir -p /mnt/sdcard sudo mount /dev/mmcblk0p3 /mnt/sdcard sudo cp -a /tmp/riscv-chroot/* /mnt/sdcard/ # Make sure everything is really written (can take a long time) sync umount /mnt/sdcard
The SD card should now boot correctly on the ?VisionFive.
Option 2: EFI with grub
With this option, we setup a grub EFI image on the EFI System Partition at the standard path "EFI/boot/bootriscv64.efi". This image will be detected and booted by u-boot.
Unfortunately, Debian is not yet capable of generating a RISC-V grub image. For now, we have to copy it from the Fedora image provided by ?StarFive.
First, configure grub:
# Add a symlink from /grub.cfg to /boot/grub.cfg # This is a workaround because the Fedora grub image only looks at /grub.cfg ln -s boot/grub.cfg /tmp/riscv-chroot/grub.cfg # Write a basic grub.cfg configuration # You should adapt the paths depending on kernel version sudo tee /tmp/riscv-chroot/boot/grub.cfg <<EOF set default=0 set timeout_style=menu set timeout=2 set debug="linux,loader,mm" set term="vt100" menuentry 'Debian kernel 5.18 for visionfive' { linux /boot/vmlinuz-5.18.0-starfive root=/dev/mmcblk0p3 rw console=tty0 console=ttyS0,115200 earlycon rootwait stmmaceth=chain_mode:1 selinux=0 devicetree /usr/lib/linux-image-5.18.0-starfive/starfive/jh7100-starfive-visionfive-v1.dtb initrd /boot/initrd.img-5.18.0-starfive } EOF
Then, if you already have a SD card with a Fedora image on it, you can just copy the grub image from it:
# Insert Fedora SD card # Mount EFI partition of Fedora SD card sudo mkdir -p /mnt/fedora-efi sudo mount /dev/mmcblk0p2 /mnt/fedora-efi # Copy EFI grub image somewhere, then unmount partition sudo cp /mnt/fedora-efi/EFI/fedora/grubriscv64.efi /tmp/ sudo umount /mnt/fedora-efi # Insert Debian SD card, then mount EFI partition sudo mount /dev/mmcblk0p2 /tmp/riscv-chroot/boot/efi # Copy EFI grub image to final destination, then umount partition sudo mkdir -p /tmp/riscv-chroot/boot/efi/EFI/boot sudo cp /tmp/grubriscv64.efi /tmp/riscv-chroot/boot/efi/EFI/boot/bootriscv64.efi sudo umount /tmp/riscv-chroot/boot/efi
Alternatively, if you don't have a Fedora SD card, you need to download the ?StarFive Fedora image and extract the file from it:
# You will need some files from the official StarFive Fedora image. # Open a terminal on the host machine and download the image from here: # https://github.com/starfive-tech/Fedora_on_StarFive # Extract the Fedora image sudo apt install zstd zstd -d Fedora-riscv64-jh7100-developer-xfce-Rawhide-20211226-214100.n.0-sda.raw.zst # Examine the partitions. Note the partition start locations and units fdisk -u -l Fedora-riscv64-jh7100-developer-xfce-Rawhide-20211226-214100.n.0-sda.raw # Mount the partition numbered 2 of the image as follows. # Compute the offset by multiplying (units * start) # For example, if the start is 69632 and units is 512 bytes, then (69632 * 512) = 35651584 # Use this offset value to mount the second partition: sudo mkdir -p /mnt/fedora-efi sudo mount -o loop,offset=35651584 Fedora-riscv64-jh7100-developer-xfce-Rawhide-20211226-214100.n.0-sda.raw /mnt/fedora-efi # Mount EFI partition of Debian SD card sudo mount /dev/mmcblk0p2 /tmp/riscv-chroot/boot/efi # Now we can copy the grub image from Fedora sudo mkdir -p /tmp/riscv-chroot/boot/efi/EFI/boot sudo cp /mnt/fedora-efi/EFI/fedora/grubriscv64.efi /tmp/riscv-chroot/boot/efi/EFI/boot/bootriscv64.efi # Unmount Debian EFI partition sudo umount /tmp/riscv-chroot/boot/efi # Unmount the Fedora partition sudo umount /mnt/fedora-efi
Run final steps:
# Copy the content of the chroot to the SD card sudo mkdir -p /mnt/sdcard sudo mount /dev/mmcblk0p3 /mnt/sdcard sudo cp -a /tmp/riscv-chroot/* /mnt/sdcard/ # Make sure everything is really written (can take a long time) sync umount /mnt/sdcard
The SD card should now boot correctly on the ?VisionFive. To verify if Debian is correctly booted through EFI, you can check if the path "/sys/firmware/efi/" exists on the running system.
Tips to handle a separate /boot partition
In case you want to use a separate boot partition, here are some tips to make it work:
- Use partition number 3 for /boot, so that uEnv.txt gets loaded from here
- Put the uEnv.txt configuration file at "/boot/boot/uEnv.txt" (assuming that your boot partition is mounted at /boot)
- Make sure your extlinux.conf or grub.cfg configuration is correct (no "/boot" prefix for initrd and kernel)
- Make sure that /etc/fstab has an entry for /boot
- You need to copy DTBs to the boot partition. This can be done automatically, see below.
Synchronizing DTBs automatically
There is a small script that automatically synchronizes DTBs to the boot partition each time you install or update a kernel.
First, make sure rsync is installed in the rootfs on the SD card. Then, assuming your rootfs is at "/mnt/sdcard" and the boot partition is mounted:
# If you used option 1 (extlinux.conf generated by u-boot-menu) cp /mnt/sdcard/usr/share/doc/u-boot-menu/examples/zz-sync-dtb /mnt/sdcard/etc/kernel/postinst.d/zz-sync-dtb chmod +x /mnt/sdcard/etc/kernel/postinst.d/zz-sync-dtb # If you used option 2 (grub EFI image) wget -O /mnt/sdcard/etc/kernel/postinst.d/zz-sync-dtb https://sources.debian.org/data/main/u/u-boot-menu/4.0.4/zz-sync-dtb chmod +x /mnt/sdcard/etc/kernel/postinst.d/zz-sync-dtb # In all cases, perform a manual initial sync (adapt kernel version) mkdir -p /mnt/sdcard/boot/usr/lib/linux-image-5.18.0-starfive rsync -a /mnt/sdcard/usr/lib/linux-image-5.18.0-starfive/. /mnt/sdcard/boot/usr/lib/linux-image-5.18.0-starfive/.
For option 1, make sure that "/boot/extlinux/extlinux.conf" has a line such as "fdtdir /usr/lib/linux-image-5.18.0-starfive/". If this is not the case, chroot and run "u-boot-update".
For option 2, make sure your "/boot/grub.cfg" has something like "devicetree /usr/lib/linux-image-5.18.0-starfive/starfive/jh7100-starfive-visionfive-v1.dtb"
Updating the kernel
To udpate the kernel, you need to:
- build a new kernel using exactly the same steps as during installation (cross-compilation)
- copy and install the resulting .deb on the device
- if using the grub EFI method, manually update /boot/grub.cfg to point to the new kernel
The rest should work automatically (DTB synchronisation, extlinux.conf generation for the legacy boot method)