虚拟机创建之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://azwzsj.com/article/cghpji.html