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。