210 likes | 428 Views
Nachos System Calls. Tingxin Yan 3/31/2010. Setup MIPS x -compiler. Make sure you are done with it! Come to my office hour tomorrow if you still have problems. Recap Nachos MIPS Machine. User programs C code Compiled to COFF binaries (equivalent to .exe in windows).
E N D
Nachos System Calls Tingxin Yan 3/31/2010
Setup MIPS x-compiler • Make sure you are done with it! • Come to my office hour tomorrow if you still have problems.
Recap Nachos MIPS Machine • User programs • C code • Compiled to COFF binaries (equivalent to .exe in windows). • Two things are needed in this Lab: • Multiprogramming • System calls
Recap System Call • What are some system calls? • I/O: open, close, read, write, lseek • Files: delete, mkdir, rmdir, truncate, chown, chgrp, .. • Process: exec, join(wait), exit…
Argument Passing • System Call argument passing: • In registers (not very much can be passed) • Write into user memory, kernel copies into kernel memory • User addresses must be translated! • Kernel has different view of memory than user • Nachos Example • r2: The code for the system call • r4,r5,r6 - arg1 to arg3 • The return value is in r2.
Nachos File System • Nachos file system is implemented in Machine.stubFileSystem • Only kernel can access it. • It means you can • User programs cannot. If they want to access file system, use system calls. • System calls to implement • Create/Open/Read/Write/Close/Unlink(delete)
Some Hints • Take create file as an example: • In User Program, it is create(string filename) • But in kernel system call handler, it is handleCreate(int a0) • a0 is the register that points to the address of the string filename. • You need to use the following method to access the string: readVirtualMemoryString(a0, MAX_LEN);
Some Hints (2) • Access to file system: • Call function Machine.stubFileSystem(); • It returns a pointer to the stub file system Nachos uses. • Then you can call the open() primitive of the file system to actually create a file. • You also need to register the file created • You need to have a data structure that stores all the files that are opened, and add the created file to open file list.
Process Management Syscall • exit: terminate the current process immediately. • exec: execute the program stored in the specified file, with the specified arguments, in a new child process. • join: suspend execution of the current process until the child process specified by the processID argument has exited.
Exec() handler • Exec() input • a0 - the command name(e.g. ‘cp’) • a1- argc, number of parameters. • a2- argv[] - parameter array. • What you need to do: • read in a0. • Directly using readVirtualMemoryString() • a1 is there. • read in a2: • first read in addresses of parameters, using readVirtualMemory(), • then read in actual parameter, using readVirtualMemoryString() • create a UserProcess, set it as child of current process, pass name and parameters, and fork it(by calling execute()).
Join() handler • Meaning of join() here – • Unlike KThread.join(), only a process's parent can join to it. For instance, if A executes B and B executes C, A is not allowed to join to C, but B is allowed to join to C. • A call of join() suspend execution of the current process until the child process specified by the processID argument has exited. • What you need to do – • Handle Join() takes two parameters – a0 and a1. • a0 is the pid of the process that is to joined. • You need to first check if a0 is a child process. • Once you joined to a child process, the parent-child relation no longer exists, so you need to remove a0 from you child process list. • get the pid of the child process, join to it.
Join() handler continued • handle post-join status • Write the join result to a1. • How to write a value to a register? • Nachos SIZE_OF_INT is 4. • Write a 4 bytes array to the register. • The order is reversed in java and MIPS. • SO, byte[] status = reverseBytes(ByteBuffer.allocate(4).putInt(statusInt).array()); writeVirtualMemory(a1,status);
Exit() handler • close all open files • by calling handleClose that you implemented. • remove link to parent process, and pass exit status to parent process. • clear page table • by calling unloadSections(). • decrease running process counter by 1. • Terminate • If it is the last running process, call Kernel.kernel.terminate(); • Otherwise call Uthread.finish()
Support multiprogramming(1) • Share the memory! • To simplify things • User program has its fixed amount of memory allocated when initiated (8 pages maximum). • Maintain available memory pages • Keep in mind that memory pages might not be allocated continuously… • For example, a Linkedlist… • How to access shared resource? • Locks/semaphores/CVs
Some Hints… • In UserKernel: • Initiate the memory management data structure. • Method to allocated X pages to a user program • Check if free memory is enough. • Return a list of free memory pages. • Method to free pages allocated to a user program • Add pages back to free pages pool. • Locks! • Which operations are atomic?
Support multiprogramming(2) • Paging Memory • Users can only see virtual memory; • Kernel allocate physical memory pages; • Need a transition. • Note - virtual memory across page boundaries.
More Detailed Hints… • In UserProcess: • Modify readVirtualMemory() and writeVirtualMemory() • readVirtualMemory() gives start point of virtual memory and length of the memory chunk • Figure out start and end page according to the start point and length. • Hint: start page number = start point of virtual memory /page size • Copy each page to physical address. • writeVirtualMemory() – similar case.
More Detailed Hints continued… • In UserProcess: • Modify loadSections() • Adding a page table data structure before load sections operations. • In load section part, you need to define if each page is read only or not in load section part. (required in the problem specification…)