Ubuntu Server on RISC-V documentation needs updating

I was reading this wiki article and I noticed that it’s outdated and needs updating. I am using Qemu but it’s possible the other documentation needs updating too. In particular I noticed:

  • The machine type in the example is -machine virt, but the linked images are for SiFive HiFive Unmatched & Unleashed, so AFAIK this should be -machine sifive_u
  • The file name is not the same as the images, it currently starts with “focal”. This one is a fairly minor one to fix though as the filename will change as new versions are published.
  • When I try to boot the image after fixing the above problems, Qemu gives me the error of No 'virtio-bus' bus found for device 'virtio-net-device', so I guess there is something missing, maybe the requirements for -machine sifive_u are different from the requirements of -machine virt and simply swapping out the name isn’t enough.

Also, if I try to boot these images on -machine virt (which I don’t expect to work), this happens:

Retrieving file: /lib/firmware/5.11.0-1007-generic/device-tree/qemu-riscv.dtb
Failed to load '/lib/firmware/5.11.0-1007-generic/device-tree/qemu-riscv.dtb'
Skipping l0r for failure retrieving fdt
SCRIPT FAILED: continuing...
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Scanning disk virtio-blk#8...
** Unrecognized filesystem type **
** Unrecognized filesystem type **
Found 6 disks
** Invalid partition 21 **
Cannot read EFI system partition
BootOrder not defined
EFI boot manager: Cannot load any image

paging @xnox to this thread

Update: It seems that -machine virt is indeed correct. I got it to work, but the documentation still needs updating beyond this, because with my current configuration if I update the kernel then the OS stops booting. I also added ,hostfwd=tcp::2222-:22 to the network configuration so that I can SSH into my VM as the serial port is quite bad and only allows one session, so I would highly recommend placing this in the documentation too. The config I have that works with the exact kernel version the 20.04 image ships with is this:

qemu-system-riscv64 \
-machine virt \
-nographic \
-m 4096 -smp 4 \
-bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-device virtio-net-pci,netdev=eth0 \
-netdev user,id=eth0,hostfwd=tcp::2222-:22 \
-drive file=ubuntu.img,format=raw,if=virtio \

Pinging @xypron also :blush:

This works for me:

#!/bin/sh

set -e

if test ! -f opensbi/build/platform/generic/firmware/fw_payload.bin; then
wget https://cdimage.ubuntu.com/releases/20.04/release/ubuntu-20.04.3-preinstalled-server-riscv64+unmatched.img.xz
xz -dk ubuntu-20.04.3-preinstalled-server-riscv64+unmatched.img.xz
export CROSS_COMPILE=riscv64-linux-gnu-
git clone https://source.denx.de/u-boot/u-boot.git
cd u-boot/
git reset --hard v2021.10-rc3
make qemu-riscv64_smode_defconfig
make -j$(nproc)
cd ..
git clone https://github.com/riscv/opensbi.git
cd opensbi/
make PLATFORM=generic FW_PAYLOAD_PATH=../u-boot/u-boot.bin
cd ..
fi
qemu-system-riscv64 -machine virt -m 1G -nographic \
-bios opensbi/build/platform/generic/firmware/fw_payload.bin \
-smp cores=2 -gdb tcp::1234 \
-device virtio-net-device,netdev=net0 \
-netdev user,id=net0,tftp=tftp \
-drive if=none,file=ubuntu-20.04.3-preinstalled-server-riscv64+unmatched.img,format=raw,id=mydisk \
-device ich9-ahci,id=ahci -device ide-hd,drive=mydisk,bus=ahci.0 \
-device virtio-rng-pci

There is no kernel upgrade available for ubuntu-20.04.3-preinstalled-server-riscv64+unmatched.img. Which image have you been using?

The latest version when I posted this thread was “ubuntu-20.04.2-preinstalled-server-riscv64.img.xz”.

Also, it would be very much appreciated if there was documentation for how to make a RISC-V VM with graphics.

@xypron Oh, I see. The link on the wiki is outdated. It is https://cdimage.ubuntu.com/releases/20.04.2/release/ which redirects to https://old-releases.ubuntu.com/releases/focal/ but the 20.04.3 image can be found at http://cdimage.ubuntu.com/releases/20.04/release/ so the problem is that link has “.2” when it shouldn’t.

Here are some instructions based on what I did which worked for me.

  1. Have Ubuntu 20.04 host and download the Ubuntu 20.04 “riscv64” image or have an Ubuntu 21.04 host and download the Ubuntu 21.04 “riscv64” image (this software is really picky about the versions matching).
  2. Install the dependencies: sudo apt install qemu-system-misc opensbi u-boot-qemu qemu-utils
  3. Optionally rename the image to something simpler.
  4. Extract the image from step 0: xz -dk ubuntu.img.xz
  5. Increase the size of the image qemu-img resize -f raw ubuntu.img +20G
    • Be aware, this can technically be changed later but it’s really annoying to do, I recommend setting the size now to whatever size you think you’ll need, I ended up running out of space and spent over an hour fiddling with fdisk and such.
  6. Make a Bash script with this command (or just run it) to boot the VM:
qemu-system-riscv64 \
-machine virt \
-nographic \
-m 8192 -smp 4 \
-bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-device virtio-net-pci,netdev=eth0 \
-netdev user,id=eth0,hostfwd=tcp::2222-:22 \
-drive file=ubuntu.img,format=raw,if=virtio \
  1. Let it boot, this may take several minutes. Then log in.
  2. Do not run sudo apt upgrade as changing the kernel or bootloader can brick the VM (in my experience).
  3. By default it uses the serial port, but this is quite bad. Run sudo apt install openssh-server, open a terminal on your host, and run ssh -p 2222 ubuntu@localhost to SSH into your VM for a much better experience.
  4. Install whatever you want as long as you don’t run upgrade. Like sudo apt install cmake gcc clang build-essential