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
的正常启动流程基本一样了。