CS 111 section 2Scribe notes for 4/17/2007by Keith Stevens and Alex TicerCalling the KernelHow to call the kernelMethod 1Treat any method calls as a simple function call. This is a very simple implementation and provides fast responses from the kernel. Unfortunatly this gives the application the same level of power as the kernal since the kernel's functionality is nothing more than a set of library calls. With this much power given to the application, it is more capable of producing malicious behaviour. This approach is best used in embedded systems where the applications well inspected and well controlled prior to being installed. Method 2This method will use interupts to switch control over to the kernel. Ordinary functions can function at full speed when performing standard operations, such as adding, multiplying, loading/storing from the applications local memory, etc. When an application needs the a service provided by the Kernel it will cause an interupt in the hardware which will then be serviced by the kernel. The kernel will maintain a table of interupt handlers which designates what actions to take based on the specific interupt number recieved. For example on the X86 processors the command INT 25 will produce an interupt to be sent from the CPU with and interupt handler 25 will take control. The advantages of this approach are that it hands all control over to the kernel since only the kernel will decide how to respond to interupts, not the application. Unfortunately this method is slower than Method 1 since interupts can occur at any time, the interupt handler must a larger amount of information than a function call requires. What can go wrong with this approach
File AccessEach process has it's own unique file descriptor table, which can be used by the process but is maintained inside the kernel. This allows each process to modify which files it can read or write from without affecting any other process. the contents of each entry in the file descriptor table points to a System wide file table which only the kernel has access to. Standard File Descriptor Entries
Below is an example of how redirection of a file descriptor might be implemented. Example: sort>/tmp/foo
However, this doesn't work because the file descriptor 0 might be available. Open() works such that it returns -1 on failure and otherwise the number of the lowest available file descriptor. The use of the function dup2(int old_fd, int new_fd) is required. It will make a copy of the old file descriptor and return the int new_fd upon success. Thus, now they are pointing to the same file but if an error occurs it returns -1. No operation occurs if old_fd == new_fd and old_fd is a file descriptor number. Instead use this style
This should solve most of the problems that might occur because it checks to make sure the function opened and didn't have an error. If PipesPipes are used to link the output of one process to the input of another process while keeping these processes completely seperate. An example of piping commands together is given below: $ du | sort -n
This is a general overview of what is taking place. From the parent shell a fork is done. This splits the parent shell and process A. In the parent it will call Process AInside process A, in this case Possible code for setting up process A:
if(pipe_fds[0] !=0){
Process BInside process B, in this case Possible code for setting up process B:
if(pipe_fds[1] !=0){
Diagram of File Descriptor Tables and Pipe SetupThings to consider:Normally if What if the parent is slow and the children are really fast?Thus, by the time the parent looks to |