Outline TTIT61: Process Programming and Operating Systems Alexandru Andrei alean@ida.liu.se phone: 282698, room: B 3D:439 Lab 2 : System Calls Introduction to – and – making user programs in Nachos User memory vs Kernel memory in Nachos File & Console related syscalls Synchronizing kernel functions and data structures Lab 3 : Memory Management & System Calls 3.1 Memory management with linear page tables Multiprogramming - multiple user processes Page tables Process handling 3.2 Memory management with software TLB alean@ida -2- TTIT61 Lab lesson System Calls Four Components of a Computer System #include <stdio.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> /* System calls are written in bold italic. Type “man 2 sys_call_name” for info in Linux or “man –s 2 sys_call_name” in Solaris */ int fd, n; char buf[1024]; fd = open(“datafile.txt”, O_RDWR); n = read(fd, buf, 1024); printf(“Have read %d bytes: %s\n”, n, buf); lseek(fd, 0, SEEK_SET); write(fd, “Some other text”, strlen(“Some other text”) + 1); write(fd, buf, n); close(fd); alean@ida -3- TTIT61 Lab lesson alean@ida -4- TTIT61 Lab lesson User Programs System Call Execution Located in the Nachos directory: code/test/ Compiled with cross-compiler to MIPS machine code (see code/test/Makefile) MIPS is a RISC architecture, with delayed loads Cross compile – compile in one machine for a different target machine Emulation – runs on MIPS simulator Class Machine emulates the MIPS processor alean@ida -5- TTIT61 Lab lesson alean@ida -6- TTIT61 Lab lesson 1 User Program - Example User Programs (cont.) Simple C programs (any C program that doesn’t use library functions like printf) In nachos-3.4/code/test For a new test program, add it to the Makefile from nachos-3.4/code/test alean@ida TTIT61 Lab lesson -7- Test Program Makefile In code/testprogram/Makefile Use copy paste to add another testprogram #include ”syscall.h” void main(void) { int file_id; char a[10]; for (i=0;i<=8;i++) a[i]=’a’; a[9]=’\0’; Create(a); file_id = Open(a); Write(”some text”, 10, file_id); Close(file_id); Halt(); } alean@ida The User Space Definition of the Syscall Functions .globl Create .ent addiu $2,$0,SC_Create syscall j $31 .end Create start.o: start.s ../userprog/syscall.h $(CPP) $(CPPFLAGS) start.s > strt.s $(AS) $(ASFLAGS) -o start.o strt.s rm strt.s TAB (not spaces) alean@ida Create Create: all: halt shell matmult sort halt.o: halt.c $(CC) $(CFLAGS) -c halt.c halt: halt.o start.o $(LD) $(LDFLAGS) start.o halt.o -o halt.coff ../bin/coff2noff halt.coff halt TTIT61 Lab lesson -9- TTIT61 Lab lesson -8- code/test/start.s .globl Open .ent Open Open: addiu $2,$0,SC_Open syscall j $31 .end Open alean@ida TTIT61 Lab lesson -10- Program Execution Under the Hood The MIPS processor fetches instructions from memory and executes them one by one void Machine::Run() { // code/machine/mipssim.cc Instruction *instr = new Instruction; How does Nachos execute the binary code How does Nachos execute system calls interrupt->setStatus(UserMode); for (;;) { OneInstruction(instr); interrupt->OneTick(); } } alean@ida -11- TTIT61 Lab lesson alean@ida -12- TTIT61 Lab lesson 2 OneInstruction() (cont.) OneInstruction() void Machine::OneInstruction(Instruction *instr){ int raw; int nextLoadReg = 0; int nextLoadValue = 0; if (!machine->ReadMem(registers[PCReg],4,&raw)) return; // exception occurred instr->value = raw; instr->Decode(); pcAfter = registers[NextPCReg] + 4; switch (instr->opCode) { Ænextslide alean@ida switch case case case TTIT61 Lab lesson -13- (instr->opCode) { OP_ADD: … OP_DIV: … OP_SYSCALL: RaiseException(SyscallException, 0); return; alean@ida -14- TTIT61 Lab lesson Exception Handling: System Calls RaiseException() The processor has detected an exception and passes the control to the operating system for exception handling void Machine::RaiseException(//code/machine/machine.cc ExceptionType which, int badVAddr){ DEBUG('m', "Exception: %s\n", exceptionNames[which]); registers[BadVAddrReg] = badVAddr; DelayedLoad(0, 0); // finish anything in progress interrupt->setStatus(SystemMode); ExceptionHandler(which); //interrupts are enabled at this point interrupt->setStatus(UserMode); // code/userprog/exception.cc 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); } } alean@ida -15- TTIT61 Lab lesson alean@ida Exception Handling: System Calls void ExceptionHandler(ExceptionType which) { int type = machine->ReadRegister(2); if ((which == SyscallException)) { switch (type) { case SC_Halt: { { break; break; break; -17- TTIT61 Lab lesson Exception Handling: System Calls The list of the system call ids (the value from register 2) is in the file code/userprog/syscall.h DEBUG('a', "Shutdown, initiated by user program.\n"); interrupt->Halt(); } case SC_Create: //your code; } case SC_Open: { //your code; } case SC_Read: { //your code; } …. } //end of switch }//end if } alean@ida -16- TTIT61 Lab lesson For example: #define SC_Halt #define SC_Exit #define SC_Exec #define SC_Join #define SC_Create #define SC_Open #define SC_Read #define SC_Write #define SC_Length #define SC_Close alean@ida 0 1 2 3 4 5 6 7 8 9 -18- TTIT61 Lab lesson 3 Exception Handling: System Calls ”syscall” machine code instruction The system call id is stored in register 2 The arguments of the syscall are stored in the registers, starting with register 4 arg1 -- r4, arg2 -- r5, etc. System calls return values in reg. r2 see …/code/test/start.s ExceptionHandler see …/code/userprog/exception.cc SC_Halt already implemented The list of the system calls is in the file code/userprog/syscall.h void Write(char *buffer, int size, OpenFileId id); int Read(char *buffer, int size, OpenFileId id); void Close(int fileid); OpenFileId Open(char *filename); void Exit(int status); SpaceId Exec(char *name); int Join(SpaceId id); void Halt(); alean@ida -19- System Calls and Exception Handling TTIT61 Lab lesson alean@ida Exception Handling: System Calls -20- TTIT61 Lab lesson Two Types of Arguments void ExceptionHandler(ExceptionType which) { … switch (type) { case SC_Create: //read from register 4 the argument //use machine->ReadRegister(4); //create the file //does not return any value //if it would return, it should write //the return value in register 2 break; } … alean@ida -21- TTIT61 Lab lesson Arguments passed by value void Exit(int status); case SC_EXIT: int status=machine->ReadRegister(4); Arguments passed by address (pointers) void Create(char *filename); case SC_EXIT: int address_of_pointer=machine->ReadRegister(4); alean@ida -22- User Programs&User Memory Process1: char buffer[10] Create(buffer); Process2: char buffer[10] Open(buffer); 0000 0004 0008 0000 FFFF Kernel Process 1 AAA0 0000 AAA4 FFFF Process 2 FFFF Memory TTIT61 Lab lesson Important ! User space vs. Kernel Space User address vs. Kernel Address Pointer arguments passed to system calls must be translated to/from user space Example: Create(char* filename) -> UserToKernel Read(char* buf, int size, OpenFileId id) -> KernelToUser Virtual memory vs. Phisycal memory alean@ida -23- TTIT61 Lab lesson alean@ida -24- TTIT61 Lab lesson 4 UserToKernel void UserToKernel(void) { //buffer allocated in kernel space; we copy here //the content of buffer from the user program char* filename = new char[100]; //address int address = machine->ReadRegister(4); i=0; for (;;) { int data; machine->ReadMem(address + i, 1, &data); filename[i] = data; if (filename[i]==’\0’) break; i++; } } alean@ida -25- machine->ReadMem machine->ReadMem(address ,n_of_bytes, &data) Translates internally the virtual address address to a physical address, reads n_of_bytes from that address and stores them in the variable data machine->WriteMem also available in Nachos TTIT61 Lab lesson alean@ida -26- OpenFile FileSystem class FileSystem { TTIT61 Lab lesson // code/filesys/filesys.h class OpenFile { public: FileSystem(bool format) {} // code/filesys/openfile.h public: OpenFile(int f) { file = f; currentOffset = 0; } bool Create(char *name, int initialSize) { ~OpenFile() { Close(file); } int fileDescriptor = OpenForWrite(name); if (fileDescriptor == -1) return FALSE; close(fileDescriptor); return TRUE; int Read(char *into, int numBytes) { … } } OpenFile* Open(char *name) { int Write(char *from, int numBytes) { int fileDescriptor = OpenForReadWrite(name, FALSE); … } …… if (fileDescriptor == -1) return NULL; return new OpenFile(fileDescriptor); } } bool Remove(char *name) { return Unlink(name) == 0; } }; alean@ida -27- TTIT61 Lab lesson alean@ida -28- Exception Handling: System Calls TTIT61 Lab lesson Assignment 2 void ExceptionHandler(ExceptionType which) { … switch (type) { case SC_Create: char k_filename[20]; UserToKernel(k_filename); fileSystem->Create(k_filename); break; } … alean@ida -29- TTIT61 Lab lesson Implement and test the system calls related to file & console operations alean@ida -30- TTIT61 Lab lesson 5 Why OpenFileID ? System Calls for File Operations File operations (lab 2) void Create(char* filename) Create an empty file OpenFileId Open(char *filename) open file for read/write int Read(char* buf, int size, OpenFileId id) read from an open file void Write(char* buf, int size, OpenFileId id) write to an open file void Close(int fileid) Close an open file See code/userprog/syscall.h for the list alean@ida -31- #include ”syscall.h” void main(void) { int file_id; char a[10]; for (i=0;i<=8;i++) a[i]=’a’; a[9]=’\0’; Create(a); //a is the name of the file file_id = Open(a); //a is the name of the file Write(”some text”, 10, file_id); //file_id is the OpenFileId Close(file_id); //file_id is the OpenFileId Halt(); } TTIT61 Lab lesson alean@ida File Related System Calls OpenFileId (an integer) Global unique id for each open file ConsoleInput (o_id==0) and ConsoleOutput (o_id==1) The operating system keeps a list of open files Read and Write on an open file or on the Console must be choosen based on the OpenFileId if (o_id>=2) then file; else console; The actual file operations are handled by the FileSystem and OpenFile alean@ida -33- TTIT61 Lab lesson TTIT61 Lab lesson -32- List of Open Files Implement in the kernel a list of files that are open For each open file, store in the list: OpenFileId (this could be the index of your list) OpenFile pointer Pointer to the thread that opened the file (currentThread) ... Open and Close system calls append and remove files from this list alean@ida TTIT61 Lab lesson -34- Console Console Internals Console class constructor: The Console class handles reading/writing from/to the console at the char level One object with type Console must be used throughout Nachos void PutChar(char ch) char GetChar() TODO: introduce the possibility to read/write strings (char* or char[]) ie. synchronize the console operations alean@ida -35- TTIT61 Lab lesson Console( char *readFile, char *writeFile, VoidFunctionPtr readAvail, VoidFunctionPtr writeDone, int callArg ); alean@ida -36- TTIT61 Lab lesson 6 Console Internals void ReadAvail(int arg) {…} void WriteDone(int arg) {…} console = new Console(NULL,NULL,ReadAvail,WriteDone,0); An example of a console implementation is given in: code/userprog/progtest.cc Hint: use two semaphores to signal the availability of an input character (for Read) and the finishing of a char writing (for Write) alean@ida -37- TTIT61 Lab lesson TODO: System Calls for File Operations (Lab2) File operations (lab 2) void Create(char* filename) Create an empty file OpenFileId Open(char *filename) open file for read/write int Read(char* buf, int size, OpenFileId id) void Write(char* buf, int size, OpenFileId id) void Close(int fileid) See …/code/userprog/syscall.h for details Compile and run nachos always in code/userprog directory Test programs implemented and compiled in code/test directory alean@ida Nachos Syscalls Info Read ”Road Map through Nachos” Machine: section 2.1 – 2.4 Examine exception handling in machine/mipssim.cc (RaiseException) machine.cc (Machine::RaiseException) Userprog/exception.cc (ExceptionHandler) System calls ”prototypes” in syscall.h FileSystem and OpenFile: 5.2 – 5.3 User Level Processes: Section 4 alean@ida -39- TTIT61 Lab lesson -38- Nachos Syscalls Info (cont) Source files: Working dir. is ../code/userprog Central files for assignment ”Exception.cc” contains ExceptionHandler function syscall.h - definitions and constants for system calls Files necessary for understanding how Nachos works Progtest.cc – test routines, how to load & execute user prog. Example of running Nachos with a user program: ¾nachos –x <user_program_name> ¾E.g.: ../userprog/nachos –x ../test/halt /machine/machine.* - how MIPS emulator works alean@ida -40- In code/userprog: addrspace.h, addrspace.cc data structures to keep track of executing user programs (address spaces) In code/machine: translate.cc ¾data structures for managing translation from virtual page # -> physical page # ¾used for managing memory on behalf of user programs mipssim.cc (ReadMem, Writemem, Translate, and OneInstruction) -41- TTIT61 Lab lesson TTIT61 Lab lesson Lab 3 Nachos Syscalls Info (cont.) alean@ida TTIT61 Lab lesson Memory Management Linear Page Table TLB alean@ida -42- TTIT61 Lab lesson 7 Lab 3 - Memory Management User Programs Multiprogramming Several processes (user programs) reside in memory at the same time Exec Exit Join Reside in user address space Communication with the kernel through system calls (open file, read, write, start a new process, etc.) Only one user program in the lab #2 alean@ida TTIT61 Lab lesson -43- alean@ida -44- Example 1 /*test2.c*/ #include ”syscall.h” void main(void) { Write(”test2”,5,1); Exit(1); } /*test1.c*/ #include ”syscall.h” void main(void) { Write(”test1”,5,1); Exec(”test2”); Exit(1); } alean@ida -45- TTIT61 Lab lesson Example 2 /*test1.c*/ #include ”syscall.h” void main(void) { int x,s; Write(”test1”,5,1); x=Exec(”test2”); s=Join(x;) Write(”test2 exited with status”,s,1); Exit(1); } alean@ida /*test2.c*/ #include ”syscall.h” void main(void) { Write(”test2”,5,1); Exit(2); } -46- Lab 3 -47- TTIT61 Lab lesson User Level Processes When starting a user program Create an address space (memory for the process) Copy the content of the instructions’ and initialized variable segments into the address space. Associate a new kernel thread to the process Uninitialized variable section are not read from the file (as it contains all 0’s). Memory Management Linear Page Table TLB alean@ida TTIT61 Lab lesson TTIT61 Lab lesson alean@ida -48- TTIT61 Lab lesson 8 Memory Organization Lab 3 - Page tables in lab 3 machine.h: #define PageSize SectorSize #define NumPhysPages 32 //CHANGE IT ! #define MemorySize (NumPhysPages * PageSize) Memory 0 Process1 2 Pages •Page number •Same size •Allocation unit for a process 3 4 5 Physical Memory 0 1 2 3 1 Virtual Memory (virtual pages) ? Process2 0 1 2 0 1 2 3 4 5 6 7 Physical pages machine.h contains the details regarding the memory size, number of pages, page size, etc. alean@ida TTIT61 Lab lesson -49- alean@ida Lab 3 - Page tables in lab 3 Process1 0 1 2 3 pgTable1 0 1 2 3 0 1 2 3 4 5 6 7 pgTable2 Process2 0 1 2 0 1 2 Physical Memory 4 1 0 3 2 5 6 alean@ida Lab 3 - Page tables in lab 3 Process1 is running now The machine page table points to the page table of Process1 Process1 0 1 2 3 TTIT61 Lab lesson 0 1 2 alean@ida Process2 is running now The machine page table points to the page table of Process2 Process1 pgTable1 0 1 2 3 0 1 2 alean@ida Physical Memory pgTable 0 1 2 pgTable2 Process2 0 1 2 4 1 0 3 2 5 6 -53- 2 5 6 0 1 2 3 4 5 6 7 TTIT61 Lab lesson 4 1 0 3 pgTable2 Process2 Physical Memory pgTable 0 1 2 3 4 1 0 3 2 5 6 -52- 0 1 2 3 4 5 6 7 TTIT61 Lab lesson Lab 3 - Memory Management Lab 3 - Page tables in lab 3 0 1 2 3 pgTable1 0 1 2 3 0 1 2 -51- TTIT61 Lab lesson -50- Multiprogramming Several processes (user programs) reside in memory at the same time machine->pageTable contains the pageTable of the current thread’s (process) address space One address space (class AddrSpace) object for each process Different page table for each process currentThread->space points to the current AddrSpace A pageTable inside the AddrSpace object: translation of virtual address to physical address alean@ida -54- TTIT61 Lab lesson 9 AddrSpace::RestoreState() void AddrSpace::RestoreState() { machine->pageTable = pageTable; machine->pageTableSize = numPages; } Called by Nachos at every context switch alean@ida -55- AddrSpace AddrSpace::AddrSpace(OpenFile *executable, SpaceId id) { NoffHeader noffH; unsigned int size; //reading the noffH.code.size, //noffH.initData.size//noffH.uninitData.size from the Nachos executable file // how big is address space? size = noffH.code.size + noffH.initData.size + noffH.uninitData.size + UserStackSize; // we need to increase the size // to leave room for the stack numPages = divRoundUp(size, PageSize); size = numPages * PageSize; ASSERT(numPages <= NumPhysPages); TTIT61 Lab lesson alean@ida -56- AddrSpace AddrSpace::AddrSpace(OpenFile *executable, SpaceId id) { ... pageTable = new TranslationEntry[numPages]; for (i = 0; i < numPages; i++) { // for now, virtual page = phys page pageTable[i].virtualPage = i; pageTable[i].physicalPage = i; pageTable[i].valid = TRUE; pageTable[i].use = FALSE; pageTable[i].dirty = FALSE; pageTable[i].readOnly = FALSE; } .... (continues on the next slide) alean@ida -57- Allocating the Address Space Address spaces (AddrSpace object) AddrSpace constructor allocates memory pages In lab 2 all memory is assigned to one address space In lab 3 several address spaces will exist Use a BitMap object to keep track of free pages BitMap(int nitems)// total number of items Mark // mark (allocate) a position Clear // clear (free) a position Test // check if a position is marked Find // find a free position and mark it bitmap.h, bitmap.cc TTIT61 Lab lesson alean@ida -58- AddrSpace AddrSpace::AddrSpace(OpenFile *executable, SpaceId id) { ... pageTable = new TranslationEntry[numPages]; for (i = 0; i < numPages; i++) { //now, virtual page != phys page !!! pageTable[i].virtualPage = i; pageTable[i].physicalPage = xxx //USE THE BITMAP pageTable[i].valid = TRUE; pageTable[i].use = FALSE; pageTable[i].dirty = FALSE; pageTable[i].readOnly = FALSE; } .... alean@ida -59- TTIT61 Lab lesson TTIT61 Lab lesson TTIT61 Lab lesson At This Point ... ...you have reserved the required memory space for each process Process1 0 1 2 3 pgTable1 0 1 2 3 0 1 2 alean@ida 0 1 2 3 4 5 6 7 pgTable2 Process2 0 1 2 Physical Memory 4 1 0 3 2 5 6 -60- TTIT61 Lab lesson 10 Now, Load the Binary Code AddrSpace AddrSpace::AddrSpace(OpenFile *executable, SpaceId id) { ... pageTable = new TranslationEntry[numPages]; ... //CHANGE HERE if (noffH.code.size > 0) { executable->ReadAt(&(machine->mainMemory[noffH.code.virtualAddr]), noffH.code.size, noffH.code.inFileAddr); } if (noffH.initData.size > 0) { executable->ReadAt(&(machine>mainMemory[noffH.initData.virtualAddr]), noffH.initData.size, noffH.initData.inFileAddr); } }//done AddrSpace alean@ida -61- TTIT61 Lab lesson alean@ida -62- Lab 3 - Address spaces Process Creation (Exec) Nachos process are formed by: Create a new thread Creating an address space associated to the thread Allocating physical memory for the AddrSpace Load content of executable into the physical memory Initialize registers and address translation tables Invoke machine::Run() to start executing. machine::Run() turns on the simulated MIPS machine that enters into an infinite loop, executing one instruction at a time. progtest.cc to see an example alean@ida -63- TTIT61 Lab lesson AddrSpace constructor Takes an executable (filename) Allocates memory, sets up page table Amount of memory needed is stored in noff-header Loads the executable Noff binary format, noff header NoffHeader object stored in the beginning of the file Three Segment objects in the header alean@ida -64- Noff Executable Format Noff: Nachos Object File Format Compare with coff(Unix), com, exe (DOS) Noff consists of four parts Noff header (information concerning segments below) Code segment – program residence Initialized variables segment Unitialized variables segment alean@ida -65- TTIT61 Lab lesson TTIT61 Lab lesson TTIT61 Lab lesson Noff Format (cont) Noff: header information concerning segments below Describe content of the rest of the file, giving information about programs’s instructions, initialized and uninitialized variables noffMagic: Noff format check (4 bytes) Reserved number indicating that the file is in Noff format For each of the remaining sections Nachos maintains virtualAddr: segment’s starting address in virtual memory inFileAddr: start of the segment in Noff file Size: size of the segment alean@ida -66- TTIT61 Lab lesson 11 Lab 3 - Address Space Address Spaces Segments: code the executable machine code initData initialized data (constant strings etc) uninitData Declared but unassigned data (empty arrays etc). Not stored in the file. alean@ida -67- TTIT61 Lab lesson The Segment object: virtualAddr start address of segment in the address space inFileAddr offset of segment in the file size size of the segment alean@ida Memory Management 1: Linear Page Tables TODO: Allocate/Deallocate physical pages (addrspace) Setting translation tables Implement Exec, Exit (and optionally Join) Tests: Simultaneously running user programs Using pre-emptive switches between threads alean@ida -69- TTIT61 Lab lesson TTIT61 Lab lesson -68- TODO: Lab 3 System Calls for Exit & Join Implement at least on the following system calls int Join(SpaceId id) Wait for the process with id id to exit Return the exit status of that process void Exit(int status) exits the calling user process returns ”status” to the parent process (Select 2 syscalls between Exec, Exit, Join) alean@ida TTIT61 Lab lesson -70- Lab 3 Translation Look-Aside Buffer frame page offset CPU frame offset TLB Memory Management Linear Page Table TLB TLB hit TLB miss page { Memory Page table alean@ida -71- TTIT61 Lab lesson alean@ida -72- TTIT61 Lab lesson 12 TLB RestoreState: Invalidate the TLB void AddrSpace::RestoreState() { #ifdef USE_TLB //machine->pageTable = pageTable; //machine->pageTableSize = numPages; Is a hardware device Is an associative memory, i.e. it is not addressed by address but by data Instead of “show me the house at number 10”, you say “show me the house where the Simpson’s live”, i.e. instead of “give the 5th entry in the TLB”, you say “give me the entry in the TLB that corresponds to virtual page X” int i; printf("using TLB\n"); for (i=0;i<TLBSize;i++) { machine->tlb[i].valid=FALSE; } What happens to the context of the TLB upon a context switch? Invalidate all its entries ! alean@ida -73- #endif } TTIT61 Lab lesson alean@ida Exception Handling: TLB Fault TLB Upon a TLB miss, a new page table entry is copied in the TLB If all TLB entries are occupied, one of them must be replaced Replacement algorithms: Random, Least Recently Used (LRU), Round-Robin, etc. alean@ida -75- TTIT61 Lab lesson // code/userprog/exception.cc 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(); } if (which == PageFaultException){ //Page fault handling } alean@ida -76- Handling a Page Fault Bring the faulty page in the TLB If there is a free entry in the TLB, bring the faulty page in that entry (free TLB entry: machine->tlb[i].valid==FALSE) machine->tlb[i].physicalPage=currentThread->space>pageTable[faulty_page].physicalPage; machine->tlb[i].virtualPage=currentThread->space>pageTable[faulty_page].virtuallPage; Otherwise select from the TLB an entry and replace it with the faulty page Make sure that you will not have two consecutinve TLB misses resulting from the same page ! Round robin TLB page replacement ? alean@ida -77- TTIT61 Lab lesson TTIT61 Lab lesson -74- TTIT61 Lab lesson ReadMem & WriteMem ReadMem and WriteMem return TRUE if the operation succeeded and FALSE otherwise In case of a page fault when doing ReadMem or WriteMem inside a system call, you need to call again Read/WriteMem #ifdef USE_TLB while (machine->ReadMem(userAddr, 1, &c)==FALSE); userAddr++; #else machine->ReadMem(userAddr++, 1, &c); alean@ida -78- TTIT61 Lab lesson 13 code/vm directory Compile and run nachos from the code/vm directory ! Test the TLB implementation by running the same tests you did for the linear page table alean@ida -79- TTIT61 Lab lesson 14