之前打算整理一下在Guest VM, KVM, QEMU中IO处理的整个流程,通过查阅资料和阅读源码,已经大致知道IO在Guest KVM中的处理流程.当想要整理IO在KVM和QEMU中的处理时,发现很难理清楚QEMU和KVM之间的跳转和交互的过程,于是促使自己去了解QEMU和KVM启动的过程.(本文展示的代码中,qemu版本为1.6.0, linux内核版本为3.7.10)

为了介绍qemu和kvm的交互过程,我首先介绍一下kvm给用户提供的接口.kvm是一个内核模块,它实现了一个/dev/kvm的字符设备来与用户进行交互,通过调用一系列ioctl函数可以实现qemu和kvm之间的切换.当要创建一个新的虚拟机时,首先打开/dev/kvm设备,在其上调用ioctl函数:

  1. system_fd = open("/dev/kvm", ORDWR);
  2. vm_fd = ioctl(system_fd, KVM_CREATE_VM, 0);

ioctl函数在kvm中的实现为virt/kvm/kvm_main.c中kvm_dev_ioctl函数,当传入的参数为KVM_CREATE_VM时,该函数会创建一个VM,并且返回一个fd,通过该fd可以操作虚拟机.

创建完虚拟机之后,需要在该虚拟机上面创建vcpu,调用的接口也是ioctl,只是此时对应的fd为创建虚拟机时返回的fd.

  1. vcpu_fd = ioctl(vm_fd, VM_CREATE_VCPU, 0)

此时ioctl函数对应的实现为virt/kvm/kvm_main.c中kvm_vm_ioctl函数,当传入的参数为VM_CREATE_VCPU时,与KVM_CREATE_VM过程类似,它创建一个vcpu并且返回可以操作该vcpu的fd.

创建完vcpu后,可以在该vcpu上面调用ioctl函数进入guest vm.

  1. ret = ioctl(vcpu_fd, KVM_RUN, 0);

此时ioctl函数对应的实现为virt/kvm/kvm_main.c中kvm_vcpu_ioctl函数,若传入的参数为KVM_RUN,它最终会调用vcpu_enter_guest函数进入guest vm.

