CSC468h Tutorial Notes: Week 6 Setting up your own copy of Minotaur: The scripts in include/mutil can be used to set up links to the minotaur source code and make local copies as appropriate. The scripts are: mtsetup -- This is used to create a "minotaur" directory in YOUR own directory that contains symbolic links to the real minotaur files in /local/include/oot/Minotaur. To call this script just type: mtsetup mtcopy -- Since the files in your minotaur directory are links, you can't change these files so you need to create your own copy of any file you want to change. To do this, go to your own minotaur directory and call mtcopy with the name of the file you want a copy of. For example, if you wanted your own copy of the "System" file, you would type: mtcopy System NOTE: if you need local copies of files in a linked directory, you will first need to create a local directory and then relink to the files in that directory. See the file include/mutil/mutil.README for more details. Once you have set up your own minotaur directory, you should run oot in your own directory instead of /local/include/oot/Minotaur. Creating a new system program in your minotaur/sysprogs directory: You will need to write a system program that uses YIELD in order to test A2. System programs are written in the mini turing language. See /local/include/oot/Minotaur/sysprogs/*.mt for some examples. You will need to create your system program file in the minotaur/sysprogs directory in your own copy of Minotaur. First, you'll need make sure that you can write to that directory (by removing the symbolic link for sysprogs, recreating the directory, and then relinking the other files). % cd ~/minotaur % \rm sysprogs % mkdir sysprogs % cd sysprogs % ln -s /local/include/oot/Minotaur/sysprogs ORIG % ln -s ORIG/* ORIG/.[A-z]* . Then create your system program in your minotaur/sysprogs directory. % cp sysprogs/testfork.mt sysprogs/test.mt And compile it using the mini turing program. % cd sysprogs % toot /local/include/oot/mtunis/mturing/mturing test.mt This creates a "test" executable that can be included in the Minotaur file system. Now we need to create a new Minotaur file system (stdfile) that includes the "test" system program. You do this by starting up oot2. Click on mkfs/mkfs in your copy of minotaur in your home directory. Click on Run." It will ask you for the name of the file system to create, and it will go through each program in your sysprogs directory, asking you one at a time if you would like to include them in the file system. The next time you start up Minotaur from your home directory, you'll be able to see this new program when you type 'ls' from the minotaur '%' prompt. At the minotaur prompty, type 'test' to run your program. Changes to System The System file defines a bunch of constants including the system path. This should be changed from %oot/Minotaur to your own path in order to run mkfs. Hints for Assignment 2: 1) Try to understand minotaur well before writing code. This will likely save you time in the long run. 2) Read the documentation and all the code that seems relevant. This will help you achieve #1. Notes on Assignment 2: For this assignment your will have to change Minotaur's scheduling policy to use a two-level feedback queue. Part of this new policy involves implementing a new system call, "Yield". This system call allows a process to be nice and give up its use of the CPU so that another process can run. (See the assignment handout for more details.) Adding A New System Call: To add a new system call you will need to write new minotaur code in oot. The test programs that minotaur runs are written in MiniTuring. MiniTuring programs will not be aware of the new system call you have implemented in oot without further work on your part. To save you trouble, a generic SysCall facility has been implemented which MiniTuring will recognize. This SYSCALL can be used in your MiniTuring test programs to call the new minotaur system call you have written. The call is identified by the trap number you have associated with the new system call. There are more details on the generic syscall facility in the documentation. Processes: There are two main structures associated with a process: the UserStruct and the ProcStruct. UserStruct is used to store information about the cpu state for the given process. It also contains a pointer to the process struct, the fileTable and system call parameters. This structure may be easily obtained for the process which is currently on the CPU. A pointer to the user struct is stored at the same address of virtual address space for each process. The ProcStruct contains information about the process such as its ID and its family relationships. It is also used to store scheduling information and process statistics such as the number of CPU cycles used and the amount of CPU time used in milliseconds. These stucture are kept in the kernel's process table (in Kernel/Process). There is a Dispatch oot process (running the code in Kernel/Dispatch.b) associated with each CPU that picks the next ready process and executes it. There is an oot process associated with each minotaur process. The ProcMon monitor (see Kernel/ProcMon) is used to switch control between the CPU's dispatch process and the user process it wants to run. This ensures that the CPU can run only one process at a time. The Schedule monitor (see Kernel/Schedule) implements the RR ready process queue. The CPU's Dispatch process takes ready processes from this queue and runs them. The processes get put back onto the queue when their timeslice expires, or if they become ready after being blocked on some event. Kernel processes (processes with ProcStruct.Priority = KernelPriority) are placed at the front of the queue. All other processes are placed at the end of the queue. Timeslices As a process' instructions are being executed, they are counted in a counter variable. When the counter reaches the max number of instructions that can be executed in one timeslice, a TRAP is generated. This switches the CPU back into execution of kernel code. The function "Process.Tick" is called to accomplish this. This function also places the process back onto the ready queue. Daemons A daemon process is a "helper" process for the kernel. Daemon processes are run periodically to do some work for the kernel. The module Kernel/Daemons is responsible for managing the minotaur daemons. After each context switch, the procedure Daemons.Tick is called. This procedure wakes up a daemon every couple of times it is called. For example, the only daemon currently used by Minotaur is the Page Daemon which is run every 12 (4 * numProcessors) times Daemons.Tick is called. When a daemon is woken up it is placed on the process ready queue. Since they are kernel processes they are placed at the front of the queue. Tasks for Assignment 2: -- Implement the YIELD system call. -- Change the scheduling from using a global RR ready queue to using two queues. A foreground queue for Kernel processes, new processes, and yielded processes; and a background queue for the rest of the processes. -- Setup minotaur so that the background queue is periodically scanned. Processes that are using less CPU time than the system wide average are moved into the foreground queue.