mmap()
. While mmap can be (and is) used to allocate large chunks of memory, the more interesting use of mmap() is that of mapping a file into memory. This means, you call mmap once, with a file descriptor as argument, and the file immediately appears in virtual memory.
There are at least two main ways to do this. The first is eager: when mmap is called, have the kernel read the file as instructed, put it somewhere convenient in memory, and return a pointer to the location. The second is lazy: take note of the user's request, and return without doing anything further. When the user tries to access the memory, deal with the resulting page-fault, reading in only those pages that the user tries to read, when the user tries to read them.
git fetch
the latest changes, then checkout the origin/hw4 branch which contains some minimal template code, and some more extensive testing code. To test your solution, rebuild and start xv6, then run eager_mmap
and lazy_mmap
from the xv6 command line.
sys_mmap()
has already been created for you, only it doesn't do much yet. The majority of the homework solution should go here, or in functions called by sys_mmap()
. When you run the test programs lazy_mmap
and eager_mmap
, they crash with the current sys_mmap()
implementation. This is to be expected.
lazy
argument is 0
, sys_mmap()
allocates and maps all the memory needed for the file contents (see allocuvm()
for an example of how to do this, but for the heap), and reads all of the file contents into the newly allocated memory.
For both the eager and the lazy solution, you should map mmap()
regions into addresses 0x40000000 and above - halfway between zero and the kernel area at 0x80000000. You should expect there to be more than one call to mmap()
, so you can't overwrite/reuse any mmap
areas you created in earlier calls. You'll want to store any state you need to keep inside struct proc
.
To test your program, run the user program eager_mmap
which exists in the hw4 branch from the xv6 command line.
lazy
argument is 1
, sys_mmap()
should not allocate or map any memory, nor does it read anything from disk. Instead, it records the request in struct proc
, and returns a pointer immediately. Initially, this pointer points to an unallocated and unmapped part of the virtual address space.
Later, when the process tries to read from or write to the memory area it just mmap
ed, a page fault occurs. You should create page fault handling code (in trap.c, or called from trap.c) that allocates the appropriate page to serve this read/write, and fills the page with the appropriate contents from the file. To figure out what address the program tried to access, just read the CR2 register. There is a handy helper function for this, called rcr2()
, defined in x86.h.
To test your program, run the user program lazy_mmap
. The hw4 template has a modification to exit()
, that prints out the number of system free pages before exiting. The lazy solution should have about 17 more free pages than the eager solution. A full sample of the correct solution output is provided below.
$ eager_mmap About to make first mmap. Next, you should see the first sentence from README xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6) Second mmap coming xv6 @ UIC ROCKS!!! Exiting process. System free pages is 56761 $ lazy_mmap About to make first mmap. Next, you should see the first sentence from README xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6) Second mmap coming xv6 @ UIC ROCKS!!! Exiting process. System free pages is 56778
Copyright 2016 The Board of Trustees of the University of Illinois.webmaster@cs.uic.edu |
WISEST Helping Women Faculty Advance Funded by NSF | ![]() | ![]() |