1、添加任务状态段
介绍了当多个程序需要同时运行于同一颗CPU内核上时,操作系统需要做什么才能让多个程序看起来是同时运行的。
操作系统会轮流在不同的程序间给予一定的时间运行。当要从一个程序切换至另一个程序时,会先将之前程序的运行状态保存起来,然后再切换。等到将来再恢复到该程序运行时,恢复到之前运行状态,继续往下运行。
x86在硬件上对这种运行状态的保存和恢复提供了相应的支持,既通过TSS(任务状态段)保存有关任务的运行状态。
2、任务相互切换
多个程序之间切换运行的方法:
保存前一程序的运行状态到其TSS中,再从下一程序的TSS中提取运行状态恢复到相应的位置
任务状态段TSS内容比较多且复杂,该结构大致可以分为以下几部分
通过TSS结构,就能够知道一个程序的当前状态。进行不同程序运行的切换时,需要将前一个程序完整的运行状态全部保存到TSS,这样当后续该程序需要再次运行时,再将该状态进行从TSS中恢复,从而就像能完整地继续从上次切换的位置继续往下运行,好像什么都没发生一样。
目前只需要在切换时,保存号当前的段寄存器、通用寄存器、EIP、EFLAGS中的内容到当前程序的TSS中,然后再加载下一个将要运行程序的TSS中段寄存器、通用寄存器、EIP、EFLAGS值进行恢复。
3、 另一种高效的任务切换方法
一个任务或进程,它所有的运行状态在进行任务切换之前都会保存到这个任务状态段之中。然后当任务需要恢复运行的时候,就会从这个任务状态段中提取出相应的寄存器的值,恢复到CPU内部的内核寄存器中。这种话效率比较低。
分析了有哪些寄存器需要保存,哪一些不需要。比如根据函数的调用原理分析出其中一些寄存器不需要保存。所有任务都会使用相同的段寄存器,所以一些段寄存器也不需要保存
最终任务切换这个过程就变成了将一些寄存器保存在当前任务的栈中,并且从下一个任务的栈中提取出相应寄存器值再恢复到 CPU的内核寄存器中。这个过程就是更加简单高效的进程上下文切换的过程。
4、简单实现双任务相互切换
在任务状态TSS配置好后,需要将其加入到CPU的硬件数据配置中,添加方法是在GDT表中添加一个专门的TSS描述符指向该结构,当前执行哪个任务,则由Task Register指向相应的描述符
在任务初始化时,从GDT表中分配了相应的空闲描述符,然后按TSS描述符格式进行初始化。
配置完所有的描述符之后,就可以通过远跳转far_jump()跳转到另一个任务运行。在执行该指令时,CPU会自动将保存当前任务的状态到TSS,然后从另一任务的TSS中取出状态进行恢复。通过不断地反复跳转,实现了在不同任务之间轮流切换执行。 这个过程由硬件自动完成,具体过程没有在代码中体现出来。