XEN启动过程分析

  • Post author:
  • Post category:其他



Xen




Hypervisor


运行在


Ring0


,在启动过程中,


Xen


首先被引导:系统由


Grub


启动,遵循


Multiboot


引导规范;然后


Linux


内核做为


module


也被引导入内存,同时


initrd


镜像文件也一样。整个引导过程如下图


示:






<?xml:namespace prefix = v ns = “urn:schemas-microsoft-com:vml” /> ‍‍







1 当加电后首先是


BIOS


自检、


Grub


引导。


Xen


遵循


Multiboot


引导规范,它


需要从


Grub


读入内存信息,通过置位标志位第


1


位来实现的。



主要过程是从grub-xen(‍head.S, trampoline.S, x86_32.S,位于‍\xen\arch\x86\boot中:),


head.S:‍装入GDT(trampoline_gdt); ‍进入保护模式;‍初始化页表,将线性空间的0-12M和__PAGE_OFFSET-__PAGE_OFFSET+12M都映射到物理地址的 0-12M;而将线性空间的12M-16M映射到物理地址的12M-16M;‍解析早期命令行参数;‍跳转到 trampoline_boot_cpu_entry;


‍trampoline.S:‍进入实模式,读取内存,磁盘,显示信息;‍再次进入保护模式,装入新的GDT(gdt_table);‍加载前面初始化了的页表,启用分页机制,跳转到__high_start。然后就是x86_32.S文件。



2.


x86_32.S


是从


Grub


进入


Xen


的入口文件。


Grub


根据镜像头信息获得入口地址,然后读入整个镜像,最后把控制权交给


Xen





可以使用


readelf


命令来查看编译后生成的


Xen


的内核,它表明文件类型为可执行文件,并且程序的入口点是


Oxl0000(


原本这是


Linux


内核的位置


)


,这表明


Xen


被引导程序放在了物理内存


1M


的位置上。





x86_32.S





start


入口点上,主要是为进行后续工作做准备,包括简单地设置


GDT





IDT


以及初始化分页等。然后


start


将保存着引导程序启动信息地址的


EBX


压栈,再调用真正的初始化流程函数





<?xml:namespace prefix = o ns = “urn:schemas-microsoft-com:office:office” />



3.__startxen()


函数中首先会从启动信息中获取物理内存分配情况,初始化


E820


内存图。


物理内存是只有


Xen


才有权限进行管理和分配的,无论是


Domain0


还是


DomainU


,它们得到的都是


Xen


给它们的物理内存假相。


4.之后是分页初始化、


IRQ


中断初始化、调度程序初始化、异常处理程序表初始化、时间设置、安全机制设置等初始化工作,并且


Xen


会初始化一个空闲虚拟域


(Idle Domain)


,当没有合适的虚拟域可以运行的时候,


Xen


会选择空闲虚拟域来运行,这很类似于


Linux


中的


init


进程。


5.当


Xen


初始化工作结束后,便开始设置


Domain0


的数据结构。


每个虚拟域都有一个


struct domain


结构体,在这里主要定义了它的


ID


、共享信息、内存分配、虚拟


CPU


、事件通道和授权表等。分配好


DomainO


的数据结构,


Xen


将通过


construct_dom0()


函数来将主控域的运行环境设置好。



6。然后


Xen


将控制权交给


Domain0


中的


Linux


,而自己进入


idie_loop


。主控域得到控制权后,开始自己的引导过程,只是它需要的信息是从


xen_start_info


数据结构中获取。进入


Domain0





EIP


指向


_start_32


,它会再跳转到


start_kernel


,之后的启动流程就和


Linux


的正常启动流程基本一样了。