jos实验6记录.docx
- 文档编号:23289538
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:12
- 大小:603.52KB
jos实验6记录.docx
《jos实验6记录.docx》由会员分享,可在线阅读,更多相关《jos实验6记录.docx(12页珍藏版)》请在冰豆网上搜索。
jos实验6记录
JOS实验六实验记录
作者:
卓达城
邮箱:
zhuodc@(欢迎来信)
在开始实验之前先把相关lab5的代码和lab6合并
lab6代码量和逻辑没有lab5多,编程技巧的运用也没有lab4多,也没有lab2和lab3涉及底层的东西多,如果前面的实验做得足够完美,应该是很简单。
但是世界上是没有完美的东西的。
。
lab6的调试工作可以用痛苦来形容,因为lab6的涉及前面五个实验,只要前面有一点点错,往往要花一两天才能查出来。
我的天啊~~~~~~~
做实验之前先来改正一下前面的错误(这些错误找起来真的是呕心沥血啊~~):
syscall.c
serv.c
pmap.c
这个bug我足足用了两天的时间来修正,两天,两天,两天。
。
。
。
。
。
功能增强:
serv.c
增加新建文件的功能。
做lab6之前要先明白lab6到底要做什么?
lab6要做的就是父子进程共享文件、管道还有shell。
第一步共享文件:
具体点描述就是父进程开了一个文件,然后fork一个子进程,然后子进程改文件的东西,父进程读文件的时候,文件的内容跟子进程改变之后的是一样的。
回顾lab4中的copyonwrite机制:
当父进程或者子进程要写它们共有的东西的时候,系统会新开一页,然后把原来那页的内容复制过去,这样做能使父子进程完全相互独立,就是说子进程开始之后,父进程不能影响子进程(如果子进程不愿意的话)。
现在我们要做的事情就是如果父进程有打开文件的话,父子进程共享这个文件,无论父进程还是子进程修改这个文件,父子进程读这个文件的时候都会是改变之后的文件(仅限于文件所在内存页是这样,其它还是相互独立的)。
第二步管道:
说白了就是通过文件的共享特性实现进程之间的通信。
第三部shell:
就是利用管道来实现一些类似echohello|cat这样的命令。
第一部分:
共享文件
EX1
修改fork.c
如果是PTE_SHARE类型的话,映射到共同的物理页。
EX2
把父进程打开的文件映射到子进程里面。
这里主要作用是用来作为输入和输出文件的。
EX3
修改文件服务器进程,使所有打开的文件都具有PTE_SHARE属性
函数voidserve_map(envid_tenvid,structFsreq_map*rq)
函数:
voidserve_open(envid_tenvid,structFsreq_open*rq)
这里好像jos的作者已经给出了。
EX4
请见下文
第二部分管道
由于我是把实验做完了再开始写文档的,所以解决冲突的代码也在里面了。
先说下大概原理,这里很难讲清楚,所以最好是看实验要求文档,哪里写得很清楚(锻炼锻炼英文吧)。
流程大概如下:
父进程通过pipe建立两个文件,这两个文件跟其它的不一样,我们用a,b表示文件句柄(fd),ay,by表示句柄映射的数据页。
如果按照之前的文件系统他们会独立映射,但是现在不是,现在的情况是ay=by,就是数据页是相同的。
子进程建立,复制共享父进程的文件,所以a,b句柄相同,然后他们映射的页也相同。
现在是pageref(a)=2,pageref(b)=2,pageref(ay)=4
如果pageref(a)=2,pageref(ay)=2,那就表明b已经关闭了。
我们为了让进程不会老是在等待,所以如果b关闭了,就会返回0,用a来读的进程就会知道,不再一直等待。
但是用这样的方法来判断会由于进程切换而导致错误,具体为什么可以自己想一想,同时强烈建议看实验要求(就是mit那份英文的文档),写的非常详细透彻。
在pipe.c里面我们要完成3个函数,修改2个函数
staticint_pipeisclosed(structFd*fd,structPipe*p)
这里通过统计进程的运行次数来达到原子操作的效果。
为了达到这个效果,我们会在每一次运行进程的时候把env_runs++,这样,如果在进程切换的时候执行上述函数,上述函数就会进入循环继续执行。
我们还需要改代码:
(env.cenv_run函数)
staticssize_tpiperead(structFd*fd,void*vbuf,size_tn,off_toffset)
这个函数我一开始没有按照作者的意思去写,结果测试用例可以过,但是shell的时候不能过,调了很久,后来发现是调用它的函数决定了它必须按照作者的意思去写。
请看jos作者的代码注释。
staticssize_tpipewrite(structFd*fd,constvoid*vbuf,size_tn,off_toffset)
同上
要修改的函数
staticintpipeclose(structFd*fd)
为了解决竞争问题,必须先调用sys_page_unmap函数。
要修改的函数
所在文件:
fd.c
intdup(intoldfdnum,intnewfdnum)
同样是为了解决竞争问题。
第三部分:
shell
EX8
先添加一个键盘中断
添加一个中断要做三步:
trap.c
idt_init函数
trapentry.S
至于中断的原理前面已经讲得很多了,这里就不多说了。
EX9
sh.c
按照jos的设计方案,所有在shell运行的程序的输入都是fd[0],输出文件都是fd[1]。
下面是要添加的代码:
把任意一个fd复制到fd[0],shell将会把它作为shell运行的程序的输入文件。
把任意一个fd复制到fd[1],将会作为shell运行的程序的输出文件。
这个就是管道的实现
把第一个运行的程序的输出作为第二个要运行的程序的输入。
这就是管道的实现原理。
至此,实验完成。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- jos 实验 记录