cs50300:fall16:lab0

By the end of this lab students will be able to:

  • Log onto a XINU Lab workstation, download, extract, and compile a copy of the XINU source
  • View the status of existing XINU backends
  • Load a built XINU image onto a XINU backend and successfully boot the image
  • Modify the source for XINU to start several processes that print messages to the console

To use Xinu, several environment variables must be set. First log onto one of the frontends xinu01.cs.purdue.edu, xinu02.cs.purdue.edu, …, xinu21.cs.purdue.edu which are Linux PCs. For remote login see task 5. To login you should be able to use your career account user and password. If you have any trouble with your account and its setup, please see the department help pages at http://www.cs.purdue.edu/help. If these pages do not address your particular problem, please use the trouble command from the command line to report the problem.

The following assumes that your shell is bash. The syntax may vary slightly if you use a different shell. (Run 'echo $0'; to determine your current shell.)

Setting environment variables for Xinu:

  1. Edit your .bashrc in your home directory by adding /p/xinu/bin to your path: export PATH=${PATH}:/p/xinu/bin
  2. Run source .bashrc (or its equivalent) to make the change take effect.

Accessing and untar-ing Xinu tarball source files:

  1. Change to your home directory, if you are not already in it.
  2. Unpack: tar zxvf /u/u3/cs503/xinu/xinu-fall2016-lab0.tar.gz
  3. In your home directory, you will now have a directory called xinu-fall2016-lab0. The sub-directories under this directory contain source code, header files, configuration files, and Makefile for compiling XINU.

To compile the XINU kernel which will be loaded and executed on a backend machine, run make in the compile directory:

cd xinu-fall2016-lab0/compile
make

This creates an executable file called xinu.

The executable XINU binary runs on a selected backend machine. We have 96 dedicated backends: galileo101.cs.purdue.edu, …, galileo196.cs.purdue.edu.

The backends are all Intel Galileo development boards which run the quark system on chip processor.

The backend machines are shared resources. When a backend machine is grabbed by a student, it is dedicated for use by that student to run his/her version of XINU. To see which backends are available for booting XINU, type:

cs-status -c quark

This will show you who is using each backend and how long they have been using it. As with all hardware, sometimes they fail and may become unavailable until repaired by our technical staff.

To boot your copy of XINU on a backend, connect to a back-end by issuing the command:

cs-console [galileo1__]

With no arguments cs-console will connect you to the first available backend.

To load your copy of XINU onto the backend:

(control-@) OR (control-spacebar)     //esc to local command-mode

(command-mode) d    //download command

file: xinu     //tell it to download 'xinu' (this example assumes that you are in the xinu-fall2016-lab0/compile directory)

(control-@) OR (control-spacebar)    //esc to local command-mode 

(command-mode) p    //power cycle the backend

After several seconds, XINU should boot with a 'Welcome to Xinu!' message that looks something like this:

Xinu for galileo -- version #3  (rkarandi)  Thu Aug 28 18:28:38 EDT 2014

 250113568 bytes of free memory.  Free list:
           [0x001531E0 to 0x0EFD8FFF]
           [0x0FDEF000 to 0x0FDEFFFF]
     79624 bytes of Xinu code.
           [0x00100000 to 0x00113707]
    131496 bytes of data.
           [0x00117100 to 0x001372A7]

...initializing network stack
...using dhcp to obtain an IP address

IP address is 128.10.3.101   (0x800a0365)
Subnet mask is 255.255.255.0 and router is 128.10.3.250

...creating a shell


------------------------------------------
   __    __   _____    _   _    _    _
   \ \  / /  |__ __|  | \ | |  | |  | |
    \ \/ /     | |    |  \| |  | |  | |
    / /\ \    _| |_   | \   |  | |  | |
   / /  \ \  |     |  | | \ |  \  --  /
   --    --   -----    -   -     ----
------------------------------------------


Welcome to Xinu!


xsh $

To disconnect and free up the backend:

(control-@) OR (control-spacebar)

(command-mode) p    //power cycle the backend

(control-@) OR (control-spacebar)

(command-mode) q    //quit

NOTE: Please do not leave a running copy of your XINU on a backend. This will prevent others from using that backend.

  1. We only show the mapping from bash to tcsh. If you use other shell types, please contact the TAs. The mapping is as follows:
    1. Edit .cshrc instead of .bashrc
    2. Add a line setenv PATH ${PATH}:/p/xinu/bin instead of export PATH=${PATH}:/p/xinu/bin
    3. Run tcsh instead of source .bashrc
  2. Try to figure out what's going on by yourself. Oftentimes the steps described above were not precisely followed.
  3. When your XINU executable misbehaves or crashes (i.e., does not do what you intended when programming the kernel) then debug the problem(s) and try again. Since your version of the Xinu kernel runs over dedicated hardware, you are in full control. That is, there are no hidden side effects introduced by other software layers that you are not privy to. By the same token, everything rests on your shoulders.
  4. If you get repeatedly stuck with Booting XINU on … please contact the TAs.
  5. If you are not able to get a free backend, please contact the TAs.

Use of the backends is limited to implementing, testing, and evaluating lab assignments of CS 503. To access the backends, you don't have to be physically present in the XINU lab but may remote login using ssh to one of the lab's frontend machines.

By default, when XINU boots up, it runs a shell (xsh). To view all the usable shell commands, run the help command:

xsh $ help

shell commands are:

argecho      date         help         memstat      udp          ?            
arp          devdump      ipaddr       ping         udpecho      
cat          echo         kill         ps           udpeserver   
clear        exit         memdump      sleep        uptime 

