Hints for A3

This file may be updated, so check back periodically.


Quick Topic Links


Getting Started

When you reconfigure your kernel for Assignment 3, major changes will be made that will prevent your kernel from compiling. These changes include:

If you look at addrspace.c you will find empty skeletons for the addrspace methods. They used to be implemented in dumbvm.c, which is no longer being compiled. The idea is that you should put your new implementations of those functions into addrspace.c

The best way to get started on A3 is to first get back to where you can compile and run your kernel, and then start to implement the requirements for A3. If you don't do this, you will will not be able to test your A3 work incrementally as you get it done, and you'll be left with a huge mess to test at the end - almost a guarantee of testing and debugging nightmares.

One way to get started is to simply copy the implementations of the addrspace functions from dumbvm.c to addrspace.c. You will also need implementations of the other functions from dumbvm.c (like the fault handler, vm_fault and the various low level VM and physical memory functions, such as vm_bootstrap and getppages). You can either add a separate file to hold these functions, or you can simply copy them into addrspace.c as well. Finally, you will need to patch up the addrspace structure in addrspace.h so that the fields that went away when OPT_DUMBVM stopped being defined will be present again. Once you've made these changes, make sure that you can build your kernel and that things that ran after A2 continue to run.

Once you have done this, you can start working on the various parts of A3. Since you have a working kernel, you should be able to test each part of A3 as you build it.


Synchronization


Handling TLB Faults


as_copy


Testing


I didn't get the A2 system calls working. What can I do?

Most of the testing for A3 will involve only writes to the console and _exit. If you have at least that functionality working from A2, you can work with that, and you can ignore the rest of this section.

If you do not even have console writes and _exit working from A2, you can use the following instructions for a quick-and-dirty implementation of those two system calls. These implementations don't do much (in particular, this _exit simply reboots the machine) but it is enough to support most of the A3 testing.

First, modify the function mips_syscall(struct trapframe *tf) in kern/arch/mips/mips/syscall.c as shown below. Note that you may need to include some header files for this to compile.

mips_syscall(struct trapframe *tf)

  ...

  switch (callno) {
    case SYS_reboot:
      err = sys_reboot(tf->tf_a0);
      break;

    /* BEGIN NEW CODE ------------------------------------------- */
    /* NEW: Simple code to handle writes to console */
    /*   this *only* works for writing null-terminated */
    /*   strings, which should be sufficient to handle */
    /*   printf()s in the application code */
    case SYS_write:
      /* check that the write is to stdout */
      assert(tf->tf_a0 == STDOUT_FILENO);
      kprintf("%s", (char *) tf->tf_a1);
      retval = strlen((char *) tf->tf_a1);
      break;

    /* NEW: Simple code to handle _exit call */
    /* 
    case SYS__exit:
      thread_exit(); /* NOTE: need to modify thread_exit(); */
      break;         /* may require #include <thread.h> */
    /* END NEW CODE ------------------------------------------- */

    /* don't forget to comment out or otherwise disable */
    /* any existing implementation of SYS_write and */
    /* SYS__exit that you may have */

    default:
      kprintf("Unknown syscall %d\n", callno);
      err = ENOSYS;
      break;
  }
Next, in kern/thread/thread.c , modify the thread_exit function:
void
thread_exit(void)
{
  /* BEGIN NEW CODE ------------------------------------------- */
  /* NEW: just shut everything down */
  extern int sys_reboot(int code);
  sys_reboot(RB_POWEROFF); /* may require #include <kern/unistd.h> */
  /* END NEW CODE ------------------------------------------- */

  /* leave everything else here */

  ...
Finally, in kern/arch/mips/mips/trap.c, modify kill_curthread so that thread_exit will get called.
void
kill_curthread(u_int32_t epc, unsigned code, u_int32_t vaddr)
{
   /* BEGIN NEW CODE ------------------------------------------- */
   /* New: if the current thread gets killed */
   thread_exit();         /* may require #include <thread.h> */
   /* END NEW CODE ------------------------------------------- */

   ...