java linux virt_Linux 内核的virtio框架

VirtIO 是一个用来实现“虚拟IO”的通用框架,典型的用于虚拟机上面实现虚拟的pci,网卡,磁盘等虚拟设备,kvm等都使用了这个技术。大概浏览了一下相关的内核代码,这个virtio应该是专门应用于那种“半虚拟化?(部分虚拟化)”的虚拟机的来虚拟各种通用io设备的,好像不是很适合单纯的用来虚拟设备。

参考资料

KVM的virtio说明文档:

内核相关示例源码有;

前段接口(guest端)的例子:

如果想用virtio来实现一个虚拟设备大概流程是这样的:

1、自己实现scan设备的功能,然后调用register_virtio_device 函数来注册发现的虚拟设备。参考drivers/lguest/lguest_device.c里面的scan_devices 函数。一个典型的实现是,虚拟机主机提供的共享内存配置,里面提供了虚拟设备的列表一样的配置,然后自己根据配置注册device。

注:pci总线等应该也是要扫描各个插槽,然后发现新的pci设备,然后创建device结构,再调用到驱动的probe函数里面的,应该各个总线都有发现新设备的机制,device一般是scan的时候创建。

2、为virtio_device 设备准备好virtqueue 队列。参考drivers/s390/kvm/kvm_virtio.c 里面的kvm_find_vq 函数。特别的是要提供自己的virtqueue 结构的notify函数。notify函数用于通知host主机队列里面已经有消息存在了,一般是hypercall ,就是通过vmcall指令或者traps(中断?)来通知主机。例如这个kvm代码。

160/*

161* When the virtio_ring code wants to notify the Host, it calls us here and we

162* make a hypercall. We hand the address of the virtqueue so the Host

163* knows which virtqueue we're talking about.

164*/

165static void kvm_notify(struct virtqueue *vq)

166{

167        struct kvm_vqconfig *config = vq->priv;

168

169        kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, config->address);

170}

171

69

70/* This instruction is vmcall. On non-VT architectures, it will generate a

71* trap that we will then rewrite to the appropriate instruction.

72*/

73#define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"

74

75/* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun

76* instruction. The hypervisor may replace it with something else but only the

77* instructions are guaranteed to be supported.

78*

79* Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively.

80* The hypercall number should be placed in rax and the return value will be

81* placed in rax. No other registers will be clobbered unless explicited

82* noted by the particular hypercall.

83*/

84

85static inline long kvm_hypercall0(unsigned int nr)

86{

87        long ret;

88        asm volatile(KVM_HYPERCALL

89                     : "=a"(ret)

90                     : "a"(nr)

91                     : "memory");

92        return ret;

93}

94

95static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)

96{

97        long ret;

98        asm volatile(KVM_HYPERCALL

99                     : "=a"(ret)

100                     : "a"(nr), "b"(p1)

101                     : "memory");

102        return ret;

103}

104

3、应该/drivers/net/virtio_net.c 等代码已经实现了前端的网卡,磁盘等驱动了。所以只要你register_virtio_device注册了之后,客户机应该是可以看到相应的虚拟网卡的了。

这些驱动使用virtio的框架方法大概是这样的,

virtqueue_add_buf 把发送到消息缓存写到virtqueue队列,然后 调用virtqueue_kick函数来通知host主机队列里面有消息需要它接受。 virtqueue_kick将调用到virtqueue结构的notify函数,notify函数通过中断或者高级的虚拟机指令mcall通知到host主机。 host主机,根据实现可能是共享内存的hypercall的,就可以直接复制相应的内存过去就可以了。可以去看相应的虚拟机的hypercall的实现代码。

virtio的作用就是提供一种居于virtqueue的通用的虚拟io框架。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值