Magenta- 支持虚拟化
来源:互联网 发布:傲剑紫霞神功数据 编辑:程序博客网 时间:2024/06/05 07:35
Magenta- 支持虚拟化
Magneta实现了类似于Kvm+Qemu一套东西,但要简单得多,当前只支持在物理magenta上虚拟运行另一个magenta实例。
Mageta目前只支持x86,类似于Kvm,利用了x86的Intel-VT (Virtualization Technology)技术,在VMX root operation 和 VMX non-root operation间切换。类似于Qemu,Magenta也有user space的service,当前只支持I/O操作和空间访问异常操作。
Magenta提供了guest命令作为虚拟化运行的入口。命令的使用方式如下:
usage:guest kernel.bin [ramdisk.bin]kernel.bin: 指magenta.bin文件ramdisk.bin: 指ramdisk image文件
接下来我们看看命令guest的流程。
创建Hypervisor object
Magenta分别为Hypervisor和Guset创建对应的Context,以方便管理各自的状态和2者间的切换。
using HypervisorContext = VmxonContext;using GuestContext = VmcsContext;
Hypervisor object实际指向的就是VmxonContext,这是个单实例。
- VmxonContext为每个CPU分配一个VmxonPerCpu实例;
- VmxonPerCpu做如下初始化:
- 其会为本CPU分配1个page,作为将来指令vmxon的参数之用;
- 每个CPU使能vmxon
至此,CPU进入了VMX root operation模式。
创建guest物理mem
在当前进程的地址空间上为guest创建物理mem空间,大小为1GB。
- 创建1个大小为1GB的vmo;
- 将此vmo映射至当前进程。在映射时,会分配物理页填满此1G空间。
创建guest object
guest的context是VmcsContext,所以其object指向此context。
- 创建一个Fifo,作为将来kernel和user的交互通道;
- 创建VmcsContext:
- 为每个CPU分配VmcsPerCpu实例;
- 基于前面所创建的guest物理mem空间,创建GuestPhysicalAddressSpace对象
- 分配1个page,作为guest空间的页目录,为guest创建256G的虚拟地址空间;
- 将 guest物理mem映射进guest地址空间,是以ExtendedPageTable(EPT)的方式映射;
- 分配1个page,将其映射到guest空间的APIC_PHYS_BASE=0xfee00000处,后期在设置vmcs的APIC_ACCESS_ADDRESS时需要使用到此page;
- 将IO-Apic物理基地址0xfec00000的映射从guest空间中去除,后期guest在访问IO-Apic时会trap进kernel,由kernel通过Fifo将消息传递至user,从而由user处理此事件;
- 为每个CPU初始化VmcsPerCpu;
- 配置vmcs,这部分太细,想了解的可以看手册《64-ia-32-architectures-software-developer-vol-3c-part-3-manual.pdf》。这里列几部分如下:
- 配置EPT_POINTER指向前面所创建的guest页目录;
- 配置HOST_RIP指向vmx_exit_entry,这是从guest从non-roo进入root模式的入口;
- 在guest物理mem起始地址处创建页表,页表的覆盖地址范围是1GB;
- 紧接着页表,创建acpi able;
- 在物理mem偏移0x800000处创建bootdata参数,供guest os启动之用。启动参数包括:
- ACPI table;
- E820 table用于描述物理mem分布;
- 将kernel.bin读取至物理mem的偏移0x100000处;解析kernel.bin的header,得到其entry函数地址;
- 如果提供了ramdisk,则将其加载至bootdata之后;
- 配置VmcsPerCpu的general purpose register (gpr),即配置guest的gpr。将寄存器rsi指向0x800000处,即bootdata处。这是因为Magenta启动时会默认认为rsi寄存器中保存的就是bootdata的地址;
- 将kernel.bin的entry地址设置到guest的寄存器IP;
- 设置guest cr3为0,这是因为页表位于guest物理mem的起始地址,而物理mem在guest空间是从0开始的。
- 创建长度是1个page的vmo,让guest的Local-Apic即VIRTUAL_APIC_ADDRESS指向此vmo的物理页地址;并将此物理页也映射进本进程,以便后期user可以处理虚拟中断;
创建service线程
此线程监听Fifo消息,如果接收到kernel的消息,则解析消息并处理。当前只支持3种消息类型:
PORT_IN PORT_OUTMEM_TRAP
当前MEM_TRAP只处理3中类型的trap:
Local-APIC访问异常IO-APIC访问异常TPM访问异常
vm enter
追后走至VmcsPerCpu的Enter函数:
- 保存host现场,包括CR3,FS 的基地址等等;
- 设置guest的CR3和IP至vmcs;
- 调用函数vmx_enter
- 保存host的gpr,载入guest的gpr(还记得之前设置的rsi吗);将vmx_enter的返回地址保存为host RIP,从而后期可正常返回;
- 调用vmlaunch,进入non-root模式
vmx exit handler
vm的退出,并不是直接返回指令vmlaunch之后,而是返回至vmx_exit_entry:
- 保存guest的gprs,并加载host的gprs;
- 将返回地址host RIP压栈,以便可以ret返回;
- 重新加载TSS,重新加载IDT。重新加载都是因为2者的描述符的VMX所设的limit默认值不合适;
做完以上的配置后,执行ret后就可返回至vmx_ente之后。然后处理退出事件,当前包括如下事件:
EXTERNAL_INTERRUPT = 1u,INTERRUPT_WINDOW = 7u,CPUID = 10u,HLT = 12u,VMCALL = 18u,IO_INSTRUCTION = 30u,RDMSR = 31u,WRMSR = 32u,ENTRY_FAILURE_GUEST_STATE = 33u,ENTRY_FAILURE_MSR_LOADING = 34u,APIC_ACCESS = 44u,EPT_VIOLATION = 48u,XSETBV = 55u,
关于访问Local-APIC和IO-APIC引起的vm exit,两者使用了不同的机制。Local-APIC是利用了VMX的固有功能从而触发了APIC_ACCESS:
44: APIC access. Guest software attempted to access memory at a physical address on the APIC-access page and the“virtualize APIC accesses” VM-execution control was 1 (see Section 29.4).
而IO-APIC是利用了缺页中断的方式触发了EPT_VIOLATION。
这2种事件经过打包成package后,通过Fifo发送到user的service thread,并等待service的回应;service处理完后再通过Fifo发送结果至handler。
- Magenta- 支持虚拟化
- Magenta
- Magenta
- Magenta
- Magenta
- Magenta
- Magenta
- Magenta
- 支持虚拟化 主机配置
- 设置主板支持虚拟化
- 如何打开虚拟化支持
- 判断cpu是否支持全虚拟化
- 英特尔支持虚拟化技术处理器列表
- 查看是否支持虚拟化技术
- 支持与兼容性问题阻碍虚拟化部署
- 查看CPU是否支持虚拟化
- cpu虚拟化支持情况查看。
- 查看CPU是否支持虚拟化
- 解决centos7 +tomcat8 启动过慢的方法
- AlarmManager定时器发送一个延时广播
- Kotlin初体验--环境搭建与Hello Word
- 自己碰到的问题,记录一下
- Spring Mybatis 配置、多数据源配置(数据源动态匹配问题)
- Magenta- 支持虚拟化
- linux查看命令属于哪个安装包
- Spring-Boot项目实现热部署
- 服务器
- 一个Java对象到底占用多大内存?
- 自定义在springMvc中实现struts2的赋值操作
- 双向可控硅在交流调压电路中的使用
- java邮件
- 整数中1出现的次数(从1到n整数中1出现的次数)(java版)