nachos实验一代码(共23页).doc
精选优质文档-倾情为你奉上Test文件下: shell.c: #include "syscall.h"intmain() SpaceId newProc; OpenFileId input = ConsoleInput; OpenFileId output = ConsoleOutput; char ch, buffer60; int i;Write( "tt<-ZhangCJ's shell welcome you->n", 34, output); while( 1 ) Write( "<-Please Input-> :", 20, output);i = 0;do Read(&bufferi, 1, input); while( bufferi+ != 'n' );buffer-i = '0' if(Strncmp(buffer,"exit",4)=0) Halt(); if( i > 0 ) newProc = Exec(buffer);Join(newProc); Start.s :/* Start.s *Assembly language assist for user programs running on top of Nachos. * *Since we don't want to pull in the entire C library, we define *what we need for a user program here, namely Start and the system *calls. */#define IN_ASM#include "syscall.h" .text .align 2/* - * _start *Initialize running a C program, by calling "main". * * NOTE: This has to be first, so that it gets loaded at location 0. *The Nachos kernel always starts a program by jumping to location 0. * - */.globl _start.ent_start_start:jalmainmove$4,$0jalExit /* if we return from main, exit(0) */.end _start/* - * System call stubs: *Assembly language assist to make system calls to the Nachos kernel. *There is one stub per system call, that places the code for the *system call into register r2, and leaves the arguments to the *system call alone (in other words, arg1 is in r4, arg2 is *in r5, arg3 is in r6, arg4 is in r7) * * The return value is in r2. This follows the standard C calling * convention on the MIPS. * - */.globl Halt.entHaltHalt:addiu $2,$0,SC_Haltsyscallj$31.end Halt.globl Add.entAddAdd:addiu $2,$0,SC_Addsyscallj $31.end Add.globl Exit.entExitExit:addiu $2,$0,SC_Exitsyscallj$31.end Exit.globl Exec.entExecExec:addiu $2,$0,SC_Execsyscallj$31.end Exec.globl ExecV.entExecVExecV:addiu $2,$0,SC_ExecVsyscallj$31.end ExecV.globl Join.entJoinJoin:addiu $2,$0,SC_Joinsyscallj$31.end Join.globl Create.entCreateCreate:addiu $2,$0,SC_Createsyscallj$31.end Create.globl Remove.entRemoveRemove:addiu $2,$0,SC_Removesyscallj$31.end Remove.globl Open.entOpenOpen:addiu $2,$0,SC_Opensyscallj$31.end Open.globl Read.entReadRead:addiu $2,$0,SC_Readsyscallj$31.end Read.globl Write.entWriteWrite:addiu $2,$0,SC_Writesyscallj$31.end Write.globl Close.entCloseClose:addiu $2,$0,SC_Closesyscallj$31.end Close.globl Seek.entSeekSeek:addiu $2,$0,SC_Seeksyscallj$31.end Seek.globl Delete.entDeleteDelete: addiu $2,$0,SC_Deletesyscallj$31.end Delete .globl ThreadFork .ent ThreadForkThreadFork: addiu $2,$0,SC_ThreadFork syscall j $31 .end ThreadFork .globl ThreadYield .ent ThreadYieldThreadYield: addiu $2,$0,SC_ThreadYield syscall j $31 .end ThreadYield.globl ThreadExit.ent ThreadExitThreadExit:addiu $2, $0, SC_ThreadExitsyscallj $31.end ThreadExit.globl ThreadJoin.ent ThreadJoinThreadJoin:addiu $2, $0, SC_ThreadJoinsyscallj $31.end ThreadJoin.globl getSpaceID.entgetSpaceIDgetSpaceID:addiu $2,$0,SC_getSpaceIDsyscallj$31.end getSpaceID.globl getThreadID.entgetThreadIDgetThreadID:addiu $2,$0,SC_getThreadIDsyscallj$31.end getThreadID.globl Ipc.ent IpcIpc: addiu $2,$0,SC_Ipcsyscallj $31.end Ipc.globl Clock.ent ClockClock:addiu $2,$0,SC_Clocksyscallj $31.end Clock/* dummy function to keep gcc happy */ .globl _main .ent _main_main: j $31 .end _main.globl Strncmp.ent StrncmpStrncmp: addiu $2,$0,SC_Strncmp syscall j $31 .end Strncmp .globl Exit .ent ExitUserprog文件夹下Exception.cc: / exception.cc /Entry point into the Nachos kernel from user programs./There are two kinds of things that can cause control to/transfer back to here from user code:/syscall - The user code explicitly requests to call a procedure/in the Nachos kernel. Right now, the only function we support is/"Halt"./exceptions - The user code does something that the CPU can't handle./For instance, accessing memory that doesn't exist, arithmetic errors,/etc. /Interrupts (which can also cause control to transfer from user/code into the Nachos kernel) are handled elsewhere./ For now, this only handles the Halt() system call./ Everything else core dumps./ Copyright (c) 1992-1996 The Regents of the University of California./ All rights reserved. See copyright.h for copyright notice and limitation / of liability and disclaimer of warranty provisions.#include "copyright.h"#include "main.h"#include "syscall.h"#include "ksyscall.h"/-/ ExceptionHandler/ Entry point into the Nachos kernel. Called when a user program/is executing, and either does a syscall, or generates an addressing/or arithmetic exception./ For system calls, the following is the calling convention:/ system call code - r2/arg1 - r4/arg2 - r5/arg3 - r6/arg4 - r7/The result of the system call, if any, must be put back into r2. / If you are handling a system call, don't forget to increment the pc/ before returning. (Or else you'll loop making the same system call forever!)/"which" is the kind of exception. The list of possible exceptions /is in machine.h./-voidExceptionHandler(ExceptionType which) int type = kernel->machine->ReadRegister(2); DEBUG(dbgSys, "Received Exception " << which << " type: " << type << "n"); switch (which) case SyscallException: switch(type) case SC_Halt:DEBUG(dbgSys, "Shutdown, initiated by user program.n");SysHalt();ASSERTNOTREACHED();break;case SC_Write:DEBUG(dbgSys,"Write from buffer to consoleOutput"<<kernel->machine->ReadRegister(4)<<kernel->machine->ReadRegister(5)<<kernel->machine->ReadRegister(6)<<"n");char wbuffer60; int size ;size=(int)kernel->machine->ReadRegister(5);OpenFileId printOut;printOut= (OpenFileId)kernel->machine->ReadRegister(6);int addressOne;addressOne=(int)kernel->machine->ReadRegister(4);int i;i=0;dokernel->machine->ReadMem(addressOne+,1,(int*)&wbufferi+); while(i<size);int n1;n1=SysWrite(char*)wbuffer,size,printOut);kernel->machine->WriteRegister(2,n1);kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg);kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4);kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4); return;ASSERTNOTREACHED();break;case SC_Read:DEBUG(dbgSys, "read from buffer" << kernel->machine->ReadRegister(4) << kernel->machine->ReadRegister(5)<< kernel->machine->ReadRegister(6) << "n"); int rsize ;rsize=(int)kernel->machine->ReadRegister(5);OpenFileId enterIn;enterIn = (OpenFileId)kernel->machine->ReadRegister(6);char addressTwo;addressTwo = (char)kernel->machine->ReadRegister(4);int local ;local= (int)kernel->machine->ReadRegister(4);int n2 ;n2= SysRead(&addressTwo,rsize,enterIn);kernel->machine->WriteMem(local,1,(int)addressTwo);kernel->machine->WriteRegister(2,n2); kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg);kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4);kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);return;ASSERTNOTREACHED();break;case SC_Exec:DEBUG(dbgSys,"execute a command"<<kernel->machine->ReadRegister(4)<<"n");char ebuffer60;int addressThree;addressThree = kernel->machine->ReadRegister(4);int c;c = 0;dokernel->machine->ReadMem(addressThree+,1,(int*)&ebufferc+); while(c<60);kernel->machine->WriteRegister(2,SysExec(ebuffer);kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg);kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4);kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);return;ASSERTNOTREACHED();break;case SC_Join:DEBUG(dbgSys,"jion "<<kernel->machine->ReadRegister(4)<<"n");kernel->machine->WriteRegister(2,SysJoin(SpaceId)kernel->machine->ReadRegister(4);kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg);kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4);kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);return;ASSERTNOTREACHED();break;case SC_Strncmp:DEBUG(dbgSys, "compare two string " << kernel->machine->ReadRegister(4) <<kernel->machine->ReadRegister(5) << kernel->machine->ReadRegister(6) << "n");int addressFour;addressFour = kernel->machine->ReadRegister(4);int addressFive;addressFive = kernel->machine->ReadRegister(5);char str1buffer60;char str2buffer60;int d,e;d= 0;e=0;dokernel->machine->ReadMem(addressFour+,1,(int*)&str1bufferd+); while(d<60);-addressFour;do kernel->machine->ReadMem(addressFive+,1,(int*)&str2buffere+);while(e<60);-addressFive;int n3;n3=SysStrncmp(str1buffer,str2buffer,kernel->machine->ReadRegister(6);kernel->machine->WriteRegister(2,n3);kernel->machine->WriteRegister(PrevPCReg,kernel->machine->ReadRegister(PCReg);kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) +4);kernel->machine->WriteRegister(NextPCReg,kernel->machine->ReadRegister(PCReg)+4);return;ASSERTNOTREACHED();break; case SC_Add:DEBUG(dbgSys, "Add " << kernel->machine->ReadRegister(4) << " + " << kernel->machine->ReadRegister(5) << "n");/* Process SysAdd Systemcall*/int result;result = SysAdd(/* int op1 */(int)kernel->machine->ReadRegister(4),/* int op2 */(int)kernel->machine->ReadRegister(5);DEBUG(dbgSys, "Add returning with " << result << "n");/* Prepare Result */kernel->machine->WriteRegister(2, (int)result);/* Modify return point */ /* set previous programm counter (debugging only)*/ kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg); /* set programm counter to next instruction (all Instructions are 4 byte wide)*/ kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4); /* set next programm counter for brach execution */ kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg)+4);return;ASSERTNOTREACHED();break; default:cerr << "Unexpected system call " << type << "n"break; break; default: cerr << "Unexpected user mode exception" << (int)which << "n" break; ASSERTNOTREACHED();Ksyscall.h : /* * * userprog/ksyscall.h * * Kernel interface for systemcalls * * by Marcus Voelp (c) Universitaet Karlsruhe * */#ifndef _USERPROG_KSYSCALL_H_ #define _USERPROG_KSYSCALL_H_ #include "kernel.h"#include <stdlib.h>#include <string.h>#include <sys/time.h>#include <sys/file.h>#include <stdarg.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/wait.h>#include <sched.h>#include <signal.h>#include <sys/types.h>#include <pthread.h>#define SHELL "/bin/sh" int SysWrite(char*buffer ,int size,OpenFileId id) return write(id,buffer,(size_t)size);int SysRead(char*buffer ,int size,OpenFileId id) return read(id, buffer, (size_t)size);SpaceId SysExec(char* exec_name)pid_t child;child = vfork();if(child = 0)execl (SHELL, SHELL, "-c", exec_name, NULL); _exit (EXIT_FAILURE);else if(child < 0)return EPERM;return (SpaceId) child;int SysJoin(SpaceId id)return waitpid(pid_t)id, (int*)0, 0); int SysStrncmp(char*buffer,char *str,int n) return strncmp(buffer,str,(size_t)n);void SysHalt() kernel->interrupt->Halt();int SysAdd(int op1, int op2) return op1 + op2;#endif /* ! _USERPROG_KSYSCALL_H_ */Syscall.h: /* syscalls.h * Nachos system call interface. These are Nachos kernel operations * that can be invoked from user programs, by trapping to the kernel *via the "syscall" instruction. * *This file is included by user programs and by the Nachos kernel. * * Copyright (c) 1992-1993 The Regents of the University of California. * All rights reserved. See copyright.h for copyright notice and limitation * of liability and disclaimer of warranty provisions. */#ifndef SYSCALLS_H#define SYSCALLS_H#include "copyright.h"#include "errno.h"/* system call codes - used by the stubs to tell the kernel which system call * is being asked for */#define SC_Halt0#define SC_Exit1#define SC_Exec2#define SC_Join3#define SC_Create4#define SC_Remove 5#define SC_Open6#define SC_Read7#define SC_Write8#define SC_Seek 9#define SC_Close10#define SC_Delete 11#define SC_ThreadFork12#define SC_ThreadYield13#define SC_ExecV14#define SC_ThreadExit 15#define SC_ThreadJoin 16#define SC_getSpaceID 17#define SC_getThreadID 18#define SC_Ipc 19#define SC_Clock 20#define SC_Add42#define SC_Strncmp 43