虚拟机创建之qemu逻辑

qemu模块注册:

创新互联长期为数千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为芗城企业提供专业的成都网站制作、成都网站建设、外贸营销网站建设芗城网站改版等技术服务。拥有10年丰富建站经验和众多成功案例,为您定制开发。

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

Qemu/hw下所有.c文件基本上都有type_init()函数,type_init是个宏,具体定义在qemu/include/qemu/module.h中。

module_init是个宏,调用register_module_init函数,定义如下:

find_type()函数会调用初始化链表数组,并返回对应type的链表指针。

Qemu的main函数入口在softmmu/main.c(注:qemu版本4.2.50)

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

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

1)初始化QOM,上面已经阐述在main函数之前,module_init会对qemu/hw下所有初始化函数进行注册至链表中。

例如,qemu/hw/virtio/virtio-net-pci.c文件里的初始化函数virtio_net_pci_register。则module_call_init就会回调virtio_net_pci_register进行初始化操作(具体初始化逻辑都在对应的qemu/hw/virtio/virtio-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回调。

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等。


本文题目:虚拟机创建之qemu逻辑
文章地址:http://pwwzsj.com/article/cghpji.html