陈奇网络工作室

虚拟机创建的qemu逻辑

Qemu模块注册:

Qemu模块注册主要是指hw(硬件)注册,核心代码在qemu/hw目录下。

全部。Qemu/hw下的c文件基本都有type_init()函数,type_init是QEMU/include/QEMU/module.h中定义的宏。

Module_init是一个宏,调用register_module_init的函数,定义如下:

find_type()函数调用初始化链表数组,返回与类型对应的链表指针。

Qemu的主函数入口在softmmu/main.c(注:Qemu 4 . 2 . 50版)。

第32行是主函数入口,qemu_main是宏,具体指向第46行。然后分别调用qemu_init()、qemu_main_loop()和qemu_cleanup()的函数。

其中qemu_init函数比较长,这里主要看几个关键部分。

1)初始化QOM。如上所述,在主函数之前,module_init会将qemu/hw下的所有初始化函数注册到链表中。

比如QEMU/HW/virt io/virt io-net-PCI . c文件中的初始化函数virtio_net_pci_register,那么module_call_init就会调用virtio_net_pci_register进行初始化(具体的初始化逻辑在对应的QEMU/HW/virt io/virt io-net-PCI . c中,这里就不详细分析了)。

2)创建一个kvm虚拟机

Configure_accelerators()调用do_configure_accelerator。

accel_init_machine()函数中的核心逻辑是acc-init_machine(ms),其中init_machine是在accel/kvm/kvm-all.c中定义的函数指针(注意:这里以kvm为例,所以对应的文件是accel/kvm/kvm-all.c)。

接下来,重点分析kvm_init函数。

Kvm_init函数会创建kvm fd,并通过kvm_ioctl创建vm,然后调用kvm_arch_init函数初始化x86架构(本文以x86为例),对应的文件是arch/i386/KVM.c。

以x86为例,kvm_arch_init函数主要实现TSS和EPT(extend pagetable)的初始化。

Machine_run_board_init主要实现主机初始化,核心代码是最后一行的init回调。

初始化回调是在hw/i386/pc_piix.c(针对x86)中定义的,函数名是pc_init1。

Pc_init_isa定义如下:

所以init回调是pc_init1()

pc_init1()函数主要用于初始化硬件,包括cpu、pci总线、vga、NIC等。

看看vcpu的创建和初始化。

X86_cpu_new函数最终会执行x86_cpu_realizefn函数。

由于调用qemu_init_vcpu函数的链接比较长,这里简单给出函数调用链接关系,如下图:

qemu_init_vcpu函数定义如下:

因为是基于kvm的,所以这里只看qemu_kvm_start_vcpu()函数。

qemu_kvm_start_vcpu()函数的定义如下:

qemu_thread_create()函数创建一个线程,线程函数是qemu_kvm_cpu_thread_fn()。

线程函数qemu_kvm_cpu_thread_fn()定义如下:

kvm_cpu_exec()函数主要调用kvm_vcpu_ioctl进入内核状态,由kvm处理。(本文不会进入内核kvm的过程,内容太多,后面章节分析。)

然后就是初始化内存,NUMA,VNC等。这里就不一一介绍了。

总结:以上是qemu下创建虚拟机的过程。vm的工作机制比非VM复杂得多,因为VM上使用的资源(内存、cpu)都是由主机托管的。虽然我们看到VM拥有子机的内存和CPU,但实际上它最终是通过VMM被调度到主机上执行的。当然,VMM调度是一个非常复杂的过程,包括内存阴影页表、陷印、virtio等等。

更多关于云服务器,域名注册,虚拟主机的问题,请访问西部数码代理官网:www.chenqinet.cn。

相关推荐

后台-系统设置-扩展变量-手机广告位-内容页底部广告位3