Skip to main content

Lab 3: Virtual Memory

Due: October 15 @ 11:59 PM

In this lab you'll be managing page tables and simulating what happens when a process forks. You'll be given code that simulates the MMU, and code that can modify page table entries (PTEs) without low-level C code. You'll implement two fork strategies: one that creates a new page table and copies all page tables, and another that creates a new page table and uses a copy-on-write optimization. We'll be using the Sv39 multi-level page table design as discussed in the lectures.

Setup

Ensure you're in the ece344 directory within VSCode. Make sure you have the latest skeleton code from us by running: git pull upstream main.

This will create a merge, which you should be able to do cleanly. If you don't know how to do this read Pro Git. Be sure to read chapter 3.1 and 3.2 fully. This is how software developers coordinate and work together in large projects. For this course, you should always merge to maintain proper history between yourself and the provided repository. You should never rebase in this course, and in general you should never rebase unless you have a good reason to. It will be important to keep your code up-to-date during this lab as the test cases may change with your help.

You can finally run: cd vms to begin the lab.

First Step

After you build you'll have a build/vms executable. The source code for this executable is in src/main.c and is meant for you to test your code and experiment easily. It sets up page tables such that virtual address 0xABC123 is valid. You should read src/main.c and understand the library functions it uses from include/vms.h.

Task

Only modify src/vms.c.

You'll have to implement two library functions in vms.h: first vms_fork_copy() and then vms_fork_copy_on_write(). Both functions should return a new L2 page table that's set up as if the currently running process calls fork (you should call vms_get_root_page_table()).

vms_fork_copy_on_write() is independent of the non copy-on-write version, and will be trickier to get correct. You'll have to take advantage of handling page faults through implementing page_fault_handler in src/vms.c. In this function you may modify the faulting PTE and make it valid. After the MMU generates a page fault, it will re-try the operation once. If the MMU generates a page fault again, your process will exit with the EFAULT error code. You'll also be able to use a bit in the PTE for whatever purpose you would like. You can access it through vms_pte_custom (it also has clear and set like the other bits). Finally, you'll want to keep track of the number of references to some pages. You may take advantage of the defined values in pages.h and that the system will not create more pages (assume it represents physical memory which does not change).

Errors

You need to check for and properly handle errors. For fatal errors, you should exit with the errno of the first fatal error. However, your implementation should not generate errors

Building

First, make sure you're in the vms directory if you're not already. After, run the following commands:

meson setup build
meson compile -C build

Whenever you make changes, you can run the compile command again. You should only need to run setup once.

Testing

You cannot execute your library directly, however you can run the test programs manually. Please find the files in tests/*.c. You should be able to read and understand what they're doing with your library. You'll find the executables in build/tests/*.

You may also choose to run the test suite provided with the command:

meson test --print-errorlogs -C build

Grading

Run the ./grade.py script in the directory. This will rebuild your program, run the tests, and give you a grade out of 100 based on your test results. Note that these test cases may not be complete, more may be added before the due date, or there may be hidden test cases. These labs are new, so we may need to change.

Tips

Carefully review the multi-level page table lecture, and draw a diagram of how the page tables look for the example given to you in src/main.c. You should be able to make any virtual address valid to read and write to.

Aside from what's given in the description of the task, you should have everything except memcpy. That should be the only library function you need. Otherwise, please read vms.h and understand src/main.c.

Submission

Simply push your code using git push origin main (or simply git push) to submit it. You need to create your own commits to push, you can use as many as you'd like. You'll need to use the git add and git commit commands. You may push as many commits as you want, your latest commit that modifies the lab files counts as your submission. For submission time we will only look at the timestamp on our server. We will never use your commit times (or file access times) as proof of submission, only when you push your code to the course Git server.