- 论坛徽章:
- 0
|
yhb04,mik :
谢谢两位的详细回复。
yhb04,
我对你回复理解如下:
对于1、在进程A(CPL=0)-> 进程B(CPL=3)时,即ring 0 -> ring 3,有以下2种情况,
1)B从内核态返回用户态需要从内核堆栈切换回用户堆栈
2)从A的内核栈切换到B的内核栈
这两种情况下都需要栈切换,但都不会用到TSS,只会从当前用户进程的内核栈中将SS和ESP恢复以实现栈切换。
对于2、在A-->B时,
1)A和B的内核栈指针都会被保存到进程表里面作为以后再调用/恢复时的初始值(因为内核栈指针非空)。
2)TSS的ESP0是每次都被缺省指向进程内核栈为空时的值,但当进程获得CPU时会被更新成进程表中的ESP值(即1中提到内核指针值)。
对于3、我有点不明白,因为如果进程调度模块要进行堆栈操作时,难道它使用的也是用户进程的内核栈?
另外,对上面的问题我还有些疑问和个人的一些理解:
1、既然ring0->ring3 不需要使用TSS,为什么ring3 -> ring0要使用TSS(直接重复向1中的操作不行吗?)?
2、从上面2来看,进程切换似乎只解决了如何获得 esp0 的值,而没有提到进程如何获得 esp3 (这里 esp3 指的是用户堆栈指针)。我想如果要切换至用户进程,肯定也要一起切换至用户堆栈吧。那到底如何获得这个 esp3 呢?
3、我的一些理解
假设以下场景:
M:进程调度模块(CPL=0)
A:用户进程1(CPL=3)
B:用户进程2(CPL=3)
C:用户进程3(CPL=0)
如果 A->B,则必须经过以下过程:
1)A(ring 3) -> A(ring 0)
2)A(ring 0) -> M(ring 0)
3)M(ring 0) -> B(ring 0)
4)B(ring 0) -> B(ring 3)
其中,
对于1),就是常说的 ring 3-> ring 0,而且从这可以判断出 "ring 3->ring 0"必定是对同一进程而言(比如说1)里面指的就是用户进程A,ring0和ring3则只是指A的两种运行状态)。就像如果存在A->C,虽然看上去也是从特权级3->特权级0,但这个不是指我们常说的"ring 3-> ring 0"。而堆栈的切换是从 “进程A的用户栈”切换至“进程A的内核栈”。esp0的获取:esp0<-TSS.esp0<-进程表中的esp域。
对于2),属于进程调度模块对进程A的操作。会发生堆栈切换吗?还是说堆栈操作仅仅对A的内核栈的操作而言。
对于3),属于进程调度模块对进程B的操作。会发生堆栈切换吗?还是说堆栈操作仅仅对B的内核栈的操作而言。
对于4),与1)类似,就是常说的 ring 0-> ring 3 。而堆栈的切换是从“进程B的内核栈”切换至“进程B的用户栈”。esp3的获取:未知?
在这4点中,只有1)用到TSS,而且 esp0 的值指的是”用户进程A“在 ring0 状态下(即内核栈)的堆栈入口指针。
不知道我的理解对不对?
[ 本帖最后由 sherf 于 2008-10-30 23:22 编辑 ] |
|