有关trapframe的相关信息

28 views
Skip to first unread message

Yu Chen

unread,
Apr 9, 2012, 5:47:39 AM4/9/12
to jimmyyao, os-course, yos-c...@googlegroups.com
在lab4中,每个内核线程有一个trapframe,用于保存由于中断(或异常)产生后被打断的执行现场。

topaddr=next->kstack + KSTACKSIZE 是用户进程/内核线程的内核栈栈顶,

tf=topaddr-sizeof(struct trapframe) 是用户进程/内核线程的proc_struct->tf指向的地方。

(tf, topaddr)这段内存空间,放了用户进程/内核线程的trapframe内容。

若某内核线程执行,则CPU是在特权态0(在lab4中会出现),如果发生了中断/异常/系统调用,CPU会继续保持在特权态0,且CPU
会从当前内核栈指针esp 所指的位置开始压栈保存被中断/异常/系统调用打断的内核态执行现场。当处理完中断/异常/系统调用后,最后通过执行iret指令,CPU会把esp中指向的以前保存的cs,
eip,eflags等恢复,则CPU继续在内核态。且CPU又回到了内核态的内核线程被打断的地方继续执行。

若某用户进程执行,则CPU是在特权态3(当然在lab4中不会出现,但在lab5中会出现),如果发生了中断/异常/系统调用,CPU会切换到特权态0(设置CS的低两位为0),且会查找TS(Task
Segment)中的域esp0,把这个域esp0保存的值赋给esp,然后把cs,
eip,eflags等压入esp指向的栈中,其实就是给此此用户进程的进程控制块proc_struct中的trapframe赋值。当处理完中断/异常/系统调用后,最后通过执行iret指令,CPU会把esp中指向的以前保存的cs,
eip,eflags等恢复,则CPU又回到了用户态的用户进程被打断的地方继续执行。

在 2012年4月9日 下午4:46,jimmyyao <jimm...@163.com> 写道:
> 在lab4 的manual的第7页中 介绍了switch_to 函数完成两个执行现场的切换的具体流程,
> 其中 2. 设置任务状态段ts 中特权态0 下的栈顶指针esp0 为next 内核线程initproc 的内核栈的栈顶,即
> next->kstack + KSTACKSIZE ;
> 这一步没看懂,而且next->kstack + KSTACKSIZE ;这个公式的由来没搞清楚,老师能否讲解一下~
>
> 谢谢老师~


--
Best Regards
==============================================
Chen Yu
Ph.D. Associate Professor
System Software&Software Engineering Group,
Laboratory of Pervasive Computing,
Dept. of Computer Science and Technology
Tsinghua University, Beijing 100084, P.R. China
E-Mail: mailto:yuc...@tsinghua.edu.cn chy...@gmail.com
==============================================

Yu Chen

unread,
Apr 9, 2012, 9:30:18 AM4/9/12
to yos-c...@googlegroups.com
---------- 已转发邮件 ----------
发件人: Yu Chen <chy...@gmail.com>
日期: 2012年4月9日 下午9:29
主题: Re: 有关trapframe的相关信息
收件人: osco...@googlegroups.com


下面是我的解释,不知是否说清楚了。
-------------------------------------------------------------------------------------------
0 ucore在内核不会被抢占,ucore采用FIFO or RR调度算法 (这是ucore当前的设计)

1 ucore创建进程A,B。当ucore调度器让A执行时,会设置Task Segment(简称TS)
TS.esp0=A.kstack+KSTACKSIZE

2 如果某进程A在用户态调用syscall sleep(sleep 0.01秒),会执行int 0x80,这样硬件设置ss和esp,
ss=TS.ss0
esp=TS.esp0
然后CPU会把用户态的cs,eip+n(n=sizeof(int 0x80指令),即int 0x80之后的下一条指令)
,eflags压栈,接着ucore也会进一步压栈,都压完栈后
esp=TS.esp0+KSTACKSIZE-sizeof(trapframe)=A.kstack+KSTACKSIZE-sizeof(trapframe)
这时A的内核栈中已经压了一个trapframe,且A继续执行,也许还要调用几个函数,导致此时A的内核esp=0xXXXX,满足条件
A.kstack < A.esp < A.kstack+KSTACKSIZE-sizeof(trapframe)

