Enhancing Virtio support in Zephyr with a new API and additional components
Published:
Topics: Open OS, Open source tools
Virtual I/O (Virtio), described in an open specification by OASIS Open, provides interfaces that allow Virtual Machines (VMs) to access virtual devices (i.e. devices that are not emulated based on real hardware). Compared to physical device emulation, where a hypervisor emulates a device in full, translating into more overhead, Virtio offers more efficient virtualization with less overhead because the guest operating system (OS) communicates directly with the hypervisor through special drivers. This makes Virtio a frequently used virtualization option for hypervisors such as KVM. Virtio also provides a wide variety of drivers for various guest OSes and excels at high performance combined with minimal impact on the emulated system.
Initially, Antmicro used Virtio to integrate a host filesystem in Renode to load filesystem images dynamically and make them available, for example, in a Linux simulation without recompiling and reloading the kernel or root filesystem. Later on, Antmicro improved that integration by adding support for the Virtio filesystem (virtiofs), which enabled sharing parts of the host machine’s directory tree with the simulated device without the need to re-pack the root filesystem with every code iteration.
Subsequently, we added Virtio support in Zephyr, which increased the RTOS’ usability as a unikernel because Virtio streamlines communication between the hypervisor and the VM. Following up on this work, we’ve been expanding Virtio support in Zephyr with new features and improvements to enable even more use cases. This includes a new API, virtiofs, new drivers, and fixes.
In this article, we will show you how Virtio support has been added in Zephyr, describe Antmicro’s recent contributions, and demonstrate the use of Zephyr’s filesystem API over virtiofs.
Virtio in Zephyr: implementation and use cases
Antmicro implemented Virtio in Zephyr by defining the Virtio API for such device operations as:
- device initialization;
- feature flags/bits negotiation;
- accessing virtqueues (a communication mechanism); and
- accessing device-specific data.
A Virtio device is a virtual host that communicates with a guest (a driver) but looks like a physical device from the guests’s perspective. This enables the guest to use standard drivers and discovery mechanisms, which facilitates the communication. Such a device exposes the Virtio interface through transfer methods like PCI or MMIO. Using Virtio in Zephyr enables you to save time, reduce the processing power, and enhance security by:
- testing PCI devices in a virtualized environment;
- reducing the footprint thanks to specialized micro VMs;
- separating critical tasks into isolated units (for example, vehicle control algorithms in automotives); and
- multiplexing hardware resources in a continuous integration environment (useful for standardized tests and development).
New contributions by Antmicro and the Zephyr community
Antmicro has enhanced the support for Virtio in Zephyr, which now allows using a wider array of devices in a virtualized environment thanks to additional driver components:
- Virtio base and PCI - enable Zephyr running on PCI platforms to use Virtio and introduce an API and such components common to all Virtio options as virtqueues and interrupt service routines.
- Virtiofs - enables a VM guest to access the host’s filesystem in Zephyr. This driver uses FUSE messages to communicate between the two.
- Console and network interfaces - paravirtualized serial interfaces allowing faster operation in comparison to other, emulated serial and network interfaces, respectively; these are our latest additions, and, with the former selected, the Virtio console is automatically configured in QEMU through CMake.
For the Virtio console, we have fixed a deadlock and an issue with adding a port during polling. Additionally, we have dealt with an off-by-one error during virtiofs initialization and introduced a cleanup for some Virtio drivers. Apart from that, minor fixes and changes have been introduced both by Antmicro and the Zephyr community at large.
There are other additions possible in the future, such as including more devices (for example, virtio-blk), VSock, legacy Virtio, and optional optimization features, like indirect virtq descriptors for better workload dispatching.
Demo: using Zephyr’s filesystem API over virtiofs
The following demo presents Zephyr’s ability to access the host’s filesystem using virtiofs. Here, Zephyr’s filesystem API is used to list and read files placed in the directory on the host, which is mounted in Zephyr in /virtiofs, allowing data transfer between the guest and the host.
To launch the demo above, run the following command:
west build -b qemu_x86_64 samples/subsys/fs/virtiofs
It requires an operating virtiofsd, embedded QEMU’s arguments through CONFIG_QEMU_EXTRA_FLAGS, and the socket path set to /tmp/vhostqemu. You can find the whole sample here.
You can use Virtio in Zephyr through a common drivers/virtio API for device drivers. For user applications, Virtio is exposed using standard driver APIs. For Virtio, Zephyr uses standard Kconfig and a Devicetree configuration.
We are currently working on enabling Renode-based testing of your virtiofs Zephyr applications, leveraging our previous work on Linux simulation.
Amplify your Zephyr experience with Antmicro’s serivces
Antmicro is constantly expanding Zephyr to cover more use cases, and helps customers build complete products running Zephyr on various architectures, including RISC-V. Thanks to the improved Virtio support, you can use more devices and perform more actions in Zephyr.
If you need specific platform support or new functionalities in Zephyr, or simply need help further improving Virtio support in the OS, don’t hesitate to contact us at contact@antmicro.com.