Exercise

In this exercise, we trace KThread.selfTest() to study the boot process of Nachos. This and the next exercise will help one prepare for the thread and synchronization project. Besides manually going through the source codes, the best way to trace Nachos code is to use break points and the debug mode in Eclipse.

Let us start with the nacho.machine.Machine.Main method – the entry point of the boot process. The config file used is in the Project 1 directory.

1  Machine.stubFileSystem = false
2  Machine.processor = false
3  Machine.console = false
4  Machine.disk = false
5  Machine.bank = false
6  Machine.networkLink = false
7  ElevatorBank.allowElevatorGUI = true
8  NachosSecurityManager.fullySecure = false
9  ThreadedKernel.scheduler = nachos.threads.RoundRobinScheduler
10  Kernel.kernel = nachos.threads.ThreadedKernel

The nacho.machine.Machine.Main method is given below:

1   public static void main(final String[] args) {
2   ...
3   processArgs();
4  
5   Config.load(configFileName);
6  
7   ...
8   createDevices();
9  
10   ...
11   autoGrader = (AutoGrader) Lib.constructObject(autoGraderClassName);
12  
13   new TCB().start(new Runnable() {
14   public void run() {
15   autoGrader.start(privilege);
16   }
17   });
18   }

In Line 3, processArgs() processes all command lines arguments. Line 5 reads parameters specified in the configure file. In Line 8, devices are initialized including interrupt, timer, and elevator bank, processor, console, file system and network link as specified by the config file1 . The number of pages in the main memory is specified to create the processor.

Question:
  1. Using the config file given above, what is the number of physical pages in the main memory?
  2. Why is not any processor object created in this example? How can Nachos simulate a machine without any processor?

In Line 13 – 17 of the nacho.machine.Machine.Main method, a new thread control block object TCB is created with a Runnable object, which if run will create a new Java thread and execute the autoGrader’s start method with a specific privilege.

1   public void nachos.ag.AutoGrader.start(Privilege privilege) {
2   Lib.assert(this.privilege == null, "start() called multiple times");
3   this.privilege = privilege;
4  
5   String[] args = Machine.getCommandLineArguments();
6  
7   extractArguments(args);
8  
9   ...
10  
11   init();
12  
13   ...
14   kernel = (Kernel) Lib
15   .constructObject(Config.getString("Kernel.kernel"));
16   kernel.initialize(args);
17  
18   run();
19   }

In AutoGrader.start, Line 7 extracts command line inputs specific to the autograder (See Section 2). Further initialization codes can be included by overriding init() called in Line 11. Finally, the specific kernel object is created and initialized. Since in the config file we choose nachos.threads.ThreadedKernel, its respective initialize method will be called. The method creates a scheduler, the first thread, and an alarm, and enables interrupts. It creates a file system if necessary. Up until the creation of the first thread (Line 16 of nachos.thread.ThreadedKernel.initialize), like any other single-threaded Java program, Nachos code is executing on the initial Java thread created automatically for it by Java. Afterwards, Nachos manages its own thread for kernel or user processes. Threads are the basic unit of execution. More detailed discussion on Nachos threads can be found in Section 4.

1   public void nachos.thread.ThreadedKernel.initialize(String[] args) {
2   // set scheduler
3   String schedulerName = Config.getString("ThreadedKernel.scheduler");
4   scheduler = (Scheduler) Lib.constructObject(schedulerName);
5  
6   // set fileSystem
7   String fileSystemName = Config.getString("ThreadedKernel.fileSystem");
8   if (fileSystemName != null)
9   fileSystem = (FileSystem) Lib.constructObject(fileSystemName);
10   else if (Machine.stubFileSystem() != null)
11   fileSystem = Machine.stubFileSystem();
12   else
13   fileSystem = null;
14  
15   // start threading
16   new KThread(null);
17  
18   alarm = new Alarm();
19  
20   Machine.interrupt().enable();
21   }

Line 18 in AutoGrader.start runs the kernel selfTest, executes and terminates the kernel. After kernel termination, the machine halts.

1   void run() {
2   kernel.selfTest();
3   kernel.run();
4   kernel.terminate();
5   }
Question: Provide a snapshot of the outputs from Nachos running the config file in Project 1. Compare the results when running it multiple times. Are they all the same? Why?