一.结合虚拟化技术分析Linux系统的一般执行过程
1、Linux系统的一般执行过程
最一般的情况:正在运行的用户态进程X切换到运行用户态进程Y的过程
(1)正在运行的用户态进程X
(2)发生中断——save cs:eip/esp/eflags(current) to kernel stack,then load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).
(3)SAVE_ALL //保存现场
(4)中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换
(5)标号1之后开始运行用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)
(6)restore_all //恢复现场
(7)iret - pop cs:eip/ss:esp/eflags from kernel stack
(8)继续运行用户态进程Y(中断上下文和进程长下文切换。前者是CPU内部的切换;后者是在内核中堆栈的切换)
2、虚拟化环境中的执行过程
(1)首先,物理设备的中断信号被发送到宿主机。宿主机操作系统会将这个中断信号抽象成一个虚拟中断信号,并通过Hypervisor将它传递到对应的虚拟机。
外设中断信号(Hypervisor已经将其配置成虚拟中断)到达GIC;
GIC Distributor将该物理IRQ发送至CPU;
CPU trap到Hyp模式,此时将会退出Guest OS的运行,并返回到Host OS;
Host OS将响应该物理中断,也就是Host OS驱动响应外设中断信号;
Hypervisor往List Register写入虚拟中断,Virtual CPU interface将virtual irq信号发送至vCPU;
CPU将处理该异常,Guest OS会从Virtual CPU Interface读取中断状态进行响应;
KVM和QEMU可能是Linux中流行且常用的Hypervisor。
KVM是Linux内核提供的虚拟化架构,可以让QEMU使用硬件辅助的虚拟化技术。KVM/QEMU允许客户操作系统直接访问虚拟化硬件并获得几乎与直接访问硬件相同的性能(如果该客户操作系统运行在物理机之上)。
(2)在虚拟机接收到中断信号后,虚拟CPU会将当前应用程序的执行状态保存到内存中的上下文环境中,然后切换到虚拟机内核的代码执行中。这个过程被称为上下文切换(Context Switch)。
虚拟cpu
创建虚拟机时,Hypervisor会将预定义的内存和CPU分配给虚拟机,分配给虚拟机的CPU资源会被客户操作系统视为专用物理CPU。由于有些客户操作系统对于支持的CPU套接字有限制,因此较新版本的Hypervisor会根据CPU套接字的颗粒度及内核数量来提供CPU资源。
虚拟内存
为虚拟机分配内存也要使用共享技术。通过共享技术将内存分配给Hypervisor时,同样会让客户操作系统认为是在使用物理内存资源。类似内存页和磁盘交换空间等技术会被用于虚拟机操作系统,分配的全部可用内存都由其独占使用。
(3) 虚拟机内核接收到中断请求后,会根据中断的类型和原因进行相应的处理,例如响应磁盘中断的IO操作或处理网络中断处理网络数据包等。如果需要访问外部数据,虚拟机内核会将的IO操作传递到虚拟磁盘或虚拟网络设备驱动程序中,以便后续使用。
Qemu模拟外设,通过irqfd来触发Hypervisor进行中断注入;
Hypervisor往List Register写入虚拟中断,Virtual CPU interface将virtual irq信号发送至vCPU;
CPU将处理该异常,Guest OS会从Virtual CPU Interface读取中断状态进行响应;
irqfd提供了一种机制用于注入虚拟中断,而这个中断源可以来自虚拟外设;
irqfd是基于eventfd的机制来实现的,用于用户态与内核态,以及内核态之间的事件通知;
事件源可以是虚拟设备,比如VFIO框架等。
i.初始化的操作包括两部分:1)设置Routing entry(【a】vgic_init初始化的时候创建默认的entry;【b】:用户层通过KVM_SET_GSI_ROUTING来设置);2)设置irqfd;
ii.初始化设置完成后,系统可以随时响应事件触发了,当事件源触发时,将调度到irqfd_inject函数;
iii.irqfd_inject函数完成虚拟中断的注入操作,在该函数中会去回调set函数,而set函数是在Routing entry初始化的时候设置好的;
iv.实际的注入操作在vgic_irqfd_set_irq函数中完成;
v.kvm_vcpu_kick函数,将Guest OS切回到Host OS,中断注入后再切回到Guest OS就可以响应了;
I/O设备分配
串行及其他I/O设备在虚拟机之间实现共享,是通过在同一时间内只将它们分配给一个虚拟机来实现的。这样一来,Hypervisor就可以基于特定的触发条件来切换资源分配。
例如在ESXi中,如果将键盘分配给虚拟机的控制台,ESXi截取到Ctrl+Alt组合键之后,就会将键盘从控制台中分离出来并连接到其他虚拟机上。
(4)处理完成后,虚拟机内核会重新加载先前保存的上下文环境,并返回到原先应用程序的执行状态中继续执行。这个过程可能涉及到虚拟化技术中的内存管理、调度、交互等多个方面。
二、课程收获
之前没有怎么接触过Linux,本门课程主要基于Linux内核分析系统调用、进程切换、可执行程序工作原理等。通过本门课程,学习了编译内核,构建根文件系统,通过qemu模拟环境启动内核,使用gdb断点调试内核程序并据此分析,也学会了通过vscode远程调试linux内核,从一个个关键函数分析一个程序运行时的过程,这门课的干货很多,对于我今后对linux的学习与深入打下了一个良好的基础,也让我对linux内核源码有了更加浓厚的兴趣。