讲解的nachos的运行机制

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

nachos 的machine类模拟了一台电脑,这台电脑有内存,寄存器,磁盘。
当你的shell源码被 交叉编译器 编译后,形成了 shell.noff 文件,这个文件只能被 nachos 执行,因为这个文件中的机器指令只有nachos 模拟的那台电脑认识.

比如你在shell文件中有一句 Write("abc",3,ConsleOutput);
交叉编译器 会插入 SC_WRITE 到 shell.noff 文件,
当nachos 模拟的那台电脑 读到SC_WRITE时,它会 RaiseException ( 该函数在machine类的 OneInstrucion 函数中被调用)

查看RaiseException函数,它调用了ExceptionHandler函数

在ExceptionHandler函数中:
通过 switch 判断出是 SC_WRITE 。

接下来是你要做的事了!!

在RaiseException函数 所在的 文件 中,有一段注释:
// 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.



它是说:如果有一个nachod系统函数叫 int f(int a,char* b,int c);
调用它时: 在nachos 模拟的那台电脑中 a 参数在第4个register中, b 参数在第5个register中,c 参数在第6个register中,所有 nachod系统函数 最多有4个参数!!!
具体代码:
result = SysAdd( (int)kernel->machine->ReadRegister(4),
(int)kernel->machine->ReadRegister(5)
);
f函数的返回值写在第2个register中;
具体代码;
kernel->machine->WriteRegister(2, (int)result);

那我继续写!!

接着,PC ( program counter ) 指向下一条指令:
具体代码:
/* 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);

那我们应怎样实现 nachos 系统函数 Write ??
在 中,加入:

case SC_Write: // 调用 nachos 系统函数 Write 就会 产生这个东西,SC_Write 在syscall.h 中有定义

result = SysWrite( (int)kernel->machine->ReadRegister(4), //向处理函数 SysWrite(见后) 传入参数
(int)kernel->machine->ReadRegister(5),
(OpenFileId)kernel->machine->ReadRegister(6)
);

kernel->machine->WriteRegister(2, (int)result);//把 SysWrite的result写入第2个register中

kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRe

gister(PCReg)+4);

在 ksyscall.h 中,加入:

int SysWrite(int buffer, int size, OpenFileId id)
{ int ch;
int i=-1;
if (id==CnslOutput)
{ while(++imachine->ReadMem(buffer,1,&ch))
{ kernel->synchConsoleOut->PutChar( (char)ch );
++buffer;
}
}
return i;
}
特别说明:
kernel->machine->ReadMem(buffer,1,&ch) :这个是从“nachos 模拟的那台电脑的内存”(注意啊!!)中,在地址 buffer 读出一个字符,






在 machine.h 有一个属性:char * mainMemory;(很小,注意找哈);

继续前面的!!!

nachos 模拟的那台电脑 使用 整数 即 int 来 作为内存地址!!! 详见 machine.h的 Translate函数,在 ReadMem 和 WriteMem 函数中 有调用:
原文:
bool
Machine::WriteMem(int addr, int size, int value)
{
ExceptionType exception;
int physicalAddress;

DEBUG(dbgAddr, "Writing VA " << addr << ", size " << size << ", value " << value);

exception = Translate(addr, &physicalAddress, size, TRUE);//这里!!!!!!!!!!

++buffer;//内存地址向前进 1, 好读下一个字符

kernel->synchConsoleOut->PutChar( (char)ch ); //使用nachos 模拟的那台电脑的控制台 输出一个字符

一定要注意啊:
nachos 操作系统自己模拟了一台电脑,这台电脑有自己的内存,磁盘(在build.linux文件夹中有一个文件DISK_0,即磁盘),控制台。


因为 是 nachos 的源文件,ksyscall.h 也是,所以你修改了这两个文件后,要重新编译 nachos.



这台电脑有自己的内存,磁盘(在build.linux文件夹中有一个文件DISK_0,即磁盘),控制台。


是的,你写的函数 只能和 nachos模拟的那台电脑打交道!!!!

相关文档
最新文档