1、QEMU创建虚拟机发起:kvm_ioctl(s, KVM_CREATE_VM, type);

KVM中kvm_dev_ioctl判断参数-》kvm_dev_ioctl_create_vm-》kvm_create_vm该函数中创建并初始化了对应qemu模拟的内存条模型kvm->memslots【kvm结构体】

2、QEMU创建vcpu发起:kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));

KVM中kvm_vm_ioctl判断参数-》kvm_vm_ioctl_create_vcpu-》

(1)kvm_arch_vcpu_create借助kvm_x86_ops->vcpu_create即vmx_create_vcpu完成任务:(1.1)kvm_vcpu_init初始化,主要是填充结构体【kvm_vcpu】,注意vcpu->run分派了一页内存,该函数继续kvm_arch_vcpu_init负责填充x86 CPU结构体【kvm_vcpu_arch】,该函数还kvm_mmu_create则是初始化MMU的函数,每个MMU都是vcpu独有。(1.2)分配一页给vmcs(执行vm entry的时候将vmm状态保存到vmcs的host area,并加载对应vm的vmcs guest area信息到CPU中,vm exit的时候则反之,vmcs具体结构分配由硬件实现,程序员只需要通过VMWRITE和VMREAD指令去访问)(1.3)vmx_vcpu_load加载VCPU的信息,切换到指定cpu,进入到vmx模式,将loaded_vmcs的vmcs和当前cpu的vmcs绑定到一起(1.4)vmx_vcpu_setup则是初始化vmcs内容,主要是赋值计算

(2)kvm_arch_vcpu_setup-》kvm_x86_ops->vcpu_load(vcpu, cpu)即vmx_vcpu_load,就是进入vcpu模式下准备工作。

(3)create_vcpu_fd为proc创建控制fd,让qemu使用

3、QEMU要运行vcpu发起:kvm_vcpu_ioctl(cpu, KVM_RUN, 0);

KVM中kvm_vcpu_ioctl判断参数-》kvm_arch_vcpu_ioctl_run-》__vcpu_run-》

(1)在while循环里面调用vcpu_enter_guest进入guest模式,该函数(1.1)首先处理vcpu->requests,对应的request做处理,kvm_mmu_reload加载mmu,通过kvm_x86_ops->prepare_guest_switch(vcpu)准备陷入到guest,prepare_guest_switch实现是vmx_save_host_state,顾名思义,就是保存host的当前状态(1.2)然后加载guest的寄存器等信息,fpu,xcr0,将vcpu模式设置为guest状态,屏蔽中断响应,准备进入guest。但仍进行一次检查,vcpu->mode和vcpu->requests等,如果有问题,则恢复host状态。(1.3)kvm_guest_enter做了两件事:account_system_vtime计算虚拟机系统时间;rcu_virt_note_context_switch对rcu锁数据进行保护,完成上下文切换。(1.4)准备工作搞定,kvm_x86_ops->run(vcpu),开始运行guest,由vmx_vcpu_run实现,该函数主要是内联汇编。(1.5)vmx_vcpu_run退出后返回到vcpu_enter_guest通过hw_breakpoint_restore恢复硬件断点(1.6)走到kvm_x86_ops->handle_exit(vcpu);即vmx_handle_exit处理虚拟机的退出:主要设置vcpu->run->exit_reason,让外部感知退出原因,并对应handle_exit函数集处理(有handle_task_switch进行任务切换,handle_io处理qemu的外部模拟IO等)。

(2)退回到__vcpu_run函数,在while (r > 0)中,循环受vcpu_enter_guest返回值控制,只有运行异常的时候才退出循环,否则通过kvm_resched一直运行下去。

(3)再退就到了kvm_arch_vcpu_ioctl_run函数,return到kvm_vcpu_ioctl,就ioctl返回到qemu的kvm_cpu_exec中,此时kvm run的执行也结束。

4、QEMU初始化虚拟机内存发起:kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);

KVM中kvm_vm_ioctl把参数copy_from_user复制后-》kvm_vm_ioctl_set_memory_region逐层调用到__kvm_set_memory_region在KVM中建立与QEMU相对应的内存槽结构-》

(1)id_to_memslot根据qemu的内存槽号得到kvm结构下的内存槽号 kvm_memory_slot,转换关系来自id_to_index数组(在kvm_create_vm虚拟机创建过程中,kvm_init_memslots_id初始化对应关系slots->id_to_index[i] = slots->memslots[i].id = i)。

