doc: develop: Convert README.virtio to reST

This converts the existing README.virtio to reST, and puts it under
the develop/driver-model/ directory.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
Bin Meng 2021-04-29 17:40:07 +08:00
parent b8db1c1388
commit 9cea9abbe4
2 changed files with 63 additions and 28 deletions

View File

@ -27,3 +27,4 @@ subsystems
soc-framework soc-framework
spi-howto spi-howto
usb-info usb-info
virtio

View File

@ -1,11 +1,10 @@
# SPDX-License-Identifier: GPL-2.0+ .. SPDX-License-Identifier: GPL-2.0+
# .. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
VirtIO Support VirtIO Support
============== ==============
This document describes the information about U-Boot support for VirtIO [1] This document describes the information about U-Boot support for VirtIO_
devices, including supported boards, build instructions, driver details etc. devices, including supported boards, build instructions, driver details etc.
What's VirtIO? What's VirtIO?
@ -15,7 +14,7 @@ just the guest's device driver "knows" it is running in a virtual environment,
and cooperates with the hypervisor. This enables guests to get high performance and cooperates with the hypervisor. This enables guests to get high performance
network and disk operations, and gives most of the performance benefits of network and disk operations, and gives most of the performance benefits of
paravirtualization. In the U-Boot case, the guest is U-Boot itself, while the paravirtualization. In the U-Boot case, the guest is U-Boot itself, while the
virtual environment are normally QEMU [2] targets like ARM, RISC-V and x86. virtual environment are normally QEMU_ targets like ARM, RISC-V and x86.
Status Status
------ ------
@ -49,6 +48,8 @@ Building U-Boot for pre-configured QEMU targets is no different from others.
For example, we can do the following with the CROSS_COMPILE environment For example, we can do the following with the CROSS_COMPILE environment
variable being properly set to a working toolchain for ARM: variable being properly set to a working toolchain for ARM:
.. code-block:: bash
$ make qemu_arm_defconfig $ make qemu_arm_defconfig
$ make $ make
@ -56,11 +57,13 @@ You can even create a QEMU ARM target with VirtIO devices showing up on both
MMIO and PCI buses. In this case, you can enable the PCI transport driver MMIO and PCI buses. In this case, you can enable the PCI transport driver
from 'make menuconfig': from 'make menuconfig':
Device Drivers ---> .. code-block:: none
...
VirtIO Drivers ---> Device Drivers --->
... ...
[*] PCI driver for virtio devices VirtIO Drivers --->
...
[*] PCI driver for virtio devices
Other drivers are at the same location and can be tuned to suit the needs. Other drivers are at the same location and can be tuned to suit the needs.
@ -74,6 +77,8 @@ Testing
The following QEMU command line is used to get U-Boot up and running with The following QEMU command line is used to get U-Boot up and running with
VirtIO net and block devices on ARM. VirtIO net and block devices on ARM.
.. code-block:: bash
$ qemu-system-arm -nographic -machine virt -bios u-boot.bin \ $ qemu-system-arm -nographic -machine virt -bios u-boot.bin \
-netdev tap,ifname=tap0,id=net0 \ -netdev tap,ifname=tap0,id=net0 \
-device virtio-net-device,netdev=net0 \ -device virtio-net-device,netdev=net0 \
@ -82,6 +87,8 @@ VirtIO net and block devices on ARM.
On x86, command is slightly different to create PCI VirtIO devices. On x86, command is slightly different to create PCI VirtIO devices.
.. code-block:: bash
$ qemu-system-i386 -nographic -bios u-boot.rom \ $ qemu-system-i386 -nographic -bios u-boot.rom \
-netdev tap,ifname=tap0,id=net0 \ -netdev tap,ifname=tap0,id=net0 \
-device virtio-net-pci,netdev=net0 \ -device virtio-net-pci,netdev=net0 \
@ -93,6 +100,8 @@ parameters. It is also possible to specify both MMIO and PCI VirtIO devices.
For example, the following commnad creates 3 VirtIO devices, with 1 on MMIO For example, the following commnad creates 3 VirtIO devices, with 1 on MMIO
and 2 on PCI bus. and 2 on PCI bus.
.. code-block:: bash
$ qemu-system-arm -nographic -machine virt -bios u-boot.bin \ $ qemu-system-arm -nographic -machine virt -bios u-boot.bin \
-netdev tap,ifname=tap0,id=net0 \ -netdev tap,ifname=tap0,id=net0 \
-device virtio-net-pci,netdev=net0 \ -device virtio-net-pci,netdev=net0 \
@ -104,6 +113,8 @@ and 2 on PCI bus.
By default QEMU creates VirtIO legacy devices by default. To create non-legacy By default QEMU creates VirtIO legacy devices by default. To create non-legacy
(aka modern) devices, pass additional device property/value pairs like below: (aka modern) devices, pass additional device property/value pairs like below:
.. code-block:: bash
$ qemu-system-i386 -nographic -bios u-boot.rom \ $ qemu-system-i386 -nographic -bios u-boot.rom \
-netdev tap,ifname=tap0,id=net0 \ -netdev tap,ifname=tap0,id=net0 \
-device virtio-net-pci,netdev=net0,disable-legacy=true,disable-modern=false \ -device virtio-net-pci,netdev=net0,disable-legacy=true,disable-modern=false \
@ -112,6 +123,8 @@ By default QEMU creates VirtIO legacy devices by default. To create non-legacy
A 'virtio' command is provided in U-Boot shell. A 'virtio' command is provided in U-Boot shell.
.. code-block:: none
=> virtio => virtio
virtio - virtio block devices sub-system virtio - virtio block devices sub-system
@ -127,10 +140,14 @@ A 'virtio' command is provided in U-Boot shell.
To probe all the VirtIO devices, type: To probe all the VirtIO devices, type:
.. code-block:: none
=> virtio scan => virtio scan
Then we can show the connected block device details by: Then we can show the connected block device details by:
.. code-block:: none
=> virtio info => virtio info
Device 0: QEMU VirtIO Block Device Device 0: QEMU VirtIO Block Device
Type: Hard Disk Type: Hard Disk
@ -138,6 +155,8 @@ Then we can show the connected block device details by:
And list the directories and files on the disk by: And list the directories and files on the disk by:
.. code-block:: none
=> ls virtio 0 / => ls virtio 0 /
<DIR> 4096 . <DIR> 4096 .
<DIR> 4096 .. <DIR> 4096 ..
@ -167,6 +186,8 @@ Driver Internals
---------------- ----------------
There are 3 level of drivers in the VirtIO driver family. There are 3 level of drivers in the VirtIO driver family.
.. code-block:: none
+---------------------------------------+ +---------------------------------------+
| virtio device drivers | | virtio device drivers |
| +-------------+ +------------+ | | +-------------+ +------------+ |
@ -199,20 +220,26 @@ The transport drivers provide a set of ops (struct dm_virtio_ops) for the real
virtio device driver to call. These ops APIs's parameter is designed to remind virtio device driver to call. These ops APIs's parameter is designed to remind
the caller to pass the correct 'struct udevice' id of the virtio device, eg: the caller to pass the correct 'struct udevice' id of the virtio device, eg:
int virtio_get_status(struct udevice *vdev, u8 *status) .. code-block:: C
int virtio_get_status(struct udevice *vdev, u8 *status)
So the parameter 'vdev' indicates the device should be the real virtio device. So the parameter 'vdev' indicates the device should be the real virtio device.
But we also have an API like: But we also have an API like:
struct virtqueue *vring_create_virtqueue(unsigned int index, unsigned int num, .. code-block:: C
unsigned int vring_align,
struct udevice *udev) struct virtqueue *vring_create_virtqueue(unsigned int index, unsigned int num,
unsigned int vring_align,
struct udevice *udev)
Here the parameter 'udev' indicates the device should be the transport device. Here the parameter 'udev' indicates the device should be the transport device.
Similar naming is applied in other functions that are even not APIs, eg: Similar naming is applied in other functions that are even not APIs, eg:
static int virtio_uclass_post_probe(struct udevice *udev) .. code-block:: C
static int virtio_uclass_child_pre_probe(struct udevice *vdev)
static int virtio_uclass_post_probe(struct udevice *udev)
static int virtio_uclass_child_pre_probe(struct udevice *vdev)
So it's easy to tell which device these functions are operating on. So it's easy to tell which device these functions are operating on.
@ -223,20 +250,29 @@ ID 2) are supported. If you want to develop new driver for new devices,
please follow the guideline below. please follow the guideline below.
1. add new device ID in virtio.h 1. add new device ID in virtio.h
#define VIRTIO_ID_XXX X
.. code-block:: C
#define VIRTIO_ID_XXX X
2. update VIRTIO_ID_MAX_NUM to be the largest device ID plus 1 2. update VIRTIO_ID_MAX_NUM to be the largest device ID plus 1
3. add new driver name string in virtio.h 3. add new driver name string in virtio.h
#define VIRTIO_XXX_DRV_NAME "virtio-xxx"
.. code-block:: C
#define VIRTIO_XXX_DRV_NAME "virtio-xxx"
4. create a new driver with name set to the name string above 4. create a new driver with name set to the name string above
U_BOOT_DRIVER(virtio_xxx) = {
.name = VIRTIO_XXX_DRV_NAME, .. code-block:: C
...
.remove = virtio_reset, U_BOOT_DRIVER(virtio_xxx) = {
.flags = DM_FLAG_ACTIVE_DMA, .name = VIRTIO_XXX_DRV_NAME,
} ...
.remove = virtio_reset,
.flags = DM_FLAG_ACTIVE_DMA,
}
Note the driver needs to provide the remove method and normally this can be Note the driver needs to provide the remove method and normally this can be
hooked to virtio_reset(). The driver flags should contain DM_FLAG_ACTIVE_DMA hooked to virtio_reset(). The driver flags should contain DM_FLAG_ACTIVE_DMA
@ -247,7 +283,5 @@ for the remove method to be called before jumping to OS.
6. do funny stuff with the driver 6. do funny stuff with the driver
References .. _VirtIO: http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf
---------- .. _QEMU: https://www.qemu.org
[1] http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.pdf
[2] https://www.qemu.org