高级操作系统——Nachos内存管理(TLB异常处理)

mac2024-07-02  66

对系统 machine.h: 1:定义页表大小,页表最大内存 2:异常种类 3:寄存器种类

machine.cc 1:将寄存器,页表和快表,全置为空 Machine 2:处理异常 RaiseException 3:调试 Debugger 4:输出所有寄存器的值DumpState 5:写入或者读出寄存器的值ReadRegister, WriteRegister

exception.cc: 1:处理异常ExceptionHandler 对用户:

progtest.cc: 1:开启用户程序 StartProcess (调用addrespace),初始化寄存器,页表,快表 2:控制台交互 ConsoleTest

addrespace: 1:分配用户的代码段,初始化数据段,未初始化数据段,栈段等地址,真正初始化寄存器,页表,快表,将代码和数据写入内存 2:初始化machine寄存器 InitRegisters 利用machine.cc 的WriteRegister 3:页表地址装载至machine RestoreState

translate.h: 1:定义页表项 TranslationEntry(标志位)

translate.cc: 1:将虚拟地址转换为物理地址 Translate 2:虚拟地址上写value WriteMem 3:虚拟地址上读value ReadMem

Exercise 2 TLB MISS异常处理 修改code/userprog目录下exception.cc中的ExceptionHandler函数,使得Nachos系统可以对TLB异常进行处理(TLB异常时,Nachos系统会抛出PageFaultException,详见code/machine/machine.cc)。

1:首先查找页表是在translate.cc的 Translate()中,部分代码如下

if (entry == NULL) { DEBUG('a', "*** no valid TLB entry found for this virtual page!\n"); return PageFaultException; }

这里已经抛出了一个异常,无需修改 2:明确谁接收了Translate返回的return PageFaultException;。观察代码,可以看到是 translate.cc的ReadMem()和:WriteMem(),即通过虚拟地址寻找时,没有找到对应的TLB的entry,部分代码如下

exception = Translate(addr, &physicalAddress, size, TRUE); if (exception != NoException) { machine->RaiseException(exception, addr); return FALSE; }

3:可以看到,接下来将异常抛出给exception.cc中的ExceptionHandler。 我们将ExceptionHandler修改为:

if ((which == SyscallException) && (type == SC_Halt)) { DEBUG('a', "Shutdown, initiated by user program.\n"); interrupt->Halt(); } if (which == PageFaultException) { int address = machine->ReadRegister(BadVAddrReg); DEBUG('a', "The exception is %d\n",which ); } else { printf("Unexpected user mode exception %d %d\n", which, type); ASSERT(FALSE); }

可以看到就是新增了一个if判断,里面增加逻辑就好了 4:接下来我们还要增加异常种类,分别在machine.cc和machine.h中增加 machine.h //异常管理

