Running Virtual Machines on Orange Pi 5

with Libvirt and Ubuntu

In this guide, we’ll walk through the steps to install libvirt on the Single Board Computer (SBC) Orange Pi 5 (opi5) for running virtual machines (VMs). I’ve compiled these steps after dealing with the opi5 instructions, searching on the internet and communities, and my own experience. I hope this guide helps someone accomplish this task more quickly than I did initially.

Installing Orange Pi 5

The first step is to install an Operating System (OS) on the opi5. You have several options here: you can use official images, third-party images, or build your own. In this case, I used a third-party image, Ubuntu. Additionally, I used a PCIe NVMe SSD for storage. Here are the installation steps:

  1. Install Ubuntu on the NVMe, following the opi5 official docs for burning it to the SSD.
  2. Apply basic configurations, including:
    • Network
    • Locale
    • Keyboard
  3. Perform a package update/upgrade.

Installing Libvirt

To install libvirt, you will need to install some other related packages and add a user to the libvirt group. You may also consider applying a workaround for running UEFI VMs. Afterward, you can easily test with a Cirros VM. Follow these steps to accomplish this.

## `--no-install-recommends` for avoiding recommended pkgs in a server
## alternative or additional pkgs
## `qemu-system`  for all qemu architecture or
## `qemu-efi-arm` for arm 32bits efi
## `u-boot-qemu` if planning to use uboot
# install pkgs in ubuntu 22.04
sudo apt install --no-install-recommends libvirt-daemon \
  libvirt-daemon-system libvirt-clients qemu-kvm qemu-system-arm \
  qemu-utils qemu-efi-aarch64 qemu-efi-arm arm-trusted-firmware \
  seabios bridge-utils virtinst dnsmasq-base ipxe-qemu

# add user to libvirt group
sudo adduser $USER libvirt
newgrp libvirt
export LIBVIRT_DEFAULT_URI=qemu:///system

# workaround
# set `60-edk2-aarch64.json` as the default uefi configuration
# using a symlink to place the descritor file first
sudo ln -s  /usr/share/qemu/firmware/60-edk2-aarch64.json \

# test cirros VM
## download cirros image
sudo wget \
  -P /var/lib/libvirt/images
## create root qcow2 from image
sudo qemu-img create -b /var/lib/libvirt/images/cirros-0.5.2-aarch64-disk.img \
  -F qcow2 -f qcow2 /var/lib/libvirt/images/test.qcow2
## autostart default net
virsh net-autostart --network default
virsh net-start default
## install test VM in ubuntu host
virt-install -n test --memory 1024 --arch aarch64 --vcpus 1 \
  --disk /var/lib/libvirt/images/test.qcow2,device=disk,bus=virtio \
  --os-variant=cirros0.5.2 \
  --nographic \
  --boot loader=/usr/share/AAVMF/AAVMF_CODE.fd,loader.readonly=yes,loader.type=pflash

On Debian?

I attempted to install libvirt on a Debian image on the opi5, but I was not successful. I subsequently switched to Ubuntu. Here are the steps that I used to install libvirt on Debian, in case anyone wants to explore that route.

sudo apt install --no-install-recommends qemu-system-arm libvirt-clients \
  libvirt-daemon-system bridge-utils virtinst libvirt-daemon qemu-utils \

Have Fun

Originally, my goal with a Single Board Computer (SBC) was to unwind and take a break from the usual work routine. I opted for an opi5 in the way. However, lo and behold, here I am, enabling virtualization, almost like it’s a rarity in my line of work over at Krestomatio! It’s been a fun experience, nonetheless.

See also