Nachos之系统调用

来源:互联网 发布:水杉软件 编辑:程序博客网 时间:2024/04/29 10:06

        今天仔细研究了Nachos的系统调用(主要阅读Nachos Study Book.pdf),基本上理解了Nachos系统调用的过程.

        首先来明确一下系统调用的概念,系统调用是指用户程序调用系统提供的程序接口,而使系统进入内核态执行对应功能代码的过程。Nachos模拟了这一机制.那么Nachos是如何模拟的呢?

当用户程序调用系统调用接口时,Nachos会执行与此系统调用相对应的Stub.系统调用的Stub定义在start.s文件中.Stub主要完成三件事情.

  1. 将系统调用号写入2号寄存器
  2. 执行syscall指令
  3. 返回到31号寄存器存放的地址处,该地址为用户程序返回地址.
这里说的系统调用号,是Nachos为系统调用接口指定的一个整形编号,该编号定义在syscall.h文件中,syscall.h文件中还定义了系统调用接口.syscall.h的部分文件内容如下:
#define SC_Halt0#define SC_Exit1#define SC_Exec2#define SC_Join3#define SC_Create4#define SC_Open5#define SC_Read6#define SC_Write7#define SC_Close8#define SC_Fork9#define SC_Yield10void Halt();void Exit(int status);SpaceId Exec(char *name);int Join(SpaceId id); 
默认情况下,Nachos定义了11个系统调用号,每个号对应一个系统调用.比如SC_Halt为0,对应着系统调用Halt.
       syscall指令又是做什么的呢?当系统执行syscall指令时,在MIPS R2/3000处理器的模拟器中会捕获该指令,对应的代码在mipssim.cc的OneInstruction()方法中:代码如下:
      case OP_SYSCALL:RaiseException(SyscallException, 0);return; 
处理器当发现执行该指令时,会调用RaiseException(SyscallException,0)方法来抛出一个SyscallException异常,那么RaiseException方法(定义在machine.cc中)内到底做了什么呢?见代码:
void Machine::RaiseException(ExceptionType which, int badVAddr){    DEBUG('m', "Exception: %s\n", exceptionNames[which]);    //  ASSERT(interrupt->getStatus() == UserMode);    registers[BadVAddrReg] = badVAddr;    DelayedLoad(0, 0);// finish anything in progress    interrupt->setStatus(SystemMode);    ExceptionHandler(which);// interrupts are enabled at this point    interrupt->setStatus(UserMode);}
从interrupt->setStatus(SystemMode)你可以看出,此时系统进入核心态,接着执行ExceptionHandler(witch),ExceptionHandler方法在exception内进行实现,那么该方法到底做什么了呢?见代码:
void ExceptionHandler(ExceptionType which){    int type = machine->ReadRegister(2);    if ((which == SyscallException) && (type == SC_Halt)) {DEBUG('a', "Shutdown, initiated by user program.\n");   interrupt->Halt();    } else {printf("Unexpected user mode exception %d %d\n", which, type);ASSERT(FALSE);    }}
从这段代码中可以看出,首先从2号寄存处中取出系统调用号,然后判断发生的异常是不是SyscallException和系统调用好是不是SC_Halt如果是,则调用interrupt->Halt()执行Halt()方法的具体代码.注意这儿有两个条件判断,一是判断不是系统调用异常,而是根据系统调用号执行系统调用的具体代码.此处只对Halt系统调用进行了处理,我们可以在这儿扩展其他系统调用的处理代码。
       执行完ExceptionHandler后,会回到machine.cc的RaiseException代码,继续执行interrupt->setStatus(UserModel),重新回到用户态.RaiseException方法执行完后,回到Stub继续执行返回用户程序指令j $31。回到用户程序继续执行。
上述阐述了系统调用的过程,Nachos的系统调用时序图如下所示(以Halt调用为例):





原创粉丝点击