summaryrefslogtreecommitdiffstats
path: root/doc/pintos_2.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/pintos_2.html')
-rw-r--r--doc/pintos_2.html1734
1 files changed, 1734 insertions, 0 deletions
diff --git a/doc/pintos_2.html b/doc/pintos_2.html
new file mode 100644
index 0000000..ae51974
--- /dev/null
+++ b/doc/pintos_2.html
@@ -0,0 +1,1734 @@
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html40/loose.dtd">
3<HTML>
4<!-- Created on March, 6 2012 by texi2html 1.66 -->
5<!--
6Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
7 Karl Berry <karl@freefriends.org>
8 Olaf Bachmann <obachman@mathematik.uni-kl.de>
9 and many others.
10Maintained by: Many creative people <dev@texi2html.cvshome.org>
11Send bugs and suggestions to <users@texi2html.cvshome.org>
12
13-->
14<HEAD>
15<TITLE>Pintos Projects: Project 0--Introducing Pintos</TITLE>
16
17<META NAME="description" CONTENT="Pintos Projects: Project 0--Introducing Pintos">
18<META NAME="keywords" CONTENT="Pintos Projects: Project 0--Introducing Pintos">
19<META NAME="resource-type" CONTENT="document">
20<META NAME="distribution" CONTENT="global">
21<META NAME="Generator" CONTENT="texi2html 1.66">
22<LINK REL="stylesheet" HREF="pintos.css">
23</HEAD>
24
25<BODY >
26
27<A NAME="SEC15"></A>
28<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
29<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos_1.html#SEC1"> &lt;&lt; </A>]</TD>
30<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos_3.html#SEC41"> &gt;&gt; </A>]</TD>
31<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos.html#SEC_Top">Top</A>]</TD>
32<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos.html#SEC_Contents">Contents</A>]</TD>
33<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
34<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos_abt.html#SEC_About"> ? </A>]</TD>
35</TR></TABLE>
36
37<HR SIZE=2>
38<H1> 2. Project 0: Introducing Pintos </H1>
39<!--docid::SEC15::-->
40<P>
41
42In this assignment, you will learn about the existing functionality
43in Pintos, and add two small features to the system: a more efficient
44implementation of <Q><SAMP>sleep</SAMP></Q>, and the ability to pass command line
45arguments to user programs.
46</P>
47<P>
48
49You will be working in the <Q><TT>threads</TT></Q> directory for the first part
50of this assignment (with some work in the <Q><TT>devices</TT></Q> directory on
51the side), and modify the file <Q><TT>userprog/process.c</TT></Q> in the second part.
52</P>
53<P>
54
55The tests for Project 0 are executed by changing the working directory
56to <Q><TT>intro</TT></Q> and running <Q><SAMP>make</SAMP></Q> followed by <Q><SAMP>make check</SAMP></Q>.
57</P>
58<P>
59
60Before you read the description of this project, you should read all of
61the following sections: <A HREF="pintos_1.html#SEC1">1. Introduction</A>, <A HREF="pintos_6.html#SEC89">B. Coding Standards</A>,
62<A HREF="pintos_8.html#SEC96">D. Debugging Tools</A>, and <A HREF="pintos_9.html#SEC109">E. Development Tools</A>. You should at least
63skim the material from <A HREF="pintos_5.html#SEC49">A.1 Loading</A> through <A HREF="pintos_5.html#SEC69">A.5 Memory Allocation</A>, especially <A HREF="pintos_5.html#SEC58">A.3 Synchronization</A>.
64</P>
65<P>
66
67<A NAME="Understanding Threads"></A>
68<HR SIZE="6">
69<A NAME="SEC16"></A>
70<H2> 2.1 Understanding Threads </H2>
71<!--docid::SEC16::-->
72<P>
73
74The first step is to read and understand the code for the initial thread
75system.
76Pintos already implements thread creation and thread completion,
77a simple scheduler to switch between threads, and synchronization
78primitives (semaphores, locks, condition variables, and optimization
79barriers).
80</P>
81<P>
82
83Some of this code might seem slightly mysterious. If
84you haven't already compiled and run the base system, as described in
85the introduction (see section <A HREF="pintos_1.html#SEC1">1. Introduction</A>), you should do so now. You
86can read through parts of the source code to see what's going
87on. If you like, you can add calls to <CODE>printf()</CODE> almost
88anywhere, then recompile and run to see what happens and in what
89order. You can also run the kernel in a debugger and set breakpoints
90at interesting spots, single-step through code and examine data, and
91so on.
92</P>
93<P>
94
95When a thread is created, you are creating a new context to be
96scheduled. You provide a function to be run in this context as an
97argument to <CODE>thread_create()</CODE>. The first time the thread is
98scheduled and runs, it starts from the beginning of that function
99and executes in that context. When the function returns, the thread
100terminates. Each thread, therefore, acts like a mini-program running
101inside Pintos, with the function passed to <CODE>thread_create()</CODE>
102acting like <CODE>main()</CODE>.
103</P>
104<P>
105
106At any given time, exactly one thread runs and the rest, if any,
107become inactive. The scheduler decides which thread to
108run next. (If no thread is ready to run
109at any given time, then the special &quot;idle&quot; thread, implemented in
110<CODE>idle()</CODE>, runs.)
111Synchronization primitives can force context switches when one
112thread needs to wait for another thread to do something.
113</P>
114<P>
115
116The mechanics of a context switch are
117in <Q><TT>threads/switch.S</TT></Q>, which is 80<VAR>x</VAR>86
118assembly code. (You don't have to understand it.) It saves the
119state of the currently running thread and restores the state of the
120thread we're switching to.
121</P>
122<P>
123
124Using the GDB debugger, slowly trace through a context
125switch to see what happens (see section <A HREF="pintos_8.html#SEC102">D.5 GDB</A>). You can set a
126breakpoint on <CODE>schedule()</CODE> to start out, and then
127single-step from there.<A NAME="DOCF1" HREF="pintos_fot.html#FOOT1">(1)</A> Be sure
128to keep track of each thread's address
129and state, and what procedures are on the call stack for each thread.
130You will notice that when one thread calls <CODE>switch_threads()</CODE>,
131another thread starts running, and the first thing the new thread does
132is to return from <CODE>switch_threads()</CODE>. You will understand the thread
133system once you understand why and how the <CODE>switch_threads()</CODE> that
134gets called is different from the <CODE>switch_threads()</CODE> that returns.
135See section <A HREF="pintos_5.html#SEC57">A.2.3 Thread Switching</A>, for more information.
136</P>
137<P>
138
139<STRONG>Warning</STRONG>: In Pintos, each thread is assigned a small,
140fixed-size execution stack just under 4 kB in size. The kernel
141tries to detect stack overflow, but it cannot do so perfectly. You
142may cause bizarre problems, such as mysterious kernel panics, if you
143declare large data structures as non-static local variables,
144e.g. <Q><SAMP>int buf[1000];</SAMP></Q>. Alternatives to stack allocation include
145the page allocator and the block allocator (see section <A HREF="pintos_5.html#SEC69">A.5 Memory Allocation</A>).
146</P>
147<P>
148
149<A NAME="Project 1 Source Files"></A>
150<HR SIZE="6">
151<A NAME="SEC17"></A>
152<H3> 2.1.1 Source Files </H3>
153<!--docid::SEC17::-->
154<P>
155
156Here is a brief overview of the files in the <Q><TT>threads</TT></Q>
157directory. You will not need to modify most of this code, but the
158hope is that presenting this overview will give you a start on what
159code to look at.
160</P>
161<P>
162
163</P>
164<DL COMPACT>
165<DT><Q><TT>loader.S</TT></Q>
166<DD><DT><Q><TT>loader.h</TT></Q>
167<DD>The kernel loader. Assembles to 512 bytes of code and data that the
168PC BIOS loads into memory and which in turn finds the kernel on disk,
169loads it into memory, and jumps to <CODE>start()</CODE> in <Q><TT>start.S</TT></Q>.
170See section <A HREF="pintos_5.html#SEC50">A.1.1 The Loader</A>, for details. You should not need to look at
171this code or modify it.
172<P>
173
174</P>
175<DT><Q><TT>start.S</TT></Q>
176<DD>Does basic setup needed for memory protection and 32-bit
177operation on 80<VAR>x</VAR>86 CPUs. Unlike the loader, this code is
178actually part of the kernel. See section <A HREF="pintos_5.html#SEC51">A.1.2 Low-Level Kernel Initialization</A>,
179for details.
180<P>
181
182</P>
183<DT><Q><TT>kernel.lds.S</TT></Q>
184<DD>The linker script used to link the kernel. Sets the load address of
185the kernel and arranges for <Q><TT>start.S</TT></Q> to be near the beginning
186of the kernel image. See section <A HREF="pintos_5.html#SEC50">A.1.1 The Loader</A>, for details. Again, you
187should not need to look at this code
188or modify it, but it's here in case you're curious.
189<P>
190
191</P>
192<DT><Q><TT>init.c</TT></Q>
193<DD><DT><Q><TT>init.h</TT></Q>
194<DD>Kernel initialization, including <CODE>main()</CODE>, the kernel's &quot;main
195program.&quot; You should look over <CODE>main()</CODE> at least to see what
196gets initialized. You might want to add your own initialization code
197here. See section <A HREF="pintos_5.html#SEC52">A.1.3 High-Level Kernel Initialization</A>, for details.
198<P>
199
200</P>
201<DT><Q><TT>thread.c</TT></Q>
202<DD><DT><Q><TT>thread.h</TT></Q>
203<DD>Basic thread support. Much of your work will take place in these files.
204<Q><TT>thread.h</TT></Q> defines <CODE>struct thread</CODE>, which you are likely to modify
205in all three projects. See <A HREF="pintos_5.html#SEC55">A.2.1 <CODE>struct thread</CODE></A> and <A HREF="pintos_5.html#SEC54">A.2 Threads</A> for
206more information.
207<P>
208
209</P>
210<DT><Q><TT>switch.S</TT></Q>
211<DD><DT><Q><TT>switch.h</TT></Q>
212<DD>Assembly language routine for switching threads. Already discussed
213above. See section <A HREF="pintos_5.html#SEC56">A.2.2 Thread Functions</A>, for more information.
214<P>
215
216</P>
217<DT><Q><TT>palloc.c</TT></Q>
218<DD><DT><Q><TT>palloc.h</TT></Q>
219<DD>Page allocator, which hands out system memory in multiples of 4 kB
220pages. See section <A HREF="pintos_5.html#SEC70">A.5.1 Page Allocator</A>, for more information.
221<P>
222
223</P>
224<DT><Q><TT>malloc.c</TT></Q>
225<DD><DT><Q><TT>malloc.h</TT></Q>
226<DD>A simple implementation of <CODE>malloc()</CODE> and <CODE>free()</CODE> for
227the kernel. See section <A HREF="pintos_5.html#SEC71">A.5.2 Block Allocator</A>, for more information.
228<P>
229
230</P>
231<DT><Q><TT>interrupt.c</TT></Q>
232<DD><DT><Q><TT>interrupt.h</TT></Q>
233<DD>Basic interrupt handling and functions for turning interrupts on and
234off. See section <A HREF="pintos_5.html#SEC65">A.4 Interrupt Handling</A>, for more information.
235<P>
236
237</P>
238<DT><Q><TT>intr-stubs.S</TT></Q>
239<DD><DT><Q><TT>intr-stubs.h</TT></Q>
240<DD>Assembly code for low-level interrupt handling. See section <A HREF="pintos_5.html#SEC66">A.4.1 Interrupt Infrastructure</A>, for more information.
241<P>
242
243</P>
244<DT><Q><TT>synch.c</TT></Q>
245<DD><DT><Q><TT>synch.h</TT></Q>
246<DD>Basic synchronization primitives: semaphores, locks, condition
247variables, and optimization barriers. You will need to use these for
248synchronization in all
249four projects. See section <A HREF="pintos_5.html#SEC58">A.3 Synchronization</A>, for more information.
250<P>
251
252</P>
253<DT><Q><TT>io.h</TT></Q>
254<DD>Functions for I/O port access. This is mostly used by source code in
255the <Q><TT>devices</TT></Q> directory that you won't have to touch.
256<P>
257
258</P>
259<DT><Q><TT>vaddr.h</TT></Q>
260<DD><DT><Q><TT>pte.h</TT></Q>
261<DD>Functions and macros for working with virtual addresses and page table
262entries. These will be more important to you in project 2. For now,
263you can ignore them.
264<P>
265
266</P>
267<DT><Q><TT>flags.h</TT></Q>
268<DD>Macros that define a few bits in the 80<VAR>x</VAR>86 &quot;flags&quot; register.
269Probably of no interest. See [ <A HREF="pintos_10.html#IA32-v1">IA32-v1</A>], section 3.4.3, &quot;EFLAGS
270Register,&quot; for more information.
271</DL>
272<P>
273
274<A NAME="devices code"></A>
275<HR SIZE="6">
276<A NAME="SEC18"></A>
277<H4> 2.1.1.1 <Q><TT>devices</TT></Q> code </H4>
278<!--docid::SEC18::-->
279<P>
280
281The basic threaded kernel also includes these files in the
282<Q><TT>devices</TT></Q> directory:
283</P>
284<P>
285
286</P>
287<DL COMPACT>
288<DT><Q><TT>timer.c</TT></Q>
289<DD><DT><Q><TT>timer.h</TT></Q>
290<DD>System timer that ticks, by default, 100 times per second. You will
291modify this code in this project.
292<P>
293
294</P>
295<DT><Q><TT>vga.c</TT></Q>
296<DD><DT><Q><TT>vga.h</TT></Q>
297<DD>VGA display driver. Responsible for writing text to the screen.
298You should have no need to look at this code. <CODE>printf()</CODE>
299calls into the VGA display driver for you, so there's little reason to
300call this code yourself.
301<P>
302
303</P>
304<DT><Q><TT>serial.c</TT></Q>
305<DD><DT><Q><TT>serial.h</TT></Q>
306<DD>Serial port driver. Again, <CODE>printf()</CODE> calls this code for you,
307so you don't need to do so yourself.
308It handles serial input by passing it to the input layer (see below).
309<P>
310
311</P>
312<DT><Q><TT>block.c</TT></Q>
313<DD><DT><Q><TT>block.h</TT></Q>
314<DD>An abstraction layer for <EM>block devices</EM>, that is, random-access,
315disk-like devices that are organized as arrays of fixed-size blocks.
316Out of the box, Pintos supports two types of block devices: IDE disks
317and partitions.
318<P>
319
320</P>
321<DT><Q><TT>ide.c</TT></Q>
322<DD><DT><Q><TT>ide.h</TT></Q>
323<DD>Supports reading and writing sectors on up to 4 IDE disks.
324<P>
325
326</P>
327<DT><Q><TT>partition.c</TT></Q>
328<DD><DT><Q><TT>partition.h</TT></Q>
329<DD>Understands the structure of partitions on disks, allowing a single
330disk to be carved up into multiple regions (partitions) for
331independent use.
332<P>
333
334</P>
335<DT><Q><TT>kbd.c</TT></Q>
336<DD><DT><Q><TT>kbd.h</TT></Q>
337<DD>Keyboard driver. Handles keystrokes passing them to the input layer
338(see below).
339<P>
340
341</P>
342<DT><Q><TT>input.c</TT></Q>
343<DD><DT><Q><TT>input.h</TT></Q>
344<DD>Input layer. Queues input characters passed along by the keyboard or
345serial drivers.
346<P>
347
348</P>
349<DT><Q><TT>intq.c</TT></Q>
350<DD><DT><Q><TT>intq.h</TT></Q>
351<DD>Interrupt queue, for managing a circular queue that both kernel
352threads and interrupt handlers want to access. Used by the keyboard
353and serial drivers.
354<P>
355
356</P>
357<DT><Q><TT>rtc.c</TT></Q>
358<DD><DT><Q><TT>rtc.h</TT></Q>
359<DD>Real-time clock driver, to enable the kernel to determine the current
360date and time. By default, this is only used by <Q><TT>thread/init.c</TT></Q>
361to choose an initial seed for the random number generator.
362<P>
363
364</P>
365<DT><Q><TT>speaker.c</TT></Q>
366<DD><DT><Q><TT>speaker.h</TT></Q>
367<DD>Driver that can produce tones on the PC speaker.
368<P>
369
370</P>
371<DT><Q><TT>pit.c</TT></Q>
372<DD><DT><Q><TT>pit.h</TT></Q>
373<DD>Code to configure the 8254 Programmable Interrupt Timer. This code is
374used by both <Q><TT>devices/timer.c</TT></Q> and <Q><TT>devices/speaker.c</TT></Q>
375because each device uses one of the PIT's output channel.
376</DL>
377<P>
378
379<A NAME="lib files"></A>
380<HR SIZE="6">
381<A NAME="SEC19"></A>
382<H4> 2.1.1.2 <Q><TT>lib</TT></Q> files </H4>
383<!--docid::SEC19::-->
384<P>
385
386Finally, <Q><TT>lib</TT></Q> and <Q><TT>lib/kernel</TT></Q> contain useful library
387routines. (<Q><TT>lib/user</TT></Q> will be used by user programs, starting in
388project 2, but it is not part of the kernel.) Here's a few more
389details:
390</P>
391<P>
392
393</P>
394<DL COMPACT>
395<DT><Q><TT>ctype.h</TT></Q>
396<DD><DT><Q><TT>inttypes.h</TT></Q>
397<DD><DT><Q><TT>limits.h</TT></Q>
398<DD><DT><Q><TT>stdarg.h</TT></Q>
399<DD><DT><Q><TT>stdbool.h</TT></Q>
400<DD><DT><Q><TT>stddef.h</TT></Q>
401<DD><DT><Q><TT>stdint.h</TT></Q>
402<DD><DT><Q><TT>stdio.c</TT></Q>
403<DD><DT><Q><TT>stdio.h</TT></Q>
404<DD><DT><Q><TT>stdlib.c</TT></Q>
405<DD><DT><Q><TT>stdlib.h</TT></Q>
406<DD><DT><Q><TT>string.c</TT></Q>
407<DD><DT><Q><TT>string.h</TT></Q>
408<DD>A subset of the standard C library. See section <A HREF="pintos_6.html#SEC91">B.2 C99</A>, for
409information
410on a few recently introduced pieces of the C library that you might
411not have encountered before. See section <A HREF="pintos_6.html#SEC92">B.3 Unsafe String Functions</A>, for
412information on what's been intentionally left out for safety.
413<P>
414
415</P>
416<DT><Q><TT>debug.c</TT></Q>
417<DD><DT><Q><TT>debug.h</TT></Q>
418<DD>Functions and macros to aid debugging. See section <A HREF="pintos_8.html#SEC96">D. Debugging Tools</A>, for
419more information.
420<P>
421
422</P>
423<DT><Q><TT>random.c</TT></Q>
424<DD><DT><Q><TT>random.h</TT></Q>
425<DD>Pseudo-random number generator. The actual sequence of random values
426will not vary from one Pintos run to another, unless you do one of
427three things: specify a new random seed value on the <Q><SAMP>-rs</SAMP></Q>
428kernel command-line option on each run, or use a simulator other than
429Bochs, or specify the <Q><SAMP>-r</SAMP></Q> option to <CODE>pintos</CODE>.
430<P>
431
432</P>
433<DT><Q><TT>round.h</TT></Q>
434<DD>Macros for rounding.
435<P>
436
437</P>
438<DT><Q><TT>syscall-nr.h</TT></Q>
439<DD>System call numbers. Not used until project 2.
440<P>
441
442</P>
443<DT><Q><TT>kernel/list.c</TT></Q>
444<DD><DT><Q><TT>kernel/list.h</TT></Q>
445<DD>Doubly linked list implementation. Used all over the Pintos code, and
446you'll probably want to use it a few places yourself.
447<P>
448
449</P>
450<DT><Q><TT>kernel/bitmap.c</TT></Q>
451<DD><DT><Q><TT>kernel/bitmap.h</TT></Q>
452<DD>Bitmap implementation. You can use this in your code if you like, but
453you probably won't have any need for it in project 0 and project 1.
454<P>
455
456</P>
457<DT><Q><TT>kernel/hash.c</TT></Q>
458<DD><DT><Q><TT>kernel/hash.h</TT></Q>
459<DD>Hash table implementation.
460<P>
461
462</P>
463<DT><Q><TT>kernel/console.c</TT></Q>
464<DD><DT><Q><TT>kernel/console.h</TT></Q>
465<DD><DT><Q><TT>kernel/stdio.h</TT></Q>
466<DD>Implements <CODE>printf()</CODE> and a few other functions.
467</DL>
468<P>
469
470<A NAME="Project 1 Synchronization"></A>
471<HR SIZE="6">
472<A NAME="SEC20"></A>
473<H3> 2.1.2 Synchronization </H3>
474<!--docid::SEC20::-->
475<P>
476
477Proper synchronization is an important part of the solutions to these
478problems. Any synchronization problem can be easily solved by turning
479interrupts off: while interrupts are off, there is no concurrency, so
480there's no possibility for race conditions. Therefore, it's tempting to
481solve all synchronization problems this way, but <STRONG>don't</STRONG>.
482Instead, use semaphores, locks, and condition variables to solve the
483bulk of your synchronization problems. Read the tour section on
484synchronization (see section <A HREF="pintos_5.html#SEC58">A.3 Synchronization</A>) or the comments in
485<Q><TT>threads/synch.c</TT></Q> if you're unsure what synchronization primitives
486may be used in what situations.
487</P>
488<P>
489
490In the Pintos projects, the only class of problem best solved by
491disabling interrupts is coordinating data shared between a kernel thread
492and an interrupt handler. Because interrupt handlers can't sleep, they
493can't acquire locks. This means that data shared between kernel threads
494and an interrupt handler must be protected within a kernel thread by
495turning off interrupts.
496</P>
497<P>
498
499This project only requires accessing a little bit of thread state from
500interrupt handlers. For the alarm clock, the timer interrupt needs to
501wake up sleeping threads. In the advanced scheduler, the timer
502interrupt needs to access a few global and per-thread variables. When
503you access these variables from kernel threads, you will need to disable
504interrupts to prevent the timer interrupt from interfering.
505</P>
506<P>
507
508When you do turn off interrupts, take care to do so for the least amount
509of code possible, or you can end up losing important things such as
510timer ticks or input events. Turning off interrupts also increases the
511interrupt handling latency, which can make a machine feel sluggish if
512taken too far.
513</P>
514<P>
515
516The synchronization primitives themselves in <Q><TT>synch.c</TT></Q> are
517implemented by disabling interrupts. You may need to increase the
518amount of code that runs with interrupts disabled here, but you should
519still try to keep it to a minimum.
520</P>
521<P>
522
523Disabling interrupts can be useful for debugging, if you want to make
524sure that a section of code is not interrupted. You should remove
525debugging code before turning in your project. (Don't just comment it
526out, because that can make the code difficult to read.)
527</P>
528<P>
529
530There should be no busy waiting in your submission. A tight loop that
531calls <CODE>thread_yield()</CODE> is one form of busy waiting.
532</P>
533<P>
534
535<A NAME="Development Suggestions"></A>
536<HR SIZE="6">
537<A NAME="SEC21"></A>
538<H3> 2.1.3 Development Suggestions </H3>
539<!--docid::SEC21::-->
540<P>
541
542In the past, many groups divided the assignment into pieces, then each
543group member worked on his or her piece until just before the
544deadline, at which time the group reconvened to combine their code and
545submit. <STRONG>This is a bad idea. We do not recommend this
546approach.</STRONG> Groups that do this often find that two changes conflict
547with each other, requiring lots of last-minute debugging. Some groups
548who have done this have turned in code that did not even compile or
549boot, much less pass any tests.
550</P>
551<P>
552
553Instead, we recommend integrating your team's changes early and often,
554using the source code control system git.
555This is less likely to produce surprises, because everyone can see
556everyone else's code as it is written, instead of just when it is
557finished. These systems also make it possible to review changes and,
558when a change introduces a bug, drop back to working versions of code.
559</P>
560<P>
561
562You should expect to run into bugs that you simply don't understand
563while working on this and subsequent projects. When you do,
564reread the appendix on debugging tools, which is filled with
565useful debugging tips that should help you to get back up to speed
566(see section <A HREF="pintos_8.html#SEC96">D. Debugging Tools</A>). Be sure to read the section on backtraces
567(see section <A HREF="pintos_8.html#SEC100">D.4 Backtraces</A>), which will help you to get the most out of every
568kernel panic or assertion failure.
569</P>
570<P>
571
572<A NAME="Understanding User Programs"></A>
573<HR SIZE="6">
574<A NAME="SEC22"></A>
575<H2> 2.2 Understanding User Programs </H2>
576<!--docid::SEC22::-->
577<P>
578
579The tests for both the alarm clock assignment in Project 0, and the
580priority scheduler in Project 1, run as part of the operating system
581kernel, with full access to privileged parts of the system.
582Once we start running user programs on top of the operating system, this
583is no longer true.
584</P>
585<P>
586
587We allow more than one process to run at a time. Each process has one
588thread (multithreaded processes are not supported). User programs are
589written under the illusion that they have the entire machine. This
590means that when you load and run multiple processes at a time, you must
591manage memory, scheduling, and other state correctly to maintain this
592illusion.
593</P>
594<P>
595
596In Project 2, we will test your operating system by running
597user programs. This gives you much greater freedom. You must make sure
598that the user program interface meets the specifications described here,
599but given that constraint you are free to restructure or rewrite kernel
600code however you wish.
601</P>
602<P>
603
604<A NAME="User Program Source Files"></A>
605<HR SIZE="6">
606<A NAME="SEC23"></A>
607<H3> 2.2.1 Source Files </H3>
608<!--docid::SEC23::-->
609<P>
610
611</P>
612<DL COMPACT>
613<DT><Q><TT>process.c</TT></Q>
614<DD><DT><Q><TT>process.h</TT></Q>
615<DD>Loads ELF binaries and starts processes.
616<P>
617
618</P>
619<DT><Q><TT>pagedir.c</TT></Q>
620<DD><DT><Q><TT>pagedir.h</TT></Q>
621<DD>A simple manager for 80<VAR>x</VAR>86 hardware page tables.
622Although you probably won't want to modify this code for this project,
623you may want to call some of its functions.
624See <A HREF="pintos_4.html#Page Tables">Page Tables</A>, for more information.
625<P>
626
627</P>
628<DT><Q><TT>syscall.c</TT></Q>
629<DD><DT><Q><TT>syscall.h</TT></Q>
630<DD>Whenever a user process wants to access some kernel functionality, it
631invokes a system call.
632<P>
633
634</P>
635<DT><Q><TT>exception.c</TT></Q>
636<DD><DT><Q><TT>exception.h</TT></Q>
637<DD>When a user process performs a privileged or prohibited operation, it
638traps into the kernel as an &quot;exception&quot; or &quot;fault.&quot;<A NAME="DOCF2" HREF="pintos_fot.html#FOOT2">(2)</A> These files handle
639exceptions. In project 2, you will need to modify the page fault
640handler to support lazy page loading and stack growth.
641<P>
642
643</P>
644<DT><Q><TT>gdt.c</TT></Q>
645<DD><DT><Q><TT>gdt.h</TT></Q>
646<DD>The 80<VAR>x</VAR>86 is a segmented architecture. The Global Descriptor
647Table (GDT) is a table that describes the segments in use. These
648files set up the GDT. You should not need to modify these
649files for any of the projects. You can read the code if
650you're interested in how the GDT works.
651<P>
652
653</P>
654<DT><Q><TT>tss.c</TT></Q>
655<DD><DT><Q><TT>tss.h</TT></Q>
656<DD>The Task-State Segment (TSS) is used for 80<VAR>x</VAR>86 architectural
657task switching. Pintos uses the TSS only for switching stacks when a
658user process enters an interrupt handler, as does Linux. You
659should not need to modify these files for any of the projects.
660You can read the code if you're interested in how the TSS
661works.
662</DL>
663<P>
664
665<A NAME="Using the File System"></A>
666<HR SIZE="6">
667<A NAME="SEC24"></A>
668<H3> 2.2.2 Using the File System </H3>
669<!--docid::SEC24::-->
670<P>
671
672You will need to interface to the file system code, because
673user programs are loaded from the file system and most of the
674system calls you must implement deal with the file system.
675You will want to look over the <Q><TT>filesys.h</TT></Q> and <Q><TT>file.h</TT></Q>
676interfaces to understand how to use the file system, and especially
677its many limitations.
678</P>
679<P>
680
681There is no need to modify the file system code in this course, and so
682we recommend that you do not. Working on the file system is likely to
683distract you from the project's foci.
684</P>
685<P>
686
687You will have to tolerate the following limitations, however:
688</P>
689<P>
690
691<UL>
692<LI>
693No internal synchronization. Concurrent accesses will interfere with one
694another. You should use synchronization to ensure that only one process at a
695time is executing file system code.
696<P>
697
698</P>
699<LI>
700File size is fixed at creation time. The root directory is
701represented as a file, so the number of files that may be created is also
702limited.
703<P>
704
705</P>
706<LI>
707File data is allocated as a single extent, that is, data in a single
708file must occupy a contiguous range of sectors on disk. External
709fragmentation can therefore become a serious problem as a file system is
710used over time.
711<P>
712
713</P>
714<LI>
715No subdirectories.
716<P>
717
718</P>
719<LI>
720File names are limited to 14 characters.
721<P>
722
723</P>
724<LI>
725A system crash mid-operation may corrupt the disk in a way
726that cannot be repaired automatically. There is no file system repair
727tool anyway.
728</UL>
729<P>
730
731One important feature is included:
732</P>
733<P>
734
735<UL>
736<LI>
737Unix-like semantics for <CODE>filesys_remove()</CODE> are implemented.
738That is, if a file is open when it is removed, its blocks
739are not deallocated and it may still be accessed by any
740threads that have it open, until the last one closes it. See <A HREF="pintos_2.html#Removing an Open File">Removing an Open File</A>, for more information.
741</UL>
742<P>
743
744You need to be able to create a simulated disk with a file system
745partition. The <CODE>pintos-mkdisk</CODE> program provides this
746functionality. From the <Q><TT>userprog/build</TT></Q> directory, execute
747<CODE>pintos-mkdisk filesys.dsk --filesys-size=2</CODE>. This command
748creates a simulated disk named <Q><TT>filesys.dsk</TT></Q> that contains a 2
749MB Pintos file system partition. Then format the file system
750partition by passing <Q><SAMP>-f -q</SAMP></Q> on the kernel's command line:
751<CODE>pintos -f -q</CODE>. The <Q><SAMP>-f</SAMP></Q> option causes the file system to
752be formatted, and <Q><SAMP>-q</SAMP></Q> causes Pintos to exit as soon as the
753format is done.
754</P>
755<P>
756
757You'll need a way to copy files in and out of the simulated file system.
758The <CODE>pintos</CODE> <Q><SAMP>-p</SAMP></Q> (&quot;put&quot;) and <Q><SAMP>-g</SAMP></Q> (&quot;get&quot;)
759options do this. To copy <Q><TT><VAR>file</VAR></TT></Q> into the
760Pintos file system, use the command <Q><TT>pintos -p <VAR>file</VAR> -- -q</TT></Q>.
761(The <Q><SAMP>--</SAMP></Q> is needed because <Q><SAMP>-p</SAMP></Q> is for the <CODE>pintos</CODE>
762script, not for the simulated kernel.) To copy it to the Pintos file
763system under the name <Q><TT><VAR>newname</VAR></TT></Q>, add <Q><SAMP>-a
764<VAR>newname</VAR></SAMP></Q>: <Q><TT>pintos -p <VAR>file</VAR> -a <VAR>newname</VAR> -- -q</TT></Q>. The
765commands for copying files out of a VM are similar, but substitute
766<Q><SAMP>-g</SAMP></Q> for <Q><SAMP>-p</SAMP></Q>.
767</P>
768<P>
769
770Incidentally, these commands work by passing special commands
771<CODE>extract</CODE> and <CODE>append</CODE> on the kernel's command line and copying
772to and from a special simulated &quot;scratch&quot; partition. If you're very
773curious, you can look at the <CODE>pintos</CODE> script as well as
774<Q><TT>filesys/fsutil.c</TT></Q> to learn the implementation details.
775</P>
776<P>
777
778Here's a summary of how to create a disk with a file system partition,
779format the file system, copy the <CODE>echo</CODE> program into the new
780disk, and then run <CODE>echo</CODE>, passing argument <CODE>x</CODE>.
781(Argument passing won't work until you implemented it.) It assumes
782that you've already built the examples in <Q><TT>examples</TT></Q> and that the
783current directory is <Q><TT>userprog/build</TT></Q>:
784</P>
785<P>
786
787<TABLE><tr><td>&nbsp;</td><td class=example><pre>pintos-mkdisk filesys.dsk --filesys-size=2
788pintos -f -q
789pintos -p ../../examples/echo -a echo -- -q
790pintos -q run 'echo x'
791</pre></td></tr></table><P>
792
793The three final steps can actually be combined into a single command:
794</P>
795<P>
796
797<TABLE><tr><td>&nbsp;</td><td class=example><pre>pintos-mkdisk filesys.dsk --filesys-size=2
798pintos -p ../../examples/echo -a echo -- -f -q run 'echo x'
799</pre></td></tr></table><P>
800
801If you don't want to keep the file system disk around for later use or
802inspection, you can even combine all four steps into a single command.
803The <CODE>--filesys-size=<VAR>n</VAR></CODE> option creates a temporary file
804system partition
805approximately <VAR>n</VAR> megabytes in size just for the duration of the
806<CODE>pintos</CODE> run. The Pintos automatic test suite makes extensive
807use of this syntax:
808</P>
809<P>
810
811<TABLE><tr><td>&nbsp;</td><td class=example><pre>pintos --filesys-size=2 -p ../../examples/echo -a echo -- -f -q run 'echo x'
812</pre></td></tr></table><P>
813
814You can delete a file from the Pintos file system using the <CODE>rm
815<VAR>file</VAR></CODE> kernel action, e.g. <CODE>pintos -q rm <VAR>file</VAR></CODE>. Also,
816<CODE>ls</CODE> lists the files in the file system and <CODE>cat
817<VAR>file</VAR></CODE> prints a file's contents to the display.
818</P>
819<P>
820
821<A NAME="How User Programs Work"></A>
822<HR SIZE="6">
823<A NAME="SEC25"></A>
824<H3> 2.2.3 How User Programs Work </H3>
825<!--docid::SEC25::-->
826<P>
827
828Pintos can run normal C programs, as long as they fit into memory and use
829only the system calls you implement. Notably, <CODE>malloc()</CODE> cannot be
830implemented because none of the system calls required for this project
831allow for memory allocation. Pintos also can't run programs that use
832floating point operations, since the kernel doesn't save and restore the
833processor's floating-point unit when switching threads.
834</P>
835<P>
836
837The <Q><TT>src/examples</TT></Q> directory contains a few sample user
838programs. The <Q><TT>Makefile</TT></Q> in this directory
839compiles the provided examples, and you can edit it
840compile your own programs as well. Some of the example programs will
841not work with the current implementation of Pintos.
842</P>
843<P>
844
845Pintos can load <EM>ELF</EM> executables with the loader provided for you
846in <Q><TT>userprog/process.c</TT></Q>. ELF is a file format used by Linux,
847Solaris, and many other operating systems for object files,
848shared libraries, and executables. You can actually use any compiler
849and linker that output 80<VAR>x</VAR>86 ELF executables to produce programs
850for Pintos. (We've provided compilers and linkers that should do just
851fine.)
852</P>
853<P>
854
855You should realize immediately that, until you copy a
856test program to the simulated file system, Pintos will be unable to do
857useful work. You won't be able to do
858interesting things until you copy a variety of programs to the file system.
859You might want to create a clean reference file system disk and copy that
860over whenever you trash your <Q><TT>filesys.dsk</TT></Q> beyond a useful state,
861which may happen occasionally while debugging.
862</P>
863<P>
864
865<A NAME="Virtual Memory Layout"></A>
866<HR SIZE="6">
867<A NAME="SEC26"></A>
868<H3> 2.2.4 Virtual Memory Layout </H3>
869<!--docid::SEC26::-->
870<P>
871
872Virtual memory in Pintos is divided into two regions: user virtual
873memory and kernel virtual memory. User virtual memory ranges from
874virtual address 0 up to <CODE>PHYS_BASE</CODE>, which is defined in
875<Q><TT>threads/vaddr.h</TT></Q> and defaults to <TT>0xc0000000</TT> (3 GB). Kernel
876virtual memory occupies the rest of the virtual address space, from
877<CODE>PHYS_BASE</CODE> up to 4 GB.
878</P>
879<P>
880
881User virtual memory is per-process.
882When the kernel switches from one process to another, it
883also switches user virtual address spaces by changing the processor's
884page directory base register (see <CODE>pagedir_activate()</CODE> in
885<Q><TT>userprog/pagedir.c</TT></Q>). <CODE>struct thread</CODE> contains a pointer to a
886process's page table.
887</P>
888<P>
889
890Kernel virtual memory is global. It is always mapped the same way,
891regardless of what user process or kernel thread is running. In
892Pintos, kernel virtual memory is mapped one-to-one to physical
893memory, starting at <CODE>PHYS_BASE</CODE>. That is, virtual address
894<CODE>PHYS_BASE</CODE> accesses physical
895address 0, virtual address <CODE>PHYS_BASE</CODE> + <TT>0x1234</TT> accesses
896physical address <TT>0x1234</TT>, and so on up to the size of the machine's
897physical memory.
898</P>
899<P>
900
901A user program can only access its own user virtual memory. An attempt to
902access kernel virtual memory causes a page fault, handled by
903<CODE>page_fault()</CODE> in <Q><TT>userprog/exception.c</TT></Q>, and the process
904will be terminated. Kernel threads can access both kernel virtual
905memory and, if a user process is running, the user virtual memory of
906the running process. However, even in the kernel, an attempt to
907access memory at an unmapped user virtual address
908will cause a page fault.
909</P>
910<P>
911
912<A NAME="Typical Memory Layout"></A>
913<HR SIZE="6">
914<A NAME="SEC27"></A>
915<H4> 2.2.4.1 Typical Memory Layout </H4>
916<!--docid::SEC27::-->
917<P>
918
919Conceptually, each process is
920free to lay out its own user virtual memory however it
921chooses. In practice, user virtual memory is laid out like this:
922</P>
923<P>
924
925<CENTER>
926<TABLE><tr><td>&nbsp;</td><td class=example><pre> PHYS_BASE +----------------------------------+
927 | user stack |
928 | | |
929 | | |
930 | V |
931 | grows downward |
932 | |
933 | |
934 | |
935 | |
936 | grows upward |
937 | ^ |
938 | | |
939 | | |
940 +----------------------------------+
941 | uninitialized data segment (BSS) |
942 +----------------------------------+
943 | initialized data segment |
944 +----------------------------------+
945 | code segment |
946 0x08048000 +----------------------------------+
947 | |
948 | |
949 | |
950 | |
951 | |
952 0 +----------------------------------+
953</pre></td></tr></table></CENTER>
954<P>
955
956In this project, the user stack is fixed in size, but in project 2 it
957will be allowed to grow. Traditionally, the size of the uninitialized
958data segment can be adjusted with a system call, but you will not have
959to implement this.
960</P>
961<P>
962
963The code segment in Pintos starts at user virtual address
964<TT>0x08084000</TT>, approximately 128 MB from the bottom of the address
965space. This value is specified in [ <A HREF="pintos_10.html#SysV-i386">SysV-i386</A>] and has no deep
966significance.
967</P>
968<P>
969
970The linker sets the layout of a user program in memory, as directed by a
971&quot;linker script&quot; that tells it the names and locations of the various
972program segments. You can learn more about linker scripts by reading
973the &quot;Scripts&quot; chapter in the linker manual, accessible via <Q><SAMP>info
974ld</SAMP></Q>.
975</P>
976<P>
977
978To view the layout of a particular executable, run <CODE>objdump</CODE>
979(80<VAR>x</VAR>86) or <CODE>i386-elf-objdump</CODE> (SPARC) with the <Q><SAMP>-p</SAMP></Q>
980option.
981</P>
982<P>
983
984<A NAME="Accessing User Memory"></A>
985<HR SIZE="6">
986<A NAME="SEC28"></A>
987<H3> 2.2.5 Accessing User Memory </H3>
988<!--docid::SEC28::-->
989<P>
990
991As part of a system
992call, the kernel must often access memory through pointers provided by a user
993program. The kernel must be very careful about doing so, because
994the user can pass a null pointer, a pointer to
995unmapped virtual memory, or a pointer to kernel virtual address space
996(above <CODE>PHYS_BASE</CODE>). All of these types of invalid pointers must
997be rejected without harm to the kernel or other running processes, by
998terminating the offending process and freeing its resources.
999</P>
1000<P>
1001
1002There are at least two reasonable ways to do this correctly. The
1003first method is to verify
1004the validity of a user-provided pointer, then dereference it.
1005The second method is to check only that a user
1006pointer points below <CODE>PHYS_BASE</CODE>, then dereference it.
1007An invalid user pointer will cause a &quot;page fault&quot; that you can
1008handle by modifying the code for <CODE>page_fault()</CODE> in
1009<Q><TT>userprog/exception.c</TT></Q>. This technique is normally faster
1010because it takes advantage of the processor's MMU, so it tends to be
1011used in real kernels (including Linux). It is also the way
1012access to user pointers is implemented in the Pintos version provided.
1013</P>
1014<P>
1015
1016In either case, one needs to make sure not to &quot;leak&quot; resources. For
1017example, suppose that your system call has acquired a lock or
1018allocated memory with <CODE>malloc()</CODE>. If you encounter an invalid user pointer
1019afterward, you must still be sure to release the lock or free the page
1020of memory. If you choose to verify user pointers before dereferencing
1021them, this should be straightforward. It's more difficult to handle
1022if an invalid pointer causes a page fault,
1023because there's no way to return an error code from a memory access.
1024</P>
1025<P>
1026
1027<A NAME="Project 0 Requirements"></A>
1028<HR SIZE="6">
1029<A NAME="SEC29"></A>
1030<H2> 2.3 Requirements </H2>
1031<!--docid::SEC29::-->
1032<P>
1033
1034<A NAME="Project 0 Design Document"></A>
1035<HR SIZE="6">
1036<A NAME="SEC30"></A>
1037<H3> 2.3.1 Design Document </H3>
1038<!--docid::SEC30::-->
1039<P>
1040
1041Before you turn in your project, you must copy <A HREF="start.tmpl">the
1042project 0 design document template</A> into your source tree under the name
1043<Q><TT>pintos/src/intro/DESIGNDOC</TT></Q> and fill it in. We recommend that
1044you read the design document template before you start working on the
1045project. See section <A HREF="pintos_7.html#SEC93">C. Project Documentation</A>, for a sample design document
1046that goes along with a fictitious project.
1047</P>
1048<P>
1049
1050<A NAME="Alarm Clock"></A>
1051<HR SIZE="6">
1052<A NAME="SEC31"></A>
1053<H3> 2.3.2 Alarm Clock </H3>
1054<!--docid::SEC31::-->
1055<P>
1056
1057Reimplement <CODE>timer_sleep()</CODE>, defined in <Q><TT>devices/timer.c</TT></Q>.
1058Although a working implementation is provided, it &quot;busy waits,&quot; that
1059is, it spins in a loop checking the current time and calling
1060<CODE>thread_yield()</CODE> until enough time has gone by. Reimplement it to
1061avoid busy waiting.
1062</P>
1063<P>
1064
1065<A NAME="IDX1"></A>
1066</P>
1067<DL>
1068<DT><U>Function:</U> void <B>timer_sleep</B> (int64_t <VAR>ticks</VAR>)
1069<DD>Suspends execution of the calling thread until time has advanced by at
1070least <VAR>x</VAR> timer ticks. Unless the system is otherwise idle, the
1071thread need not wake up after exactly <VAR>x</VAR> ticks. Just put it on
1072the ready queue after they have waited for the right amount of time.
1073<P>
1074
1075<CODE>timer_sleep()</CODE> is useful for threads that operate in real-time,
1076e.g. for blinking the cursor once per second.
1077</P>
1078<P>
1079
1080The argument to <CODE>timer_sleep()</CODE> is expressed in timer ticks, not in
1081milliseconds or any another unit. There are <CODE>TIMER_FREQ</CODE> timer
1082ticks per second, where <CODE>TIMER_FREQ</CODE> is a macro defined in
1083<CODE>devices/timer.h</CODE>. The default value is 100. We don't recommend
1084changing this value, because any change is likely to cause many of
1085the tests to fail.
1086</P>
1087</DL>
1088<P>
1089
1090Separate functions <CODE>timer_msleep()</CODE>, <CODE>timer_usleep()</CODE>, and
1091<CODE>timer_nsleep()</CODE> do exist for sleeping a specific number of
1092milliseconds, microseconds, or nanoseconds, respectively, but these will
1093call <CODE>timer_sleep()</CODE> automatically when necessary. You do not need
1094to modify them.
1095</P>
1096<P>
1097
1098If your delays seem too short or too long, reread the explanation of the
1099<Q><SAMP>-r</SAMP></Q> option to <CODE>pintos</CODE> (see section <A HREF="pintos_1.html#SEC6">1.1.4 Debugging versus Testing</A>).
1100</P>
1101<P>
1102
1103The tests for the <A HREF="pintos_2.html#SEC31">2.3.2 Alarm Clock</A> assignment are executed by changing the
1104working directory <Q><TT>intro</TT></Q>. The run <Q><SAMP>make</SAMP></Q> to build the
1105Pintos kernel. Finally run <Q><SAMP>make check</SAMP></Q> to run the tests,
1106followed by <Q><SAMP>make grade</SAMP></Q> to obtain your score.
1107</P>
1108<P>
1109
1110The alarm clock implementation is not needed for later projects.
1111</P>
1112<P>
1113
1114<A NAME="Argument Passing"></A>
1115<HR SIZE="6">
1116<A NAME="SEC32"></A>
1117<H3> 2.3.3 Argument Passing </H3>
1118<!--docid::SEC32::-->
1119<P>
1120
1121Currently, <CODE>process_execute()</CODE> does not support passing arguments to
1122new processes. Implement this functionality, by extending
1123<CODE>process_execute()</CODE> so that instead of simply taking a program file
1124name as its argument, it divides it into words at spaces. The first
1125word is the program name, the second word is the first argument, and so
1126on. That is, <CODE>process_execute(&quot;grep foo bar&quot;)</CODE> should run
1127<CODE>grep</CODE> passing two arguments <CODE>foo</CODE> and <CODE>bar</CODE>.
1128</P>
1129<P>
1130
1131Within a command line, multiple spaces are equivalent to a single
1132space, so that <CODE>process_execute(&quot;grep foo bar&quot;)</CODE>
1133is equivalent to our original example. You can impose a reasonable
1134limit on the length of the command line arguments. For example, you
1135could limit the arguments to those that will fit in a single page (4
1136kB). (There is an unrelated limit of 128 bytes on command-line
1137arguments that the <CODE>pintos</CODE> utility can pass to the kernel.)
1138</P>
1139<P>
1140
1141You can parse argument strings any way you like. If you're lost,
1142look at <CODE>strtok_r()</CODE>, prototyped in <Q><TT>lib/string.h</TT></Q> and
1143implemented with thorough comments in <Q><TT>lib/string.c</TT></Q>. You can
1144find more about it by looking at the man page (run <CODE>man strtok_r</CODE>
1145at the prompt).
1146</P>
1147<P>
1148
1149See section <A HREF="pintos_2.html#SEC39">2.5.1 Program Startup Details</A>, for information on exactly how you
1150need to set up the stack.
1151</P>
1152<P>
1153
1154<A NAME="Project 0 FAQ"></A>
1155<HR SIZE="6">
1156<A NAME="SEC33"></A>
1157<H2> 2.4 FAQ </H2>
1158<!--docid::SEC33::-->
1159<P>
1160
1161</P>
1162<DL COMPACT>
1163<DT><B>How much code will I need to write?</B>
1164<DD><P>
1165
1166Here's a summary of our reference solution, produced by the
1167<CODE>diffstat</CODE> program. The final row gives total lines inserted
1168and deleted; a changed line counts as both an insertion and a deletion.
1169</P>
1170<P>
1171
1172The reference solution represents just one possible solution. Many
1173other solutions are also possible and many of those differ greatly from
1174the reference solution. Some excellent solutions may not modify all the
1175files modified by the reference solution, and some may modify files not
1176modified by the reference solution.
1177</P>
1178<P>
1179
1180<TABLE><tr><td>&nbsp;</td><td class=example><pre> devices/timer.c | 40 +++++++++++-
1181 threads/thread.h | 3 +
1182 userprog/process.c | 148 ++++++++++++++++++++++++++++++-----------
1183 3 files changed, 150 insertions(+), 41 deletions(-)
1184</pre></td></tr></table></DL>
1185<P>
1186
1187<A NAME="Threads FAQ"></A>
1188<HR SIZE="6">
1189<A NAME="SEC34"></A>
1190<H3> 2.4.1 Threads FAQ </H3>
1191<!--docid::SEC34::-->
1192<P>
1193
1194</P>
1195<DL COMPACT>
1196<DT><B>How do I update the <Q><TT>Makefile</TT></Q>s when I add a new source file?</B>
1197<DD><P>
1198
1199<A NAME="Adding Source Files"></A>
1200To add a <Q><TT>.c</TT></Q> file, edit the top-level <Q><TT>Makefile.build</TT></Q>.
1201Add the new file to variable <Q><SAMP><VAR>dir</VAR>_SRC</SAMP></Q>, where
1202<VAR>dir</VAR> is the directory where you added the file. For this
1203project, that means you should add it to <CODE>threads_SRC</CODE> or
1204<CODE>devices_SRC</CODE>. Then run <CODE>make</CODE>. If your new file
1205doesn't get
1206compiled, run <CODE>make clean</CODE> and then try again.
1207</P>
1208<P>
1209
1210When you modify the top-level <Q><TT>Makefile.build</TT></Q> and re-run
1211<CODE>make</CODE>, the modified
1212version should be automatically copied to
1213<Q><TT>threads/build/Makefile</TT></Q>. The converse is
1214not true, so any changes will be lost the next time you run <CODE>make
1215clean</CODE> from the <Q><TT>threads</TT></Q> directory. Unless your changes are
1216truly temporary, you should prefer to edit <Q><TT>Makefile.build</TT></Q>.
1217</P>
1218<P>
1219
1220A new <Q><TT>.h</TT></Q> file does not require editing the <Q><TT>Makefile</TT></Q>s.
1221</P>
1222<P>
1223
1224</P>
1225<DT><B>What does <CODE>warning: no previous prototype for `<VAR>func</VAR>'</CODE> mean?</B>
1226<DD><P>
1227
1228It means that you defined a non-<CODE>static</CODE> function without
1229preceding it by a prototype. Because non-<CODE>static</CODE> functions are
1230intended for use by other <Q><TT>.c</TT></Q> files, for safety they should be
1231prototyped in a header file included before their definition. To fix
1232the problem, add a prototype in a header file that you include, or, if
1233the function isn't actually used by other <Q><TT>.c</TT></Q> files, make it
1234<CODE>static</CODE>.
1235</P>
1236<P>
1237
1238</P>
1239<DT><B>What is the interval between timer interrupts?</B>
1240<DD><P>
1241
1242Timer interrupts occur <CODE>TIMER_FREQ</CODE> times per second. You can
1243adjust this value by editing <Q><TT>devices/timer.h</TT></Q>. The default is
1244100 Hz.
1245</P>
1246<P>
1247
1248We don't recommend changing this value, because any changes are likely
1249to cause many of the tests to fail.
1250</P>
1251<P>
1252
1253</P>
1254<DT><B>How long is a time slice?</B>
1255<DD><P>
1256
1257There are <CODE>TIME_SLICE</CODE> ticks per time slice. This macro is
1258declared in <Q><TT>threads/thread.c</TT></Q>. The default is 4 ticks.
1259</P>
1260<P>
1261
1262We don't recommend changing this value, because any changes are likely
1263to cause many of the tests to fail.
1264</P>
1265<P>
1266
1267</P>
1268<DT><B>How do I run the tests?</B>
1269<DD><P>
1270
1271See section <A HREF="pintos_1.html#SEC8">1.2.1 Testing</A>.
1272</P>
1273<P>
1274
1275See section <A HREF="pintos_8.html#SEC100">D.4 Backtraces</A>, for more information.
1276</DL>
1277<P>
1278
1279<A NAME="Alarm Clock FAQ"></A>
1280<HR SIZE="6">
1281<A NAME="SEC35"></A>
1282<H3> 2.4.2 Alarm Clock FAQ </H3>
1283<!--docid::SEC35::-->
1284<P>
1285
1286</P>
1287<DL COMPACT>
1288<DT><B>Do I need to account for timer values overflowing?</B>
1289<DD><P>
1290
1291Don't worry about the possibility of timer values overflowing. Timer
1292values are expressed as signed 64-bit numbers, which at 100 ticks per
1293second should be good for almost 2,924,712,087 years. By then, we
1294expect Pintos to have been phased out of the curriculum.
1295</DL>
1296<P>
1297
1298<A NAME="Userprog FAQ"></A>
1299<HR SIZE="6">
1300<A NAME="SEC36"></A>
1301<H3> 2.4.3 Userprog FAQ </H3>
1302<!--docid::SEC36::-->
1303<P>
1304
1305</P>
1306<DL COMPACT>
1307<DT><B>The kernel always panics when I run <CODE>pintos -p <VAR>file</VAR> -- -q</CODE>.</B>
1308<DD><P>
1309
1310Did you format the file system (with <Q><SAMP>pintos -f</SAMP></Q>)?
1311</P>
1312<P>
1313
1314Is your file name too long? The file system limits file names to 14
1315characters. A command like <Q><SAMP>pintos -p ../../examples/echo -- -q</SAMP></Q>
1316will exceed the limit. Use <Q><SAMP>pintos -p ../../examples/echo -a echo
1317-- -q</SAMP></Q> to put the file under the name <Q><TT>echo</TT></Q> instead.
1318</P>
1319<P>
1320
1321Is the file system full?
1322</P>
1323<P>
1324
1325Does the file system already contain 16 files? The base Pintos file
1326system has a 16-file limit.
1327</P>
1328<P>
1329
1330The file system may be so fragmented that there's not enough contiguous
1331space for your file.
1332</P>
1333<P>
1334
1335</P>
1336<DT><B>When I run <CODE>pintos -p ../file --</CODE>, <Q><TT>file</TT></Q> isn't copied.</B>
1337<DD><P>
1338
1339Files are written under the name you refer to them, by default, so in
1340this case the file copied in would be named <Q><TT>../file</TT></Q>. You
1341probably want to run <CODE>pintos -p ../file -a file --</CODE> instead.
1342</P>
1343<P>
1344
1345You can list the files in your file system with <CODE>pintos -q ls</CODE>.
1346</P>
1347<P>
1348
1349</P>
1350<DT><B>All my user programs die with page faults.</B>
1351<DD><P>
1352
1353This will happen if you haven't implemented argument passing
1354(or haven't done so correctly). The basic C library for user programs tries
1355to read <VAR>argc</VAR> and <VAR>argv</VAR> off the stack. If the stack
1356isn't properly set up, this causes a page fault.
1357</P>
1358<P>
1359
1360</P>
1361<DT><B>How can I disassemble user programs?</B>
1362<DD><P>
1363
1364The <CODE>objdump</CODE> (80<VAR>x</VAR>86) or <CODE>i386-elf-objdump</CODE>
1365(SPARC) utility can disassemble entire user
1366programs or object files. Invoke it as <CODE>objdump -d
1367<VAR>file</VAR></CODE>. You can use GDB's
1368<CODE>disassemble</CODE> command to disassemble individual functions
1369(see section <A HREF="pintos_8.html#SEC102">D.5 GDB</A>).
1370</P>
1371<P>
1372
1373</P>
1374<DT><B>Why do many C include files not work in Pintos programs?</B>
1375<DD><DT><B>Can I use lib<VAR>foo</VAR> in my Pintos programs?</B>
1376<DD><P>
1377
1378The C library we provide is very limited. It does not include many of
1379the features that are expected of a real operating system's C library.
1380The C library must be built specifically for the operating system (and
1381architecture), since it must make system calls for I/O and memory
1382allocation. (Not all functions do, of course, but usually the library
1383is compiled as a unit.)
1384</P>
1385<P>
1386
1387The chances are good that the library you want uses parts of the C library
1388that Pintos doesn't implement. It will probably take at least some
1389porting effort to make it work under Pintos. Notably, the Pintos
1390user program C library does not have a <CODE>malloc()</CODE> implementation.
1391</P>
1392<P>
1393
1394</P>
1395<DT><B>How do I compile new user programs?</B>
1396<DD><P>
1397
1398Modify <Q><TT>src/examples/Makefile</TT></Q>, then run <CODE>make</CODE>.
1399</P>
1400<P>
1401
1402</P>
1403<DT><B>Can I run user programs under a debugger?</B>
1404<DD><P>
1405
1406Yes, with some limitations. See section <A HREF="pintos_8.html#SEC102">D.5 GDB</A>.
1407</P>
1408<P>
1409
1410</P>
1411<DT><B>How can I run user programs that need more than 4 kB stack space?</B>
1412<DD><P>
1413
1414You may modify the stack setup code to allocate more than one page of
1415stack space for each process. In project 2, you will implement a better
1416solution.
1417</P>
1418<P>
1419
1420</P>
1421<DT><B>What happens when an open file is removed?</B>
1422<DD><A NAME="Removing an Open File"></A>
1423<P>
1424
1425You should implement the standard Unix semantics for files. That is, when
1426a file is removed any process which has a file descriptor for that file
1427may continue to use that descriptor. This means that
1428they can read and write from the file. The file will not have a name,
1429and no other processes will be able to open it, but it will continue
1430to exist until all file descriptors referring to the file are closed
1431or the machine shuts down.
1432</P>
1433<P>
1434
1435</DL>
1436<P>
1437
1438<A NAME="Argument Passing FAQ"></A>
1439<HR SIZE="6">
1440<A NAME="SEC37"></A>
1441<H3> 2.4.4 Argument Passing FAQ </H3>
1442<!--docid::SEC37::-->
1443<P>
1444
1445</P>
1446<DL COMPACT>
1447<DT><B>Isn't the top of stack in kernel virtual memory?</B>
1448<DD><P>
1449
1450The top of stack is at <CODE>PHYS_BASE</CODE>, typically <TT>0xc0000000</TT>, which
1451is also where kernel virtual memory starts.
1452But before the processor pushes data on the stack, it decrements the stack
1453pointer. Thus, the first (4-byte) value pushed on the stack
1454will be at address <TT>0xbffffffc</TT>.
1455</P>
1456<P>
1457
1458</P>
1459<DT><B>Is <CODE>PHYS_BASE</CODE> fixed?</B>
1460<DD><P>
1461
1462No. You should be able to support <CODE>PHYS_BASE</CODE> values that are
1463any multiple of <TT>0x10000000</TT> from <TT>0x80000000</TT> to <TT>0xf0000000</TT>,
1464simply via recompilation.
1465</DL>
1466<P>
1467
1468<A NAME="80x86 Calling Convention"></A>
1469<HR SIZE="6">
1470<A NAME="SEC38"></A>
1471<H2> 2.5 80<VAR>x</VAR>86 Calling Convention </H2>
1472<!--docid::SEC38::-->
1473<P>
1474
1475This section summarizes important points of the convention used for
1476normal function calls on 32-bit 80<VAR>x</VAR>86 implementations of Unix.
1477Some details are omitted for brevity. If you do want all the details,
1478refer to [ <A HREF="pintos_10.html#SysV-i386">SysV-i386</A>].
1479</P>
1480<P>
1481
1482The calling convention works like this:
1483</P>
1484<P>
1485
1486<OL>
1487<LI>
1488The caller pushes each of the function's arguments on the stack one by
1489one, normally using the <CODE>PUSH</CODE> assembly language instruction.
1490Arguments are pushed in right-to-left order.
1491<P>
1492
1493The stack grows downward: each push decrements the stack pointer, then
1494stores into the location it now points to, like the C expression
1495<Q><SAMP>*--sp = <VAR>value</VAR></SAMP></Q>.
1496</P>
1497<P>
1498
1499</P>
1500<LI>
1501The caller pushes the address of its next instruction (the <EM>return
1502address</EM>) on the stack and jumps to the first instruction of the callee.
1503A single 80<VAR>x</VAR>86 instruction, <CODE>CALL</CODE>, does both.
1504<P>
1505
1506</P>
1507<LI>
1508The callee executes. When it takes control, the stack pointer points to
1509the return address, the first argument is just above it, the second
1510argument is just above the first argument, and so on.
1511<P>
1512
1513</P>
1514<LI>
1515If the callee has a return value, it stores it into register <CODE>EAX</CODE>.
1516<P>
1517
1518</P>
1519<LI>
1520The callee returns by popping the return address from the stack and
1521jumping to the location it specifies, using the 80<VAR>x</VAR>86 <CODE>RET</CODE>
1522instruction.
1523<P>
1524
1525</P>
1526<LI>
1527The caller pops the arguments off the stack.
1528</OL>
1529<P>
1530
1531Consider a function <CODE>f()</CODE> that takes three <CODE>int</CODE> arguments.
1532This diagram shows a sample stack frame as seen by the callee at the
1533beginning of step 3 above, supposing that <CODE>f()</CODE> is invoked as
1534<CODE>f(1, 2, 3)</CODE>. The initial stack address is arbitrary:
1535</P>
1536<P>
1537
1538<CENTER>
1539<TABLE><tr><td>&nbsp;</td><td class=example><pre> +----------------+
1540 0xbffffe7c | 3 |
1541 0xbffffe78 | 2 |
1542 0xbffffe74 | 1 |
1543stack pointer --&gt; 0xbffffe70 | return address |
1544 +----------------+
1545</pre></td></tr></table></CENTER>
1546<P>
1547
1548<A NAME="Program Startup Details"></A>
1549<HR SIZE="6">
1550<A NAME="SEC39"></A>
1551<H3> 2.5.1 Program Startup Details </H3>
1552<!--docid::SEC39::-->
1553<P>
1554
1555The Pintos C library for user programs designates <CODE>_start()</CODE>, in
1556<Q><TT>lib/user/entry.c</TT></Q>, as the entry point for user programs. This
1557function is a wrapper around <CODE>main()</CODE> that calls <CODE>exit()</CODE> if
1558<CODE>main()</CODE> returns:
1559</P>
1560<P>
1561
1562<TABLE><tr><td>&nbsp;</td><td class=example><pre>void
1563_start (int argc, char *argv[])
1564{
1565 exit (main (argc, argv));
1566}
1567</pre></td></tr></table><P>
1568
1569The kernel must put the arguments for the initial function on the stack
1570before it allows the user program to begin executing. The arguments are
1571passed in the same way as the normal calling convention (see section <A HREF="pintos_2.html#SEC38">2.5 80<VAR>x</VAR>86 Calling Convention</A>).
1572</P>
1573<P>
1574
1575Consider how to handle arguments for the following example command:
1576<Q><SAMP>/bin/ls -l foo bar</SAMP></Q>.
1577First, break the command into words: <Q><SAMP>/bin/ls</SAMP></Q>,
1578<Q><SAMP>-l</SAMP></Q>, <Q><SAMP>foo</SAMP></Q>, <Q><SAMP>bar</SAMP></Q>. Place the words at the top of the
1579stack. Order doesn't matter, because they will be referenced through
1580pointers.
1581</P>
1582<P>
1583
1584Then, push the address of each string plus a null pointer sentinel, on
1585the stack, in right-to-left order. These are the elements of
1586<CODE>argv</CODE>. The null pointer sentinel ensures that <CODE>argv[argc]</CODE>
1587is a null pointer, as required by the C standard. The order ensures
1588that <CODE>argv[0]</CODE> is at the lowest virtual address. Word-aligned
1589accesses are faster than unaligned accesses, so for best performance
1590round the stack pointer down to a multiple of 4 before the first push.
1591</P>
1592<P>
1593
1594Then, push <CODE>argv</CODE> (the address of <CODE>argv[0]</CODE>) and <CODE>argc</CODE>,
1595in that order. Finally, push a fake &quot;return address&quot;: although the
1596entry function will never return, its stack frame must have the same
1597structure as any other.
1598</P>
1599<P>
1600
1601The table below shows the state of the stack and the relevant registers
1602right before the beginning of the user program, assuming
1603<CODE>PHYS_BASE</CODE> is <TT>0xc0000000</TT>:
1604</P>
1605<P>
1606
1607<CENTER>
1608</P>
1609<TABLE>
1610<TR><TD>Address </TD><TD> Name </TD><TD> Data </TD><TD> Type</TD>
1611</TR>
1612<TR><TD><TT>0xbffffffc</TT> </TD><TD> <CODE>argv[3][<small>...</small>]</CODE> </TD><TD> <Q><SAMP>bar\0</SAMP></Q> </TD><TD> <CODE>char[4]</CODE></TD>
1613</TR>
1614<TR><TD><TT>0xbffffff8</TT> </TD><TD> <CODE>argv[2][<small>...</small>]</CODE> </TD><TD> <Q><SAMP>foo\0</SAMP></Q> </TD><TD> <CODE>char[4]</CODE></TD>
1615</TR>
1616<TR><TD><TT>0xbffffff5</TT> </TD><TD> <CODE>argv[1][<small>...</small>]</CODE> </TD><TD> <Q><SAMP>-l\0</SAMP></Q> </TD><TD> <CODE>char[3]</CODE></TD>
1617</TR>
1618<TR><TD><TT>0xbfffffed</TT> </TD><TD> <CODE>argv[0][<small>...</small>]</CODE> </TD><TD> <Q><SAMP>/bin/ls\0</SAMP></Q> </TD><TD> <CODE>char[8]</CODE></TD>
1619</TR>
1620<TR><TD><TT>0xbfffffec</TT> </TD><TD> word-align </TD><TD> 0 </TD><TD> <CODE>uint8_t</CODE></TD>
1621</TR>
1622<TR><TD><TT>0xbfffffe8</TT> </TD><TD> <CODE>argv[4]</CODE> </TD><TD> <TT>0</TT> </TD><TD> <CODE>char *</CODE></TD>
1623</TR>
1624<TR><TD><TT>0xbfffffe4</TT> </TD><TD> <CODE>argv[3]</CODE> </TD><TD> <TT>0xbffffffc</TT> </TD><TD> <CODE>char *</CODE></TD>
1625</TR>
1626<TR><TD><TT>0xbfffffe0</TT> </TD><TD> <CODE>argv[2]</CODE> </TD><TD> <TT>0xbffffff8</TT> </TD><TD> <CODE>char *</CODE></TD>
1627</TR>
1628<TR><TD><TT>0xbfffffdc</TT> </TD><TD> <CODE>argv[1]</CODE> </TD><TD> <TT>0xbffffff5</TT> </TD><TD> <CODE>char *</CODE></TD>
1629</TR>
1630<TR><TD><TT>0xbfffffd8</TT> </TD><TD> <CODE>argv[0]</CODE> </TD><TD> <TT>0xbfffffed</TT> </TD><TD> <CODE>char *</CODE></TD>
1631</TR>
1632<TR><TD><TT>0xbfffffd4</TT> </TD><TD> <CODE>argv</CODE> </TD><TD> <TT>0xbfffffd8</TT> </TD><TD> <CODE>char **</CODE></TD>
1633</TR>
1634<TR><TD><TT>0xbfffffd0</TT> </TD><TD> <CODE>argc</CODE> </TD><TD> 4 </TD><TD> <CODE>int</CODE></TD>
1635</TR>
1636<TR><TD><TT>0xbfffffcc</TT> </TD><TD> return address </TD><TD> 0 </TD><TD> <CODE>void (*) ()</CODE></TD>
1637</TR></TABLE>
1638</CENTER>
1639<P>
1640
1641In this example, the stack pointer would be initialized to
1642<TT>0xbfffffcc</TT>.
1643</P>
1644<P>
1645
1646As shown above, your code should start the stack at the very top of
1647the user virtual address space, in the page just below virtual address
1648<CODE>PHYS_BASE</CODE> (defined in <Q><TT>threads/vaddr.h</TT></Q>).
1649</P>
1650<P>
1651
1652You may find the non-standard <CODE>hex_dump()</CODE> function, declared in
1653<Q><TT>&lt;stdio.h&gt;</TT></Q>, useful for debugging your argument passing code.
1654Here's what it would show in the above example:
1655</P>
1656<P>
1657
1658<TABLE><tr><td>&nbsp;</td><td class=example><pre>bfffffc0 00 00 00 00 | ....|
1659bfffffd0 04 00 00 00 d8 ff ff bf-ed ff ff bf f5 ff ff bf |................|
1660bfffffe0 f8 ff ff bf fc ff ff bf-00 00 00 00 00 2f 62 69 |............./bi|
1661bffffff0 6e 2f 6c 73 00 2d 6c 00-66 6f 6f 00 62 61 72 00 |n/ls.-l.foo.bar.|
1662</pre></td></tr></table><P>
1663
1664<A NAME="System Call Details"></A>
1665<HR SIZE="6">
1666<A NAME="SEC40"></A>
1667<H3> 2.5.2 System Call Details </H3>
1668<!--docid::SEC40::-->
1669<P>
1670
1671We already know one way that the operating system
1672can regain control from a user program: interrupts from timers and I/O
1673devices. These are &quot;external&quot; interrupts, because they are caused
1674by entities outside the CPU (see section <A HREF="pintos_5.html#SEC68">A.4.3 External Interrupt Handling</A>).
1675</P>
1676<P>
1677
1678The operating system also deals with software exceptions, which are
1679events that occur in program code (see section <A HREF="pintos_5.html#SEC67">A.4.2 Internal Interrupt Handling</A>). These can be errors such as a page fault or division by
1680zero. Exceptions are also the means by which a user program
1681can request services (&quot;system calls&quot;) from the operating system.
1682</P>
1683<P>
1684
1685In the 80<VAR>x</VAR>86 architecture, the <Q><SAMP>int</SAMP></Q> instruction is the
1686most commonly used means for invoking system calls. This instruction
1687is handled in the same way as other software exceptions. In Pintos,
1688user programs invoke <Q><SAMP>int $0x30</SAMP></Q> to make a system call. The
1689system call number and any additional arguments are expected to be
1690pushed on the stack in the normal fashion before invoking the
1691interrupt (see section <A HREF="pintos_2.html#SEC38">2.5 80<VAR>x</VAR>86 Calling Convention</A>).
1692</P>
1693<P>
1694
1695Thus, when the system call handler <CODE>syscall_handler()</CODE> gets control,
1696the system call number is in the 32-bit word at the caller's stack
1697pointer, the first argument is in the 32-bit word at the next higher
1698address, and so on. The caller's stack pointer is accessible to
1699<CODE>syscall_handler()</CODE> as the <Q><SAMP>esp</SAMP></Q> member of the
1700<CODE>struct intr_frame</CODE> passed to it. (<CODE>struct intr_frame</CODE> is on the kernel
1701stack.)
1702</P>
1703<P>
1704
1705The 80<VAR>x</VAR>86 convention for function return values is to place them
1706in the <CODE>EAX</CODE> register. System calls that return a value can do
1707so by modifying the <Q><SAMP>eax</SAMP></Q> member of <CODE>struct intr_frame</CODE>.
1708</P>
1709<P>
1710
1711You should try to avoid writing large amounts of repetitive code for
1712implementing system calls. Each system call argument, whether an
1713integer or a pointer, takes up 4 bytes on the stack. You should be able
1714to take advantage of this to avoid writing much near-identical code for
1715retrieving each system call's arguments from the stack.
1716<A NAME="Project 1--Threads"></A>
1717<HR SIZE="6">
1718<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
1719<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos_2.html#SEC15"> &lt;&lt; </A>]</TD>
1720<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos_3.html#SEC41"> &gt;&gt; </A>]</TD>
1721<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos.html#SEC_Top">Top</A>]</TD>
1722<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos.html#SEC_Contents">Contents</A>]</TD>
1723<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
1724<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="pintos_abt.html#SEC_About"> ? </A>]</TD>
1725</TR></TABLE>
1726<BR>
1727<FONT SIZE="-1">
1728This document was generated
1729by on <I>March, 6 2012</I>
1730using <A HREF="http://texi2html.cvshome.org"><I>texi2html</I></A>
1731</FONT>
1732
1733</BODY>
1734</HTML>