新进程运行分析
进程刚创建时的内核栈分布如下:
当从swtch中的ret返回后,新进程回到forkret中执行。
forkret首先会释放ptable.lock这个锁,这个锁是在scheduler线程中获取的,所以要释放。如果是第一个进程运行此函数的话,会执行iinit和initlog。
forkret主要工作就是释放锁,执行完毕后会执行trapret函数:
trapret定义在trapasm.S中,tf中断帧结构如下:
第一个进程init的tf中断帧被构造成如下的数值:
可以看出如下信息:
- 通用寄存器全部被初始化为0,CS段寄存器用的是用户段的选择子,其他数据段寄存器页都用的是用户端的选择子。
- eflag中的中断标志被打开,表示允许中断。
- 栈指针被设置为用户栈地址。
- eip被设置为新进程的代码段起始地址,对于init进程而言,就是0地址。
在iret之前,将栈指针调整到保存eip的位置,这时栈空间分布如下:
这个栈分布就和从用户空间产生中断陷入内核空间后,cpu硬件在内核栈中保存的数据结构一致了,当执行iret指令后,cpu就从当前的内核级别恢复到用户级别执行eip指示的用户空间代码了,同时栈空间也被恢复为用户空间栈。
评论