enum ExceptionType { NoException, // Everything ok! SyscallException, // A program executed a system call. PageFaultException, // No valid translation found ReadOnlyException, // Write attempted to page marked // "read-only" BusErrorException, // Translation resulted in an // invalid physical address AddressErrorException, // Unaligned reference or one that // was beyond the end of the // address space OverflowException, // Integer overflow in add or sub. IllegalInstrException, // Unimplemented or reserved instr. NumExceptionTypes, PageFaultException }; machine.cc static char* exceptionNames[] = { "no exception", "syscall", "page fault/no TLB entry", "page read only", "bus error", "address error", "overflow", "illegal instruction","PageFaultException" }; 完成==不得不说这是最简单的一个exercise==

Exercise 3 置换算法 为TLB机制实现至少两种置换算法,通过比较不同算法的置换次数可比较算法的优劣。 基础知识:存在tlb和pageTable两种调度机制 pageTable在addrSpace中初始化 ==本来是pageTable[i].virtualPage = i; pageTable[i].physicalPage = i;==但为了适应后面的代码,还是假设为多线程分配【可以参考后面】 而tlb的更新必须依赖于pageTable

首先梳理逻辑: 1:translate.cc的ReadMem()和:WriteMem()调用页,发现缺页 2:exception.cc结束异常 3::machine执行置换算法 4:置换成功,ReadMem()和:WriteMem()重新调用该页 第一步:首先设置ReadMem()和WriteMem()的二次访问。因为在处理完异常后tlb可查找,所以需要再次查找

ReadMem(): if (exception != NoException) { machine->RaiseException(exception, addr); if(exception==TLBFaultException){ exception = Translate(addr, &physicalAddress, size, FALSE); } else return FALSE; } WriteMem() : if (exception != NoException) { machine->RaiseException(exception, addr); if(exception==TLBFaultException){ exception = Translate(addr, &physicalAddress, size, FALSE); } else return FALSE; }

translate.cc:

if(tlb=NULL){---} else { for (entry = NULL, i = 0; i < TLBSize; i++) if (tlb[i].valid && (tlb[i].virtualPage == vpn)) { entry = &tlb[i]; // FOUND! break; } if (entry == NULL) { // not found DEBUG('z', "*** no valid TLB entry found for this virtual page!\n"); return TLBFaultException; // really, this is a TLB fault, // the page may be in memory, // but not in the TLB }

第二步:exception.cc异常访问调用,异常时调用machine->TLBSwap(address);

if (which == TLBFaultException) { int address = machine->ReadRegister(BadVAddrReg); machine->TLBSwap(address); DEBUG('a', "The exception is %d\n",address); }

第三步:写TLBSwap 对于:FIFO,利用tlb[i]的序号,因为越小的序号肯定越早进入,所以当去掉某页时,将序号整体后移即可。最后需要将tlb[TLBSize - 1] = pageTable[i]; machine.h: void TLBSwap(int address) ; machine.cc:

void Machine::TLBSwap(int address) { vpn = (unsigned)address / PageSize; offset = (unsigned)address % PageSize; for (int i = TLBSize - 1; i > 0; i--) { tlb[i] = tlb[i - 1]; } tlb[0].virtualPage = vpn; tlb[0].physicalPage = vpn; tlb[0].valid=TRUE; printf("now the tlb[%d].virtualPage is %d ,the thread's pid is \n",0,vpn); } } }

对于:最久未调用。新设置一个属性time,记录调用时的stats->totalTicks。那我们只要找到最小的time调出即可

void Machine::TLBSwap(int address) { vpn = (unsigned)address / PageSize; offset = (unsigned)address % PageSize; int times = tlb[0].time; int swap=0; int i = 0; for (i = 1; i < TLBSize - 1; i++) { if (tlb[i].time < times) { swap = i; } } for (i = 0; i < numPages; i++) { if (pageTable[i].virtualPage == vpn) { tlb[swap].virtualPage = vpn; tlb[swap].physicalPage = pageTable[i].physicalPage; } break; } tlb[swap].time=stats->totalTicks; }

因为增加了属性,所以我们还需要修改以下地方;

translate.h: class TranslationEntry { public: int virtualPage; // The page number in virtual memory. int physicalPage; // The page number in real memory (relative to the // start of "mainMemory" bool valid; // If this bit is set, the translation is ignored. // (In other words, the entry hasn't been initialized.) bool readOnly; // If this bit is set, the user program is not allowed // to modify the contents of the page. bool use; // This bit is set by the hardware every time the // page is referenced or modified. bool dirty; // This bit is set by the hardware every time the // page is modified. int time; };

translate.cc:对于成功的搜寻,也要改变tlb[i].time=stats->totalTicks;

for (entry = NULL, i = 0; i < TLBSize; i++) if (tlb[i].valid && (tlb[i].virtualPage == vpn)) { entry = &tlb[i]; tlb[i].time=stats->totalTicks; } ``` 验证: 利用test下的已经有的sort.c进行验证,注意需要修改sort.c的文件,源文件中A[1024]修改到A[5],之后也对应修改。==因为内存过小== 第一步:code下整体编译 make 第二部;运行sort文件【仍然是在code下】 userprog/nachos -x test/sort 技巧: 通过Assertion和DEBUG以及printf打印数据从而纠错 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191112101330336.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTY4MDAwNw==,size_16,color_FFFFFF,t_70)
最新回复(0)