【nachos】山东大学操作系统课设实验nachos系统(6)系统调用Exec()和Exit()

实验目的

尝试实现系统调用Exec() 和 Exit()

实验步骤

需要注意,在前三个步骤不需要修改代码。

一、nachos中系统调用的实现机制
观察nachos/machine/machine,mipssim中的实现可以看出,每一条用户程序中的指令在虚拟机中被读取后,包装成一个OneInstruction对象,经过解码,在mipssim中的一串长SWITCH语句中分别执行不同的操作。
而对于系统调用,在用户程序中的表现是调用nachos/userprog/syscall.h中定义的一系列系统调用函数,而这些函数的实现是定义在nachos/test/start.s中的汇编代码。
这里写图片描述
可以看出,实际上start.s中,不同的系统调用实际上是把系统调用的类型(SC_***)放入二号寄存器,然后执行指令syscall。
在mipssim中的switch语句中,对syscall的处理如下:
这里写图片描述
可以看出,这里抛出了一个异常,交给异常处理函数去处理。要注意的是,这里不同于其他指令的处理方式,没有使用break而是使用了return,而一般指令在break之后会进行一些其他处理:
这里写图片描述
可以看出其中包括了对pc的推进操作。
所以,直接return造成的后果是没有对pc进行推进,那么程序就会再次读入这条系统调用操作,无限循环。所以我们要手动添加这部分对pc推进的代码,稍后会讲到。

而RaiseException函数实际上最终调用的是nachos/userprog/exception.cc中的函数ExceptionHandler(ExceptionType which)。在这里ExceptionType是int的别名,可以当做int处理。
在这个函数中,我们可以看到,它利用了条件判断语句来进行判断,当前错误是系统调用还是用户程序出错,并进一步判断是什么错误。
这里写图片描述
也不难看出,程序当前只处理了Halt这个系统调用。
所以要完成Exec和Exit,就要在这里添加实现。

二、对Exec和Exit系统调用的分析
对于Exec系统调用来说,在syscall.h中的定义如下:
这里写图片描述
该调用的功能是,从可执行文件name运行一个新的用户程序,并行执行,并返回新的程序的内存空间标识符SpaceId。

具体的实现思路:根据name指向的地址打开可执行文件,创建AddrSpace,再fork出一个新的线程,将其内存空间设为刚创建的AddrSpace对象,目标函数中,对AddrSpace对象调用InitRegister和RestoreState方法,设置好虚拟机寄存器、内存空间的状态,调用machine->Run()执行。而执行系统调用的线程在fork出新线程后,将SpaceID返回,然后调用AdvancePC使pc寄存器的值前进,避免循环。

对于Exit系统调用来说,在syscall.h中的定义如下:
这里写图片描述
该调用的功能是,结束用户程序的运行。传入0时正常退出。由于我们没有其他退出情况要处理,所以这个状态码暂时不利用。

具体实现思路:简单地调用currentThread->Finsh()终止当前线程即可。

三、系统调用中对参数、返回值的读取和传递
系统调用中的返回值不同于普通函数的参数传递,参照exception.cc中的注释可以知道,它们是通过寄存器来储存的。

这里写图片描述

可以看出,参数分别储存在r4到r7内。
而返回值需要放在r2寄存器中。

而我们的参数不能以直接转换成指针的形式从内存中读取,原因是这里的内存地址实际上是虚拟机的内存,而转换成指针形式的内存地址是真实机器中的地址。所以读取要用machine->ReadMem(int addr,int size,int *value)方法。而读取字符串,则需要循环至读取到\0为止。

这里写图片描述

  • 8
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值