Move some FAQs into the specification for mmap'd files.
[pintos-anon] / doc / vm.texi
1 @node Project 3--Virtual Memory, Project 4--File Systems, Project 2--User Programs, Top
2 @chapter Project 3: Virtual Memory
3
4 By now you should be familiar with the inner workings of Pintos.  Your
5 OS can properly handle multiple threads of execution with proper
6 synchronization, and can load multiple user programs at once.  However,
7 the number and size of programs that can run is limited by the machine's
8 main memory size.  In this assignment, you will remove that limitation.
9
10 You will build this assignment on top of the last one.  It will benefit
11 you to get your project 2 in good working order before this assignment
12 so those bugs don't keep haunting you.  Test programs from the previous
13 project should also work with this project.
14
15 You will continue to handle Pintos disks and file systems the same way
16 you did in the previous assignment (@pxref{Using the File System}).
17
18 @menu
19 * Project 3 Background::        
20 * Project 3 Requirements::      
21 * Project 3 FAQ::               
22 @end menu
23
24 @node Project 3 Background
25 @section Background
26
27 @menu
28 * Project 3 Source Files::      
29 * Page Faults::                 
30 * Disk as Backing Store::       
31 * Memory Mapped Files Background::  
32 @end menu
33
34 @node Project 3 Source Files
35 @subsection Source Files
36
37 You will work in the @file{vm} directory for this project.  The
38 @file{vm} directory contains only @file{Makefile}s.  The only
39 change from @file{userprog} is that this new @file{Makefile} turns on
40 the setting @option{-DVM}.  All code you write will be in new
41 files or in files introduced in earlier projects.
42
43 You will probably be encountering just a few files for the first time:
44
45 @table @file
46 @item devices/disk.h
47 @itemx devices/disk.c
48 Provides access to the physical disk, abstracting away the rather awful
49 IDE interface.  You will use this interface to access the swap disk.
50 @end table
51
52 @menu
53 * Page Faults::
54 * Disk as Backing Store::
55 * Memory Mapped Files::
56 @end menu
57
58 @node Page Faults
59 @subsection Page Faults
60
61 For the last assignment, whenever a context switch occurred, the new
62 process installed its own page table into the machine.  The new page
63 table contained all the virtual-to-physical translations for the
64 process.  Whenever the processor needed to look up a translation, it
65 consulted the page table.  As long as the process only accessed
66 memory that it owned, all was well.  If the process accessed
67 memory it didn't own, it ``page faulted'' and @func{page_fault}
68 terminated the process.
69
70 When we implement virtual memory, the rules have to change.  A page
71 fault is no longer necessarily an error, since it might only indicate
72 that the page must be brought in from a disk file or from swap.  You
73 will have to implement a more sophisticated page fault handler to
74 handle these cases.
75
76 @menu
77 * Page Table Structure::        
78 * Working with Virtual Addresses::  
79 * Accessed and Dirty Bits::     
80 @end menu
81
82 @node Page Table Structure
83 @subsubsection Page Table Structure
84
85 On the 80@var{x}86, the page table format is fixed by hardware.  We
86 have provided code for managing page tables for you to use in
87 @file{userprog/pagedir.c}.  The functions in there provide an
88 abstract interface to all the page table functionality that you should need
89 to complete the project.  However, you may still find it worthwhile to
90 understand a little about the hardware page table format, so we'll go
91 into a little of detail about that in this section.
92
93 The top-level paging data structure is a page called the ``page
94 directory'' (PD) arranged as an array of 1,024 32-bit page directory
95 entries (PDEs), each of which represents 4 MB of virtual memory.  Each
96 PDE may point to the physical address of another page called a
97 ``page table'' (PT) arranged, similarly, as an array of 1,024
98 32-bit page table entries (PTEs), each of which translates a single 4
99 kB virtual page to a physical page.
100
101 Translation of a virtual address into a physical address follows
102 the three-step process illustrated in the diagram
103 below:@footnote{Actually, virtual to physical translation on the
104 80@var{x}86 architecture occurs via an intermediate ``linear
105 address,'' but Pintos (and most other 80@var{x}86 OSes) set up the CPU
106 so that linear and virtual addresses are one and the same.  Thus, you
107 can effectively ignore this CPU feature.}
108
109 @enumerate 1
110 @item
111 The most-significant 10 bits of the virtual address (bits 22@dots{}32)
112 index the page directory.  If the PDE is marked ``present,'' the
113 physical address of a page table is read from the PDE thus obtained.
114 If the PDE is marked ``not present'' then a page fault occurs.
115
116 @item
117 The next 10 bits of the virtual address (bits 12@dots{}21) index
118 the page table.  If the PTE is marked ``present,'' the physical
119 address of a data page is read from the PTE thus obtained.  If the PTE
120 is marked ``not present'' then a page fault occurs.
121
122 @item
123 The least-significant 12 bits of the virtual address (bits 0@dots{}11)
124 are added to the data page's physical base address, yielding the final
125 physical address.
126 @end enumerate
127
128 @example
129 @group
130  31                  22 21                  12 11                   0
131 +----------------------+----------------------+----------------------+
132 | Page Directory Index |   Page Table Index   |    Page Offset       |
133 +----------------------+----------------------+----------------------+
134              |                    |                     |
135      _______/             _______/                _____/
136     /                    /                       /
137    /    Page Directory  /      Page Table       /    Data Page
138   /     .____________. /     .____________.    /   .____________.
139   |1,023|____________| |1,023|____________|    |   |____________|
140   |1,022|____________| |1,022|____________|    |   |____________|
141   |1,021|____________| |1,021|____________|    \__\|____________|
142   |1,020|____________| |1,020|____________|       /|____________|
143   |     |            | |     |            |        |            |
144   |     |            | \____\|            |_       |            |
145   |     |      .     |      /|      .     | \      |      .     |
146   \____\|      .     |_      |      .     |  |     |      .     |
147        /|      .     | \     |      .     |  |     |      .     |
148         |      .     |  |    |      .     |  |     |      .     |
149         |            |  |    |            |  |     |            |
150         |____________|  |    |____________|  |     |____________|
151        4|____________|  |   4|____________|  |     |____________|
152        3|____________|  |   3|____________|  |     |____________|
153        2|____________|  |   2|____________|  |     |____________|
154        1|____________|  |   1|____________|  |     |____________|
155        0|____________|  \__\0|____________|  \____\|____________|
156                            /                      /
157 @end group
158 @end example
159
160 @node Working with Virtual Addresses
161 @subsubsection Working with Virtual Addresses
162
163 Header @file{threads/mmu.h} has useful functions for various
164 operations on virtual addresses.  You should look over the header
165 yourself.  The most important functions are described below.
166
167 @deftypefun uintptr_t pd_no (const void *@var{va})
168 Returns the page directory index for virtual address @var{va}.
169 @end deftypefun
170
171 @deftypefun uintptr_t pt_no (const void *@var{va})
172 Returns the page table index for virtual address @var{va}.
173 @end deftypefun
174
175 @deftypefun unsigned pg_ofs (const void *@var{va})
176 Returns the page offset of virtual address @var{va}.
177 @end deftypefun
178
179 @deftypefun {void *} pg_round_down (const void *@var{va})
180 Returns @var{va} rounded down to the nearest page boundary, that is,
181 @var{va} with its page offset set to 0.
182 @end deftypefun
183
184 @deftypefun {void *} pg_round_up (const void *@var{va})
185 Returns @var{va} rounded up to the nearest page boundary.
186 @end deftypefun
187
188 @node Accessed and Dirty Bits
189 @subsubsection Accessed and Dirty Bits
190
191 Most of the page table is under the control of the operating system, but
192 two bits in each page table entry are also manipulated by the CPU.  On
193 any read or write to the page referenced by a PTE, the CPU sets the
194 PTE's @dfn{accessed bit} to 1; on any write, the CPU sets the @dfn{dirty
195 bit} to 1.  The CPU never resets these bits to 0, but the OS may do so.
196
197 You will need to use the accessed and dirty bits in your submission to
198 choose which pages to evict from memory and to decide whether evicted
199 pages need to be written to disk.  The page table code in
200 @file{userprog/pagedir.c} provides functions for checking and setting
201 these bits.  These functions are described at the end of this section.
202
203 You need to watch out for @dfn{aliases}, that is, two (or more)
204 different virtual pages that refer to the same physical page frame.
205 When an aliased page is accessed, the accessed and dirty bits are
206 updated in only one page table entry (the one for the virtual address
207 used to access the page).  The accessed and dirty bits for the other
208 aliased virtual addresses are not updated.
209
210 In Pintos, every user virtual page is aliased to its kernel virtual
211 address.  You must manage these aliases somehow.  For example, your code
212 could check and update the accessed and dirty bits for both addresses.
213 Alternatively, the kernel could avoid the problem by only accessing user
214 data through the user virtual address.
215
216 @deftypefun bool pagedir_is_dirty (uint32_t *@var{pd}, const void *@var{vpage})
217 @deftypefunx bool pagedir_is_accessed (uint32_t *@var{pd}, const void *@var{vpage})
218 Returns true if page directory @var{pd} contains a page table entry for
219 virtual page @var{vpage} that is marked dirty (or accessed).  Otherwise,
220 returns false.
221 @end deftypefun
222
223 @deftypefun void pagedir_set_dirty (uint32_t *@var{pd}, const void *@var{vpage}, bool @var{value})
224 @deftypefunx void pagedir_set_accessed (uint32_t *@var{pd}, const void *@var{vpage}, bool @var{value})
225 If page directory @var{pd} has a page table entry for @var{vpage}, then
226 its dirty (or accessed) bit is set to @var{value}.
227 @end deftypefun
228
229 @node Disk as Backing Store
230 @subsection Disk as Backing Store
231
232 VM systems effectively use memory as a cache for disk.  From another
233 perspective, disk is a ``backing store'' for memory.  This provides the
234 abstraction of an (almost) unlimited virtual memory size.  You must
235 implement such a system, with the additional constraint that performance
236 should be close to that provided by physical memory.  You can use dirty
237 bits to tell whether pages need to be written back to disk when they're
238 evicted from main memory, and the accessed bits for page replacement
239 algorithms (@pxref{Accessed and Dirty Bits}).
240
241 As with any caching system, performance depends on the policy used to
242 decide what to keep in the cache and what to evict.  On a page fault,
243 the kernel must decide which page to replace.  Ideally, it will throw
244 out a page that will not be referenced for a long time, keeping in
245 memory those pages that are soon to be referenced.  Another
246 consideration is that if the replaced page has been modified, the page
247 must be first written to disk before the needed page can be brought in.
248 Many virtual memory systems avoid this extra overhead by writing
249 modified pages to disk in advance, so that later page faults can be
250 completed more quickly (but you do not have to implement this
251 optimization).
252
253 @node Memory Mapped Files Background
254 @subsection Memory Mapped Files
255
256 The file system is most commonly accessed with @code{read} and
257 @code{write} system calls.  A secondary interface is to ``map''
258 the file into the virtual address space.  The program can then use load
259 and store instructions directly on the file data.  An alternative view
260 is to see the file system is as ``durable memory'': files just store
261 data structures, so if you access ordinary data structures using normal
262 program instructions, why not access durable data structures the same
263 way?
264
265 Suppose file @file{foo} is @t{0x1000} bytes (4 kB, or one page) long.
266 If @file{foo} is mapped into memory starting at address @t{0x5000}, then
267 any memory accesses to locations @t{0x5000}@dots{}@t{0x5fff} will access
268 the corresponding bytes of @file{foo}.
269
270 A consequence of memory mapped files is that address spaces are
271 sparsely populated with lots of segments, one for each memory mapped
272 file (plus one each for code, data, and stack).
273
274 @node Project 3 Requirements
275 @section Requirements
276
277 This assignment is an open-ended design problem.  We are going to say as
278 little as possible about how to do things.  Instead we will focus on
279 what functionality we require your OS to support.  We will expect
280 you to come up with a design that makes sense.  You will have the
281 freedom to choose how to handle page faults, how to organize the swap
282 disk, how to implement paging, etc.
283
284 @menu
285 * Project 3 Design Document::   
286 * Page Table Management::       
287 * Paging To and From Disk::     
288 * Lazy Loading::                
289 * Stack Growth::                
290 * Memory Mapped Files::         
291 @end menu
292
293 @node Project 3 Design Document
294 @subsection Design Document
295
296 Before you turn in your project, you must copy @uref{vm.tmpl, , the
297 project 3 design document template} into your source tree under the name
298 @file{pintos/src/vm/DESIGNDOC} and fill it in.  We recommend that you
299 read the design document template before you start working on the
300 project.  @xref{Project Documentation}, for a sample design document
301 that goes along with a fictitious project.
302
303 @node Page Table Management
304 @subsection Page Table Management
305
306 Implement page directory and page table management to support virtual
307 memory.  You will need data structures to accomplish the following
308 tasks:
309
310 @itemize @bullet
311 @item
312 Some way of translating in software from virtual page frames to
313 physical page frames.  Pintos provides a hash table that you may find
314 useful for this purpose (@pxref{Hash Table}).
315
316 It is possible to do this translation without adding a new data
317 structure, by modifying the code in @file{userprog/pagedir.c}.  However,
318 if you do that you'll need to carefully study and understand section 3.7
319 in @bibref{IA32-v3}, and in practice it is probably easier to add a new
320 data structure.
321
322 @item
323 Some way of finding a page on disk (in a file or in swap) if it is not
324 in memory.
325
326 You can generalize the virtual-to-physical page table, so that it allows
327 you to locate a page wherever it is in physical memory or on disk, or
328 you can make this a separate table.
329
330 @item
331 Some way of translating from physical page frames back to virtual page
332 frames, so that when you evict a physical page from its frame, you can
333 invalidate its page table entry (or entries).
334 @end itemize
335
336 The page fault handler, @func{page_fault} in
337 @file{threads/exception.c}, needs to do roughly the following:
338
339 @enumerate 1
340 @item
341 Locate the page backing the virtual
342 address that faulted.  It might be in the file system, in swap,
343 or it might be an invalid virtual address.
344 If you implement sharing, it might even
345 already be in physical memory, but not in the page table.
346
347 If the virtual address is invalid, that is, if there's nothing
348 assigned to go there, or if the virtual address is above
349 @code{PHYS_BASE}, meaning that it belongs to the kernel instead of the
350 user, then the process's memory access must be disallowed.  
351 In this case, terminate the process and free all of its resources.
352
353 @item
354 If the page is not in physical memory, fetch it by appropriate means.
355 If necessary to make room, first evict some other page from memory.
356 (When you do that you need to first remove references to the page from
357 any page table that refers to it.)
358
359 @item
360 Point the page table entry for the faulting virtual address to the
361 physical page.  You can use the functions in @file{userprog/pagedir.c}.
362 @end enumerate
363
364 You'll need to modify the ELF loader in @file{userprog/process.c} to
365 do page table management according to your new design.  As supplied,
366 it reads all the process's pages from disk and initializes the page
367 tables for them at the same time.  As a first step, you might
368 want to leave the code that reads the pages from disk, but
369 use your new page table management code to construct the page tables
370 only as page faults occur for them.
371
372 You should use the @func{palloc_get_page} function to get the page
373 frames that you use for storing user virtual pages.  Be sure to pass
374 the @code{PAL_USER} flag to this function when you do so, because that
375 allocates pages from a ``user pool'' separate from the ``kernel pool''
376 that other calls to @func{palloc_get_page} make (@pxref{Why PAL_USER?}).
377
378 You might find the Pintos bitmap code, in @file{lib/kernel/bitmap.c} and
379 @file{lib/kernel/bitmap.h}, useful for tracking pages.  A bitmap is an
380 array of bits, each of which can be true or false.  Bitmaps are
381 typically used to track usage in a set of (identical) resources: if
382 resource @var{n} is in use, then bit @var{n} of the bitmap is true.
383
384 There are many possible ways to implement virtual memory.  The above
385 is simply an outline of our suggested implementation.
386
387 @node Paging To and From Disk
388 @subsection Paging To and From Disk
389
390 Implement paging to and from files and the swap disk.  You may use the
391 disk on interface @code{hd1:1} as the swap disk, using the disk
392 interface prototyped in @code{devices/disk.h}.  From the @file{vm/build}
393 directory, use the command @code{pintos-mkdisk swap.dsk @var{n}} to
394 create an @var{n} MB swap disk named @file{swap.dsk}.  Afterward,
395 @file{swap.dsk} will automatically be attached as @code{hd1:1} when you run
396 @command{pintos}.  Alternatively, you can tell @command{pintos} to
397 use a temporary @var{n}-MB swap disk for a single run with
398 @option{--swap-disk=@var{n}}.
399
400 You will need routines to move a page from memory to disk and from
401 disk to memory, where ``disk'' is either a file or the swap disk.  If
402 you do a good job, your VM should still work when you
403 implement your own file system for the next assignment.
404
405 To fully handle page faults, you will need a way to track pages that
406 are used by a process but which are not in physical memory.  Pages in
407 swap should not be constrained to any particular ordering.  You will
408 also need a way to track physical page frames, to find an unused one
409 when needed, or to evict a page when memory is needed but no empty pages
410 are available.  The page table data structure that you designed should
411 do most of the work for you.
412
413 Implement a global page replacement algorithm.  You should be able to
414 use the ``accessed'' and ``dirty'' bits (@pxref{Accessed and Dirty
415 Bits}) to implement an approximation to LRU.  Your algorithm should
416 perform at least as well as the ``second chance'' or ``clock''
417 algorithm.
418
419 Your design should allow for parallelism.  Multiple processes should
420 be able to process page faults at once.  If one page fault require
421 I/O, in the meantime processes that do not fault should continue
422 executing and other page faults that do not require I/O should be able to
423 complete.  These criteria require some synchronization effort.
424
425 @node Lazy Loading
426 @subsection Lazy Loading
427
428 Since you will already be paging from disk, you should implement a
429 ``lazy'' loading scheme for new processes.  When a process is created,
430 it will not need all of its resources immediately, so it doesn't make
431 sense to load all its code, data, and stack into memory when the process
432 is created.  Instead, bring pages in from
433 the executable only as needed.  Use the
434 executable file itself as backing store for read-only segments, since
435 these segments won't change.  This means that read-only pages should not
436 be written to swap.
437
438 The core of the program loader is the loop in @func{load_segment} in
439 @file{userprog/process.c}.
440 Each time around the loop, @code{read_bytes} receives the number of
441 bytes to read from the executable file and @code{zero_bytes} receives
442 the number of bytes to initialize to zero following the bytes read.  The
443 two always sum to @code{PGSIZE} (4,096).  The handling of a page depends
444 on these variables' values:
445
446 @itemize @bullet
447 @item
448 If @code{read_bytes} equals @code{PGSIZE}, the page should be demand
449 paged from disk on its first access.
450
451 @item
452 If @code{zero_bytes} equals @code{PGSIZE}, the page does not need to
453 be read from disk at all because it is all zeroes.  You should handle
454 such pages by creating a new page consisting of all zeroes at the
455 first page fault.
456
457 @item
458 If neither @code{read_bytes} nor @code{zero_bytes} equals
459 @code{PGSIZE}, then part of the page is to be read from disk and the
460 remainder zeroed.  This is a special case.  You are allowed to handle
461 it by reading the partial page from disk at executable load time and
462 zeroing the rest of the page.  This is the only case in which we will
463 allow you to load a page in a non-``lazy'' fashion.  Many real OSes
464 such as Linux do not load partial pages lazily.
465 @end itemize
466
467 Incidentally, if you have trouble handling the third case above, you
468 can eliminate it temporarily by linking the test programs with a
469 special ``linker script.''  Read @file{Makefile.userprog} for
470 details.  We will not test your submission with this special linker
471 script, so the code you turn in must properly handle all cases.
472
473 @node Stack Growth
474 @subsection Stack Growth
475
476 Implement stack growth.  In project 2, the stack was a single page at
477 the top of the user virtual address space, and programs were limited to
478 that much stack.  Now, if the stack grows past its current size,
479 allocate additional page as necessary.
480
481 Allocate additional pages only if they ``appear'' to be stack accesses.
482 Devise a heuristic that attempts to distinguish stack accesses from
483 other accesses.  You can retrieve the user program's current stack
484 pointer from the @struct{intr_frame}'s @code{esp} member.
485
486 User programs are buggy if they write to the stack below the stack
487 pointer, because typical real OSes may interrupt a process at any time
488 to deliver a ``signal,'' which pushes data on the stack.@footnote{This rule is
489 common but not universal.  One modern exception is the
490 @uref{http://www.x86-64.org/documentation/abi.pdf, @var{x}86-64 System V
491 ABI}, which designates 128 bytes below the stack pointer as a ``red
492 zone'' that may not be modified by signal or interrupt handlers.}
493 However, the 80@var{x}86 @code{PUSH} instruction checks access
494 permissions before it adjusts the stack pointer, so it may cause a page
495 fault 4 bytes below the stack pointer.  (Otherwise, @code{PUSH} would
496 not be restartable in a straightforward fashion.)  Similarly, the
497 @code{PUSHA} instruction pushes 32 bytes at once, so it can fault 32
498 bytes below the stack pointer.
499
500 You may impose some absolute limit on stack size, as do most OSes.
501 (Some OSes make the limit user-adjustable, e.g.@: with the
502 @command{ulimit} command on many Unix systems.)
503
504 The first stack page need not be allocated lazily.  You can initialize
505 it with the command line arguments at load time, with no need to wait
506 for it to be faulted in.  (Even if you did wait, the very first
507 instruction in the user program is likely to be one that faults in the
508 page.)
509
510 @node Memory Mapped Files
511 @subsection Memory Mapped Files
512
513 Implement memory mapped files, including the following system calls.
514
515 @deftypefn {System Call} mapid_t mmap (int @var{fd}, void *@var{addr})
516 Maps the file open as @var{fd} into the process's virtual address
517 space.  The entire file is mapped into consecutive virtual pages
518 starting at @var{addr}.
519
520 If the file's length is not a multiple of @code{PGSIZE}, then some
521 bytes in the final mapped page ``stick out'' beyond the end of the
522 file.  Set these bytes to zero when the page is faulted in from disk,
523 and discard them when the page is written back to disk.
524 A partial page need not be lazily loaded, as in the case of a partial
525 page in an executable (@pxref{Lazy Loading}).
526
527 If successful, this function returns a ``mapping ID'' that
528 uniquely identifies the mapping within the process.  On failure,
529 it must return -1, which otherwise should not be a valid mapping id,
530 and the process's mappings must be unchanged.
531
532 A call to @code{mmap} may fail if the file open as @var{fd} has a
533 length of zero bytes.  It must fail if @var{addr} is not page-aligned
534 or if the range of pages mapped overlaps any existing set of mapped
535 pages, including the stack or pages mapped at executable load time.
536 It must also fail if @var{addr} is 0, because some Pintos code assumes
537 virtual page 0 is not mapped.  Finally, file descriptors 0 and 1,
538 representing console input and output, are not mappable.
539
540 Your VM system should use the @code{mmap}'d file itself as backing
541 store for the mapping.  That is, to evict a page mapped by
542 @code{mmap}, write it to the file it was mapped from.  (In fact, you
543 may choose to implement executable mappings as special, copy-on-write
544 file mappings.)
545 @end deftypefn
546
547 @deftypefn {System Call} void munmap (mapid_t @var{mapping})
548 Unmaps the mapping designated by @var{mapping}, which must be a
549 mapping ID returned by a previous call to @code{mmap} by the same
550 process that has not yet been unmapped.
551 @end deftypefn
552
553 All mappings are implicitly unmapped when a process exits, whether via
554 @code{exit} or by any other means.  When a mapping is unmapped, whether
555 implicitly or explicitly, all pages written to by the process are
556 written back to the file, and pages not written must not be.  The pages
557 are then removed from the process's list of virtual pages.
558
559 Closing or removing a file does not unmap any of its mappings.  Once
560 created, a mapping is valid until @code{munmap} is called or the process
561 exits, following the Unix convention.  @xref{Removing an Open File}, for
562 more information.
563
564 If two or more processes map the same file, there is no requirement that
565 they see consistent data.  Unix handles this by making the two mappings
566 share the same physical page, but the @code{mmap} system call also has
567 an argument allowing the client to specify whether the page is shared or
568 private (i.e.@: copy-on-write).
569
570 @node Project 3 FAQ
571 @section FAQ
572
573 @table @b
574 @item How much code will I need to write?
575
576 Here's a summary of our reference solution, produced by the
577 @command{diffstat} program.  The final row gives total lines inserted
578 and deleted; a changed line counts as both an insertion and a deletion.
579
580 This summary is relative to the Pintos base code, but we started from
581 the reference solution to project 2.  @xref{Project 2 FAQ}, for the
582 summary of project 2.
583
584 @verbatim
585  Makefile.build       |    4 
586  devices/timer.c      |   42 ++
587  threads/init.c       |    5 
588  threads/interrupt.c  |    2 
589  threads/thread.c     |   31 +
590  threads/thread.h     |   37 +-
591  userprog/exception.c |   12 
592  userprog/pagedir.c   |   10 
593  userprog/process.c   |  319 +++++++++++++-----
594  userprog/syscall.c   |  545 ++++++++++++++++++++++++++++++-
595  userprog/syscall.h   |    1 
596  vm/frame.c           |  162 +++++++++
597  vm/frame.h           |   23 +
598  vm/page.c            |  297 ++++++++++++++++
599  vm/page.h            |   50 ++
600  vm/swap.c            |   85 ++++
601  vm/swap.h            |   11 
602  17 files changed, 1532 insertions(+), 104 deletions(-)
603 @end verbatim
604
605 @item Do we need a working HW 2 to implement HW 3?
606
607 Yes.
608
609 @item What extra credit is available?
610
611 You may implement sharing: when multiple processes are created that use
612 the same executable file, share read-only pages among those processes
613 instead of creating separate copies of read-only segments for each
614 process.  If you carefully designed your page table data structures,
615 sharing of read-only pages should not make this part significantly
616 harder.
617
618 @end table
619
620 @menu
621 * Page Table and Paging FAQ::   
622 * Memory Mapped File FAQ::      
623 @end menu
624
625 @node Page Table and Paging FAQ
626 @subsection Page Table and Paging FAQ
627
628 @table @b
629 @item Does the virtual memory system need to support data segment growth?
630
631 No.  The size of the data segment is determined by the linker.  We still
632 have no dynamic allocation in Pintos (although it is possible to
633 ``fake'' it at the user level by using memory-mapped files).  Supporting
634 data segment growth should add little additional complexity to a
635 well-designed system.
636
637 @item Why should I use @code{PAL_USER} for allocating page frames?
638 @anchor{Why PAL_USER?}
639
640 Passing @code{PAL_USER} to @func{palloc_get_page} causes it to allocate
641 memory from the user pool, instead of the main kernel pool.  Running out
642 of pages in the user pool just causes user programs to page, but running
643 out of pages in the kernel pool will cause many failures because so many
644 kernel functions need to obtain memory.
645 You can layer some other allocator on top of @func{palloc_get_page} if
646 you like, but it should be the underlying mechanism.
647
648 Also, you can use the @option{-u} option to @command{pintos} to limit
649 the size of the user pool, which makes it easy to test your VM
650 implementation with various user memory sizes.
651 @end table
652
653 @node Memory Mapped File FAQ
654 @subsection Memory Mapped File FAQ
655
656 @table @b
657 @item How do we interact with memory-mapped files?
658
659 Let's say you want to map a file called @file{foo} into your address
660 space at address @t{0x10000000}. You open the file then use @code{mmap}:
661
662 @example
663 #include <stdio.h>
664 #include <syscall.h>
665
666 int main (void)
667 @{
668     void *addr = (void *) 0x10000000;
669     int fd = open ("foo");
670     mapid_t map = mmap (fd, addr);
671     if (map != -1)
672         printf ("success!\n");
673 @}
674 @end example
675
676 Suppose @file{foo} is a text file and you want to print the first 64
677 bytes on the screen (assuming, of course, that the length of the file
678 is at least 64).  Without @code{mmap}, you'd need to allocate a
679 buffer, use @code{read} to get the data from the file into the buffer,
680 and finally use @code{write} to put the buffer out to the display. But
681 with the file mapped into your address space, you can directly address
682 it like so:
683
684 @example
685 write (addr, 64, STDOUT_FILENO);
686 @end example
687
688 Similarly, if you wanted to replace the first byte of the file,
689 all you need to do is:
690
691 @example
692 addr[0] = 'b';
693 @end example
694
695 When you're done using the memory-mapped file, you simply unmap
696 it:
697
698 @example
699 munmap (map);
700 @end example
701
702 The @command{mcp} program in @file{src/examples} shows how to copy a
703 file using memory-mapped I/O.
704 @end table