Clarify stack limit.
[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 Other aliases should only arise if you implement sharing, as extra
217 credit (@pxref{VM Extra Credit}), or as bugs elsewhere in your code.
218
219 @deftypefun bool pagedir_is_dirty (uint32_t *@var{pd}, const void *@var{vpage})
220 @deftypefunx bool pagedir_is_accessed (uint32_t *@var{pd}, const void *@var{vpage})
221 Returns true if page directory @var{pd} contains a page table entry for
222 virtual page @var{vpage} that is marked dirty (or accessed).  Otherwise,
223 returns false.
224 @end deftypefun
225
226 @deftypefun void pagedir_set_dirty (uint32_t *@var{pd}, const void *@var{vpage}, bool @var{value})
227 @deftypefunx void pagedir_set_accessed (uint32_t *@var{pd}, const void *@var{vpage}, bool @var{value})
228 If page directory @var{pd} has a page table entry for @var{vpage}, then
229 its dirty (or accessed) bit is set to @var{value}.
230 @end deftypefun
231
232 @node Disk as Backing Store
233 @subsection Disk as Backing Store
234
235 VM systems effectively use memory as a cache for disk.  From another
236 perspective, disk is a ``backing store'' for memory.  This provides the
237 abstraction of an (almost) unlimited virtual memory size.  You must
238 implement such a system, with the additional constraint that performance
239 should be close to that provided by physical memory.  You can use dirty
240 bits to tell whether pages need to be written back to disk when they're
241 evicted from main memory, and the accessed bits for page replacement
242 algorithms (@pxref{Accessed and Dirty Bits}).
243
244 As with any caching system, performance depends on the policy used to
245 decide what to keep in the cache and what to evict.  On a page fault,
246 the kernel must decide which page to replace.  Ideally, it will throw
247 out a page that will not be referenced for a long time, keeping in
248 memory those pages that are soon to be referenced.  Another
249 consideration is that if the replaced page has been modified, the page
250 must be first written to disk before the needed page can be brought in.
251 Many virtual memory systems avoid this extra overhead by writing
252 modified pages to disk in advance, so that later page faults can be
253 completed more quickly (but you do not have to implement this
254 optimization).
255
256 @node Memory Mapped Files Background
257 @subsection Memory Mapped Files
258
259 The file system is most commonly accessed with @code{read} and
260 @code{write} system calls.  A secondary interface is to ``map''
261 the file into the virtual address space.  The program can then use load
262 and store instructions directly on the file data.  An alternative view
263 is to see the file system is as ``durable memory'': files just store
264 data structures, so if you access ordinary data structures using normal
265 program instructions, why not access durable data structures the same
266 way?
267
268 Suppose file @file{foo} is @t{0x1000} bytes (4 kB, or one page) long.
269 If @file{foo} is mapped into memory starting at address @t{0x5000}, then
270 any memory accesses to locations @t{0x5000}@dots{}@t{0x5fff} will access
271 the corresponding bytes of @file{foo}.
272
273 A consequence of memory mapped files is that address spaces are
274 sparsely populated with lots of segments, one for each memory mapped
275 file (plus one each for code, data, and stack).
276
277 @node Project 3 Requirements
278 @section Requirements
279
280 This assignment is an open-ended design problem.  We are going to say as
281 little as possible about how to do things.  Instead we will focus on
282 what functionality we require your OS to support.  We will expect
283 you to come up with a design that makes sense.  You will have the
284 freedom to choose how to handle page faults, how to organize the swap
285 disk, how to implement paging, etc.
286
287 @menu
288 * Project 3 Design Document::   
289 * Page Table Management::       
290 * Paging To and From Disk::     
291 * Lazy Loading::                
292 * Stack Growth::                
293 * Memory Mapped Files::         
294 @end menu
295
296 @node Project 3 Design Document
297 @subsection Design Document
298
299 Before you turn in your project, you must copy @uref{vm.tmpl, , the
300 project 3 design document template} into your source tree under the name
301 @file{pintos/src/vm/DESIGNDOC} and fill it in.  We recommend that you
302 read the design document template before you start working on the
303 project.  @xref{Project Documentation}, for a sample design document
304 that goes along with a fictitious project.
305
306 @node Page Table Management
307 @subsection Page Table Management
308
309 Implement page directory and page table management to support virtual
310 memory.  You will need data structures to accomplish the following
311 tasks:
312
313 @itemize @bullet
314 @item
315 Some way of translating in software from virtual page frames to
316 physical page frames.  Pintos provides a hash table that you may find
317 useful for this purpose (@pxref{Hash Table}).
318
319 It is possible to do this translation without adding a new data
320 structure, by modifying the code in @file{userprog/pagedir.c}.  However,
321 if you do that you'll need to carefully study and understand section 3.7
322 in @bibref{IA32-v3}, and in practice it is probably easier to add a new
323 data structure.
324
325 @item
326 Some way of finding a page on disk (in a file or in swap) if it is not
327 in memory.
328
329 You can generalize the virtual-to-physical page table, so that it allows
330 you to locate a page wherever it is in physical memory or on disk, or
331 you can make this a separate table.
332
333 @item
334 Some way of translating from physical page frames back to virtual page
335 frames, so that when you evict a physical page from its frame, you can
336 invalidate its page table entry (or entries).
337 @end itemize
338
339 The page fault handler, @func{page_fault} in
340 @file{threads/exception.c}, needs to do roughly the following:
341
342 @enumerate 1
343 @item
344 Locate the page backing the virtual
345 address that faulted.  It might be in the file system, in swap,
346 or it might be an invalid virtual address.
347 If you implement sharing, it might even
348 already be in physical memory, but not in the page table.
349
350 If the virtual address is invalid, that is, if there's nothing
351 assigned to go there, or if the virtual address is above
352 @code{PHYS_BASE}, meaning that it belongs to the kernel instead of the
353 user, then the process's memory access must be disallowed.  
354 In this case, terminate the process and free all of its resources.
355
356 @item
357 If the page is not in physical memory, fetch it by appropriate means.
358 If necessary to make room, first evict some other page from memory.
359 (When you do that you need to first remove references to the page from
360 any page table that refers to it.)
361
362 @item
363 Point the page table entry for the faulting virtual address to the
364 physical page.  You can use the functions in @file{userprog/pagedir.c}.
365 @end enumerate
366
367 You'll need to modify the ELF loader in @file{userprog/process.c} to
368 do page table management according to your new design.  As supplied,
369 it reads all the process's pages from disk and initializes the page
370 tables for them at the same time.  As a first step, you might
371 want to leave the code that reads the pages from disk, but
372 use your new page table management code to construct the page tables
373 only as page faults occur for them.
374
375 You should use the @func{palloc_get_page} function to get the page
376 frames that you use for storing user virtual pages.  Be sure to pass
377 the @code{PAL_USER} flag to this function when you do so, because that
378 allocates pages from a ``user pool'' separate from the ``kernel pool''
379 that other calls to @func{palloc_get_page} make (@pxref{Why PAL_USER?}).
380
381 You might find the Pintos bitmap code, in @file{lib/kernel/bitmap.c} and
382 @file{lib/kernel/bitmap.h}, useful for tracking pages.  A bitmap is an
383 array of bits, each of which can be true or false.  Bitmaps are
384 typically used to track usage in a set of (identical) resources: if
385 resource @var{n} is in use, then bit @var{n} of the bitmap is true.
386
387 There are many possible ways to implement virtual memory.  The above
388 is simply an outline of our suggested implementation.
389
390 @node Paging To and From Disk
391 @subsection Paging To and From Disk
392
393 Implement paging to and from files and the swap disk.  You may use the
394 disk on interface @code{hd1:1} as the swap disk, using the disk
395 interface prototyped in @code{devices/disk.h}.  From the @file{vm/build}
396 directory, use the command @code{pintos-mkdisk swap.dsk @var{n}} to
397 create an @var{n} MB swap disk named @file{swap.dsk}.  Afterward,
398 @file{swap.dsk} will automatically be attached as @code{hd1:1} when you run
399 @command{pintos}.  Alternatively, you can tell @command{pintos} to
400 use a temporary @var{n}-MB swap disk for a single run with
401 @option{--swap-disk=@var{n}}.
402
403 You will need routines to move a page from memory to disk and from
404 disk to memory, where ``disk'' is either a file or the swap disk.  If
405 you do a good job, your VM should still work when you
406 implement your own file system for the next assignment.
407
408 To fully handle page faults, you will need a way to track pages that
409 are used by a process but which are not in physical memory.  Pages in
410 swap should not be constrained to any particular ordering.  You will
411 also need a way to track physical page frames, to find an unused one
412 when needed, or to evict a page when memory is needed but no empty pages
413 are available.  The page table data structure that you designed should
414 do most of the work for you.
415
416 Implement a global page replacement algorithm.  You should be able to
417 use the ``accessed'' and ``dirty'' bits (@pxref{Accessed and Dirty
418 Bits}) to implement an approximation to LRU.  Your algorithm should
419 perform at least as well as the ``second chance'' or ``clock''
420 algorithm.
421
422 Your design should allow for parallelism.  Multiple processes should
423 be able to process page faults at once.  If one page fault require
424 I/O, in the meantime processes that do not fault should continue
425 executing and other page faults that do not require I/O should be able to
426 complete.  These criteria require some synchronization effort.
427
428 @node Lazy Loading
429 @subsection Lazy Loading
430
431 Since you will already be paging from disk, you should implement a
432 ``lazy'' loading scheme for new processes.  When a process is created,
433 it will not need all of its resources immediately, so it doesn't make
434 sense to load all its code, data, and stack into memory when the process
435 is created.  Instead, bring pages in from
436 the executable only as needed.  Use the
437 executable file itself as backing store for read-only segments, since
438 these segments won't change.  This means that read-only pages should not
439 be written to swap.
440
441 The core of the program loader is the loop in @func{load_segment} in
442 @file{userprog/process.c}.
443 Each time around the loop, @code{read_bytes} receives the number of
444 bytes to read from the executable file and @code{zero_bytes} receives
445 the number of bytes to initialize to zero following the bytes read.  The
446 two always sum to @code{PGSIZE} (4,096).  The handling of a page depends
447 on these variables' values:
448
449 @itemize @bullet
450 @item
451 If @code{read_bytes} equals @code{PGSIZE}, the page should be demand
452 paged from disk on its first access.
453
454 @item
455 If @code{zero_bytes} equals @code{PGSIZE}, the page does not need to
456 be read from disk at all because it is all zeroes.  You should handle
457 such pages by creating a new page consisting of all zeroes at the
458 first page fault.
459
460 @item
461 If neither @code{read_bytes} nor @code{zero_bytes} equals
462 @code{PGSIZE}, then part of the page is to be read from disk and the
463 remainder zeroed.  This is a special case.  You are allowed to handle
464 it by reading the partial page from disk at executable load time and
465 zeroing the rest of the page.  This is the only case in which we will
466 allow you to load a page in a non-``lazy'' fashion.  Many real OSes
467 such as Linux do not load partial pages lazily.
468 @end itemize
469
470 Incidentally, if you have trouble handling the third case above, you
471 can eliminate it temporarily by linking the test programs with a
472 special ``linker script.''  Read @file{Makefile.userprog} for
473 details.  We will not test your submission with this special linker
474 script, so the code you turn in must properly handle all cases.
475
476 @node Stack Growth
477 @subsection Stack Growth
478
479 Implement stack growth.  In project 2, the stack was a single page at
480 the top of the user virtual address space, and programs were limited to
481 that much stack.  Now, if the stack grows past its current size,
482 allocate additional pages as necessary.
483
484 Allocate additional pages only if they ``appear'' to be stack accesses.
485 Devise a heuristic that attempts to distinguish stack accesses from
486 other accesses.  You can retrieve the user program's current stack
487 pointer from the @struct{intr_frame}'s @code{esp} member.
488
489 User programs are buggy if they write to the stack below the stack
490 pointer, because typical real OSes may interrupt a process at any time
491 to deliver a ``signal,'' which pushes data on the stack.@footnote{This rule is
492 common but not universal.  One modern exception is the
493 @uref{http://www.x86-64.org/documentation/abi.pdf, @var{x}86-64 System V
494 ABI}, which designates 128 bytes below the stack pointer as a ``red
495 zone'' that may not be modified by signal or interrupt handlers.}
496 However, the 80@var{x}86 @code{PUSH} instruction checks access
497 permissions before it adjusts the stack pointer, so it may cause a page
498 fault 4 bytes below the stack pointer.  (Otherwise, @code{PUSH} would
499 not be restartable in a straightforward fashion.)  Similarly, the
500 @code{PUSHA} instruction pushes 32 bytes at once, so it can fault 32
501 bytes below the stack pointer.
502
503 You may impose some absolute limit on stack size, as do most OSes.
504 Some OSes make the limit user-adjustable, e.g.@: with the
505 @command{ulimit} command on many Unix systems.  On many GNU/Linux systems,
506 the default limit is 8 MB.
507
508 The first stack page need not be allocated lazily.  You can initialize
509 it with the command line arguments at load time, with no need to wait
510 for it to be faulted in.  (Even if you did wait, the very first
511 instruction in the user program is likely to be one that faults in the
512 page.)
513
514 @node Memory Mapped Files
515 @subsection Memory Mapped Files
516
517 Implement memory mapped files, including the following system calls.
518
519 @deftypefn {System Call} mapid_t mmap (int @var{fd}, void *@var{addr})
520 Maps the file open as @var{fd} into the process's virtual address
521 space.  The entire file is mapped into consecutive virtual pages
522 starting at @var{addr}.
523
524 If the file's length is not a multiple of @code{PGSIZE}, then some
525 bytes in the final mapped page ``stick out'' beyond the end of the
526 file.  Set these bytes to zero when the page is faulted in from disk,
527 and discard them when the page is written back to disk.
528 A partial page need not be lazily loaded, as in the case of a partial
529 page in an executable (@pxref{Lazy Loading}).
530
531 If successful, this function returns a ``mapping ID'' that
532 uniquely identifies the mapping within the process.  On failure,
533 it must return -1, which otherwise should not be a valid mapping id,
534 and the process's mappings must be unchanged.
535
536 A call to @code{mmap} may fail if the file open as @var{fd} has a
537 length of zero bytes.  It must fail if @var{addr} is not page-aligned
538 or if the range of pages mapped overlaps any existing set of mapped
539 pages, including the stack or pages mapped at executable load time.
540 It must also fail if @var{addr} is 0, because some Pintos code assumes
541 virtual page 0 is not mapped.  Finally, file descriptors 0 and 1,
542 representing console input and output, are not mappable.
543
544 Your VM system should use the @code{mmap}'d file itself as backing
545 store for the mapping.  That is, to evict a page mapped by
546 @code{mmap}, write it to the file it was mapped from.  (In fact, you
547 may choose to implement executable mappings as special, copy-on-write
548 file mappings.)
549 @end deftypefn
550
551 @deftypefn {System Call} void munmap (mapid_t @var{mapping})
552 Unmaps the mapping designated by @var{mapping}, which must be a
553 mapping ID returned by a previous call to @code{mmap} by the same
554 process that has not yet been unmapped.
555 @end deftypefn
556
557 All mappings are implicitly unmapped when a process exits, whether via
558 @code{exit} or by any other means.  When a mapping is unmapped, whether
559 implicitly or explicitly, all pages written to by the process are
560 written back to the file, and pages not written must not be.  The pages
561 are then removed from the process's list of virtual pages.
562
563 Closing or removing a file does not unmap any of its mappings.  Once
564 created, a mapping is valid until @code{munmap} is called or the process
565 exits, following the Unix convention.  @xref{Removing an Open File}, for
566 more information.
567
568 If two or more processes map the same file, there is no requirement that
569 they see consistent data.  Unix handles this by making the two mappings
570 share the same physical page, but the @code{mmap} system call also has
571 an argument allowing the client to specify whether the page is shared or
572 private (i.e.@: copy-on-write).
573
574 @node Project 3 FAQ
575 @section FAQ
576
577 @table @b
578 @item How much code will I need to write?
579
580 Here's a summary of our reference solution, produced by the
581 @command{diffstat} program.  The final row gives total lines inserted
582 and deleted; a changed line counts as both an insertion and a deletion.
583
584 This summary is relative to the Pintos base code, but the reference
585 solution for project 3 starts from the reference solution to project 2.
586 @xref{Project 2 FAQ}, for the summary of project 2.
587
588 The reference solution represents just one possible solution.  Many
589 other solutions are also possible and many of those differ greatly from
590 the reference solution.  Some excellent solutions may not modify all the
591 files modified by the reference solution, and some may modify files not
592 modified by the reference solution.
593
594 @verbatim
595  Makefile.build       |    4 
596  devices/timer.c      |   42 ++
597  threads/init.c       |    5 
598  threads/interrupt.c  |    2 
599  threads/thread.c     |   31 +
600  threads/thread.h     |   37 +-
601  userprog/exception.c |   12 
602  userprog/pagedir.c   |   10 
603  userprog/process.c   |  319 +++++++++++++-----
604  userprog/syscall.c   |  545 ++++++++++++++++++++++++++++++-
605  userprog/syscall.h   |    1 
606  vm/frame.c           |  162 +++++++++
607  vm/frame.h           |   23 +
608  vm/page.c            |  297 ++++++++++++++++
609  vm/page.h            |   50 ++
610  vm/swap.c            |   85 ++++
611  vm/swap.h            |   11 
612  17 files changed, 1532 insertions(+), 104 deletions(-)
613 @end verbatim
614
615 @item Do we need a working HW 2 to implement HW 3?
616
617 Yes.
618
619 @item What extra credit is available?
620 @anchor{VM Extra Credit}
621
622 You may implement sharing: when multiple processes are created that use
623 the same executable file, share read-only pages among those processes
624 instead of creating separate copies of read-only segments for each
625 process.  If you carefully designed your page table data structures,
626 sharing of read-only pages should not make this part significantly
627 harder.
628
629 @end table
630
631 @menu
632 * Page Table and Paging FAQ::   
633 * Memory Mapped File FAQ::      
634 @end menu
635
636 @node Page Table and Paging FAQ
637 @subsection Page Table and Paging FAQ
638
639 @table @b
640 @item Does the virtual memory system need to support data segment growth?
641
642 No.  The size of the data segment is determined by the linker.  We still
643 have no dynamic allocation in Pintos (although it is possible to
644 ``fake'' it at the user level by using memory-mapped files).  Supporting
645 data segment growth should add little additional complexity to a
646 well-designed system.
647
648 @item Why should I use @code{PAL_USER} for allocating page frames?
649 @anchor{Why PAL_USER?}
650
651 Passing @code{PAL_USER} to @func{palloc_get_page} causes it to allocate
652 memory from the user pool, instead of the main kernel pool.  Running out
653 of pages in the user pool just causes user programs to page, but running
654 out of pages in the kernel pool will cause many failures because so many
655 kernel functions need to obtain memory.
656 You can layer some other allocator on top of @func{palloc_get_page} if
657 you like, but it should be the underlying mechanism.
658
659 Also, you can use the @option{-u} option to @command{pintos} to limit
660 the size of the user pool, which makes it easy to test your VM
661 implementation with various user memory sizes.
662
663 @item Data pages might need swap space.  Can I swap them out at process load?
664
665 No.  Reading data pages from the executable and writing them to swap
666 immediately at program startup is not demand paging.  You need to demand
667 page everything (except partial pages).
668 @end table
669
670 @node Memory Mapped File FAQ
671 @subsection Memory Mapped File FAQ
672
673 @table @b
674 @item How do we interact with memory-mapped files?
675
676 Let's say you want to map a file called @file{foo} into your address
677 space at address @t{0x10000000}. You open the file then use @code{mmap}:
678
679 @example
680 #include <stdio.h>
681 #include <syscall.h>
682
683 int main (void)
684 @{
685     void *addr = (void *) 0x10000000;
686     int fd = open ("foo");
687     mapid_t map = mmap (fd, addr);
688     if (map != -1)
689         printf ("success!\n");
690 @}
691 @end example
692
693 Suppose @file{foo} is a text file and you want to print the first 64
694 bytes on the screen (assuming, of course, that the length of the file
695 is at least 64).  Without @code{mmap}, you'd need to allocate a
696 buffer, use @code{read} to get the data from the file into the buffer,
697 and finally use @code{write} to put the buffer out to the display. But
698 with the file mapped into your address space, you can directly address
699 it like so:
700
701 @example
702 write (addr, 64, STDOUT_FILENO);
703 @end example
704
705 Similarly, if you wanted to replace the first byte of the file,
706 all you need to do is:
707
708 @example
709 addr[0] = 'b';
710 @end example
711
712 When you're done using the memory-mapped file, you simply unmap
713 it:
714
715 @example
716 munmap (map);
717 @end example
718
719 The @command{mcp} program in @file{src/examples} shows how to copy a
720 file using memory-mapped I/O.
721 @end table