讲解的nachos的运行机制
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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(++i
{ 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模拟的那台电脑打交道!!!!