Nachos之系统调用

        今天仔细研究了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_Halt		0
#define SC_Exit		1
#define SC_Exec		2
#define SC_Join		3
#define SC_Create	4
#define SC_Open		5
#define SC_Read		6
#define SC_Write	7
#define SC_Close	8
#define SC_Fork		9
#define SC_Yield	10


void 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调用为例):





  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值