标签:
JOS lab4 用户程序分析
faultread.c faultdie.c:
这两个用户程序一起分析
左右两个用户程序,都试图对非法地址写入数据,但是左边的就会导致 page fault ,触发的是内核trap
而后边的就会进入打印trap frame,导致系统挂掉,而右边的不会,右边的由于有用户空间的处理机制,
还是建议自己一步步跟踪去看.
faultalloc.c faultallocbad.c :
这里还是用户空间直接调用系统调用处理函数,还是通过用户程序触发page fault 之后再用用户空间page fault handler处理异常.和之前的faultread.c faultdie.c是一个原理,换汤不换药啊哈哈...
faultbadhandler.c :
这里由于设置的把 0xDeadBeef当做handler的地址,是错误的,这是个非法地址.
我特意注释了,只要按照我注释的来运行,就可以处理好这里的赋值操作引起的page fault.
同样handler设置不正确的还有
faultevilhandler.c:
这里的问题在于handler的地址 0xF0100020是个内核高地址.非法的,我们设置的用户态page fault handler必须处于用户空间内.不能放在内核地址.
faultnostack.c:
观察各种配置好的 user space page fault handler 处理机制,都有异常栈的设置,但是这里没有,于是,挂.
要知道所有的user space page fault handler都是运行在exception stack里面的,而不是normal user stack.也不是kernel stack.
而且这里仅仅只配置了内核向上衔接处理用户page fault的借口 _pgfault_upcall.连handler都没写.
forktree.c:
这个在lab4实验报告里面有
pingpong.c:
这里很有意思.fork出一个子进程,然后由父进程发送一个值给pid为who的进程(即子进程,这里注意,父进程和子进程的who变量值不同就好.父进程的who是子进程的pid,子进程的who是0).
然后两个进程都落入到while循环,首先子进程接受信息,接受到了就打印这个信息 i.
i++,接着对于子进程来说who值已经改变了,在ipc_recv的时候传参的时候是&who.这里函数内部会把谁传递信息给子进程的pid赋值给who.注意我这里没有特别说明是父进程,而用了"谁传递信息给这个子进程".因为在其他情形中,可能不仅仅只有父进程给这个子进程传递信息.
尔后双方互发信息....每个进程为i值增加1,双方交互十次然后结束.呵呵...所以这个程序看起来就像
双方打乒乓球一样...ping ping pong pong ...
spin.c:
这个用户程序看起来还是很简单的,子进程有点作死,居然死循环.这个时候会如果没有好的调度策略那么这货会一直抢占着CPU,大家也就都别玩了,,,
这样不好...怎么办呢?可以通过一个定时器中来触发外部硬件中断,由这个中断来完成进程的让出.
这里parent process 各种让出CPU,然后又被子进程霸占CPU,等一段时间了定时器开始触发中断,这个时候CPU响应中断.开始处理这个定时器中断,我们就可以在处理机制里面做手脚,怎么做呢?
看下面:
在 trap_dispatch里面添加下面的代码用来检测触发的外部硬件中断是否为定时器中断.
看,我们添加了sched_yield();主动让出这个一直抢占CPU的进程.
由于之前初始化的时间片太短了,可能测试程序的感觉不明显.
我们可以去kern/lapic.c里面修改下面的代码.
注释哪行是实验老师原来设置的默认定时器初始值,现在看到的时我自己设置的0xFFFFFFF
一个大概足够大的数据就好,我没有深究这里的意义.因为这货和CPU的主频速度有关系,是一个不断做减法的过程.(以前玩过单片机还是有好处的哇...)
这里修改过这个参数后去运行spin的话就会发现,child Spinning ...那个地方会有明显的停顿.如果不把时间增加,那地方一闪就过了.这里为什么要设置恰当的时间,实验者可以自己想想 : )
测试完之后记得把TICR的值改回去,不然grade的时候可能时间太长过不了.
先放出来一部分,后面有些再补上
未完待续...
有误解的话,恳请斧正.
标签:
原文地址:http://blog.csdn.net/cinmyheart/article/details/45197685