<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      1.主線程初始化

      • qemu層kvm初始化類
      //KVM初始化的入口的類
      static const TypeInfo kvm_accel_type = {
          .name = TYPE_KVM_ACCEL,
          .parent = TYPE_ACCEL,
          .instance_init = kvm_accel_instance_init,
          .class_init = kvm_accel_class_init,
          .instance_size = sizeof(KVMState),
      };
      說明:
      1.QOM模型,先執行class_init初始化函數,類似C++中構造函數,在new對象的時候調用
      2.QOM模型,instance_finalize實例化函數,本類的具體實現
      
      • 主線程kvm初始化
      |-qemu_init
      	|-module_call_init(MODULE_INIT_QOM); //vl.c
      		|-kvm_type_init                //初始化注冊kvm類類型
      	|-configure_accelerators           //vl.c
      		|-do_configure_accelerator     //設置為kvm加速,比如有hax、hvf、tcg、kvm、xen、whpx不同加速等
      		|-accel_init_machine
      			|-acc->init_machine(ms);   //調用kvm_init接口,這個是kvm真正初始化的入口
      				|-kvm_init             //kvm-all.c
      	|-machine_run_board_init           //主板初始化,此時運行狀態即將設置為running或者prelaunch
      		|-machine_class->init
      			|-pc_init1                 //i386/pc_piix.c 進行CPU、Memory、VGA、NIC、PCI等的初始化
      				|-x86_cpus_init        //x86的CPU初始化---cpu虛擬化
      				|-pc_guest_info_init   //guest信息初始化
      				|-smbios_set_defaults  //bios設置
      				|-pc_memory_init       //分配內存和加載rom和bios --內存虛擬化
      				|-pc_gsi_create        //中斷控制器
      				|-i440fx_init          //初始化pci總線
      				|-piix3_create         //初始化isa總線
      				|-pc_i8259_create      //中斷控制器初始化
      				|-pc_vga_init          //顯卡初始化
      				|-pc_basic_device_init //基本硬件初始化
      				|-pc_nic_init          //網卡初始化
      				|-pci_create_simple    //創建pci主橋
      關注的兩個熱點:
      1.x86_cpus_init        //cpu虛擬化
      2.pc_memory_init       //內存虛擬化
      
      • 調用堆棧
      (gdb) bt
       #0  pc_init1 (machine=0x555556e39800, pci_type=0x555556164c06 "i440FX", host_type=0x555556163b61 "i440FX-pcihost") at /home/cloud/qemu/qemu-5.0.0/hw/i386/pc_piix.c:74
       #1  0x0000555555a4362b in machine_run_board_init (machine=0x555556e39800) at hw/core/machine.c:1140
       #2  0x00005555559749ca in qemu_init (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /home/cloud/qemu/qemu-5.0.0/softmmu/vl.c:4897
       #3  0x000055555585cd19 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /home/cloud/qemu/qemu-5.0.0/softmmu/main.c:48
      

      2.Qemu層vcpu初始化

      • x86_vcpu初始化類
      static const TypeInfo x86_cpu_type_info = {
          .name = TYPE_X86_CPU,
          .parent = TYPE_CPU,
          .instance_size = sizeof(X86CPU),
          .instance_init = x86_cpu_initfn,
          .abstract = true,
          .class_size = sizeof(X86CPUClass),
          .class_init = x86_cpu_common_class_init,
      };
      x86_cpu類型注冊:
      |-type_init                                       //初始化的時候注冊,main函數運行前
      	|-x86_cpu_register_types
      		|-x86_cpu_type_info                       //class_init類似構造函數
      			|-x86_cpu_common_class_init
      				|-device_class_set_parent_realize //設置cpu初始化函數realize=x86_cpu_realizefn
      					|-qemu_init_vcpu              //開始初始化vcpu
      
      • vcpu初始化邏輯
      |-x86_cpus_init
      	|-x86_cpu_new                           //CPUState *cs = CPU(dev);
      		|-object_new
      			|-object_new_with_type
      				|-type_initialize
      				|-object_initialize_with_type
      					|-type_initialize
      						|-class_init        //調用x86_cpu_type_info的x86_cpu_common_class_init初始化x86_cpu
      		|-object_property_set_bool
      			|-object_property_set_qobject
      				|-property_set_bool
      					|-device_set_realized
      						|-x86_cpu_realizefn   //vcpu初始化的實現,先初始化struct X86CPU再初始化struct CPUState 
      							|-qemu_init_vcpu  //struct CPUState
      								|-qemu_kvm_start_vcpu
      									|-qemu_kvm_cpu_thread_fn
      										|-kvm_init_vcpu
      											|-kvm_get_vcpu        //通知kvm創建一個vcpu,返回一個kvm_fd
      											|-kvm_ioctl           //從kvm獲取映射mmap_size
      											|-mmap                //對kvm_fd進行以一個mmap_size大小映射
      											|-kvm_arch_init_vcpu  //前面vcpu創建成功之后現在來真正的初始化
      												|-kvm_arch_set_tsc_khz      //時鐘設置
      												|-kvm_vcpu_ioctl            //KVM_GET_TSC_KHZ時鐘可以用戶設置和從kvm獲取,這里從KVM獲取再保存下來
      												|-hyperv_handle_properties  //設置cpuids
      												|-cpu_x86_cpuid             //獲取所有的CPUID信息,填充結構體,設置到寄存器中
      												|-kvm_vcpu_ioctl            //前面構造KVM需要的cpuid_data數據,再通過KVM_SET_CPUID2給kvm設置cpuid
      												|-kvm_init_msrs             //通知kvm設置msr寄存器
      												|-hyperv_init_vcpu          //Hyper-V初始化vcpu保存一些信息在后續遷移時候恢復使用
      										|-kvm_init_cpu_signals
      										|-kvm_cpu_exec //每個vcpu對應一個線程,該線程循環執行
      
      x86_cpu類繼承關系:子類->父類
      struct X86CPU      -> struct CPUState -> struct DeviceState
      struct X86CPUClass -> struct CPUClass
      struct CPUX86State -> (struct X86CPU env)
      DeviceClass 可以通過DeviceState獲取得到DEVICE_GET_CLASS(dev)。
      說明:
      1.這里x86_cpu_new調用比較抽象,涉及QOM
      2.這里cpu虛擬的具體流程還要結合kvm的實現才能分析透徹
      3.先初始化父類再初始化子類,先初始化Class,再初始化Device,再初始化State如先初始化x86CPU數據結構,再去針對CPUState進行初始化,CPUState初始化結合KVM完成。CPUState記錄的是和kvm交互的狀態信息,CPUX86State記錄的是一些寄存器、cpu狀態之類信息。
      
      • 調用堆棧
      (gdb) bt
       #0  x86_cpu_realizefn (dev=0x5555572bb6c0, errp=0x7fffffffca30) at /home/cloud/qemu/qemu-5.0.0/target/i386/cpu.c:6528
       #1  0x0000555555a3ab11 in device_set_realized (obj=<optimized out>, value=<optimized out>, errp=0x7fffffffcb20) at hw/core/qdev.c:891
       #2  0x0000555555bd744e in property_set_bool (obj=0x5555572bb6c0, v=<optimized out>, name=<optimized out>, opaque=0x555556c71020, errp=0x7fffffffcb20) at qom/object.c:2243
       #3  0x0000555555bdc10f in object_property_set_qobject (obj=obj@entry=0x5555572bb6c0, value=value@entry=0x5555572d68d0, name=name@entry=0x55555619ea48 "realized", errp=errp@entry=0x7fffffffcb20) at qom/qom-qobject.c:26
       #4  0x0000555555bd98d5 in object_property_set_bool (obj=0x5555572bb6c0, value=<optimized out>, name=0x55555619ea48 "realized", errp=0x7fffffffcb20) at qom/object.c:1395
       #5  0x0000555555944ebf in x86_cpu_new (x86ms=x86ms@entry=0x555556e39850, apic_id=0, errp=0x555556b7e6b0 <error_fatal>) at /home/cloud/qemu/qemu-5.0.0/hw/i386/x86.c:129
       #6  0x0000555555944ff9 in x86_cpus_init (x86ms=0x555556e39850, default_cpu_version=<optimized out>) at /home/cloud/qemu/qemu-5.0.0/hw/i386/x86.c:168
       #7  0x000055555594c2b9 in pc_init1 (machine=0x555556e39850, pci_type=0x555556164c06 "i440FX", host_type=0x555556163b61 "i440FX-pcihost") at /home/cloud/qemu/qemu-5.0.0/hw/i386/pc_piix.c:156
       #8  0x0000555555a4362b in machine_run_board_init (machine=0x555556e39850) at hw/core/machine.c:1140
       #9  0x00005555559749ca in qemu_init (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /home/cloud/qemu/qemu-5.0.0/softmmu/vl.c:4897
       #10 0x000055555585cd19 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at /home/cloud/qemu/qemu-5.0.0/softmmu/main.c:48
      

      3.VCPU運行

      由于虛擬機涉及VM-Entey和VM-exit,這里從Qemu和KVM角度來分析vcpu運行主要機制。

      • Qemu
      |-kvm_cpu_exec
      	|-kvm_arch_process_async_events
      	|—cpu_exec_start
      	|-kvm_arch_pre_run
      	|-kvm_vcpu_ioctl            //ioctl下發KVM_RUN給KVM,進入了VM-Entry模式
      	|-kvm_arch_post_run
      	|-switch (run->exit_reason) //處理VM-Exit事件
      		|-kvm_handle_io
      		|-kvm_handle_cpuid
      		|-kvm_arch_handle_exit
      		|-......
      		|-kvm_arch_handle_exit
      	|-cpu_exec_end
      

      1.kvm_cpu_exec中能看到一個循環,在循環中kvm_vcpu_ioctl(KVM_RUN)運行這個虛擬機,這個時候CPU進入VM-Entry即進入客戶機模式。
      2.如果一直是客戶機的操作系統占用這個CPU,則會一直停留在這一行運行,一旦這個調用返回了,就說明CPU進入VM-Exit退出客戶機模式。
      3.退出客戶機模式之后將CPU交還給宿主機。在循環中會對退出的原因exit_reason進行分析處理,是因為有了I/O、還是有了中斷等,并做相應的處理。處理完畢之后再次循環,再次通過VM-Entry進入客戶機模式,如此循環直到虛擬機正常或者異常退出。

      • KVM
      KVM: //virt/kvm/kvm_main.c
      |-kvm_vcpu_ioctl                 
      	|-kvm_arch_vcpu_ioctl_run    //arch/x86/kvm/x86.c
      		|-vcpu_run
      			|-vcpu_enter_guest
      				|- 判斷是否需要退出,如果退出則設置退出的reason
      				|-kvm_x86_ops->prepare_guest_switch
      				|-kvm_x86_ops->run                    //進入guest模式
      				|-kvm_x86_ops->handle_exit            //處理eixt,可能要退出guest模式
      
      vcpu運行函數:
      static int vcpu_run(struct kvm_vcpu *vcpu)
      {
      	int r;
      	struct kvm *kvm = vcpu->kvm;
          ...
      	for (;;) {
      		if (kvm_vcpu_running(vcpu)) {
      			r = vcpu_enter_guest(vcpu);
      		} else {
      			r = vcpu_block(kvm, vcpu);
      		}
      		...
      	}
      }
      
      x86架構操作函數集://arch/x86/kvm/vmx/vmx.c
      static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
          ...
      	.run = vmx_vcpu_run,
      	.handle_exit = vmx_handle_exit,
      	...
      }
      

      1.首先是Store host registers,要從宿主機模式變為客戶機模式了,所以原來宿主機運行時候的寄存器要保存下來。
      2.接下來是Load guest registers,將原來客戶機運行時的寄存器加載進來。
      3.接下來是Enter guest mode,調用ASM_VMX_VMLAUNCH進入客戶機模型運行,或者ASM_VMX_VMRESUME恢復客戶機模型運行。
      4.如果客戶機因為某種原因退出,Save guest registers, load host registers,即保存客戶機運行的時候的寄存器,就加載宿主機運行的時候的寄存器。

      4.參考資料

      各種虛擬化:https://blog.csdn.net/qq_33588730/article/details/105397879

      posted on 2021-12-08 14:05  人生一世,草木一秋。  閱讀(862)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产内射性高湖| 久热这里有精品视频播放| 人妻无码中文专区久久app| 日韩精品一区二区蜜臀av| 国产一区二区三区不卡视频| 国产精品美女一区二三区| 亚洲国产精品综合色在线| 久久国产精品福利一区二区三区| 成人亚洲精品一区二区三区| 日本欧美大码a在线观看| 亚洲精品无码成人aaa片| 国产午夜福利小视频在线| 香蕉EEWW99国产精选免费| 亚洲天堂在线观看完整版| 国产肥臀视频一区二区三区| 国产成人精品亚洲资源| 青铜峡市| 国产精品小粉嫩在线观看| 亚洲一区二区偷拍精品| 太湖县| 日本高清成本人视频一区| 精品精品国产国产自在线| 亚洲鸥美日韩精品久久| 另类专区一区二区三区| 亚洲成人av在线系列| 国产网红女主播精品视频| 国产在线精品欧美日韩电影| 麻花传媒在线观看免费| 宝贝腿开大点我添添公视频免| 免费看国产精品3a黄的视频| 中国少妇嫖妓BBWBBW| 亚洲经典在线中文字幕| 人妻中文字幕一区二区三| 日本欧美大码a在线观看| 国产免费高清69式视频在线观看 | 国产漂亮白嫩美女在线观看| 四虎在线成人免费观看| 影音先锋男人站| 成全我在线观看免费第二季| 在线视频观看| 国产日韩av免费无码一区二区三区|