好 那我们前面已经
把这个空间建立完毕
那接下来干什么
我们希望我们的这个进程
用户进程能够去到用户态去执行
为此我们需要做个小练习
来完成trapframe一个设置
大家再回顾一下trapframe在哪见着呢
其实在我们lab1
lab1就已经涉及到了有一个
trapframe完成了中断的一个
打断的一个状态的保存
就放在什么地方呢
trapframe里面
那为什么要用这个trapframe呢
因为我们希望通过这个设置
来完成一个特权级的一个转变
从kernel空间切换到用户空间
去执行我们的程序
从而实现所谓的用户进程的一个执行
那这个过程建立在前面的基础之上
把这一步建好之后呢
就可以让这个用户进程去执行了
这是我们的练习
那为此我们需要了解一下
怎么从特权态0到特权态3
这么一个切换
其实这个过程呢
在我们讲特权级的时候呢有提及
但这里面我们再回顾一下
那时候讲的时候第一个是说
我们有一个ring0一个栈空间
然后呢我们为了能够到ring3去
我们做什么事情
在这里面构造一个
中断打断时候这个
硬件保存的栈信息
这一块
正常情况下在内核态里面
产生一个中断之后呢
它会在它这个内核堆栈里面
保存这个信息
当然你完全可以自己
构造出这么一个信息出来
因为我们希望根据这个信息呢
来使得在执行iret这条指令之后呢
能够回到用户态去
但这里面还不行
为此我们要对它
这个堆栈要做进一步的修改
SS和CS呢重新设置
从特权级0变成特权级3
而且它的地址ESP还有EIP
这个地址一个是堆栈的offset
一个是执行地址的offset
那么要重新设置
从而可以使得这个区域呢
正好是说模拟的一个
当从ring3产生中断之后
回到ring0的时候
硬件保存的信息
有了这个信息
如果我们再执行iret的时候呢
就会跳到ring3去了
当然这个前提是我们前面已经
建好了所谓这个中断门
这是我们在lab1里面要掌握的内容
那区别是什么呢
lab1呢是从ring0里面产生中断
依然回到ring0
我们这里面是要从ring0里面
要跳到ring3去执行
lab1的challenge其实要完成这个事情
直到lab5呢我们必须要完成这个事情
才能实现用户进程在用户空间执行
其实我们关注的是怎么能够去
构造出一个合理一个trapframe
使得在接下来执行iret之后呢
能够跳到用户空间去执行
那我们再小结一下可以看出来
为了能够完成ring0到ring3这个跳转
我们的进程 创建这个进程
用户进程 它有两个栈
一个是内核的stack kernel stack
一个是用户的stack
这样才能确保在用户态的时候
它用的是用户stack
在内核态的时候呢是用内核stack
它可以通过系统调用
来完成到内核的一个执行过程
在一开始
我们创建这个进程的时候呢
还需要通过特殊的机制
构造一个trapframe
使得它能够跳到 这个
用户进程的第一条指令去执行
那这个过程
需要大家通过练习来完成