Take a moment to run some shell commands and view their output. Specifically make sure you run the ps command which lists information about running processes.

xsh $ ps
Pid Name             State Prio Ppid Stack Base Stack Ptr  Stack Size
--- ---------------- ----- ---- ---- ---------- ---------- ----------
  0 prnull           ready    0    0 0x0EFDEFFC 0x0EFDEEC0     8192
  1 rdsproc          wait   200    0 0x0EFDCFFC 0x0EFDCAAC    16384
  2 Main process     recv    20    0 0x0EFD8FFC 0x0EFD8F64    65536
  3 shell            recv    50    2 0x0EFC8FFC 0x0EFC8C6C     8192
  4 ps               curr    20    3 0x0EFC6FFC 0x0EFC6E18     8192

Here you can see the several pieces of information for all processes currently running. The name gives some detail about what the process is intended for. XINU always contains a special process with process identifier (pid) 0 called the null process (or prnull). This process is the first process created by XINU and is always ready to execute. The inclusion of this process ensures that there is always something for XINU to execute even if all other processes have finished or are waiting for something. It behaves similar to the 'System Idle Process' in the Windows Operating System.

The code for the first user process that is created by XINU is located in system/main.c. The code by default creates a single process to execute the XINU shell. The code to create the shell process looks like this:

kprintf("Creating shell...\n\r");
resume(create(shell, 4096, 1, "shell", 1, CONSOLE));
retval = recvclr();
while (TRUE) {
        retval = receive();
        kprintf("\n\n\rMain process recreating shell\n\n\r");
        resume(create(shell, 4096, 1, "shell", 1, CONSOLE));
}

Processes in XINU are created using the create system call which does the following:

  1. Creates all necessary control structures for the new process
  2. Initializes the process stack for the new process

The create system call returns the process identifier (PID) for the new processes. The code for the create system call is located in create.c. Open system/create.c and familiarize yourself with what it does. Here is a summary of the create call along with its parameters:

/*------------------------------------------------------------------------
 *  create, newpid  -  Create a process to start running a procedure
 *------------------------------------------------------------------------
 */
pid32   create(
          void          *funcaddr,      /* address of function to run   */
          uint32        ssize,          /* stack size in bytes          */
          pri16         priority,       /* process priority             */
          char          *name,          /* process name (for debugging) */
          uint32        nargs,          /* number of args that follow   */
          ...
        )

The call to create in main.c creates a new process to execute the code located in the shell function.

  • The stack size is set to 4096 bytes
  • The priority is set to 1 (the larger the number the higher the priority)
  • The name of the process is set to "shell"
  • There is 1 argument sent to the shell function: the value of CONSOLE

NOTE: when a process is created, it is not automatically executed. The status of the process must be changed to ready. This is done by using the resume system call which takes as input the processed identifier. This tells XINU that the processes is ready to execute on the CPU.

Create the following function at the top of main.c:

void myprocess(int a) {
        kprintf("Hello world %d\n", a);
}

Remove the code in main.c that creates a shell process and replace it with the following:

resume(create(myprocess, 4096, 50, "helloworld", 1, 1));
while(TRUE) {
        // Do nothing
}

Compile a new xinu image, download it to your backend, and power cycle the backend.

Once XINU boots up, you should see the message “Hello world” printed to the console.

Add some additional calls to create and resume to create several processes that call the myprocess function.

resume(create(myprocess, 4096, 50, "helloworld1", 1, 1));
resume(create(myprocess, 4096, 50, "helloworld2", 1, 2));
resume(create(myprocess, 4096, 50, "helloworld3", 1, 3));
resume(create(myprocess, 4096, 50, "helloworld4", 1, 4));
resume(create(myprocess, 4096, 50, "helloworld5", 1, 5));
while(TRUE) {
        // Do nothing
}

Compile, load, and run this new code. You should see multiple messages printed to the console (one for each process).

The process scheduler in XINU uses a very simple rule for deciding which process to run. Each process gets a set time to run on the CPU before it gets context switched for another process. XINU always chooses to execute the highest priority process that is ready to run.

Create another function in the main.c file that contains the following code:

void myhungryprocess(void) {
        kprintf("I'm a looping process\n");
        while(TRUE) {
                // Do nothing forever
        }
}

Now modify your existing code in the main function to call the new process, but give it a high priority:

resume(create(myhungryprocess, 4096, 1000, "hungryprocess", 0));
resume(create(myprocess, 4096, 50, "helloworld1", 1, 1));
resume(create(myprocess, 4096, 50, "helloworld2", 1, 2));
resume(create(myprocess, 4096, 50, "helloworld3", 1, 3));
resume(create(myprocess, 4096, 50, "helloworld4", 1, 4));
while(TRUE) {
        // Do nothing
}

What do you observe when you run this on a XINU backend?

Since XINU always chooses the highest priority processes that is ready to run and all 5 of the processes created are ready, then the hungry process with priority 1000 gets to execute on the CPU. From that point on, every time the XINU scheduler runs, it chooses the hungry process to run and no other processes get to execute.

Furthermore, take a look at initialize.c. This file contains the code that creates the process to run the main function. What priority is main created with? Given main's priority in the example above does main get to run after hungryprocess is created?

Familiarize yourself with setting priorities of various processes. Take a look at the output from the ps command to see the priorities for the processes created by XINU at startup.

See your teaching assistant for additional activities and challenges.

  • cs50300/fall16/lab0.txt
  • Last modified: 2016/08/24 14:30
  • by lembkej