nachos系统调用实现Write、Read、Exec、Join

  •  了解nachos系统调用的原理:

1.  要实现nachos的系统调用,首先查看syscall.h当中声明的系统调用函数

nachos系统调用实现Write、Read、Exec、Join

可以发现Nachos已经为我们在syscall.h中声明好了这些系统调用函数。

2.  观察Start.s中的汇编代码,定义了系统调用函数的实现

nachos系统调用实现Write、Read、Exec、Join

我们可以观察到Halt函数的实现是将系统调用类型(type)SC_Halt放入了2号寄存器中,然后执行syscall。

3.  在Mipssim.cc中可以找到syscall的执行方式

nachos系统调用实现Write、Read、Exec、Join

可以看到这里调用了RaiseException异常处理函数

4.  Jump到这个异常处理函数,可以发现将SyscallException传入了ExceptionHandler函数中。

nachos系统调用实现Write、Read、Exec、Join

5.  exception.cc中ExceptionHandler函数

nachos系统调用实现Write、Read、Exec、Join

其中从2号寄存器中取出系统调用号(type),然后进行判断传入函数的是系统调用还是异常,若是系统调用则对type进行判断系统调用的类型。可以看出nachos已经为我们定义好了SC_Halt和SC_Add两种系统调用应该怎么处理,其他的系统调用需要我们自己完善。

6.  ksyscall.h中可以找到ExceptionHandler中处理系统调用时会用到的SysHalt和SysAdd函数,是对应系统调用的具体处理方法。

nachos系统调用实现Write、Read、Exec、Join

  • 关于系统调用的寄存器的介绍:

R2:用于存放系统调用类型,以及系统调用的返回值

R4:存放系统调用的第一个参数

R5: 存放系统调用的第二个参数

R6: 存放系统调用的第三个参数

nachos系统调用实现Write、Read、Exec、Join

  • 了解完了nachos的系统调用过程,接着进行系统调用代码的补充和修改,完善shell.c中需要调用的Write Read Exec Join四个系统调用的处理方法。

1.  在exception.cc的ExceptionHandler函数中编写当系统调用号为SC_Write时进行的处理,可以模仿SC_Add的处理方式。

nachos系统调用实现Write、Read、Exec、Join

将4 5 6号寄存器中存放的数据传入SysWrite函数中进行处理,分别将这三个参数规定为要写入的字符串、字符串大小和指定将要写入的文件。将SysWrite函数的返回值写入2号寄存器中以捕获异常。

更新PC的函数如下所示,更新之后此次系统调用结束,程序继续执行下一条:

nachos系统调用实现Write、Read、Exec、Join

其中调用的SysWrite函数在ksyscall.h中进行编写:

nachos系统调用实现Write、Read、Exec、Join

其调用了nachos中的ReadMem如下:

nachos系统调用实现Write、Read、Exec、Join

使用ReadMema将需要写入文件的字符串的一个字符存到ch中,再将ch中的字符存到字符数组buffer[]中,重复这个步骤直到buf中的内容全部存到buffer[]中。

最后使用write将buffer中的内容输出到id指向的地方。

2. 在exception.cc的ExceptionHandler函数中编写当系统调用号为SC_Read时进行的处理:

nachos系统调用实现Write、Read、Exec、Join

其中SysRead的代码如下:

nachos系统调用实现Write、Read、Exec、Join

将从id指定的地方提取要读的数据并以字符数组的形式存入buffer中。

3.  在exception.cc的ExceptionHandler函数中编写当系统调用号为SC_Exec时进行的处理:

nachos系统调用实现Write、Read、Exec、Join

其中SysExec的代码如下:

nachos系统调用实现Write、Read、Exec、Join

Exec的作用是传入可执行文件名,并开启一个子线程来执行。

4.  在exception.cc的ExceptionHandler函数中编写当系统调用号为SC_Join时进行的处理:

nachos系统调用实现Write、Read、Exec、Join

其中SysJoin的代码如下:

nachos系统调用实现Write、Read、Exec、Join

使用Join来等待当前子线程执行结束。函数中传入的是需要被等待的子线程号。

  • 完善了四个系统调用函数的代码之后,使用test文件夹下的shell.c对我们完善的系统调用函数进行测试:

1.观察shell.c代码:

nachos系统调用实现Write、Read、Exec、Join

1)先是调用了Write在控制台上输出”--”用于提示用户在此处输入要输入的指令,使用Read将这个指令存入buffer[],以回车作为结束,将指令字符串传入Exec中执行,并用Join来等待这个子线程执行结束,再执行下一个while循环。

2)也就是说shell.c程序实现了类似Windows下的dos,Linux下的terminal的功能。

3)由于shell程序中没有提供退出shell的方法,于是修改代码shell.c:

nachos系统调用实现Write、Read、Exec、Join

添加判断是否输入例如exit的语句,当输入exit的时候调用Halt系统调用退出。

2.  test文件夹下的Makefile已经为我们提供了编译shell.c的方法,只用在test目录下执行make命令,生成了shell.noff可执行文件

3.  在build.linux目录下执行make产生nachos,且没有error

4.  在build.Linux目录下执行./nachos –x ../test/shell.noff命令,让nachos系统运行这个可执行文件。运行结果如下:一直在等待用户输入命令:

nachos系统调用实现Write、Read、Exec、Join

试验指令ls 、ls –l、echo 、mkdir、exit,实验结果入下:

nachos系统调用实现Write、Read、Exec、Join

nachos系统调用实现Write、Read、Exec、Join

nachos系统调用实现Write、Read、Exec、Join

nachos系统调用实现Write、Read、Exec、Join

nachos系统调用实现Write、Read、Exec、Join