Several methods are available for connecting a device driver in a guest to its external service.
A device driver running in a guest can use one of the following methods to connect to a VirtIO vdev:
The method you use will depend on how your guest is configured, and how easy or difficult you want to make changing the device location. For example, in a production system direct memory mapping (where you write in your configurations the locations in memory of your devices) may be acceptable or even preferable, but you may require a more flexible approach during your project's development phase.
The PCI discovery method is most common in guests designed for x86 platforms, but it can also be used by guests on ARM platforms. PCI hardware isn't required to support this discovery mechanism, because in a hypervisor guest PCI is completely virtual.
The following illustrates how PCI mapping can be used to enable a driver in a guest to discover and connect to a VirtiO device. The example uses the virtio-blk vdev, but could also be used for other VirtIO vdevs such as virto-console or virtio-net.
Using virtio-blk as our example, and a QNX guest (QNX Neutrino OS or QNX OS for Safety guest):
Configure the VM hosting the guest to map the location of the AHCI SATA driver (located at /dev/hd1t178) through VirtIO to the guest; for example:
vdev virtio-blk hostdev /dev/hd1t178 name virtio-blk_qvm178
See vdev virtio-blk for more information about configuring this vdev in the VM.
In the guest, run pci-server (see pci-server in the Utilities Reference); for example:
pci-server –bus-scan-limit=8
In the QNX guest, use pci-tool to query the PCI device (see pci-tool in the Utilities Reference); for example:
[x86 guest QNX 7.0]% pci-tool -v B000:D00:F00 @ idx 0 vid/did: 1c05/0002 BlackBerry QNX, n/a QVM PCI host bridge class/subclass/reg: 06/00/00 Host-to-PCI Bridge Device B000:D01:F00 @ idx 1 vid/did: 1af4/1042 <vendor id - unknown>, <device id - unknown> class/subclass/reg: 01/80/00 Other Mass Storage Controller B000:D02:F00 @ idx 2 vid/did: 1af4/1041 <vendor id - unknown>, <device id - unknown> class/subclass/reg: 02/80/00 Other Network Controller B000:D03:F00 @ idx 3 vid/did: 1c05/0001 BlackBerry QNX, n/a QVM guest shared memory factory class/subclass/reg: 05/80/00 Other Memory Controller B000:D04:F00 @ idx 4 vid/did: 1af4/1043 <vendor id - unknown>, <device id - unknown> class/subclass/reg: 07/80/00 Other Simple Communications Controller
Note that the disk controller appears with a vid/did (vendor ID/device ID) of 1af4/1042; this is the VirtIO standard reference for a mass storage device. Other devices such as memory devices or network devices will also show up as PCI devices.
In a Linux guest, you can use lspci. You may see the vendor/device as 1c05/0042; this is the BlackBerry VirtIO vendor ID. The Linux kernel module understands that this is a block device.
In the QNX guest, start the VirtIO driver for block devices (devb-virtio). The driver will scan the PCI space to find the device with the 1af4/1042 vendor ID/device ID, and mount it as a block volume; for example: devb-virtio will create /dev/hd0 in the guest.
If the block volume is already formatted as a QNX6 power-safe filesystem, you can mount it; for example:
mount -tqnx6 /dev/hd0 /mydisk
The following illustrates how a device can be mapped in the host, then the mapping passed on to a driver in a guest. The example uses the virtio-blk vdev, but could also be used for other VirtIO vdevs such as virto-console or virtio-net.
Using virtio-blk as our example, and a QNX guest (QNX Neutrino OS or QNX OS for Safety guest):
Configure the VM with the path of the host file to use for the contents of the device (see vdev virtio-blk in the Virtual Device Reference chapter).
Use a location in guest-physical memory that isn't used by any other driver in the guest, and an interrupt that isn't used by any other driver or service in the guest. In this example we use 0x1c0d0000 and 41:
vdev virtio-blk loc 0x1c0d0000 intr gic:41 hostdev /dev/hd1t178 name virtio-blk_qvm178
Start the VirtIO block device driver (devb-virtio) in the guest, using the driver's startup options to map in the memory and interrupt you specified in the virtio-blk vdev configuration; in our example the options would be as follows:
devb-virtio virtio smem=0x1c0d0000,irq=41
The devb-virtio driver in the guest should now find the device in the host through the VirtIO device.
You can use FDTs to expand direct mapping to support dynamic discovery of devices. For example, on an ARM platform you could use entries in the FDT to provide the guest with information about virtual devices.
For more information about using FDT in a QNX hypervisor system, see ACPI tables and FDTs in the Configuration chapter.