操作系统-进程的初步实现上
1.进程=运行当中的程序,应用程序的目的就是解决问题,生成的可执行文件,执行会有一个进程,进程的目的就是完成任务。
思考-计算机只有一个处理器,那么如何同时执行多个任务?
远古时期的计算机系统
由上图可知,处理器一次只执行一次任务,所以当task1执行结束才会从任务等待队列中继续执行。远古时期存在的弊端-当正在执行的任务需要外部设备交互时,处理器几乎处于K线状态,其他任务无法执行,只能等待。
A.任务定义(进程定义)
在微观角度(操作系统),一个任务包含上图所拥有的。对多任务的实现我们需要完成以下的执行情况
多任务的并行执行,在多数情况下,任务数量大于处理器数量,因此,无法做到真正意义上的任务并行执行,但是可以让处理器每个时间单位执行一个任务,最终,处理器在多个任务之间切换执行
B.如何在计算机内部表示一个任务?
C语言结构体-该处表示一个进程的表示(对应之前的任务定义),rv表示寄存器的值(保存进程的状态),stack表示栈,代码与数据(程序加载到内存中)以后在详解
任务的执行状态如下图所示-结构体的寄存器的值-保存在内存当中
TSS(保存特权级转换的栈信息,会有各个寄存器的值)-在从低特权级转入0特权级执行时,进行切换栈时需要用到TSS,该表对应着右边的结构体,下图右图结构体表示前四个字节表示前一个栈信息,后续表示的是各个特权级的栈信息,unused[22],表示中间没有用到的寄存器
进程实现需要的原材料
1.LDT-x86系统中的任务使用私有的段描述符
2.TSS-特权级提升执行时需要-查看栈信息
3.RegValue-保存任务执行时的上下文信息
4.Stack-x86系统中的任务私有的栈
5.GDT-任务对应的LDT和TSS需要在GDT中注册
在这里出现的问题-如何动态在GDT中注册LDT和TSS?要设置GDT中的描述符就必须获得GDT的起始地址,这个地址如何获得?
解决方案如下(共享内存)-loader不同的地址写入交换内存,kernel可以通过在交换内存中拿到所需的地址
详细的代码放置以下链接:链接:https://pan.baidu.com/s/1LbsIhwyjzTY_4sBV96RuDw 提取码:y0zy
复制这段内容后打开百度网盘手机App,操作更方便哦
运行结果如图所示
进程的初步实现下
问题-如何通过进行上下文恢复进程执行?如何使得进程运行于3特权级
1.恢复上下文数据-通过任务数据结构中的寄存器值恢复上下文,几种esp寄存器记忆pop指令恢复通用寄存器(通过汇编中的栈操作指令以及RegValue结构体变量,设置寄存器的值),每次pop向高地址四个字节,需要注意的是启动一个新任务可以看作特殊的任务切换,切换的目标任务上下文信息中通过寄存器的值为0.
2.特权级转移(高-低)
在调用门中retf从高特权级返回低特权级,于此类似,iret指令也能从高特权级返回底特权级。在这里的操作是将esp指向目标内存位置(eip,cs,eflags,esp,ss),借助iret指令降特权级执行
在中断于中断返回时可以知道,在中断发生时,可从底特权级转移到高特权级,中断返回时,从高特权级转移到低特权级
3.中断访问程序返回时的栈变化--iret命令操作的寄存器
4.代码的执行方案如下
5.进程启动"函数"
参数是任务数据结构的地址,esp+200/202表示偏移
详细的代码放置以下链接:https://pan.baidu.com/s/1altDhV-kJNWamUcc4r5oEw 提取码:h2ao