虚拟化设备-Virtio介绍

虚拟化环境必须使用客户操作系统自身的驱动感觉不到自己运行在虚拟机上,不然让客户操作系统开发人员编写大量代码同样不是一个很好的设计方案,因此虚拟化系统需要提供抽象设备,抽象设备实现了针对特定设备类的高级接口,目前比较高效的设备虚拟化接口是Virtio,KVM、Xen、QNX等都在使用Virtio接口。

不同的虚拟化解决方案都会给操作系统带来负担,负担的大小取决于各个解决方案的需求。其中的一项开销为设备的虚拟化。virtio 并没有提供多种设备模拟机制(针对网络、块和其他驱动程序),而是为这些设备模拟提供一个通用的前端,从而标准化接口和增加代码的跨平台重用。

在传统的完全虚拟化环境中,虚拟化系统必须捕捉这些请求,然后模拟物理硬件的行为。尽管这样做提供很大的灵活性(即运行未更改的操作系统),但它的效率比较低。通过使用Virtio,客户操作系统包含了充当前端的驱动程序,虚拟化系统为特定的设备模拟实现后端驱动程序。通过在这些前端和后端驱动程序中的 virtio,为开发模拟设备提供标准化接口,从而增加代码的跨平台重用率并提高效率。在传统虚拟化系统中,会使用QEMU通过纯软件的方式来模拟I/O 设备,包括键盘、鼠标、显示器,硬盘和网卡等。QEMU对客户操作系统响应的过程如下:

  1. 客户机的设备驱动程序发起I/O 请求操作请求
  2. KVM 模块中的I/O 操作捕获代码拦截这次I/O 请求
  3. 经过处理后将本次I/O 请求的信息放到 I/O共享页(sharing page),并通知用户空间的 QEMU 程序。
  4. QEMU 程序获得I/O 操作的具体信息之后,交由硬件模拟代码来模拟出本次I/O 操作。
  5. 完成之后,QEMU 将结果放回I/O 共享页,并通知KMV 模块中的I/O 操作捕获代码。
  6. KVM 模块的捕获代码读取I/O 共享页中的操作结果,并把结果放回客户机。

注意:当客户机通过DMA (Direct Memory Access)访问大块I/O时,QEMU 模拟程序将不会把结果放进共享页中,而是通过内存映射的方式将结果直接写到客户机的内存中共,然后通知KVM模块告诉客户机DMA操作已经完成。

这种方式的优点是可以模拟出各种各样的硬件设备;其缺点是每次I/O 操作的路径比较长,需要多次上下文切换,也需要多次数据复制,所以性能较差。

通过virtio实现可以在客户操作系统内核中安装前端驱动(Front-end driver)和在虚拟机系统中实现后端驱动(Back-end)的方式。前后端驱动通过Virtqueue直接通信,这就绕过了经过操作系统内核模块的过程,达到提高I/O 性能的目的。

纯软件模拟的设备和Virtio设备的区别:virtio 省去了纯模拟模式下的异常捕获环节,客户操作系统可以和QEMU 的I/O 模块直接通信。

对于汽车智能驾驶舱系统来说,不管是QEMU和Virtio都很难保证来自系统要求的实时响应,例如CAN信号如何快速被传递给其需要的客户操作系统,需要在构建系统时特别考虑。

发布于 2019-01-15 14:06