结合虚拟化技术分析Linux系统的一般执行过程
借助虚拟化技术,用户能以单个物理硬件系统为基础创建多个模拟环境或专用资源。称为"Hypervisor"(虚拟机监控程序)的软件可直接连接到硬件,从而将一个系统划分为不同的、单独安全环境,即虚拟机(VM)。虚拟机监控程序能够将计算机资源与硬件分离并适当分配资源。配备了虚拟机监控程序的物理硬件叫做"主机",而使用其资源的虚拟机则被称为虚拟客户机。虚拟化主要是指通过软件实现的方案,常见的体系结构是一个直接在物理主机上运行虚拟机管理程序的虚拟化系统。在
x86平台虚拟化技术中,这个虚拟机管理程序通常被称为虚拟机监控器(Virtual Machine
Monitor,VMM),又称为Hypervisor。它是运行在物理机和虚拟机之间的一个软件层,物理机被称为主机(Host),虚拟机被称为客户机(Guest),中间软件层即Hypervisor。
虚拟化技术下Linux系统的执行过程如下
- 首先,在物理计算机上启动虚拟化管理程序,例如KVM、Xen等会被启动。虚拟化管理程序负责创建和管理虚拟机并提供了对硬件资源的访问和分配。之后创建根据用户要求,创建一个或多个虚拟机。
- 虚拟化管理程序会分配硬件资源,虚拟化管理程序将物理计算机的硬件资源,如CPU、内存等。
- 接着虚拟机启动引导程序,而在虚拟化环境下,所有的硬件访问都会被拦截,虚拟化层会虚拟化层会将其重定向到虚拟机中。此时操作系统内核开始执行。在Linux系统中,引导加载程序(bootloader)负责加载内核和必要的初始文件系统。所有中断相关的内容都会被虚拟机捕获,并重定向到虚拟机,完成虚拟化。
- 最后启动用户空间,虚拟化技术为每个虚拟机提供了强大的安全和隔离机制,以确保它们之间不会相互干扰。
课程收获
linux操作系统处理中断的过程
CPU执行中断相关的内核控制路径时,linux不允许进程切换,不过中断处理程序可以被另一个中断处理程序中断 ———— 中断的嵌套执行
1、确定与中断或者异常关联的向量i(0~255)
2、读idtr寄存器指向的IDT表中的第i项
3、从gdtr寄存器获得GDT的基地址,并在GDT中查找,以读取IDT表项中的段选择符所标识的段描述符
4、确定中断是由授权的发生源发出的。
Ø中断:中断处理程序的特权不能低于引起中断的程序的特权(对应GDT表项中的DPL vs CS寄存器中的CPL)
Ø编程异常:还需比较CPL与对应IDT表项中的DPL
5、检查是否发生了特权级的变化,一般指是否由用户态陷入了内核态。
如果是由用户态陷入了内核态,控制单元必须开始使用与新的特权级相关的堆栈
a,读tr寄存器,访问运行进程的tss段
b,用与新特权级相关的栈段和栈指针装载ss和esp寄存器。这些值可以在进程的tss段中找到
c,在新的栈中保存ss和esp以前的值,这些值指明了与旧特权级相关的栈的逻辑地址
将中断向量入栈
硬件层面结束
接下来为软件,可能对应代码为error_code:
保存所有其他寄存器
- 调用do_IRQ
- 取得对应的中断向量
- 调用中断处理句柄(handle_level_irq)
- 应答PIC的中断,并禁用这条IRQ线
- 调用handle_IRQ_event()执行中断服务例程
- 通知PIC重新激活这条IRQ线,允许处理同类型中断
- 跳转到ret_from_intr
用户态进程X切换到用户态进程Y的过程
以32位x86系统结构linux-3.18.6为例,以系统调用作为特殊的中断简要总结如下。
- 正在运行的用户态进程X。
- 发生中断(包括异常、系统调用等),CPU完成以下动作。
- save cs:eip/ss:esp/eflags:当前CPU上下文压入进程X的内核堆栈。
- load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack):加载当前进程内核堆栈相关信息,跳转到中断处理程序,即中断执行路径的起点。
- SAVE_ALL,保存现场,此时完成了中断上下文切换,即从进程X的用户态到进程X的内核态。
- 中断处理过程中或中断返回前调用了schedule函数,其中的switch_to做了关键的进程上下文切换。将当前进程X的内核堆栈切换到进程调度算法选出来的next进程(本例假定为进程Y)的内核堆栈,并完成了进程上下文所需的EIP等寄存器状态切换。详细过程见前述内容。
- 标号1,即前述3.18.6内核的swtich_to代码第50行“”1:\t“ ”(地址为switch_to中的“$1f”),之后开始运行进程Y(这里进程Y曾经通过以上步骤被切换出去,因此可以从标号1继续执行)。
- restore_all,恢复现场,与(3)中保存现场相对应。注意这里是进程Y的中断处理过程中,而(3)中保存现场是在进程X的中断处理过程中,因为内核堆栈从进程X切换到进程Y了。
- iret - pop cs:eip/ss:esp/eflags,从Y进程的内核堆栈中弹出(2)中硬件完成的压栈内容。此时完成了中断上下文的切换,即从进程Y的内核态返回到进程Y的用户态。
- 继续运行用户态进程Y。