QUESTION 1: (60 points) XV6.
Part A: Use the debugger
Follow the instructions on how to debug XV6 from here. Submit a screenshot of your debugger
(gdb or the vscode debugger will be accepted) in a file called partA.png or partA.jpg. If you are
using the class VM, or Vital, make sure your screenshot takes up the entire VM window not just
Now we will set a breakpoint in the system call that allocates memory. The call that
user-processes use in xv6 to allocate memory is called `sbrk()`; it’s kernel-mode
implementation is `sys_sbrk()` in `sysproc.c`. Set a breakpoint on the first line inside this
function. Then answer the following questions when you submit your patch:
1. Run a user process like: ‘ls’
2. What is the value of `n` when your breakpoint gets hit?
2. Print out the stackframe (backtrace) for this call.
Part B: Removing Eager Allocation
Change `sys_sbrk()` so that it just adjusts `proc->sz` and returns the old `proc->sz` (i.e.,
remove the call to `growproc()`).
After rebuilding xv6, try running a command like `echo hello`:
init: starting sh
$ echo hello
pid 3 sh: trap 14 err 6 on cpu 0 eip 0x12bb addr 0x4004–kill proc
What went wrong, and why? (Answering this question is not part of the assignment, just think
Part C: Implementing Lazy Allocation
The message above comes from the `trap()` function in `trap.c`. It indicates that an exception
(number 14, which corresponds to a page fault on x86) was raised by the CPU; it happened
when `eip` (the program counter) was `0x12bb`, and the faulting address was `0x4004`. It then
kills the process by setting `proc->killed` to 1. Can you find in the code in trap.c where that
happened? (Answering this question is not part of the assignment either, just getting you
familiar with the code)
Add code to `trap()` to recognize this particular exception and allocate and map the page
Once you have implemented the allocation, try running `echo hello` again. It should work
1. The constant `T_PGFLT`, defined in `traps.h`, corresponds to the exception number for a
2. The virtual address of the address that triggered the fault is available in the `cr2` register; xv6
provides the `rcr2()` function to read its value.
3. Look at the code in `allocuvm()` to see how to allocate a page of memory and map it to a
specific user address.
4. Remember that the first access might be in the middle of the page, and so you’ll have to
round down to the nearest PGSIZE bytes. xv6 has a handy function called `PGROUNDDOWN`
you can use for this.
5. You will need to use the `mappages()` function, which is declared as `static`, meaning it can’t
be seen from other C files. You’ll need to make it non-static, and then add its
[prototype](https://en.wikipedia.org/wiki/Function_prototype) to some header file that is included
by both `trap.c` and `vm.c` (`defs.h` is a good choice).
Part D: Handling Some Edge Cases
Although simple commands like `echo` work now, there are still some things that are broken.
For example, try running `cat README`. Depending on how you implemented Part 2, you may
init: starting sh
$ cat README
unexpected trap 14 from cpu 1 eip 80105282 (cr2=0x3000)
cpu1: panic: trap
8010683a 801064fa 80101f4e 80101174 80105725 8010556a 801066f9
801064fa 0 0
Why is this happening? Debug the problem and find a fix (if this part works already, you don’t
need to make any changes).
Next, let’s see if pipes work, by running `cat README.md | grep the`