RockOS KVM Demo
RockOS supports KVM virtualization based on H Extension (RISC-V Hypervisor Extension).
Currently the following are verifed as working:
- Ubuntu 24.04.1 LTS & 24.10
- openEuler 24.03 LTS & 24.09
- FreeBSD 14.1-RELEASE
- Debian testing netinst CD
Environment
- OS Version: RockOS github
- Ubuntu preinstalled image: https://cdimage.ubuntu.com/releases/24.10/release/ubuntu-24.10-preinstalled-server-riscv64.img.xz
- openEuler 24.09 QEMU: https://repo.openeuler.org/openEuler-24.09/virtual_machine_img/riscv64/
- FreeBSD 14.1-RELEASE: https://download.freebsd.org/releases/VM-IMAGES/14.1-RELEASE/riscv64/Latest/
- Debian testing netinst CD: https://cdimage.debian.org/cdimage/weekly-builds/riscv64/iso-cd/debian-testing-riscv64-netinst.iso
- Debian sid cloud image: https://cdimage.debian.org/images/cloud/sid/daily/latest/debian-sid-nocloud-riscv64-daily.qcow2
qemu-system-riscv64
is installed by default- Manually install
wget
orcurl
to download the image u-boot-qemu
andqemu-efi-riscv64
are provided in the repo, manually install them if needed
You can try other mirrors if the official server is too slow for you.
Steps
Currently QEMU does not support loading M Mode firmware via -bios
while KVM is enabled. See comments here. So here are some of the options we have now:
- Use
u-boot.elf
provided byu-boot-qemu
package- You can boot Ubuntu and FreeBSD with this method.
- Use other firmwares
- e.g. openEuler RISC-V + EDK II (distributed along side with system image)
- EDK II comes with
qemu-efi-riscv64
package
- Use
-initrd
-kernel
-append
flags- You can boot Ubuntu with this method.
- The BusyBox KVM Demo is also using this method.
- You can also boot FreeBSD this way according to FreeBSD Wiki.
- Not tested & not demonstrated in this article.
By default RockOS does not load KVM module on boot, so before we start, manually load it:
sudo modprobe kvm
Install required packages:
sudo apt update; sudo apt install -y wget u-boot-qemu qemu-efi-riscv64
Method A: Acquire U-Boot from u-boot-qemu package
For this method, we have Ubuntu preinstalled server image, FreeBSD and Debian netinst CD as examples.
Ubuntu
wget https://cdimage.ubuntu.com/releases/24.10/release/ubuntu-24.10-preinstalled-server-riscv64.img.xz
xz -dkv -T0 ubuntu-24.10-preinstalled-server-riscv64.img.xz
sudo qemu-system-riscv64 --enable-kvm -M virt -cpu host -m 2048 -smp 2 -nographic \
-device virtio-net-device,netdev=eth0 -netdev user,id=eth0 \
-device virtio-rng-pci \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-drive file=ubuntu-24.10-preinstalled-server-riscv64.img,format=raw,if=virtio
The default username and password are both ubuntu
.
For Ubuntu preinstalled image, you'll be prompted to change your password on first boot. Follow the steps and you're good to go.
FreeBSD
wget https://download.freebsd.org/releases/VM-IMAGES/14.1-RELEASE/riscv64/Latest/FreeBSD-14.1-RELEASE-riscv-riscv64.qcow2.xz
xz -dkv -T0 FreeBSD-14.1-RELEASE-riscv-riscv64.qcow2.xz
sudo qemu-system-riscv64 --enable-kvm -M virt -cpu host -m 2048 -smp 2 -nographic \
-device virtio-net-device,netdev=eth0 -netdev user,id=eth0 \
-device virtio-rng-pci \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-drive file=FreeBSD-14.1-RELEASE-riscv-riscv64.qcow2,format=qcow2,if=virtio
Use username root
for a passwordless login.
Debian cloud
Debian sid currently provides qcow2 disk images.
wget https://cdimage.debian.org/images/cloud/sid/daily/latest/debian-sid-nocloud-riscv64-daily.qcow2
sudo qemu-system-riscv64 --enable-kvm -M virt -cpu host -m 2048 -smp 2 -nographic \
-device virtio-net-device,netdev=eth0 -netdev user,id=eth0 \
-device virtio-rng-pci \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-drive file=debian-sid-nocloud-riscv64-daily.qcow2,format=qcow2,if=virtio
Debian testing netinst CD
wget https://cdimage.debian.org/cdimage/weekly-builds/riscv64/iso-cd/debian-testing-riscv64-netinst.iso
qemu-img create -f qcow2 debian.qcow2 16G
sudo qemu-system-riscv64 --enable-kvm -M virt -cpu host -m 2048 -smp 2 -nographic \
-boot d -cdrom debian-testing-riscv64-netinst.iso \
-device virtio-net-device,netdev=eth0 -netdev user,id=eth0 \
-device virtio-rng-pci \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-drive file=debian.qcow2,format=qcow2,if=virtio
Execute the commands above will create a 16G qcow2 disk image, and bring you to the Debian installer.
After the installation process, power off the VM, delete -boot d -cdrom debian-testing-riscv64-netinst.iso \
, and then you can boot straight into the installed system.
Method B: Use other firmwares (e.g. TianoCore EDK II)
Currently, openEuler, Ubuntu and Debian are verified.
For openEuler use the EDK II firmware distributed with the main system image; for Ubuntu and Debian, install qemu-efi-riscv64
and use the firmware provided by this package.
Current version of EDK II might get stuck at
Press ESCAPE within 5 seconds for boot options
(~50s). Press Enter to skip.
openEuler
Obtain and decompress the image:
wget https://repo.openeuler.org/openEuler-24.09/virtual_machine_img/riscv64/RISCV_VIRT_CODE.fd \
https://repo.openeuler.org/openEuler-24.09/virtual_machine_img/riscv64/RISCV_VIRT_VARS.fd \
https://repo.openeuler.org/openEuler-24.09/virtual_machine_img/riscv64/openEuler-24.09-riscv64.qcow2.xz \
https://repo.openeuler.org/openEuler-24.09/virtual_machine_img/riscv64/start_vm.sh
xz -dkv -T0 openEuler-24.09-riscv64.qcow2.xz
Modify the VM start script:
nano start_vm.sh
The following parts need to be changed:
- Add
--enable-kvm
flag - Change RAM allocate size:
memory=2
for 2Gram1
andram2
also need to be changed:object memory-backend-ram,size=1G,id=ram1
object memory-backend-ram,size=1G,id=ram2
- Add
if=none
flag to boot disk
The edited script should look like this:
#!/usr/bin/env bash
# The script is created for starting a riscv64 qemu virtual machine with specific parameters.
RESTORE=$(echo -en '\001\033[0m\002')
YELLOW=$(echo -en '\001\033[00;33m\002')
## Configuration
vcpu=2
memory=2
drive="$(ls *.qcow2)"
fw1="RISCV_VIRT_CODE.fd"
fw2="RISCV_VIRT_VARS.fd"
ssh_port=12055
cmd="qemu-system-riscv64 \
-nographic -machine virt,pflash0=pflash0,pflash1=pflash1,acpi=off \
--enable-kvm \
-smp "$vcpu" -m "$memory"G \
-object memory-backend-ram,size=1G,id=ram1 \
-numa node,memdev=ram1 \
-object memory-backend-ram,size=1G,id=ram2 \
-numa node,memdev=ram2 \
-blockdev node-name=pflash0,driver=file,read-only=on,filename="$fw1" \
-blockdev node-name=pflash1,driver=file,filename="$fw2" \
-drive file="$drive",format=qcow2,id=hd0,if=none \
-object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-vga \
-device virtio-rng-device,rng=rng0 \
-device virtio-blk-device,drive=hd0 \
-device virtio-net-device,netdev=usernet \
-netdev user,id=usernet,hostfwd=tcp::"$ssh_port"-:22 \
-device qemu-xhci -usb -device usb-kbd -device usb-tablet"
echo ${YELLOW}:: Starting VM...${RESTORE}
echo ${YELLOW}:: Using following configuration${RESTORE}
echo ""
echo ${YELLOW}vCPU Cores: "$vcpu"${RESTORE}
echo ${YELLOW}Memory: "$memory"G${RESTORE}
echo ${YELLOW}Disk: "$drive"${RESTORE}
echo ${YELLOW}SSH Port: "$ssh_port"${RESTORE}
echo ""
echo ${YELLOW}:: NOTE: Make sure ONLY ONE .qcow2 file is${RESTORE}
echo ${YELLOW}in the current directory${RESTORE}
echo ""
echo ${YELLOW}:: Tip: Try setting DNS manually if QEMU user network doesn\'t work well. ${RESTORE}
echo ${YELLOW}:: HOWTO -\> https://serverfault.com/a/810639 ${RESTORE}
echo ""
echo ${YELLOW}:: Tip: If \'ping\' reports permission error, try reinstalling \'iputils\'. ${RESTORE}
echo ${YELLOW}:: HOWTO -\> \'sudo dnf reinstall iputils\' ${RESTORE}
echo ""
sleep 2
eval $cmd