ts0612 发表于 2009-06-26 13:16

请教:进程切换

近日在看于渊的书,对“进程”一章的始终有一个疑问,大致如下:

环境:
1、设定了一个主程序:kernel.asm(ring0)
2、设定了3个用户程序: TestA, TestB, TestC(都是 ring1)

另注:在kernel.asm中设定了时钟中断的处理函数

整个的运行大致如下:
1、配置好中断处理函数、进程表、TSS等的内容
2、通过restart()跳转至用户程序(TestA, TestB, TestC中的一个,根据进程表的内容和调度的算法),ring0 -> ring1
3、当时钟中断发生时,转去执行时钟中断程序,并最后会通过restart()跳转至用户程序(TestA, TestB, TestC中的一个,根据进程表的内容和调度的算法),即重复执行2。同样是 ring0 -> ring1

疑问:
个人感觉这部分的内容只是涉及 ring0->ring1,并不存在 ring1->ring0。(即不存在"ring0-> ring1"和“ring1 -> ring0” 的来回切换)。但当我注释掉 TSS 的加载语句,则进程的切换不成功(屏幕没有任何输出,正常是会有整个进程切换信息输出的)。既然不存在ring1->ring0,那也就是不会用到 TSS,为何注释掉TSS的加载会使进程切换不成功呢?

注:
本人曾怀疑是当“时钟中断”到达时,系统会转去执行“时钟中断程序”,即 TestA -> kernel.asm(ring1->ring0)。但最后觉得不太可能。原因是在时钟中断处理函数里,第一句就是“call save”,将上一个用户进程的信息(寄存器、eip等)保存入它的进程表项里,那就证明在进入时钟中断程序时堆栈的指针是指向“原先运行的用户进程的进程表项”的,并没有通过TSS“自动切换”至内核栈。相反,在"call save“之后,是手工设置将esp指向内核栈的(即 "mov esp, StackTop")

各位,不知道大家有没有碰到过这个问题,有的话,烦请解答一下,谢谢。

ts0612 发表于 2009-06-26 13:17

回复 #1 ts0612 的帖子

顶一下

mik 发表于 2009-06-26 23:21

kernel 通过 retf / iret 跳到 user
user 通过 call call-gate /int n 或者 sysenter/syscall 陷入到 kernel

cjaizss 发表于 2009-06-29 00:08

一般都是通过陷阱门进入ring0的,不过一般OS上使用ring3作为用户态.
页: [1]
查看完整版本: 请教:进程切换