By now, most people should be working on ASST3.2 The essence of this part is construction of virtual memory support for userspace. The following is essentially a recapitulation of the material in the 4-4 recitation:
(1) What to implement? A virtual memory manager for processes: address space data structures and management code
(2) Where to put code? The stubs of the data structure management routines are already provided (addrspace.c). You will also need to add fault handling code (function prototype in vm.h).
(3) Interface requirements? => See addrspace.h and vm.h.
(4) Tests to run? Lots. 3.2 tests are run from userspace, as with ASST2.x. See the course website, ASST3, Section 6.2.
(5) Existing examples? => The DumbVM memory manager, a bad example
Roughly, the point of ASST3.2 is to implement a virtual memory manager for user processes. (Section 6.2) As before, have the staff review your design and structures before delving into coding. (Section 4)
DATA STRUCTURES: There are a number of them at this point. The coremap (ASST3.1) holds the state of physical memory. This is shared by the entire system; the point of the coremap is to track this usage. Address spaces (ASST3.2) hold the state of virtual memory. Each process has its own individual view of virtual memory and, hence, its own address space.
The address space is, roughly, the top-level structure of virtual memory (see addrspace.h for a structure prototype). It should at a minimum hold two substructures which, depending on the implementation, might be combined. The first of these is memory segment information. Segments, or regions, are groups of potentially valid addresses that have been assigned to the process. Note that the underlying physical memory may not yet have been allocated.
The second data structure, the pagetable, tracks the state of virtual memory as seen by the process. It is a data structure that holds page table entries (PTEs). A PTE is a data structures that holds the state of an individual virtual page.
STRUCTURE MANAGEMENT ROUTINES: See the functions in addrspace.h. There are a bunch of them; read the suggestions below about order of approach.
FAULT HANDLING: Essentially, write vm_fault() from vm.h. The other functions are part of ASST3.1 or ASST3.3. You need to understand the expected behavior or a TLB fault and the underlying mechanics of the TLB. In a nutshell, given a faulting vaddr, you first need to determine whether it is a valid address. If it is, obtain the corresponding physical page paddr.
Study the course website, Sections 2 and 2.1, the recitation VM fault decision tree slides, and TLB management function in arch/mips/include/vm.h. The equivalent code in DumbVM illustrates a per-segment base and bounds approach to vaddr-to-paddr address translation. It also contains a (crippled) approach to updating TLB entries. These need to be replaced with more robust code that uses your new memory data structures. You will need to implement dynamic page allocation (see recitation slides). Because of this, however, you may not need as_prepare_load() or as_complete_load(), as they are used in the static allocation approach by DumbVM.
SUGGESTED APPROACH: A large challenge of ASST3.2 is that, to get any working output, a number of items need to be working. To run a simple single-process Hello World program (“p bin/true”), you will need, in addition to data structures, functional implementations of as_create(), as_define_region() / stack(), as_activate(), and vm_fault(). For good measure, ensure fileonlytest passes.
Next, write as_copy() to support sys_fork() and the console shell. Get forktest working again before moving on. The most straightforward approach to as_copy() is to duplicate immediately existing the existing memory allocations of the source addrspace. Copy on write is a time and space optimization that can help with ASST3.3.
Then write as_destroy(). Clean up all memory leaks.
Finally, write sys_sbrk() to support heap management. This region, which is user managed, should be able both to grow and shrink in size. Additionally, you will need to support both dynamic memory allocation and deallocation for heap memory.
Put KASSERT() statements everywhere in your code.
Until you get to ASST3.3, once pagetables are created, they will not be accessed by any process except their own. Synchronization (except for the coremap) is not an issue until ASST3.3.
It is not necessary to implement segment permissions (read-only etc.) or page status (clean/dirty) at this point. These are optimizations that can be used in ASST3.3.
If possible, try to avoid allocating data structures that are greater than a page (4k). Larger requests will make implementing ASST3.3 much harder.