(2)根据slot中的值和要设置的值,决定要操作的类别KVM_MR_CREATE/DELETE/MOVE/_FLAGS_ONLY。如果是CREATE则kvm_arch_create_memslot函数,里面主要是一个循环做了一个3级软件页表;无论删除还是移动, 先申请一个slots,把kvm->memslots暂存到这里,通过id_to_memslot获取kvm_memory_slot,并将应标记为KVM_MEMSLOT_INVALID,然后是install_new_memslots,其实就是更新了一下slots->generation的值(也就是把刚新申请的slots装载到kvm->memslots)(这里为何先不用原来slot而是申请新的slot “如果添加的section的属性变了,如从RAM变成了ROM,那么重新进行添加也是必要的”并不理解https://blog.csdn.net/leoufung/article/details/48781185 )。

 

qemu到kvm的处理,再到vm的运行的更多相关文章

  1. Linux 桌面玩家指南:07. Linux 中的 Qemu、KVM、VirtualBox、Xen 虚拟机体验

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  2. Qemu,KVM,Virsh傻傻的分不清

    当你安装了一台Linux,想启动一个KVM虚拟机的时候,你会发现需要安装不同的软件,启动虚拟机的时候,有多种方法: virsh start kvm命令 qemu命令 qemu-kvm命令 qemu-s ...

  3. Qemu创建KVM虚拟机内存初始化流程

    转载请注明:[转载自博客xelatex KVM],并附本文链接.谢谢. [注]文章中采用的版本: Linux-3.11,https://www.kernel.org/pub/linux/kernel/ ...

  4. QEMU和KVM的关系

    首先KVM(Kernel Virtual Machine)是Linux的一个内核驱动模块,它能够让Linux主机成为一个Hypervisor(虚拟机监控器).在支持VMX(Virtual Machin ...

  5. 014-通过JDB调试,通过HSDB来查看HotSpot VM的运行时数据

    一.JDB调试        在预发环境下进行debug时,时常因为工具和环境的限制,导致debug体验非常差,那么有什么方法能够简化我们进行debug的体验吗?JDB就是一种.        JDB ...

  6. 【记录】尝试用QEMU模拟ARM开发板去加载并运行Uboot,kernel,rootfs【转】

    转自:https://www.crifan.com/try_use_qemu_emulate_arm_board_to_load_and_run_uboot_kernel_rootfs/ [背景] 手 ...

  7. kvm初体验之五:vm连接网络的两种方式:bridge和nat

    1. 在安装vm时指定网络连接方式 1)bridge virt-install --name vm1 --ram=1024 --vcpus=1 --disk path=/vm-images/vm1,s ...

  8. kvm初体验之三:vm的安装及管理

    Host: CentOS release 6.4 (Final) Guest: CentOS release 6.6 (Final) 全程以root身份操作 1. host上创建桥br0 参考< ...

  9. Qemu/Limbo/KVM镜像:Ubuntu Mate 22.04+Wine 7.8

    链接: https://pan.baidu.com/s/1cf2c_ylu7-SUaYl8ddztog 提取码: b9mi 密码 空格 手机推荐使用termux里面的Qemu运行,速度最快. 镜像特征 ...

随机推荐

  1. css3图形绘制

    以下几个例子主要是运用了css3中border.bordr-radius.transform.伪元素等属性来完成的,我们先了解下它们的基本原理. border:简单的来说border语法主要包含(bo ...

  2. 黑盒测试实践——day05

    一.任务进展情况 今天主要对web系统的“员工管理模块”和“招聘管理模块”进行测试.测试用例选取之前已经做好的excel文件.       二.存在的问题

  3. .NET Core开发日志——GraphQL

    GraphQL是什么 GraphQL既是一种用于API的查询语言也是一种通过使用对应数据的类型系统,执行数据查询的服务端运行时.GraphQL没有局限于任何数据库或存储引擎,而是通过既有代码及数据获得 ...

  4. CGI的工作原理

    文章摘自https://blog.csdn.net/nyist327/article/details/41049699 CGI是Web服务器和外部程序之间的一个接口.利用CGI程序可以处理从Web上客 ...

  5. Angular2 ng2-smart-table

    ng2-smart-table 入门 安装 你要做的就是运行以下命令: npm install --save ng2-smart-table 此命令将创建在你的`package.json`文件和安装包 ...

  6. NodeJS笔记(六)-Express HTTP服务器启动后如何关闭

    npm start启动网站,提示“3000”端口已经被使用的问题 nodejs WEB服务器并不随着cmd的关闭而终止 查看任务管理器可以看到nodejs的启动进程 可以手动关闭 如果是一直处于cmd ...

  7. 1840: Jack Straws

    1840: Jack Straws 时间限制(普通/Java):1000MS/10000MS     内存限制:65536KByte 总提交: 168            测试通过:129 描述 I ...

  8. Logstash - Working with plugins(使用插件)

    本章节开始介绍logstash的插件及功能,插件对于logstash来说非常重要,按类别分为:input.filter.codec.output四种类型. logstash有非常丰富的插件,通过安装目 ...

  9. gdb常用的指令

    推荐一篇详细的gdb文章:http://witmax.cn/gdb-usage.html 1. 常用的gdb 命令 编译程序时需要加上-g,之后才能用gdb进行调试:gcc -g main.c -o ...

  10. PyQt5之使用Qt下的designer工具将.ui文件转换成.py文件后添加什么东西后方可运行

    首先证明我是加了那些鬼东西以后可以成功运行的. 然后来叙述一下我的过程. 这是一个.ui文件生成的.py文件.(把主要的内容省去了,但是没有影响结构) # -*- coding: utf-8 -*- ...