3 然后调度器让A(即prev) sleep,即A.state=SLEEPING,切换进程B(即next)继续执行, 在proc_run(B)函数中会执行
load_esp0(next->kstack + KSTACKSIZE);
所以TS.esp0=B.kstack+KSTACKSIZE
当进一步执行完switch_to(&(prev->context), &(next->context)); 后
A.context.esp=A.esp
然后B继续执行,也许回到用户态继续执行,直到时间片到,才会有陷入到内核中,假定在此期间A
sleep的时间到了,这A.state=RUNNABLE,但A并不能马上被调度,并占用CPU执行。只有等到B结束,B主动sleep,B时间片到(采用RR调度算法)后,才会得到调度并占用CPU执行的机会。

4 假定当进程B的时间片结束后轮到进程A执行时,在执行proc_run(A)时,执行load_esp0(next->kstack + KSTACKSIZE);
这时 T.esp0=A.kstack+KSTACKSIZE
当进一步执行完switch_to(&(prev->context), &(next->context)); 后
esp= A.context.esp 也就是A上次被切换保存的esp内容
A的内核态执行现场(内核上下文)恢复完毕,即sys_sleep在内核中要干的事情结束了。

5a A继续在内核执行,当执行完iret后,A的用户态执行现场恢复完毕,从int 0x80的后一条指令继续执行。

5b A继续在内核执行,但又发生了一个中断(比如时钟中断),这是是在内核中发送的中断,特权级不会发生变化。由于是同特权级产生的中断,esp不会从新赋值,那么硬件和软件在当前esp处(即A的当前内核栈处)一样要压栈一个trapframe,此时
A.kstack < A.esp < A.kstack+KSTACKSIZE-2*sizeof(trapframe)
当执行完iret ( for 时钟中断)后,A的内核态执行现场恢复完毕,
当再执行完一个iret (for sys_sleep)后,A的用户态执行现场恢复完毕,从int 0x80的后一条指令继续执行。

-------------------------------------------------------------------------------------------------

在 2012年4月9日 下午7:42,Yijing Li <strivi...@gmail.com> 写道:
> 老师,您介绍的内容是发生中断时trapframe相关的内容。但是,在switch_to中的:


> 设置任务状态段ts 中特权态0 下的栈顶指针esp0 为next 内核线程initproc 的内核栈的栈顶,即
>> next->kstack + KSTACKSIZE

> 是在进程切换时调用的。
> 请问,在进程切换时确实应该改变ts中esp0的值以保证新进程在发生中断时能找到内核栈。但是,如果某进程A已经在内核态处理syscall,这时A的内核栈中已经压了一个trapframe。然后,由于调度器进程A被终止了,改为进程B执行。当进程B的时间片结束后轮到进程A执行时,如果按照上一个语句把esp0赋值为:next->kstack
> + KSTACKSIZE的话,那么进程A的内核栈指针espA就不等于esp0了(esp0-espA =
> sizeof(trapframe))。这样的话不会出问题吗?

>> --
>> You received this message because you are subscribed to the Google Groups
>> "os-course" group.
>> To post to this group, send email to osco...@googlegroups.com.
>> To unsubscribe from this group, send email to
>> oscourse+u...@googlegroups.com.
>> For more options, visit this group at
>> http://groups.google.com/group/oscourse?hl=en.
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "os-course" group.
> To post to this group, send email to osco...@googlegroups.com.
> To unsubscribe from this group, send email to
> oscourse+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/oscourse?hl=en.

Reply all
Reply to author
Forward
0 new messages