qemu作为一个user mode的程序,其入口为main函数,该main函数定义在vl.c文件中.main函数比较长,其中跟KVM初始化相关的主要有两个函数:configure_accelerator()和machine->init(&args). cofigure_accelerator()函数选择运用哪一种虚拟化方案,其应用到的数据结构为accel_list,会调用accel_list[i].init函数.accel_list的初始化如下所示,当使用kvm虚拟化解决方案时,accel_list[i].init对应的函数即为kvm_init.

  1. static struct {
  2. const char *opt_name;
  3. const char *name;
  4. int (*available)(void);
  5. int (*init)(void);
  6. bool *allowed;
  7. } accel_list[] = {
  8. { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
  9. { "xen", "Xen", xen_available, xen_init, &xen_allowed },
  10. { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
  11. { "qtest", "QTest", qtest_available, qtest_init, &qtest_allowed },
  12. };

kvm_init函数定义在kvm-all.c文件中,其主要功能是打开/dev/kvm设备,创建一个虚拟机.

machine->init(&arg)函数主要初始化硬件设备,并且调用qemu_init_vcpu为每一个vcpu创建一个线程,线程执行的函数为qemu_kvm_cpu_thread_fn.从qemu main到qemu_init_vcpu之间函数调用关系涉及到一些函数指针的赋值源码比较难于读懂,以下是使用gdb调试打出其调用关系.

  1. #0 qemu_init_vcpu (cpu=0x55555681ea90) at /home/dashu/kvm/qemu/qemu-dev-zwu/cpus.c:1084
  2. #1 0x0000555555909f1e in x86_cpu_realizefn (dev=0x55555681ea90, errp=0x7fffffffd8f8) at /home/dashu/kvm/qemu/qemu-dev-zwu/target-i386/cpu.c:2399
  3. #2 0x00005555556c768a in device_set_realized (obj=0x55555681ea90, value=true, err=0x7fffffffda88) at hw/core/qdev.c:699
  4. #3 0x000055555580b93f in property_set_bool (obj=0x55555681ea90, v=0x5555565bab20, opaque=0x5555565375a0, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/object.c:1300
  5. #4 0x000055555580a484 in object_property_set (obj=0x55555681ea90, v=0x5555565bab20, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/object.c:788
  6. #5 0x000055555580bbea in object_property_set_qobject (obj=0x55555681ea90, value=0x555556403e40, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/qom-qobject.c:24
  7. #6 0x000055555580a770 in object_property_set_bool (obj=0x55555681ea90, value=true, name=0x555555a01f88 "realized", errp=0x7fffffffda88) at qom/object.c:851
  8. #7 0x00005555558a7de0 in pc_new_cpu (cpu_model=0x555555a0200b "qemu64", apic_id=0, icc_bridge=0x55555655b2c0, errp=0x7fffffffdac8) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc.c:922
  9. #8 0x00005555558a7fed in pc_cpus_init (cpu_model=0x555555a0200b "qemu64", icc_bridge=0x55555655b2c0) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc.c:978
  10. #9 0x00005555558a923b in pc_init1 (system_memory=0x5555562a7240, system_io=0x5555562a7f60, ram_size=1073741824, boot_device=0x555555a0248a "cad", kernel_filename=0x0, kernel_cmdline=0x5555559f85be "",
  11. initrd_filename=0x0, cpu_model=0x0, pci_enabled=1, kvmclock_enabled=1) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc_piix.c:105
  12. #10 0x00005555558a9a36 in pc_init_pci (args=0x7fffffffdf10) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc_piix.c:245
  13. #11 0x00005555558a9a7f in pc_init_pci_1_6 (args=0x7fffffffdf10) at /home/dashu/kvm/qemu/qemu-dev-zwu/hw/i386/pc_piix.c:255
  14. #12 0x00005555558584fe in main (argc=10, argv=0x7fffffffe148, envp=0x7fffffffe1a0) at vl.c:4317

qemu_kvm_cpu_thread_fn函数创建vcpu,然后调用kvm_cpu_exec函数.kvm_cpu_exec函数调用ioctl进入kvm并最终进入guest vm.

以上即为qemu调用kvm的接口初始化kvm的过程.后续我会整理出IO在kvm和qemu之间执行过程,同时描述kvm和qemu之间如何协同工作的.

参考资料:

1. qemu-kvm的初始化与客户系统的执行:http://blog.csdn.net/lux_veritas/article/details/9383643

2. 内核虚拟化kvm/qemu----guest os,kvm,qemu工作流程:http://www.360doc.com/content/12/0619/13/7982302_219186951.shtml

转载:http://blog.csdn.net/dashulu/article/details/17074675

KVM的初始化过程的更多相关文章

  1. KVM初始化过程

    转载:http://blog.csdn.net/dashulu/article/details/17074675 之前打算整理一下在Guest VM, KVM, QEMU中IO处理的整个流程,通过查阅 ...

  2. Java类变量和成员变量初始化过程

    一.类的初始化 对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量. 类的编译决定了类的初始化过程. 编译器生成的class文件主要对定义在源文件中的类进行了如下的更改: ...

  3. 【初探Spring】------Spring IOC(三):初始化过程---Resource定位

    我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然 ...

  4. 【初探Spring】------Spring IOC(二):初始化过程---简介

    首先我们先来看看如下一段代码 ClassPathResource resource = new ClassPathResource("bean.xml"); DefaultList ...

  5. java代码的初始化过程研究

        刚刚在ITeye上看到一篇关于java代码初始化的文章,看到代码我试着推理了下结果,虽然是大学时代学的知识了,没想到还能做对.(看来自己大学时掌握的基础还算不错,(*^__^*) 嘻嘻……)但 ...

  6. java中对象产生初始化过程

    以前面试的时候,很多公司的笔试题中有关new一个对象有关一系列初始化的过程的选择题目.请看下面的题目. class Parent { static { System.out.println(" ...

  7. Spring IoC容器的初始化过程

    Spring IoC容器的初始化包括 BeanDefinition的Resource定位.载入和注册 这三个基本的过程.IoC容器的初始化过程不包含Bean依赖注入的实现.Bean依赖的注入一般会发生 ...

  8. 解析Java类和对象的初始化过程

    类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来 ...

  9. Spring IoC容器初始化过程学习

    IoC容器是什么?IoC文英全称Inversion of Control,即控制反转,我么可以这么理解IoC容器: 把某些业务对象的的控制权交给一个平台或者框架来同一管理,这个同一管理的平台可以称为I ...

随机推荐

  1. 关于CSS重要知识点(1)

    1. 盒子模型 CSS处理网页内容时,会把每一个元素"放在"一个盒子里,也就是所谓的盒子模型. 盒子模型包括4部分:内容,内边距(padding),边框(border)和外边距(m ...

  2. ubuntu中获取文件名称并生成txt文件

    简介: 在机器视觉学习过程中,通常会经常批量处理一些图片,在Ubuntu下可以使用find命令,来实现将文件名全部读取出来,生成列表txt文件,作为标签使用 (1)find命令格式如下: find / ...

  3. 少个人保护?我来!——阿里云在ICANN第3届GDD峰会纪实

    西班牙马德里以足球和斗牛闻名于世,2017年5月9日至11日,ICANN第三届全球域名部门行业峰会(GDD)在这里召开.阿里云作为亚洲域名保有量最高的注册商,代表成千上万客户的利益与权力,派出代表,前 ...

  4. Burp Suite插件推荐

    BurpSuiteHTTPSmuggler 网址 https://github.com/nccgroup/BurpSuiteHTTPSmuggler 作用 利用 中间件对 HTTP 协议的实现的特性 ...

  5. INFO: Font Metrics and the Use of Negative lfHeight

    INFO: Font Metrics and the Use of Negative lfHeight  Print  Email   Article translations  Article ID ...

  6. ShowDoc

    ShowDoc 摘自ShowDoc 每当接手一个他人开发好的模块或者项目,看着那些没有写注释的代码,我们都无比抓狂.文档呢?!文档呢?!Show me the doc !! 程序员都很希望别人能写技术 ...

  7. mybatis大于小于的转义

    最近在使用mybatis,然后用到了小于等于,直接在XML中使用了<=,结果XML文件一直显示红色错误,如下: sum(case when p.pool_year <= '2014' th ...

  8. 【Redis】命令学习笔记——列表(list)+集合(set)+有序集合(sorted set)(17+15+20个超全字典版)

    本篇基于redis 4.0.11版本,学习列表(list)和集合(set)和有序集合(sorted set)相关命令. 列表按照插入顺序排序,可重复,可以添加一个元素到列表的头部(左边)或者尾部(右边 ...

  9. Linux 下 python如何配置virtualenv

    .安装virtualenv pip3 install virtualenv pip install -i https://pypi.tuna.tsinghua.edu.cn/simple virtua ...

  10. 用path动画绘制水波纹

    用path动画绘制水波纹 效果 源码 // // ViewController.m // PathAnimation // // Created by YouXianMing on 15/7/3. / ...