update lab1-8 codes and docs. now version is 0.2
This commit is contained in:
		
							parent
							
								
									15f7ebf37b
								
							
						
					
					
						commit
						d537948e30
					
				
							
								
								
									
										774
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										774
									
								
								LICENSE
									
									
									
									
									
								
							@ -1,388 +1,388 @@
 | 
				
			|||||||
		    GNU GENERAL PUBLIC LICENSE
 | 
							    GNU GENERAL PUBLIC LICENSE
 | 
				
			||||||
		       Version 2, June 1991
 | 
							       Version 2, June 1991
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 | 
					 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 | 
				
			||||||
                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
				
			||||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
					 Everyone is permitted to copy and distribute verbatim copies
 | 
				
			||||||
 of this license document, but changing it is not allowed.
 | 
					 of this license document, but changing it is not allowed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			    Preamble
 | 
								    Preamble
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  The licenses for most software are designed to take away your
 | 
					  The licenses for most software are designed to take away your
 | 
				
			||||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
					freedom to share and change it.  By contrast, the GNU General Public
 | 
				
			||||||
License is intended to guarantee your freedom to share and change free
 | 
					License is intended to guarantee your freedom to share and change free
 | 
				
			||||||
software--to make sure the software is free for all its users.  This
 | 
					software--to make sure the software is free for all its users.  This
 | 
				
			||||||
General Public License applies to most of the Free Software
 | 
					General Public License applies to most of the Free Software
 | 
				
			||||||
Foundation's software and to any other program whose authors commit to
 | 
					Foundation's software and to any other program whose authors commit to
 | 
				
			||||||
using it.  (Some other Free Software Foundation software is covered by
 | 
					using it.  (Some other Free Software Foundation software is covered by
 | 
				
			||||||
the GNU Library General Public License instead.)  You can apply it to
 | 
					the GNU Library General Public License instead.)  You can apply it to
 | 
				
			||||||
your programs, too.
 | 
					your programs, too.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  When we speak of free software, we are referring to freedom, not
 | 
					  When we speak of free software, we are referring to freedom, not
 | 
				
			||||||
price.  Our General Public Licenses are designed to make sure that you
 | 
					price.  Our General Public Licenses are designed to make sure that you
 | 
				
			||||||
have the freedom to distribute copies of free software (and charge for
 | 
					have the freedom to distribute copies of free software (and charge for
 | 
				
			||||||
this service if you wish), that you receive source code or can get it
 | 
					this service if you wish), that you receive source code or can get it
 | 
				
			||||||
if you want it, that you can change the software or use pieces of it
 | 
					if you want it, that you can change the software or use pieces of it
 | 
				
			||||||
in new free programs; and that you know you can do these things.
 | 
					in new free programs; and that you know you can do these things.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  To protect your rights, we need to make restrictions that forbid
 | 
					  To protect your rights, we need to make restrictions that forbid
 | 
				
			||||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
					anyone to deny you these rights or to ask you to surrender the rights.
 | 
				
			||||||
These restrictions translate to certain responsibilities for you if you
 | 
					These restrictions translate to certain responsibilities for you if you
 | 
				
			||||||
distribute copies of the software, or if you modify it.
 | 
					distribute copies of the software, or if you modify it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  For example, if you distribute copies of such a program, whether
 | 
					  For example, if you distribute copies of such a program, whether
 | 
				
			||||||
gratis or for a fee, you must give the recipients all the rights that
 | 
					gratis or for a fee, you must give the recipients all the rights that
 | 
				
			||||||
you have.  You must make sure that they, too, receive or can get the
 | 
					you have.  You must make sure that they, too, receive or can get the
 | 
				
			||||||
source code.  And you must show them these terms so they know their
 | 
					source code.  And you must show them these terms so they know their
 | 
				
			||||||
rights.
 | 
					rights.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  We protect your rights with two steps: (1) copyright the software, and
 | 
					  We protect your rights with two steps: (1) copyright the software, and
 | 
				
			||||||
(2) offer you this license which gives you legal permission to copy,
 | 
					(2) offer you this license which gives you legal permission to copy,
 | 
				
			||||||
distribute and/or modify the software.
 | 
					distribute and/or modify the software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Also, for each author's protection and ours, we want to make certain
 | 
					  Also, for each author's protection and ours, we want to make certain
 | 
				
			||||||
that everyone understands that there is no warranty for this free
 | 
					that everyone understands that there is no warranty for this free
 | 
				
			||||||
software.  If the software is modified by someone else and passed on, we
 | 
					software.  If the software is modified by someone else and passed on, we
 | 
				
			||||||
want its recipients to know that what they have is not the original, so
 | 
					want its recipients to know that what they have is not the original, so
 | 
				
			||||||
that any problems introduced by others will not reflect on the original
 | 
					that any problems introduced by others will not reflect on the original
 | 
				
			||||||
authors' reputations.
 | 
					authors' reputations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Finally, any free program is threatened constantly by software
 | 
					  Finally, any free program is threatened constantly by software
 | 
				
			||||||
patents.  We wish to avoid the danger that redistributors of a free
 | 
					patents.  We wish to avoid the danger that redistributors of a free
 | 
				
			||||||
program will individually obtain patent licenses, in effect making the
 | 
					program will individually obtain patent licenses, in effect making the
 | 
				
			||||||
program proprietary.  To prevent this, we have made it clear that any
 | 
					program proprietary.  To prevent this, we have made it clear that any
 | 
				
			||||||
patent must be licensed for everyone's free use or not licensed at all.
 | 
					patent must be licensed for everyone's free use or not licensed at all.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  The precise terms and conditions for copying, distribution and
 | 
					  The precise terms and conditions for copying, distribution and
 | 
				
			||||||
modification follow.
 | 
					modification follow.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		    GNU GENERAL PUBLIC LICENSE
 | 
							    GNU GENERAL PUBLIC LICENSE
 | 
				
			||||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
					   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  0. This License applies to any program or other work which contains
 | 
					  0. This License applies to any program or other work which contains
 | 
				
			||||||
a notice placed by the copyright holder saying it may be distributed
 | 
					a notice placed by the copyright holder saying it may be distributed
 | 
				
			||||||
under the terms of this General Public License.  The "Program", below,
 | 
					under the terms of this General Public License.  The "Program", below,
 | 
				
			||||||
refers to any such program or work, and a "work based on the Program"
 | 
					refers to any such program or work, and a "work based on the Program"
 | 
				
			||||||
means either the Program or any derivative work under copyright law:
 | 
					means either the Program or any derivative work under copyright law:
 | 
				
			||||||
that is to say, a work containing the Program or a portion of it,
 | 
					that is to say, a work containing the Program or a portion of it,
 | 
				
			||||||
either verbatim or with modifications and/or translated into another
 | 
					either verbatim or with modifications and/or translated into another
 | 
				
			||||||
language.  (Hereinafter, translation is included without limitation in
 | 
					language.  (Hereinafter, translation is included without limitation in
 | 
				
			||||||
the term "modification".)  Each licensee is addressed as "you".
 | 
					the term "modification".)  Each licensee is addressed as "you".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Activities other than copying, distribution and modification are not
 | 
					Activities other than copying, distribution and modification are not
 | 
				
			||||||
covered by this License; they are outside its scope.  The act of
 | 
					covered by this License; they are outside its scope.  The act of
 | 
				
			||||||
running the Program is not restricted, and the output from the Program
 | 
					running the Program is not restricted, and the output from the Program
 | 
				
			||||||
is covered only if its contents constitute a work based on the
 | 
					is covered only if its contents constitute a work based on the
 | 
				
			||||||
Program (independent of having been made by running the Program).
 | 
					Program (independent of having been made by running the Program).
 | 
				
			||||||
Whether that is true depends on what the Program does.
 | 
					Whether that is true depends on what the Program does.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  1. You may copy and distribute verbatim copies of the Program's
 | 
					  1. You may copy and distribute verbatim copies of the Program's
 | 
				
			||||||
source code as you receive it, in any medium, provided that you
 | 
					source code as you receive it, in any medium, provided that you
 | 
				
			||||||
conspicuously and appropriately publish on each copy an appropriate
 | 
					conspicuously and appropriately publish on each copy an appropriate
 | 
				
			||||||
copyright notice and disclaimer of warranty; keep intact all the
 | 
					copyright notice and disclaimer of warranty; keep intact all the
 | 
				
			||||||
notices that refer to this License and to the absence of any warranty;
 | 
					notices that refer to this License and to the absence of any warranty;
 | 
				
			||||||
and give any other recipients of the Program a copy of this License
 | 
					and give any other recipients of the Program a copy of this License
 | 
				
			||||||
along with the Program.
 | 
					along with the Program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You may charge a fee for the physical act of transferring a copy, and
 | 
					You may charge a fee for the physical act of transferring a copy, and
 | 
				
			||||||
you may at your option offer warranty protection in exchange for a fee.
 | 
					you may at your option offer warranty protection in exchange for a fee.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  2. You may modify your copy or copies of the Program or any portion
 | 
					  2. You may modify your copy or copies of the Program or any portion
 | 
				
			||||||
of it, thus forming a work based on the Program, and copy and
 | 
					of it, thus forming a work based on the Program, and copy and
 | 
				
			||||||
distribute such modifications or work under the terms of Section 1
 | 
					distribute such modifications or work under the terms of Section 1
 | 
				
			||||||
above, provided that you also meet all of these conditions:
 | 
					above, provided that you also meet all of these conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a) You must cause the modified files to carry prominent notices
 | 
					    a) You must cause the modified files to carry prominent notices
 | 
				
			||||||
    stating that you changed the files and the date of any change.
 | 
					    stating that you changed the files and the date of any change.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    b) You must cause any work that you distribute or publish, that in
 | 
					    b) You must cause any work that you distribute or publish, that in
 | 
				
			||||||
    whole or in part contains or is derived from the Program or any
 | 
					    whole or in part contains or is derived from the Program or any
 | 
				
			||||||
    part thereof, to be licensed as a whole at no charge to all third
 | 
					    part thereof, to be licensed as a whole at no charge to all third
 | 
				
			||||||
    parties under the terms of this License.
 | 
					    parties under the terms of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c) If the modified program normally reads commands interactively
 | 
					    c) If the modified program normally reads commands interactively
 | 
				
			||||||
    when run, you must cause it, when started running for such
 | 
					    when run, you must cause it, when started running for such
 | 
				
			||||||
    interactive use in the most ordinary way, to print or display an
 | 
					    interactive use in the most ordinary way, to print or display an
 | 
				
			||||||
    announcement including an appropriate copyright notice and a
 | 
					    announcement including an appropriate copyright notice and a
 | 
				
			||||||
    notice that there is no warranty (or else, saying that you provide
 | 
					    notice that there is no warranty (or else, saying that you provide
 | 
				
			||||||
    a warranty) and that users may redistribute the program under
 | 
					    a warranty) and that users may redistribute the program under
 | 
				
			||||||
    these conditions, and telling the user how to view a copy of this
 | 
					    these conditions, and telling the user how to view a copy of this
 | 
				
			||||||
    License.  (Exception: if the Program itself is interactive but
 | 
					    License.  (Exception: if the Program itself is interactive but
 | 
				
			||||||
    does not normally print such an announcement, your work based on
 | 
					    does not normally print such an announcement, your work based on
 | 
				
			||||||
    the Program is not required to print an announcement.)
 | 
					    the Program is not required to print an announcement.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
These requirements apply to the modified work as a whole.  If
 | 
					These requirements apply to the modified work as a whole.  If
 | 
				
			||||||
identifiable sections of that work are not derived from the Program,
 | 
					identifiable sections of that work are not derived from the Program,
 | 
				
			||||||
and can be reasonably considered independent and separate works in
 | 
					and can be reasonably considered independent and separate works in
 | 
				
			||||||
themselves, then this License, and its terms, do not apply to those
 | 
					themselves, then this License, and its terms, do not apply to those
 | 
				
			||||||
sections when you distribute them as separate works.  But when you
 | 
					sections when you distribute them as separate works.  But when you
 | 
				
			||||||
distribute the same sections as part of a whole which is a work based
 | 
					distribute the same sections as part of a whole which is a work based
 | 
				
			||||||
on the Program, the distribution of the whole must be on the terms of
 | 
					on the Program, the distribution of the whole must be on the terms of
 | 
				
			||||||
this License, whose permissions for other licensees extend to the
 | 
					this License, whose permissions for other licensees extend to the
 | 
				
			||||||
entire whole, and thus to each and every part regardless of who wrote it.
 | 
					entire whole, and thus to each and every part regardless of who wrote it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thus, it is not the intent of this section to claim rights or contest
 | 
					Thus, it is not the intent of this section to claim rights or contest
 | 
				
			||||||
your rights to work written entirely by you; rather, the intent is to
 | 
					your rights to work written entirely by you; rather, the intent is to
 | 
				
			||||||
exercise the right to control the distribution of derivative or
 | 
					exercise the right to control the distribution of derivative or
 | 
				
			||||||
collective works based on the Program.
 | 
					collective works based on the Program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In addition, mere aggregation of another work not based on the Program
 | 
					In addition, mere aggregation of another work not based on the Program
 | 
				
			||||||
with the Program (or with a work based on the Program) on a volume of
 | 
					with the Program (or with a work based on the Program) on a volume of
 | 
				
			||||||
a storage or distribution medium does not bring the other work under
 | 
					a storage or distribution medium does not bring the other work under
 | 
				
			||||||
the scope of this License.
 | 
					the scope of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  3. You may copy and distribute the Program (or a work based on it,
 | 
					  3. You may copy and distribute the Program (or a work based on it,
 | 
				
			||||||
under Section 2) in object code or executable form under the terms of
 | 
					under Section 2) in object code or executable form under the terms of
 | 
				
			||||||
Sections 1 and 2 above provided that you also do one of the following:
 | 
					Sections 1 and 2 above provided that you also do one of the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a) Accompany it with the complete corresponding machine-readable
 | 
					    a) Accompany it with the complete corresponding machine-readable
 | 
				
			||||||
    source code, which must be distributed under the terms of Sections
 | 
					    source code, which must be distributed under the terms of Sections
 | 
				
			||||||
    1 and 2 above on a medium customarily used for software interchange; or,
 | 
					    1 and 2 above on a medium customarily used for software interchange; or,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    b) Accompany it with a written offer, valid for at least three
 | 
					    b) Accompany it with a written offer, valid for at least three
 | 
				
			||||||
    years, to give any third party, for a charge no more than your
 | 
					    years, to give any third party, for a charge no more than your
 | 
				
			||||||
    cost of physically performing source distribution, a complete
 | 
					    cost of physically performing source distribution, a complete
 | 
				
			||||||
    machine-readable copy of the corresponding source code, to be
 | 
					    machine-readable copy of the corresponding source code, to be
 | 
				
			||||||
    distributed under the terms of Sections 1 and 2 above on a medium
 | 
					    distributed under the terms of Sections 1 and 2 above on a medium
 | 
				
			||||||
    customarily used for software interchange; or,
 | 
					    customarily used for software interchange; or,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c) Accompany it with the information you received as to the offer
 | 
					    c) Accompany it with the information you received as to the offer
 | 
				
			||||||
    to distribute corresponding source code.  (This alternative is
 | 
					    to distribute corresponding source code.  (This alternative is
 | 
				
			||||||
    allowed only for noncommercial distribution and only if you
 | 
					    allowed only for noncommercial distribution and only if you
 | 
				
			||||||
    received the program in object code or executable form with such
 | 
					    received the program in object code or executable form with such
 | 
				
			||||||
    an offer, in accord with Subsection b above.)
 | 
					    an offer, in accord with Subsection b above.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The source code for a work means the preferred form of the work for
 | 
					The source code for a work means the preferred form of the work for
 | 
				
			||||||
making modifications to it.  For an executable work, complete source
 | 
					making modifications to it.  For an executable work, complete source
 | 
				
			||||||
code means all the source code for all modules it contains, plus any
 | 
					code means all the source code for all modules it contains, plus any
 | 
				
			||||||
associated interface definition files, plus the scripts used to
 | 
					associated interface definition files, plus the scripts used to
 | 
				
			||||||
control compilation and installation of the executable.  However, as a
 | 
					control compilation and installation of the executable.  However, as a
 | 
				
			||||||
special exception, the source code distributed need not include
 | 
					special exception, the source code distributed need not include
 | 
				
			||||||
anything that is normally distributed (in either source or binary
 | 
					anything that is normally distributed (in either source or binary
 | 
				
			||||||
form) with the major components (compiler, kernel, and so on) of the
 | 
					form) with the major components (compiler, kernel, and so on) of the
 | 
				
			||||||
operating system on which the executable runs, unless that component
 | 
					operating system on which the executable runs, unless that component
 | 
				
			||||||
itself accompanies the executable.
 | 
					itself accompanies the executable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If distribution of executable or object code is made by offering
 | 
					If distribution of executable or object code is made by offering
 | 
				
			||||||
access to copy from a designated place, then offering equivalent
 | 
					access to copy from a designated place, then offering equivalent
 | 
				
			||||||
access to copy the source code from the same place counts as
 | 
					access to copy the source code from the same place counts as
 | 
				
			||||||
distribution of the source code, even though third parties are not
 | 
					distribution of the source code, even though third parties are not
 | 
				
			||||||
compelled to copy the source along with the object code.
 | 
					compelled to copy the source along with the object code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
					  4. You may not copy, modify, sublicense, or distribute the Program
 | 
				
			||||||
except as expressly provided under this License.  Any attempt
 | 
					except as expressly provided under this License.  Any attempt
 | 
				
			||||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
					otherwise to copy, modify, sublicense or distribute the Program is
 | 
				
			||||||
void, and will automatically terminate your rights under this License.
 | 
					void, and will automatically terminate your rights under this License.
 | 
				
			||||||
However, parties who have received copies, or rights, from you under
 | 
					However, parties who have received copies, or rights, from you under
 | 
				
			||||||
this License will not have their licenses terminated so long as such
 | 
					this License will not have their licenses terminated so long as such
 | 
				
			||||||
parties remain in full compliance.
 | 
					parties remain in full compliance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  5. You are not required to accept this License, since you have not
 | 
					  5. You are not required to accept this License, since you have not
 | 
				
			||||||
signed it.  However, nothing else grants you permission to modify or
 | 
					signed it.  However, nothing else grants you permission to modify or
 | 
				
			||||||
distribute the Program or its derivative works.  These actions are
 | 
					distribute the Program or its derivative works.  These actions are
 | 
				
			||||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
					prohibited by law if you do not accept this License.  Therefore, by
 | 
				
			||||||
modifying or distributing the Program (or any work based on the
 | 
					modifying or distributing the Program (or any work based on the
 | 
				
			||||||
Program), you indicate your acceptance of this License to do so, and
 | 
					Program), you indicate your acceptance of this License to do so, and
 | 
				
			||||||
all its terms and conditions for copying, distributing or modifying
 | 
					all its terms and conditions for copying, distributing or modifying
 | 
				
			||||||
the Program or works based on it.
 | 
					the Program or works based on it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  6. Each time you redistribute the Program (or any work based on the
 | 
					  6. Each time you redistribute the Program (or any work based on the
 | 
				
			||||||
Program), the recipient automatically receives a license from the
 | 
					Program), the recipient automatically receives a license from the
 | 
				
			||||||
original licensor to copy, distribute or modify the Program subject to
 | 
					original licensor to copy, distribute or modify the Program subject to
 | 
				
			||||||
these terms and conditions.  You may not impose any further
 | 
					these terms and conditions.  You may not impose any further
 | 
				
			||||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
					restrictions on the recipients' exercise of the rights granted herein.
 | 
				
			||||||
You are not responsible for enforcing compliance by third parties to
 | 
					You are not responsible for enforcing compliance by third parties to
 | 
				
			||||||
this License.
 | 
					this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  7. If, as a consequence of a court judgment or allegation of patent
 | 
					  7. If, as a consequence of a court judgment or allegation of patent
 | 
				
			||||||
infringement or for any other reason (not limited to patent issues),
 | 
					infringement or for any other reason (not limited to patent issues),
 | 
				
			||||||
conditions are imposed on you (whether by court order, agreement or
 | 
					conditions are imposed on you (whether by court order, agreement or
 | 
				
			||||||
otherwise) that contradict the conditions of this License, they do not
 | 
					otherwise) that contradict the conditions of this License, they do not
 | 
				
			||||||
excuse you from the conditions of this License.  If you cannot
 | 
					excuse you from the conditions of this License.  If you cannot
 | 
				
			||||||
distribute so as to satisfy simultaneously your obligations under this
 | 
					distribute so as to satisfy simultaneously your obligations under this
 | 
				
			||||||
License and any other pertinent obligations, then as a consequence you
 | 
					License and any other pertinent obligations, then as a consequence you
 | 
				
			||||||
may not distribute the Program at all.  For example, if a patent
 | 
					may not distribute the Program at all.  For example, if a patent
 | 
				
			||||||
license would not permit royalty-free redistribution of the Program by
 | 
					license would not permit royalty-free redistribution of the Program by
 | 
				
			||||||
all those who receive copies directly or indirectly through you, then
 | 
					all those who receive copies directly or indirectly through you, then
 | 
				
			||||||
the only way you could satisfy both it and this License would be to
 | 
					the only way you could satisfy both it and this License would be to
 | 
				
			||||||
refrain entirely from distribution of the Program.
 | 
					refrain entirely from distribution of the Program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If any portion of this section is held invalid or unenforceable under
 | 
					If any portion of this section is held invalid or unenforceable under
 | 
				
			||||||
any particular circumstance, the balance of the section is intended to
 | 
					any particular circumstance, the balance of the section is intended to
 | 
				
			||||||
apply and the section as a whole is intended to apply in other
 | 
					apply and the section as a whole is intended to apply in other
 | 
				
			||||||
circumstances.
 | 
					circumstances.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is not the purpose of this section to induce you to infringe any
 | 
					It is not the purpose of this section to induce you to infringe any
 | 
				
			||||||
patents or other property right claims or to contest validity of any
 | 
					patents or other property right claims or to contest validity of any
 | 
				
			||||||
such claims; this section has the sole purpose of protecting the
 | 
					such claims; this section has the sole purpose of protecting the
 | 
				
			||||||
integrity of the free software distribution system, which is
 | 
					integrity of the free software distribution system, which is
 | 
				
			||||||
implemented by public license practices.  Many people have made
 | 
					implemented by public license practices.  Many people have made
 | 
				
			||||||
generous contributions to the wide range of software distributed
 | 
					generous contributions to the wide range of software distributed
 | 
				
			||||||
through that system in reliance on consistent application of that
 | 
					through that system in reliance on consistent application of that
 | 
				
			||||||
system; it is up to the author/donor to decide if he or she is willing
 | 
					system; it is up to the author/donor to decide if he or she is willing
 | 
				
			||||||
to distribute software through any other system and a licensee cannot
 | 
					to distribute software through any other system and a licensee cannot
 | 
				
			||||||
impose that choice.
 | 
					impose that choice.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This section is intended to make thoroughly clear what is believed to
 | 
					This section is intended to make thoroughly clear what is believed to
 | 
				
			||||||
be a consequence of the rest of this License.
 | 
					be a consequence of the rest of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  8. If the distribution and/or use of the Program is restricted in
 | 
					  8. If the distribution and/or use of the Program is restricted in
 | 
				
			||||||
certain countries either by patents or by copyrighted interfaces, the
 | 
					certain countries either by patents or by copyrighted interfaces, the
 | 
				
			||||||
original copyright holder who places the Program under this License
 | 
					original copyright holder who places the Program under this License
 | 
				
			||||||
may add an explicit geographical distribution limitation excluding
 | 
					may add an explicit geographical distribution limitation excluding
 | 
				
			||||||
those countries, so that distribution is permitted only in or among
 | 
					those countries, so that distribution is permitted only in or among
 | 
				
			||||||
countries not thus excluded.  In such case, this License incorporates
 | 
					countries not thus excluded.  In such case, this License incorporates
 | 
				
			||||||
the limitation as if written in the body of this License.
 | 
					the limitation as if written in the body of this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  9. The Free Software Foundation may publish revised and/or new versions
 | 
					  9. The Free Software Foundation may publish revised and/or new versions
 | 
				
			||||||
of the General Public License from time to time.  Such new versions will
 | 
					of the General Public License from time to time.  Such new versions will
 | 
				
			||||||
be similar in spirit to the present version, but may differ in detail to
 | 
					be similar in spirit to the present version, but may differ in detail to
 | 
				
			||||||
address new problems or concerns.
 | 
					address new problems or concerns.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Each version is given a distinguishing version number.  If the Program
 | 
					Each version is given a distinguishing version number.  If the Program
 | 
				
			||||||
specifies a version number of this License which applies to it and "any
 | 
					specifies a version number of this License which applies to it and "any
 | 
				
			||||||
later version", you have the option of following the terms and conditions
 | 
					later version", you have the option of following the terms and conditions
 | 
				
			||||||
either of that version or of any later version published by the Free
 | 
					either of that version or of any later version published by the Free
 | 
				
			||||||
Software Foundation.  If the Program does not specify a version number of
 | 
					Software Foundation.  If the Program does not specify a version number of
 | 
				
			||||||
this License, you may choose any version ever published by the Free Software
 | 
					this License, you may choose any version ever published by the Free Software
 | 
				
			||||||
Foundation.
 | 
					Foundation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  10. If you wish to incorporate parts of the Program into other free
 | 
					  10. If you wish to incorporate parts of the Program into other free
 | 
				
			||||||
programs whose distribution conditions are different, write to the author
 | 
					programs whose distribution conditions are different, write to the author
 | 
				
			||||||
to ask for permission.  For software which is copyrighted by the Free
 | 
					to ask for permission.  For software which is copyrighted by the Free
 | 
				
			||||||
Software Foundation, write to the Free Software Foundation; we sometimes
 | 
					Software Foundation, write to the Free Software Foundation; we sometimes
 | 
				
			||||||
make exceptions for this.  Our decision will be guided by the two goals
 | 
					make exceptions for this.  Our decision will be guided by the two goals
 | 
				
			||||||
of preserving the free status of all derivatives of our free software and
 | 
					of preserving the free status of all derivatives of our free software and
 | 
				
			||||||
of promoting the sharing and reuse of software generally.
 | 
					of promoting the sharing and reuse of software generally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			    NO WARRANTY
 | 
								    NO WARRANTY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
					  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
				
			||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
					FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
				
			||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
					OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
				
			||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
					PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
				
			||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
					OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
					MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
				
			||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
					TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
				
			||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
					PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
				
			||||||
REPAIR OR CORRECTION.
 | 
					REPAIR OR CORRECTION.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
					  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
				
			||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
					WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
				
			||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
					REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
				
			||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
					INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
				
			||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
					OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
				
			||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
					TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
				
			||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
					YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
				
			||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
					PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
				
			||||||
POSSIBILITY OF SUCH DAMAGES.
 | 
					POSSIBILITY OF SUCH DAMAGES.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		     END OF TERMS AND CONDITIONS
 | 
							     END OF TERMS AND CONDITIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    How to Apply These Terms to Your New Programs
 | 
						    How to Apply These Terms to Your New Programs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  If you develop a new program, and you want it to be of the greatest
 | 
					  If you develop a new program, and you want it to be of the greatest
 | 
				
			||||||
possible use to the public, the best way to achieve this is to make it
 | 
					possible use to the public, the best way to achieve this is to make it
 | 
				
			||||||
free software which everyone can redistribute and change under these terms.
 | 
					free software which everyone can redistribute and change under these terms.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  To do so, attach the following notices to the program.  It is safest
 | 
					  To do so, attach the following notices to the program.  It is safest
 | 
				
			||||||
to attach them to the start of each source file to most effectively
 | 
					to attach them to the start of each source file to most effectively
 | 
				
			||||||
convey the exclusion of warranty; and each file should have at least
 | 
					convey the exclusion of warranty; and each file should have at least
 | 
				
			||||||
the "copyright" line and a pointer to where the full notice is found.
 | 
					the "copyright" line and a pointer to where the full notice is found.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
					    <one line to give the program's name and a brief idea of what it does.>
 | 
				
			||||||
    Copyright (C) 19yy  <name of author>
 | 
					    Copyright (C) 19yy  <name of author>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					    This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
    it under the terms of the GNU General Public License as published by
 | 
					    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License
 | 
					    You should have received a copy of the GNU General Public License
 | 
				
			||||||
    along with this program; if not, write to the Free Software
 | 
					    along with this program; if not, write to the Free Software
 | 
				
			||||||
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
					    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Also add information on how to contact you by electronic and paper mail.
 | 
					Also add information on how to contact you by electronic and paper mail.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If the program is interactive, make it output a short notice like this
 | 
					If the program is interactive, make it output a short notice like this
 | 
				
			||||||
when it starts in an interactive mode:
 | 
					when it starts in an interactive mode:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Gnomovision version 69, Copyright (C) 19yy name of author
 | 
					    Gnomovision version 69, Copyright (C) 19yy name of author
 | 
				
			||||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
					    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
				
			||||||
    This is free software, and you are welcome to redistribute it
 | 
					    This is free software, and you are welcome to redistribute it
 | 
				
			||||||
    under certain conditions; type `show c' for details.
 | 
					    under certain conditions; type `show c' for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
					The hypothetical commands `show w' and `show c' should show the appropriate
 | 
				
			||||||
parts of the General Public License.  Of course, the commands you use may
 | 
					parts of the General Public License.  Of course, the commands you use may
 | 
				
			||||||
be called something other than `show w' and `show c'; they could even be
 | 
					be called something other than `show w' and `show c'; they could even be
 | 
				
			||||||
mouse-clicks or menu items--whatever suits your program.
 | 
					mouse-clicks or menu items--whatever suits your program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You should also get your employer (if you work as a programmer) or your
 | 
					You should also get your employer (if you work as a programmer) or your
 | 
				
			||||||
school, if any, to sign a "copyright disclaimer" for the program, if
 | 
					school, if any, to sign a "copyright disclaimer" for the program, if
 | 
				
			||||||
necessary.  Here is a sample; alter the names:
 | 
					necessary.  Here is a sample; alter the names:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
					  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
				
			||||||
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
					  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <signature of Ty Coon>, 1 April 1989
 | 
					  <signature of Ty Coon>, 1 April 1989
 | 
				
			||||||
  Ty Coon, President of Vice
 | 
					  Ty Coon, President of Vice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This General Public License does not permit incorporating your program into
 | 
					This General Public License does not permit incorporating your program into
 | 
				
			||||||
proprietary programs.  If your program is a subroutine library, you may
 | 
					proprietary programs.  If your program is a subroutine library, you may
 | 
				
			||||||
consider it more useful to permit linking proprietary applications with the
 | 
					consider it more useful to permit linking proprietary applications with the
 | 
				
			||||||
library.  If this is what you want to do, use the GNU Library General
 | 
					library.  If this is what you want to do, use the GNU Library General
 | 
				
			||||||
Public License instead of this License.
 | 
					Public License instead of this License.
 | 
				
			||||||
--------------------------------------------------------------------------------------------
 | 
					--------------------------------------------------------------------------------------------
 | 
				
			||||||
Copyright (c) 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox
 | 
					Copyright (c) 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
of this software and associated documentation files (the "Software"), to deal
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
in the Software without restriction, including without limitation the rights
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
copies of the Software, and to permit persons to whom the Software is
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
furnished to do so, subject to the following conditions:
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The above copyright notice and this permission notice shall be included in
 | 
					The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
all copies or substantial portions of the Software.
 | 
					all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
THE SOFTWARE.
 | 
					THE SOFTWARE.
 | 
				
			||||||
--------------------------------------------------------------------------------------------
 | 
					--------------------------------------------------------------------------------------------
 | 
				
			||||||
Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
 | 
					Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
 | 
				
			||||||
 The President and Fellows of Harvard College.
 | 
					 The President and Fellows of Harvard College.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
  Redistribution and use in source and binary forms, with or without
 | 
					  Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
  modification, are permitted provided that the following conditions
 | 
					  modification, are permitted provided that the following conditions
 | 
				
			||||||
  are met:
 | 
					  are met:
 | 
				
			||||||
  1. Redistributions of source code must retain the above copyright
 | 
					  1. Redistributions of source code must retain the above copyright
 | 
				
			||||||
     notice, this list of conditions and the following disclaimer.
 | 
					     notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
  2. Redistributions in binary form must reproduce the above copyright
 | 
					  2. Redistributions in binary form must reproduce the above copyright
 | 
				
			||||||
     notice, this list of conditions and the following disclaimer in the
 | 
					     notice, this list of conditions and the following disclaimer in the
 | 
				
			||||||
     documentation and/or other materials provided with the distribution.
 | 
					     documentation and/or other materials provided with the distribution.
 | 
				
			||||||
  3. Neither the name of the University nor the names of its contributors
 | 
					  3. Neither the name of the University nor the names of its contributors
 | 
				
			||||||
     may be used to endorse or promote products derived from this software
 | 
					     may be used to endorse or promote products derived from this software
 | 
				
			||||||
     without specific prior written permission.
 | 
					     without specific prior written permission.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
  THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
 | 
					  THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
 | 
				
			||||||
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
					  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
				
			||||||
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
					  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
				
			||||||
  ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
 | 
					  ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
 | 
				
			||||||
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
					  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
				
			||||||
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
					  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
				
			||||||
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
					  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
				
			||||||
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
					  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
				
			||||||
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
					  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
				
			||||||
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
					  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
				
			||||||
  SUCH DAMAGE.
 | 
					  SUCH DAMAGE.
 | 
				
			||||||
-------------------------------------------------------------------------------------------
 | 
					-------------------------------------------------------------------------------------------
 | 
				
			||||||
							
								
								
									
										78
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								README
									
									
									
									
									
								
							@ -1,27 +1,51 @@
 | 
				
			|||||||
ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University.
 | 
					INTRODUCTION
 | 
				
			||||||
The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License.
 | 
					------------
 | 
				
			||||||
The codes in the files that constitute OS/161 are written by David A. Holland.
 | 
					ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University.
 | 
				
			||||||
The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License. 
 | 
					The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License.
 | 
				
			||||||
--------------------------------------------------------------
 | 
					The codes in the files that constitute OS/161 are written by David A. Holland.
 | 
				
			||||||
lab1: boot/protect mode/stack/interrupt
 | 
					The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License. 
 | 
				
			||||||
lab2: physical memory management
 | 
					
 | 
				
			||||||
lab3: virtual memory management
 | 
					CONTENTS
 | 
				
			||||||
lab4: kernel thread management
 | 
					--------
 | 
				
			||||||
lab5: user process management
 | 
					lab1: boot/protect mode/stack/interrupt
 | 
				
			||||||
lab6: scheduling
 | 
					lab2: physical memory management
 | 
				
			||||||
lab7: mutex/sync
 | 
					lab3: virtual memory management
 | 
				
			||||||
lab8: filesystem
 | 
					lab4: kernel thread management
 | 
				
			||||||
 | 
					lab5: user process management
 | 
				
			||||||
The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub
 | 
					lab6: scheduling
 | 
				
			||||||
 | 
					lab7: mutex/sync
 | 
				
			||||||
If you have any questions about ucore labs, 
 | 
					lab8: filesystem
 | 
				
			||||||
you can subscribe to the Google Groups "os-course" group (http://groups.google.com/group/oscourse?hl=en.)
 | 
					
 | 
				
			||||||
To post to this group, send email to oscourse@googlegroups.com.
 | 
					EXERCISE STEPS
 | 
				
			||||||
To unsubscribe from this group, send email to oscourse+unsubscribe@googlegroups.com.
 | 
					--------------
 | 
				
			||||||
For more options, visit this group at http://groups.google.com/group/oscourse?hl=en.
 | 
					1 $cd labX  
 | 
				
			||||||
 | 
					2 read codes (specially the modified or added files)
 | 
				
			||||||
If you want to be a developer of ucore or pay attention to the development of ucore, 
 | 
					3 add your code
 | 
				
			||||||
you can subscribe to the Google Groups "ucore_dev" group (http://groups.google.com/group/ucore_dev?hl=en.)
 | 
					4 compile your code
 | 
				
			||||||
To post to this group, send email to ucore_dev@googlegroups.com.
 | 
					  $make
 | 
				
			||||||
To unsubscribe from this group, send email to ucore_dev+unsubscribe@googlegroups.com.
 | 
					5 check your code
 | 
				
			||||||
For more options, visit this group at http://groups.google.com/group/ucore_dev?hl=en.
 | 
					  $make qemu
 | 
				
			||||||
 | 
					OR
 | 
				
			||||||
 | 
					  $make grade
 | 
				
			||||||
 | 
					6 handin your code
 | 
				
			||||||
 | 
					  $make handin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RESOURCE REPOSITORY
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LEARNING DISSCUSS GROUPS
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					If you have any questions about ucore labs, 
 | 
				
			||||||
 | 
					you can subscribe to the Google Groups "os-course" group (http://groups.google.com/group/oscourse?hl=en.)
 | 
				
			||||||
 | 
					To post to this group, send email to oscourse@googlegroups.com.
 | 
				
			||||||
 | 
					To unsubscribe from this group, send email to oscourse+unsubscribe@googlegroups.com.
 | 
				
			||||||
 | 
					For more options, visit this group at http://groups.google.com/group/oscourse?hl=en.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEVELOPMENT DISCUSS GROUPS
 | 
				
			||||||
 | 
					--------------------------
 | 
				
			||||||
 | 
					If you want to be a developer of ucore or pay attention to the development of ucore, 
 | 
				
			||||||
 | 
					you can subscribe to the Google Groups "ucore_dev" group (http://groups.google.com/group/ucore_dev?hl=en.)
 | 
				
			||||||
 | 
					To post to this group, send email to ucore_dev@googlegroups.com.
 | 
				
			||||||
 | 
					To unsubscribe from this group, send email to ucore_dev+unsubscribe@googlegroups.com.
 | 
				
			||||||
 | 
					For more options, visit this group at http://groups.google.com/group/ucore_dev?hl=en.
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* *
 | 
					/* *
 | 
				
			||||||
@ -78,7 +78,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
				
			|||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,9 +8,9 @@
 | 
				
			|||||||
#include <clock.h>
 | 
					#include <clock.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <pmm.h>
 | 
					#include <pmm.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
int kern_init(void) __attribute__((noreturn));
 | 
					int kern_init(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					void grade_backtrace(void);
 | 
				
			||||||
static void lab1_switch_test(void);
 | 
					static void lab1_switch_test(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <sync.h>
 | 
					#include <sync.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STACKFRAME_DEPTH 20
 | 
					#define STACKFRAME_DEPTH 20
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <mmu.h>
 | 
					#include <mmu.h>
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* *
 | 
					/* *
 | 
				
			||||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
				
			|||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,9 +8,10 @@
 | 
				
			|||||||
#include <clock.h>
 | 
					#include <clock.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <pmm.h>
 | 
					#include <pmm.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int kern_init(void) __attribute__((noreturn));
 | 
					int kern_init(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					void grade_backtrace(void);
 | 
				
			||||||
static void lab1_switch_test(void);
 | 
					static void lab1_switch_test(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <sync.h>
 | 
					#include <sync.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STACKFRAME_DEPTH 20
 | 
					#define STACKFRAME_DEPTH 20
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <mmu.h>
 | 
					#include <mmu.h>
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* *
 | 
					/* *
 | 
				
			||||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
				
			|||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,9 +11,10 @@
 | 
				
			|||||||
#include <vmm.h>
 | 
					#include <vmm.h>
 | 
				
			||||||
#include <ide.h>
 | 
					#include <ide.h>
 | 
				
			||||||
#include <swap.h>
 | 
					#include <swap.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int kern_init(void) __attribute__((noreturn));
 | 
					int kern_init(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					void grade_backtrace(void);
 | 
				
			||||||
static void lab1_switch_test(void);
 | 
					static void lab1_switch_test(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick)
 | 
				
			|||||||
                    cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
 | 
					                    cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
 | 
				
			||||||
                  break;
 | 
					                  break;
 | 
				
			||||||
          }          
 | 
					          }          
 | 
				
			||||||
          assert(!PageReserved(page));
 | 
					          //assert(!PageReserved(page));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          //cprintf("SWAP: choose victim page 0x%08x\n", page);
 | 
					          //cprintf("SWAP: choose victim page 0x%08x\n", page);
 | 
				
			||||||
          
 | 
					          
 | 
				
			||||||
@ -272,8 +272,8 @@ check_swap(void)
 | 
				
			|||||||
         struct Page *p = le2page(le, page_link);
 | 
					         struct Page *p = le2page(le, page_link);
 | 
				
			||||||
         count --, total -= p->property;
 | 
					         count --, total -= p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 | 
					     cprintf("count is %d, total is %d\n",count,total);
 | 
				
			||||||
     assert(count == 0);
 | 
					     //assert(count == 0);
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     cprintf("check_swap() succeeded!\n");
 | 
					     cprintf("check_swap() succeeded!\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <sync.h>
 | 
					#include <sync.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STACKFRAME_DEPTH 20
 | 
					#define STACKFRAME_DEPTH 20
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <mmu.h>
 | 
					#include <mmu.h>
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* *
 | 
					/* *
 | 
				
			||||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
				
			|||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,9 +12,10 @@
 | 
				
			|||||||
#include <ide.h>
 | 
					#include <ide.h>
 | 
				
			||||||
#include <swap.h>
 | 
					#include <swap.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int kern_init(void) __attribute__((noreturn));
 | 
					int kern_init(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					void grade_backtrace(void);
 | 
				
			||||||
static void lab1_switch_test(void);
 | 
					static void lab1_switch_test(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
@ -482,7 +482,7 @@ check_slab(void) {
 | 
				
			|||||||
    void *v0, *v1;
 | 
					    void *v0, *v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size_t nr_free_pages_store = nr_free_pages();
 | 
					    size_t nr_free_pages_store = nr_free_pages();
 | 
				
			||||||
    size_t slab_allocated_store = slab_allocated();
 | 
					    size_t kernel_allocated_store = slab_allocated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* slab must be empty now */
 | 
					    /* slab must be empty now */
 | 
				
			||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
@ -628,7 +628,7 @@ check_pass:
 | 
				
			|||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
    assert(slab_allocated() == 0);
 | 
					    assert(slab_allocated() == 0);
 | 
				
			||||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
					    assert(nr_free_pages_store == nr_free_pages());
 | 
				
			||||||
    assert(slab_allocated_store == slab_allocated());
 | 
					    assert(kernel_allocated_store == slab_allocated());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cprintf("check_slab() succeeded!\n");
 | 
					    cprintf("check_slab() succeeded!\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick)
 | 
				
			|||||||
                    cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
 | 
					                    cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
 | 
				
			||||||
                  break;
 | 
					                  break;
 | 
				
			||||||
          }          
 | 
					          }          
 | 
				
			||||||
          assert(!PageReserved(page));
 | 
					          //assert(!PageReserved(page));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          //cprintf("SWAP: choose victim page 0x%08x\n", page);
 | 
					          //cprintf("SWAP: choose victim page 0x%08x\n", page);
 | 
				
			||||||
          
 | 
					          
 | 
				
			||||||
@ -182,7 +182,7 @@ check_swap(void)
 | 
				
			|||||||
     list_entry_t *le = &free_list;
 | 
					     list_entry_t *le = &free_list;
 | 
				
			||||||
     while ((le = list_next(le)) != &free_list) {
 | 
					     while ((le = list_next(le)) != &free_list) {
 | 
				
			||||||
        struct Page *p = le2page(le, page_link);
 | 
					        struct Page *p = le2page(le, page_link);
 | 
				
			||||||
        //assert(PageProperty(p));
 | 
					        assert(PageProperty(p));
 | 
				
			||||||
        count ++, total += p->property;
 | 
					        count ++, total += p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
     assert(total == nr_free_pages());
 | 
					     assert(total == nr_free_pages());
 | 
				
			||||||
@ -272,8 +272,8 @@ check_swap(void)
 | 
				
			|||||||
         struct Page *p = le2page(le, page_link);
 | 
					         struct Page *p = le2page(le, page_link);
 | 
				
			||||||
         count --, total -= p->property;
 | 
					         count --, total -= p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 | 
					     cprintf("count is %d, total is %d\n",count,total);
 | 
				
			||||||
     assert(count == 0);
 | 
					     //assert(count == 0);
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     cprintf("check_swap() succeeded!\n");
 | 
					     cprintf("check_swap() succeeded!\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -304,8 +304,11 @@ quick_check() {
 | 
				
			|||||||
## kernel image
 | 
					## kernel image
 | 
				
			||||||
osimg=$(make_print ucoreimg)
 | 
					osimg=$(make_print ucoreimg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## swap image
 | 
				
			||||||
 | 
					swapimg=$(make_print swapimg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## set default qemu-options
 | 
					## set default qemu-options
 | 
				
			||||||
qemuopts="-hda $osimg"
 | 
					qemuopts="-hda $osimg -drive file=$swapimg,media=disk,cache=writeback"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## set break-function, default is readline
 | 
					## set break-function, default is readline
 | 
				
			||||||
brkfun=readline
 | 
					brkfun=readline
 | 
				
			||||||
@ -316,7 +319,7 @@ quick_run 'Check VMM'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pts=5
 | 
					pts=5
 | 
				
			||||||
quick_check 'check pmm'                                         \
 | 
					quick_check 'check pmm'                                         \
 | 
				
			||||||
    'memory management: buddy_pmm_manager'                      \
 | 
					    'memory management: default_pmm_manager'                      \
 | 
				
			||||||
    'check_alloc_page() succeeded!'                             \
 | 
					    'check_alloc_page() succeeded!'                             \
 | 
				
			||||||
    'check_pgdir() succeeded!'                                  \
 | 
					    'check_pgdir() succeeded!'                                  \
 | 
				
			||||||
    'check_boot_pgdir() succeeded!'
 | 
					    'check_boot_pgdir() succeeded!'
 | 
				
			||||||
@ -340,11 +343,29 @@ quick_check 'check vmm'                                         \
 | 
				
			|||||||
    'check_pgfault() succeeded!'                                \
 | 
					    'check_pgfault() succeeded!'                                \
 | 
				
			||||||
    'check_vmm() succeeded.'
 | 
					    'check_vmm() succeeded.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pts=20
 | 
				
			||||||
 | 
					quick_check 'check swap page fault'                             \
 | 
				
			||||||
 | 
					    'page fault at 0x00001000: K/W [no page found].'            \
 | 
				
			||||||
 | 
					    'page fault at 0x00002000: K/W [no page found].'            \
 | 
				
			||||||
 | 
					    'page fault at 0x00003000: K/W [no page found].'            \
 | 
				
			||||||
 | 
					    'page fault at 0x00004000: K/W [no page found].'            \
 | 
				
			||||||
 | 
					    'write Virt Page e in fifo_check_swap'			\
 | 
				
			||||||
 | 
					    'page fault at 0x00005000: K/W [no page found].'		\
 | 
				
			||||||
 | 
					    'page fault at 0x00001000: K/W [no page found]'		\
 | 
				
			||||||
 | 
					    'page fault at 0x00002000: K/W [no page found].'		\
 | 
				
			||||||
 | 
					    'page fault at 0x00003000: K/W [no page found].'		\
 | 
				
			||||||
 | 
					    'page fault at 0x00004000: K/W [no page found].'		\
 | 
				
			||||||
 | 
					    'check_swap() succeeded!'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pts=5
 | 
					pts=5
 | 
				
			||||||
quick_check 'check ticks'                                       \
 | 
					quick_check 'check ticks'                                       \
 | 
				
			||||||
    '++ setup timer interrupts'                                 \
 | 
					    '++ setup timer interrupts'
 | 
				
			||||||
    '100 ticks'                                                 \
 | 
					
 | 
				
			||||||
    'End of Test.'
 | 
					pts=30
 | 
				
			||||||
 | 
					quick_check 'check initproc'                                    \
 | 
				
			||||||
 | 
					    'this initproc, pid = 1, name = "init"'                     \
 | 
				
			||||||
 | 
					    'To U: "Hello world!!".'                                    \
 | 
				
			||||||
 | 
					    'To U: "en.., Bye, Bye. :)"'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## print final-score
 | 
					## print final-score
 | 
				
			||||||
show_final
 | 
					show_final
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
#include <vmm.h>
 | 
					#include <vmm.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STACKFRAME_DEPTH 20
 | 
					#define STACKFRAME_DEPTH 20
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <mmu.h>
 | 
					#include <mmu.h>
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* *
 | 
					/* *
 | 
				
			||||||
@ -82,7 +82,7 @@ runcmd(char *buf, struct trapframe *tf) {
 | 
				
			|||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <trap.h>
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,9 +12,10 @@
 | 
				
			|||||||
#include <ide.h>
 | 
					#include <ide.h>
 | 
				
			||||||
#include <swap.h>
 | 
					#include <swap.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int kern_init(void) __attribute__((noreturn));
 | 
					int kern_init(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					void grade_backtrace(void);
 | 
				
			||||||
static void lab1_switch_test(void);
 | 
					static void lab1_switch_test(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
@ -487,7 +487,7 @@ check_slab(void) {
 | 
				
			|||||||
    void *v0, *v1;
 | 
					    void *v0, *v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size_t nr_free_pages_store = nr_free_pages();
 | 
					    size_t nr_free_pages_store = nr_free_pages();
 | 
				
			||||||
    size_t slab_allocated_store = slab_allocated();
 | 
					    size_t kernel_allocated_store = slab_allocated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* slab must be empty now */
 | 
					    /* slab must be empty now */
 | 
				
			||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
@ -633,7 +633,7 @@ check_pass:
 | 
				
			|||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
    assert(slab_allocated() == 0);
 | 
					    assert(slab_allocated() == 0);
 | 
				
			||||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
					    assert(nr_free_pages_store == nr_free_pages());
 | 
				
			||||||
    assert(slab_allocated_store == slab_allocated());
 | 
					    assert(kernel_allocated_store == slab_allocated());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cprintf("check_slab() succeeded!\n");
 | 
					    cprintf("check_slab() succeeded!\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -184,7 +184,7 @@ check_swap(void)
 | 
				
			|||||||
     list_entry_t *le = &free_list;
 | 
					     list_entry_t *le = &free_list;
 | 
				
			||||||
     while ((le = list_next(le)) != &free_list) {
 | 
					     while ((le = list_next(le)) != &free_list) {
 | 
				
			||||||
        struct Page *p = le2page(le, page_link);
 | 
					        struct Page *p = le2page(le, page_link);
 | 
				
			||||||
        //assert(PageProperty(p));
 | 
					        assert(PageProperty(p));
 | 
				
			||||||
        count ++, total += p->property;
 | 
					        count ++, total += p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
     assert(total == nr_free_pages());
 | 
					     assert(total == nr_free_pages());
 | 
				
			||||||
@ -277,7 +277,7 @@ check_swap(void)
 | 
				
			|||||||
         struct Page *p = le2page(le, page_link);
 | 
					         struct Page *p = le2page(le, page_link);
 | 
				
			||||||
         count --, total -= p->property;
 | 
					         count --, total -= p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
         cprintf("count is %d, total is %d\n",count,total);
 | 
					     cprintf("count is %d, total is %d\n",count,total);
 | 
				
			||||||
     //assert(count == 0);
 | 
					     //assert(count == 0);
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     cprintf("check_swap() succeeded!\n");
 | 
					     cprintf("check_swap() succeeded!\n");
 | 
				
			||||||
 | 
				
			|||||||
@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
 | 
				
			|||||||
    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
					    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
				
			||||||
    *    swap_map_swappable : set the page swappable
 | 
					    *    swap_map_swappable : set the page swappable
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * LAB5 CHALLENGE ( the implmentation Copy on Write)
 | 
				
			||||||
 | 
							There are 2 situlations when code comes here.
 | 
				
			||||||
 | 
							  1) *ptep & PTE_P == 1, it means one process try to write a readonly page. 
 | 
				
			||||||
 | 
							     If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep.
 | 
				
			||||||
 | 
							     This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method).
 | 
				
			||||||
 | 
							  2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a  swap entry.
 | 
				
			||||||
 | 
							     We should add the LAB3's results here.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
        if(swap_init_ok) {
 | 
					        if(swap_init_ok) {
 | 
				
			||||||
            struct Page *page=NULL;
 | 
					            struct Page *page=NULL;
 | 
				
			||||||
                                    //(1)According to the mm AND addr, try to load the content of right disk page
 | 
					                                    //(1)According to the mm AND addr, try to load the content of right disk page
 | 
				
			||||||
 | 
				
			|||||||
@ -103,6 +103,12 @@ alloc_proc(void) {
 | 
				
			|||||||
     *       uint32_t flags;                             // Process flag
 | 
					     *       uint32_t flags;                             // Process flag
 | 
				
			||||||
     *       char name[PROC_NAME_LEN + 1];               // Process name
 | 
					     *       char name[PROC_NAME_LEN + 1];               // Process name
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					     //LAB5 YOUR CODE : (update LAB4 steps)
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * below fields(add in LAB5) in proc_struct need to be initialized	
 | 
				
			||||||
 | 
					     *       uint32_t wait_state;                        // waiting state
 | 
				
			||||||
 | 
					     *       struct proc_struct *cptr, *yptr, *optr;     // relations between processes
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return proc;
 | 
					    return proc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -389,6 +395,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
 | 
				
			|||||||
    //    5. insert proc_struct into hash_list && proc_list
 | 
					    //    5. insert proc_struct into hash_list && proc_list
 | 
				
			||||||
    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
					    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
				
			||||||
    //    7. set ret vaule using child proc's pid
 | 
					    //    7. set ret vaule using child proc's pid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//LAB5 YOUR CODE : (update LAB4 steps)
 | 
				
			||||||
 | 
					   /* Some Functions
 | 
				
			||||||
 | 
					    *    set_links:  set the relation links of process.  ALSO SEE: remove_links:  lean the relation links of process 
 | 
				
			||||||
 | 
					    *    -------------------
 | 
				
			||||||
 | 
						*    update step 1: set child proc's parent to current process, make sure current process's wait_state is 0
 | 
				
			||||||
 | 
						*    update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
						
 | 
				
			||||||
fork_out:
 | 
					fork_out:
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -771,7 +786,7 @@ user_main(void *arg) {
 | 
				
			|||||||
static int
 | 
					static int
 | 
				
			||||||
init_main(void *arg) {
 | 
					init_main(void *arg) {
 | 
				
			||||||
    size_t nr_free_pages_store = nr_free_pages();
 | 
					    size_t nr_free_pages_store = nr_free_pages();
 | 
				
			||||||
    size_t slab_allocated_store = kallocated();
 | 
					    size_t kernel_allocated_store = kallocated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int pid = kernel_thread(user_main, NULL, 0);
 | 
					    int pid = kernel_thread(user_main, NULL, 0);
 | 
				
			||||||
    if (pid <= 0) {
 | 
					    if (pid <= 0) {
 | 
				
			||||||
@ -788,7 +803,7 @@ init_main(void *arg) {
 | 
				
			|||||||
    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
					    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
				
			||||||
    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
					    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
				
			||||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
					    assert(nr_free_pages_store == nr_free_pages());
 | 
				
			||||||
    assert(slab_allocated_store == kallocated());
 | 
					    assert(kernel_allocated_store == kallocated());
 | 
				
			||||||
    cprintf("init check memory pass.\n");
 | 
					    cprintf("init check memory pass.\n");
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -210,7 +210,7 @@ trap_dispatch(struct trapframe *tf) {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case IRQ_OFFSET + IRQ_TIMER:
 | 
					    case IRQ_OFFSET + IRQ_TIMER:
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
    LAB3 : If some page replacement algorithm need tick to change the priority of pages, 
 | 
					    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
 | 
				
			||||||
    then you can add code here. 
 | 
					    then you can add code here. 
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        /* LAB1 YOUR CODE : STEP 3 */
 | 
					        /* LAB1 YOUR CODE : STEP 3 */
 | 
				
			||||||
 | 
				
			|||||||
@ -512,6 +512,45 @@ run_test -prog 'forktest'   -check default_check
 | 
				
			|||||||
    !   'wait got too many'                                     \
 | 
					    !   'wait got too many'                                     \
 | 
				
			||||||
    ! - 'user panic at .*'
 | 
					    ! - 'user panic at .*'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pts=10
 | 
				
			||||||
 | 
					run_test -prog 'forktree'    -check default_check               \
 | 
				
			||||||
 | 
					        'kernel_execve: pid = 2, name = "forktree".'            \
 | 
				
			||||||
 | 
					      - '....: I am '\'''\'                                     \
 | 
				
			||||||
 | 
					      - '....: I am '\''0'\'                                    \
 | 
				
			||||||
 | 
					      - '....: I am '\'''\'                                     \
 | 
				
			||||||
 | 
					      - '....: I am '\''1'\'                                    \
 | 
				
			||||||
 | 
					      - '....: I am '\''0'\'                                    \
 | 
				
			||||||
 | 
					      - '....: I am '\''01'\'                                   \
 | 
				
			||||||
 | 
					      - '....: I am '\''00'\'                                   \
 | 
				
			||||||
 | 
					      - '....: I am '\''11'\'                                   \
 | 
				
			||||||
 | 
					      - '....: I am '\''10'\'                                   \
 | 
				
			||||||
 | 
					      - '....: I am '\''101'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''100'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''111'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''110'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''001'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''000'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''011'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''010'\'                                  \
 | 
				
			||||||
 | 
					      - '....: I am '\''0101'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''0100'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''0111'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''0110'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''0001'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''0000'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''0011'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''0010'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1101'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1100'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1111'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1110'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1001'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1000'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1011'\'                                 \
 | 
				
			||||||
 | 
					      - '....: I am '\''1010'\'                                 \
 | 
				
			||||||
 | 
					        'all user-mode processes have quit.'                    \
 | 
				
			||||||
 | 
					        'init check memory pass.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## print final-score
 | 
					## print final-score
 | 
				
			||||||
show_final
 | 
					show_final
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEPTH 2
 | 
					#define DEPTH 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void forktree(const char *cur);
 | 
					void forktree(const char *cur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
#include <vmm.h>
 | 
					#include <vmm.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STACKFRAME_DEPTH 20
 | 
					#define STACKFRAME_DEPTH 20
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										132
									
								
								code/lab6/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								code/lab6/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <mmu.h>
 | 
				
			||||||
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * Simple command-line kernel monitor useful for controlling the
 | 
				
			||||||
 | 
					 * kernel and exploring the system interactively.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct command {
 | 
				
			||||||
 | 
					    const char *name;
 | 
				
			||||||
 | 
					    const char *desc;
 | 
				
			||||||
 | 
					    // return -1 to force monitor to exit
 | 
				
			||||||
 | 
					    int(*func)(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct command commands[] = {
 | 
				
			||||||
 | 
					    {"help", "Display this list of commands.", mon_help},
 | 
				
			||||||
 | 
					    {"kerninfo", "Display information about the kernel.", mon_kerninfo},
 | 
				
			||||||
 | 
					    {"backtrace", "Print backtrace of stack frame.", mon_backtrace},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return if kernel is panic, in kern/debug/panic.c */
 | 
				
			||||||
 | 
					bool is_kernel_panic(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Kernel monitor command interpreter *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAXARGS         16
 | 
				
			||||||
 | 
					#define WHITESPACE      " \t\n\r"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* parse - parse the command buffer into whitespace-separated arguments */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					parse(char *buf, char **argv) {
 | 
				
			||||||
 | 
					    int argc = 0;
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        // find global whitespace
 | 
				
			||||||
 | 
					        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
 | 
				
			||||||
 | 
					            *buf ++ = '\0';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (*buf == '\0') {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // save and scan past next arg
 | 
				
			||||||
 | 
					        if (argc == MAXARGS - 1) {
 | 
				
			||||||
 | 
					            cprintf("Too many arguments (max %d).\n", MAXARGS);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        argv[argc ++] = buf;
 | 
				
			||||||
 | 
					        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
 | 
				
			||||||
 | 
					            buf ++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return argc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * runcmd - parse the input string, split it into separated arguments
 | 
				
			||||||
 | 
					 * and then lookup and invoke some related commands/
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					runcmd(char *buf, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    char *argv[MAXARGS];
 | 
				
			||||||
 | 
					    int argc = parse(buf, argv);
 | 
				
			||||||
 | 
					    if (argc == 0) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    for (i = 0; i < NCOMMANDS; i ++) {
 | 
				
			||||||
 | 
					        if (strcmp(commands[i].name, argv[0]) == 0) {
 | 
				
			||||||
 | 
					            return commands[i].func(argc - 1, argv + 1, tf);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cprintf("Unknown command '%s'\n", argv[0]);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tf != NULL) {
 | 
				
			||||||
 | 
					        print_trapframe(tf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *buf;
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        if ((buf = readline("K> ")) != NULL) {
 | 
				
			||||||
 | 
					            if (runcmd(buf, tf) < 0) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* mon_help - print the information about mon_* functions */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_help(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    for (i = 0; i < NCOMMANDS; i ++) {
 | 
				
			||||||
 | 
					        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 | 
				
			||||||
 | 
					 * print the memory occupancy in kernel.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    print_kerninfo();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 | 
				
			||||||
 | 
					 * print a backtrace of the stack.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_backtrace(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    print_stackframe();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								code/lab6/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								code/lab6/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#ifndef __KERN_DEBUG_MONITOR_H__
 | 
				
			||||||
 | 
					#define __KERN_DEBUG_MONITOR_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_backtrace(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_continue(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_step(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_list_dr(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !__KERN_DEBUG_MONITOR_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,132 +0,0 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <mmu.h>
 | 
					 | 
				
			||||||
#include <trap.h>
 | 
					 | 
				
			||||||
#include <monitor.h>
 | 
					 | 
				
			||||||
#include <kdebug.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * Simple command-line kernel monitor useful for controlling the
 | 
					 | 
				
			||||||
 * kernel and exploring the system interactively.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct command {
 | 
					 | 
				
			||||||
    const char *name;
 | 
					 | 
				
			||||||
    const char *desc;
 | 
					 | 
				
			||||||
    // return -1 to force monitor to exit
 | 
					 | 
				
			||||||
    int(*func)(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct command commands[] = {
 | 
					 | 
				
			||||||
    {"help", "Display this list of commands.", mon_help},
 | 
					 | 
				
			||||||
    {"kerninfo", "Display information about the kernel.", mon_kerninfo},
 | 
					 | 
				
			||||||
    {"backtrace", "Print backtrace of stack frame.", mon_backtrace},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* return if kernel is panic, in kern/debug/panic.c */
 | 
					 | 
				
			||||||
bool is_kernel_panic(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***** Kernel monitor command interpreter *****/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAXARGS         16
 | 
					 | 
				
			||||||
#define WHITESPACE      " \t\n\r"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* parse - parse the command buffer into whitespace-separated arguments */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
parse(char *buf, char **argv) {
 | 
					 | 
				
			||||||
    int argc = 0;
 | 
					 | 
				
			||||||
    while (1) {
 | 
					 | 
				
			||||||
        // find global whitespace
 | 
					 | 
				
			||||||
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
 | 
					 | 
				
			||||||
            *buf ++ = '\0';
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (*buf == '\0') {
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // save and scan past next arg
 | 
					 | 
				
			||||||
        if (argc == MAXARGS - 1) {
 | 
					 | 
				
			||||||
            cprintf("Too many arguments (max %d).\n", MAXARGS);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        argv[argc ++] = buf;
 | 
					 | 
				
			||||||
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
 | 
					 | 
				
			||||||
            buf ++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return argc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * runcmd - parse the input string, split it into separated arguments
 | 
					 | 
				
			||||||
 * and then lookup and invoke some related commands/
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
runcmd(char *buf, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    char *argv[MAXARGS];
 | 
					 | 
				
			||||||
    int argc = parse(buf, argv);
 | 
					 | 
				
			||||||
    if (argc == 0) {
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    for (i = 0; i < NCOMMANDS; i ++) {
 | 
					 | 
				
			||||||
        if (strcmp(commands[i].name, argv[0]) == 0) {
 | 
					 | 
				
			||||||
            return commands[i].func(argc - 1, argv + 1, tf);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cprintf("Unknown command '%s'\n", argv[0]);
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (tf != NULL) {
 | 
					 | 
				
			||||||
        print_trapframe(tf);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *buf;
 | 
					 | 
				
			||||||
    while (1) {
 | 
					 | 
				
			||||||
        if ((buf = readline("K> ")) != NULL) {
 | 
					 | 
				
			||||||
            if (runcmd(buf, tf) < 0) {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* mon_help - print the information about mon_* functions */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_help(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    for (i = 0; i < NCOMMANDS; i ++) {
 | 
					 | 
				
			||||||
        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 | 
					 | 
				
			||||||
 * print the memory occupancy in kernel.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    print_kerninfo();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 | 
					 | 
				
			||||||
 * print a backtrace of the stack.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    print_stackframe();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,19 +0,0 @@
 | 
				
			|||||||
#ifndef __KERN_DEBUG_MONITOR_H__
 | 
					 | 
				
			||||||
#define __KERN_DEBUG_MONITOR_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <trap.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_continue(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_step(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* !__KERN_DEBUG_MONITOR_H__ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,9 +12,10 @@
 | 
				
			|||||||
#include <ide.h>
 | 
					#include <ide.h>
 | 
				
			||||||
#include <swap.h>
 | 
					#include <swap.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int kern_init(void) __attribute__((noreturn));
 | 
					int kern_init(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					void grade_backtrace(void);
 | 
				
			||||||
static void lab1_switch_test(void);
 | 
					static void lab1_switch_test(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
@ -487,7 +487,7 @@ check_slab(void) {
 | 
				
			|||||||
    void *v0, *v1;
 | 
					    void *v0, *v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size_t nr_free_pages_store = nr_free_pages();
 | 
					    size_t nr_free_pages_store = nr_free_pages();
 | 
				
			||||||
    size_t slab_allocated_store = slab_allocated();
 | 
					    size_t kernel_allocated_store = slab_allocated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* slab must be empty now */
 | 
					    /* slab must be empty now */
 | 
				
			||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
@ -633,7 +633,7 @@ check_pass:
 | 
				
			|||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
    assert(slab_allocated() == 0);
 | 
					    assert(slab_allocated() == 0);
 | 
				
			||||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
					    assert(nr_free_pages_store == nr_free_pages());
 | 
				
			||||||
    assert(slab_allocated_store == slab_allocated());
 | 
					    assert(kernel_allocated_store == slab_allocated());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cprintf("check_slab() succeeded!\n");
 | 
					    cprintf("check_slab() succeeded!\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -184,7 +184,7 @@ check_swap(void)
 | 
				
			|||||||
     list_entry_t *le = &free_list;
 | 
					     list_entry_t *le = &free_list;
 | 
				
			||||||
     while ((le = list_next(le)) != &free_list) {
 | 
					     while ((le = list_next(le)) != &free_list) {
 | 
				
			||||||
        struct Page *p = le2page(le, page_link);
 | 
					        struct Page *p = le2page(le, page_link);
 | 
				
			||||||
        //assert(PageProperty(p));
 | 
					        assert(PageProperty(p));
 | 
				
			||||||
        count ++, total += p->property;
 | 
					        count ++, total += p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
     assert(total == nr_free_pages());
 | 
					     assert(total == nr_free_pages());
 | 
				
			||||||
@ -277,7 +277,7 @@ check_swap(void)
 | 
				
			|||||||
         struct Page *p = le2page(le, page_link);
 | 
					         struct Page *p = le2page(le, page_link);
 | 
				
			||||||
         count --, total -= p->property;
 | 
					         count --, total -= p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
         cprintf("count is %d, total is %d\n",count,total);
 | 
					     cprintf("count is %d, total is %d\n",count,total);
 | 
				
			||||||
     //assert(count == 0);
 | 
					     //assert(count == 0);
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     cprintf("check_swap() succeeded!\n");
 | 
					     cprintf("check_swap() succeeded!\n");
 | 
				
			||||||
 | 
				
			|||||||
@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
 | 
				
			|||||||
    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
					    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
				
			||||||
    *    swap_map_swappable : set the page swappable
 | 
					    *    swap_map_swappable : set the page swappable
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * LAB5 CHALLENGE ( the implmentation Copy on Write)
 | 
				
			||||||
 | 
							There are 2 situlations when code comes here.
 | 
				
			||||||
 | 
							  1) *ptep & PTE_P == 1, it means one process try to write a readonly page. 
 | 
				
			||||||
 | 
							     If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep.
 | 
				
			||||||
 | 
							     This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method).
 | 
				
			||||||
 | 
							  2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a  swap entry.
 | 
				
			||||||
 | 
							     We should add the LAB3's results here.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
        if(swap_init_ok) {
 | 
					        if(swap_init_ok) {
 | 
				
			||||||
            struct Page *page=NULL;
 | 
					            struct Page *page=NULL;
 | 
				
			||||||
                                    //(1)According to the mm AND addr, try to load the content of right disk page
 | 
					                                    //(1)According to the mm AND addr, try to load the content of right disk page
 | 
				
			||||||
 | 
				
			|||||||
@ -103,6 +103,22 @@ alloc_proc(void) {
 | 
				
			|||||||
     *       uint32_t flags;                             // Process flag
 | 
					     *       uint32_t flags;                             // Process flag
 | 
				
			||||||
     *       char name[PROC_NAME_LEN + 1];               // Process name
 | 
					     *       char name[PROC_NAME_LEN + 1];               // Process name
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					     //LAB5 YOUR CODE : (update LAB4 steps)
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * below fields(add in LAB5) in proc_struct need to be initialized	
 | 
				
			||||||
 | 
					     *       uint32_t wait_state;                        // waiting state
 | 
				
			||||||
 | 
					     *       struct proc_struct *cptr, *yptr, *optr;     // relations between processes
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					     //LAB6 YOUR CODE : (update LAB5 steps)
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * below fields(add in LAB6) in proc_struct need to be initialized
 | 
				
			||||||
 | 
					     *     struct run_queue *rq;                       // running queue contains Process
 | 
				
			||||||
 | 
					     *     list_entry_t run_link;                      // the entry linked in run queue
 | 
				
			||||||
 | 
					     *     int time_slice;                             // time slice for occupying the CPU
 | 
				
			||||||
 | 
					     *     skew_heap_entry_t lab6_run_pool;            // FOR LAB6 ONLY: the entry in the run pool
 | 
				
			||||||
 | 
					     *     uint32_t lab6_stride;                       // FOR LAB6 ONLY: the current stride of the process
 | 
				
			||||||
 | 
					     *     uint32_t lab6_priority;                     // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t)
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return proc;
 | 
					    return proc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -389,6 +405,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
 | 
				
			|||||||
    //    5. insert proc_struct into hash_list && proc_list
 | 
					    //    5. insert proc_struct into hash_list && proc_list
 | 
				
			||||||
    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
					    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
				
			||||||
    //    7. set ret vaule using child proc's pid
 | 
					    //    7. set ret vaule using child proc's pid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//LAB5 YOUR CODE : (update LAB4 steps)
 | 
				
			||||||
 | 
					   /* Some Functions
 | 
				
			||||||
 | 
					    *    set_links:  set the relation links of process.  ALSO SEE: remove_links:  lean the relation links of process 
 | 
				
			||||||
 | 
					    *    -------------------
 | 
				
			||||||
 | 
						*    update step 1: set child proc's parent to current process, make sure current process's wait_state is 0
 | 
				
			||||||
 | 
						*    update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
						
 | 
				
			||||||
fork_out:
 | 
					fork_out:
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -771,7 +796,7 @@ user_main(void *arg) {
 | 
				
			|||||||
static int
 | 
					static int
 | 
				
			||||||
init_main(void *arg) {
 | 
					init_main(void *arg) {
 | 
				
			||||||
    size_t nr_free_pages_store = nr_free_pages();
 | 
					    size_t nr_free_pages_store = nr_free_pages();
 | 
				
			||||||
    size_t slab_allocated_store = kallocated();
 | 
					    size_t kernel_allocated_store = kallocated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int pid = kernel_thread(user_main, NULL, 0);
 | 
					    int pid = kernel_thread(user_main, NULL, 0);
 | 
				
			||||||
    if (pid <= 0) {
 | 
					    if (pid <= 0) {
 | 
				
			||||||
@ -788,7 +813,7 @@ init_main(void *arg) {
 | 
				
			|||||||
    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
					    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
				
			||||||
    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
					    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
				
			||||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
					    assert(nr_free_pages_store == nr_free_pages());
 | 
				
			||||||
    assert(slab_allocated_store == kallocated());
 | 
					    assert(kernel_allocated_store == kallocated());
 | 
				
			||||||
    cprintf("init check memory pass.\n");
 | 
					    cprintf("init check memory pass.\n");
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@
 | 
				
			|||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <default_sched.h>
 | 
					#include <default_sched.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// the list of timer
 | 
				
			||||||
static list_entry_t timer_list;
 | 
					static list_entry_t timer_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sched_class *sched_class;
 | 
					static struct sched_class *sched_class;
 | 
				
			||||||
@ -48,7 +49,7 @@ sched_init(void) {
 | 
				
			|||||||
    sched_class = &default_sched_class;
 | 
					    sched_class = &default_sched_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rq = &__rq;
 | 
					    rq = &__rq;
 | 
				
			||||||
    rq->max_time_slice = 20;
 | 
					    rq->max_time_slice = MAX_TIME_SLICE;
 | 
				
			||||||
    sched_class->init(rq);
 | 
					    sched_class->init(rq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cprintf("sched class: %s\n", sched_class->name);
 | 
					    cprintf("sched class: %s\n", sched_class->name);
 | 
				
			||||||
@ -98,6 +99,7 @@ schedule(void) {
 | 
				
			|||||||
    local_intr_restore(intr_flag);
 | 
					    local_intr_restore(intr_flag);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// add timer to timer_list
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
add_timer(timer_t *timer) {
 | 
					add_timer(timer_t *timer) {
 | 
				
			||||||
    bool intr_flag;
 | 
					    bool intr_flag;
 | 
				
			||||||
@ -120,6 +122,7 @@ add_timer(timer_t *timer) {
 | 
				
			|||||||
    local_intr_restore(intr_flag);
 | 
					    local_intr_restore(intr_flag);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// del timer from timer_list
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
del_timer(timer_t *timer) {
 | 
					del_timer(timer_t *timer) {
 | 
				
			||||||
    bool intr_flag;
 | 
					    bool intr_flag;
 | 
				
			||||||
@ -139,6 +142,7 @@ del_timer(timer_t *timer) {
 | 
				
			|||||||
    local_intr_restore(intr_flag);
 | 
					    local_intr_restore(intr_flag);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
run_timer_list(void) {
 | 
					run_timer_list(void) {
 | 
				
			||||||
    bool intr_flag;
 | 
					    bool intr_flag;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,17 +5,20 @@
 | 
				
			|||||||
#include <list.h>
 | 
					#include <list.h>
 | 
				
			||||||
#include <skew_heap.h>
 | 
					#include <skew_heap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_TIME_SLICE 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct proc_struct;
 | 
					struct proc_struct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    unsigned int expires;
 | 
					    unsigned int expires;       //the expire time
 | 
				
			||||||
    struct proc_struct *proc;
 | 
					    struct proc_struct *proc;   //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
 | 
				
			||||||
    list_entry_t timer_link;
 | 
					    list_entry_t timer_link;    //the timer list
 | 
				
			||||||
} timer_t;
 | 
					} timer_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define le2timer(le, member)            \
 | 
					#define le2timer(le, member)            \
 | 
				
			||||||
to_struct((le), timer_t, member)
 | 
					to_struct((le), timer_t, member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// init a timer
 | 
				
			||||||
static inline timer_t *
 | 
					static inline timer_t *
 | 
				
			||||||
timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
 | 
					timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
 | 
				
			||||||
    timer->expires = expires;
 | 
					    timer->expires = expires;
 | 
				
			||||||
@ -62,9 +65,9 @@ struct run_queue {
 | 
				
			|||||||
void sched_init(void);
 | 
					void sched_init(void);
 | 
				
			||||||
void wakeup_proc(struct proc_struct *proc);
 | 
					void wakeup_proc(struct proc_struct *proc);
 | 
				
			||||||
void schedule(void);
 | 
					void schedule(void);
 | 
				
			||||||
void add_timer(timer_t *timer);
 | 
					void add_timer(timer_t *timer);     // add timer to timer_list
 | 
				
			||||||
void del_timer(timer_t *timer);
 | 
					void del_timer(timer_t *timer);     // del timer from timer_list
 | 
				
			||||||
void run_timer_list(void);
 | 
					void run_timer_list(void);          // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !__KERN_SCHEDULE_SCHED_H__ */
 | 
					#endif /* !__KERN_SCHEDULE_SCHED_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t
 | 
					static int
 | 
				
			||||||
sys_gettime(uint32_t arg[]) {
 | 
					sys_gettime(uint32_t arg[]) {
 | 
				
			||||||
    return (int)ticks;
 | 
					    return (int)ticks;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static uint32_t
 | 
					static int
 | 
				
			||||||
sys_lab6_set_priority(uint32_t arg[])
 | 
					sys_lab6_set_priority(uint32_t arg[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t priority = (uint32_t)arg[0];
 | 
					    uint32_t priority = (uint32_t)arg[0];
 | 
				
			||||||
 | 
				
			|||||||
@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case IRQ_OFFSET + IRQ_TIMER:
 | 
					    case IRQ_OFFSET + IRQ_TIMER:
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
    LAB3 : If some page replacement algorithm need tick to change the priority of pages, 
 | 
					    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
 | 
				
			||||||
    then you can add code here. 
 | 
					    then you can add code here. 
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        /* LAB1 YOUR CODE : STEP 3 */
 | 
					        /* LAB1 YOUR CODE : STEP 3 */
 | 
				
			||||||
@ -224,7 +224,14 @@ trap_dispatch(struct trapframe *tf) {
 | 
				
			|||||||
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
 | 
					        /* you should upate you lab1 code (just add ONE or TWO lines of code):
 | 
				
			||||||
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
 | 
					         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
  
 | 
					        /* LAB6 YOUR CODE */
 | 
				
			||||||
 | 
					        /* IMPORTANT FUNCTIONS:
 | 
				
			||||||
 | 
						     * run_timer_list
 | 
				
			||||||
 | 
						     *----------------------
 | 
				
			||||||
 | 
						     * you should update your lab5 code (just add ONE or TWO lines of code):
 | 
				
			||||||
 | 
					         *    Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
 | 
				
			||||||
 | 
					         *    You can use one funcitons to finish all these things.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case IRQ_OFFSET + IRQ_COM1:
 | 
					    case IRQ_OFFSET + IRQ_COM1:
 | 
				
			||||||
        c = cons_getc();
 | 
					        c = cons_getc();
 | 
				
			||||||
 | 
				
			|||||||
@ -70,7 +70,7 @@ sys_pgdir(void) {
 | 
				
			|||||||
    return syscall(SYS_pgdir);
 | 
					    return syscall(SYS_pgdir);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t
 | 
					int
 | 
				
			||||||
sys_gettime(void) {
 | 
					sys_gettime(void) {
 | 
				
			||||||
    return syscall(SYS_gettime);
 | 
					    return syscall(SYS_gettime);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ int sys_kill(int pid);
 | 
				
			|||||||
int sys_getpid(void);
 | 
					int sys_getpid(void);
 | 
				
			||||||
int sys_putc(int c);
 | 
					int sys_putc(int c);
 | 
				
			||||||
int sys_pgdir(void);
 | 
					int sys_pgdir(void);
 | 
				
			||||||
 | 
					int sys_gettime(void);
 | 
				
			||||||
/* FOR LAB6 ONLY */
 | 
					/* FOR LAB6 ONLY */
 | 
				
			||||||
void sys_lab6_set_priority(uint32_t priority);
 | 
					void sys_lab6_set_priority(uint32_t priority);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
#include <vmm.h>
 | 
					#include <vmm.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STACKFRAME_DEPTH 20
 | 
					#define STACKFRAME_DEPTH 20
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										132
									
								
								code/lab7/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								code/lab7/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <mmu.h>
 | 
				
			||||||
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * Simple command-line kernel monitor useful for controlling the
 | 
				
			||||||
 | 
					 * kernel and exploring the system interactively.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct command {
 | 
				
			||||||
 | 
					    const char *name;
 | 
				
			||||||
 | 
					    const char *desc;
 | 
				
			||||||
 | 
					    // return -1 to force monitor to exit
 | 
				
			||||||
 | 
					    int(*func)(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct command commands[] = {
 | 
				
			||||||
 | 
					    {"help", "Display this list of commands.", mon_help},
 | 
				
			||||||
 | 
					    {"kerninfo", "Display information about the kernel.", mon_kerninfo},
 | 
				
			||||||
 | 
					    {"backtrace", "Print backtrace of stack frame.", mon_backtrace},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return if kernel is panic, in kern/debug/panic.c */
 | 
				
			||||||
 | 
					bool is_kernel_panic(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Kernel monitor command interpreter *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAXARGS         16
 | 
				
			||||||
 | 
					#define WHITESPACE      " \t\n\r"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* parse - parse the command buffer into whitespace-separated arguments */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					parse(char *buf, char **argv) {
 | 
				
			||||||
 | 
					    int argc = 0;
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        // find global whitespace
 | 
				
			||||||
 | 
					        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
 | 
				
			||||||
 | 
					            *buf ++ = '\0';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (*buf == '\0') {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // save and scan past next arg
 | 
				
			||||||
 | 
					        if (argc == MAXARGS - 1) {
 | 
				
			||||||
 | 
					            cprintf("Too many arguments (max %d).\n", MAXARGS);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        argv[argc ++] = buf;
 | 
				
			||||||
 | 
					        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
 | 
				
			||||||
 | 
					            buf ++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return argc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * runcmd - parse the input string, split it into separated arguments
 | 
				
			||||||
 | 
					 * and then lookup and invoke some related commands/
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					runcmd(char *buf, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    char *argv[MAXARGS];
 | 
				
			||||||
 | 
					    int argc = parse(buf, argv);
 | 
				
			||||||
 | 
					    if (argc == 0) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    for (i = 0; i < NCOMMANDS; i ++) {
 | 
				
			||||||
 | 
					        if (strcmp(commands[i].name, argv[0]) == 0) {
 | 
				
			||||||
 | 
					            return commands[i].func(argc - 1, argv + 1, tf);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cprintf("Unknown command '%s'\n", argv[0]);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tf != NULL) {
 | 
				
			||||||
 | 
					        print_trapframe(tf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *buf;
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        if ((buf = readline("K> ")) != NULL) {
 | 
				
			||||||
 | 
					            if (runcmd(buf, tf) < 0) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* mon_help - print the information about mon_* functions */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_help(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    for (i = 0; i < NCOMMANDS; i ++) {
 | 
				
			||||||
 | 
					        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 | 
				
			||||||
 | 
					 * print the memory occupancy in kernel.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    print_kerninfo();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 | 
				
			||||||
 | 
					 * print a backtrace of the stack.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_backtrace(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    print_stackframe();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								code/lab7/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								code/lab7/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#ifndef __KERN_DEBUG_MONITOR_H__
 | 
				
			||||||
 | 
					#define __KERN_DEBUG_MONITOR_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_backtrace(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_continue(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_step(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_list_dr(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !__KERN_DEBUG_MONITOR_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,132 +0,0 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <mmu.h>
 | 
					 | 
				
			||||||
#include <trap.h>
 | 
					 | 
				
			||||||
#include <monitor.h>
 | 
					 | 
				
			||||||
#include <kdebug.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * Simple command-line kernel monitor useful for controlling the
 | 
					 | 
				
			||||||
 * kernel and exploring the system interactively.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct command {
 | 
					 | 
				
			||||||
    const char *name;
 | 
					 | 
				
			||||||
    const char *desc;
 | 
					 | 
				
			||||||
    // return -1 to force monitor to exit
 | 
					 | 
				
			||||||
    int(*func)(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct command commands[] = {
 | 
					 | 
				
			||||||
    {"help", "Display this list of commands.", mon_help},
 | 
					 | 
				
			||||||
    {"kerninfo", "Display information about the kernel.", mon_kerninfo},
 | 
					 | 
				
			||||||
    {"backtrace", "Print backtrace of stack frame.", mon_backtrace},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* return if kernel is panic, in kern/debug/panic.c */
 | 
					 | 
				
			||||||
bool is_kernel_panic(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***** Kernel monitor command interpreter *****/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAXARGS         16
 | 
					 | 
				
			||||||
#define WHITESPACE      " \t\n\r"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* parse - parse the command buffer into whitespace-separated arguments */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
parse(char *buf, char **argv) {
 | 
					 | 
				
			||||||
    int argc = 0;
 | 
					 | 
				
			||||||
    while (1) {
 | 
					 | 
				
			||||||
        // find global whitespace
 | 
					 | 
				
			||||||
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
 | 
					 | 
				
			||||||
            *buf ++ = '\0';
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (*buf == '\0') {
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // save and scan past next arg
 | 
					 | 
				
			||||||
        if (argc == MAXARGS - 1) {
 | 
					 | 
				
			||||||
            cprintf("Too many arguments (max %d).\n", MAXARGS);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        argv[argc ++] = buf;
 | 
					 | 
				
			||||||
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
 | 
					 | 
				
			||||||
            buf ++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return argc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * runcmd - parse the input string, split it into separated arguments
 | 
					 | 
				
			||||||
 * and then lookup and invoke some related commands/
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
runcmd(char *buf, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    char *argv[MAXARGS];
 | 
					 | 
				
			||||||
    int argc = parse(buf, argv);
 | 
					 | 
				
			||||||
    if (argc == 0) {
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    for (i = 0; i < NCOMMANDS; i ++) {
 | 
					 | 
				
			||||||
        if (strcmp(commands[i].name, argv[0]) == 0) {
 | 
					 | 
				
			||||||
            return commands[i].func(argc - 1, argv + 1, tf);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cprintf("Unknown command '%s'\n", argv[0]);
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (tf != NULL) {
 | 
					 | 
				
			||||||
        print_trapframe(tf);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *buf;
 | 
					 | 
				
			||||||
    while (1) {
 | 
					 | 
				
			||||||
        if ((buf = readline("K> ")) != NULL) {
 | 
					 | 
				
			||||||
            if (runcmd(buf, tf) < 0) {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* mon_help - print the information about mon_* functions */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_help(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    for (i = 0; i < NCOMMANDS; i ++) {
 | 
					 | 
				
			||||||
        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 | 
					 | 
				
			||||||
 * print the memory occupancy in kernel.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    print_kerninfo();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 | 
					 | 
				
			||||||
 * print a backtrace of the stack.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    print_stackframe();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,19 +0,0 @@
 | 
				
			|||||||
#ifndef __KERN_DEBUG_MONITOR_H__
 | 
					 | 
				
			||||||
#define __KERN_DEBUG_MONITOR_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <trap.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_continue(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_step(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* !__KERN_DEBUG_MONITOR_H__ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,9 +12,10 @@
 | 
				
			|||||||
#include <ide.h>
 | 
					#include <ide.h>
 | 
				
			||||||
#include <swap.h>
 | 
					#include <swap.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int kern_init(void) __attribute__((noreturn));
 | 
					int kern_init(void) __attribute__((noreturn));
 | 
				
			||||||
 | 
					void grade_backtrace(void);
 | 
				
			||||||
static void lab1_switch_test(void);
 | 
					static void lab1_switch_test(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
 | 
				
			|||||||
@ -487,7 +487,7 @@ check_slab(void) {
 | 
				
			|||||||
    void *v0, *v1;
 | 
					    void *v0, *v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size_t nr_free_pages_store = nr_free_pages();
 | 
					    size_t nr_free_pages_store = nr_free_pages();
 | 
				
			||||||
    size_t slab_allocated_store = slab_allocated();
 | 
					    size_t kernel_allocated_store = slab_allocated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* slab must be empty now */
 | 
					    /* slab must be empty now */
 | 
				
			||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
@ -633,7 +633,7 @@ check_pass:
 | 
				
			|||||||
    check_slab_empty();
 | 
					    check_slab_empty();
 | 
				
			||||||
    assert(slab_allocated() == 0);
 | 
					    assert(slab_allocated() == 0);
 | 
				
			||||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
					    assert(nr_free_pages_store == nr_free_pages());
 | 
				
			||||||
    assert(slab_allocated_store == slab_allocated());
 | 
					    assert(kernel_allocated_store == slab_allocated());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cprintf("check_slab() succeeded!\n");
 | 
					    cprintf("check_slab() succeeded!\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -184,7 +184,7 @@ check_swap(void)
 | 
				
			|||||||
     list_entry_t *le = &free_list;
 | 
					     list_entry_t *le = &free_list;
 | 
				
			||||||
     while ((le = list_next(le)) != &free_list) {
 | 
					     while ((le = list_next(le)) != &free_list) {
 | 
				
			||||||
        struct Page *p = le2page(le, page_link);
 | 
					        struct Page *p = le2page(le, page_link);
 | 
				
			||||||
        //assert(PageProperty(p));
 | 
					        assert(PageProperty(p));
 | 
				
			||||||
        count ++, total += p->property;
 | 
					        count ++, total += p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
     assert(total == nr_free_pages());
 | 
					     assert(total == nr_free_pages());
 | 
				
			||||||
@ -277,7 +277,7 @@ check_swap(void)
 | 
				
			|||||||
         struct Page *p = le2page(le, page_link);
 | 
					         struct Page *p = le2page(le, page_link);
 | 
				
			||||||
         count --, total -= p->property;
 | 
					         count --, total -= p->property;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
         cprintf("count is %d, total is %d\n",count,total);
 | 
					     cprintf("count is %d, total is %d\n",count,total);
 | 
				
			||||||
     //assert(count == 0);
 | 
					     //assert(count == 0);
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     cprintf("check_swap() succeeded!\n");
 | 
					     cprintf("check_swap() succeeded!\n");
 | 
				
			||||||
 | 
				
			|||||||
@ -460,6 +460,15 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
 | 
				
			|||||||
    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
					    *    page_insert : build the map of phy addr of an Page with the linear addr la
 | 
				
			||||||
    *    swap_map_swappable : set the page swappable
 | 
					    *    swap_map_swappable : set the page swappable
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * LAB5 CHALLENGE ( the implmentation Copy on Write)
 | 
				
			||||||
 | 
							There are 2 situlations when code comes here.
 | 
				
			||||||
 | 
							  1) *ptep & PTE_P == 1, it means one process try to write a readonly page. 
 | 
				
			||||||
 | 
							     If the vma includes this addr is writable, then we can set the page writable by rewrite the *ptep.
 | 
				
			||||||
 | 
							     This method could be used to implement the Copy on Write (COW) thchnology(a fast fork process method).
 | 
				
			||||||
 | 
							  2) *ptep & PTE_P == 0 & but *ptep!=0, it means this pte is a  swap entry.
 | 
				
			||||||
 | 
							     We should add the LAB3's results here.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
        if(swap_init_ok) {
 | 
					        if(swap_init_ok) {
 | 
				
			||||||
            struct Page *page=NULL;
 | 
					            struct Page *page=NULL;
 | 
				
			||||||
                                    //(1)According to the mm AND addr, try to load the content of right disk page
 | 
					                                    //(1)According to the mm AND addr, try to load the content of right disk page
 | 
				
			||||||
 | 
				
			|||||||
@ -103,6 +103,22 @@ alloc_proc(void) {
 | 
				
			|||||||
     *       uint32_t flags;                             // Process flag
 | 
					     *       uint32_t flags;                             // Process flag
 | 
				
			||||||
     *       char name[PROC_NAME_LEN + 1];               // Process name
 | 
					     *       char name[PROC_NAME_LEN + 1];               // Process name
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					     //LAB5 YOUR CODE : (update LAB4 steps)
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * below fields(add in LAB5) in proc_struct need to be initialized	
 | 
				
			||||||
 | 
					     *       uint32_t wait_state;                        // waiting state
 | 
				
			||||||
 | 
					     *       struct proc_struct *cptr, *yptr, *optr;     // relations between processes
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					     //LAB6 YOUR CODE : (update LAB5 steps)
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * below fields(add in LAB6) in proc_struct need to be initialized
 | 
				
			||||||
 | 
					     *     struct run_queue *rq;                       // running queue contains Process
 | 
				
			||||||
 | 
					     *     list_entry_t run_link;                      // the entry linked in run queue
 | 
				
			||||||
 | 
					     *     int time_slice;                             // time slice for occupying the CPU
 | 
				
			||||||
 | 
					     *     skew_heap_entry_t lab6_run_pool;            // FOR LAB6 ONLY: the entry in the run pool
 | 
				
			||||||
 | 
					     *     uint32_t lab6_stride;                       // FOR LAB6 ONLY: the current stride of the process
 | 
				
			||||||
 | 
					     *     uint32_t lab6_priority;                     // FOR LAB6 ONLY: the priority of process, set by lab6_set_priority(uint32_t)
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return proc;
 | 
					    return proc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -389,6 +405,15 @@ do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
 | 
				
			|||||||
    //    5. insert proc_struct into hash_list && proc_list
 | 
					    //    5. insert proc_struct into hash_list && proc_list
 | 
				
			||||||
    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
					    //    6. call wakup_proc to make the new child process RUNNABLE
 | 
				
			||||||
    //    7. set ret vaule using child proc's pid
 | 
					    //    7. set ret vaule using child proc's pid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//LAB5 YOUR CODE : (update LAB4 steps)
 | 
				
			||||||
 | 
					   /* Some Functions
 | 
				
			||||||
 | 
					    *    set_links:  set the relation links of process.  ALSO SEE: remove_links:  lean the relation links of process 
 | 
				
			||||||
 | 
					    *    -------------------
 | 
				
			||||||
 | 
						*    update step 1: set child proc's parent to current process, make sure current process's wait_state is 0
 | 
				
			||||||
 | 
						*    update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
						
 | 
				
			||||||
fork_out:
 | 
					fork_out:
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -771,7 +796,7 @@ user_main(void *arg) {
 | 
				
			|||||||
static int
 | 
					static int
 | 
				
			||||||
init_main(void *arg) {
 | 
					init_main(void *arg) {
 | 
				
			||||||
    size_t nr_free_pages_store = nr_free_pages();
 | 
					    size_t nr_free_pages_store = nr_free_pages();
 | 
				
			||||||
    size_t slab_allocated_store = kallocated();
 | 
					    size_t kernel_allocated_store = kallocated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int pid = kernel_thread(user_main, NULL, 0);
 | 
					    int pid = kernel_thread(user_main, NULL, 0);
 | 
				
			||||||
    if (pid <= 0) {
 | 
					    if (pid <= 0) {
 | 
				
			||||||
@ -790,7 +815,7 @@ init_main(void *arg) {
 | 
				
			|||||||
    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
					    assert(list_next(&proc_list) == &(initproc->list_link));
 | 
				
			||||||
    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
					    assert(list_prev(&proc_list) == &(initproc->list_link));
 | 
				
			||||||
    assert(nr_free_pages_store == nr_free_pages());
 | 
					    assert(nr_free_pages_store == nr_free_pages());
 | 
				
			||||||
    assert(slab_allocated_store == kallocated());
 | 
					    assert(kernel_allocated_store == kallocated());
 | 
				
			||||||
    cprintf("init check memory pass.\n");
 | 
					    cprintf("init check memory pass.\n");
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@
 | 
				
			|||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <default_sched.h>
 | 
					#include <default_sched.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// the list of timer
 | 
				
			||||||
static list_entry_t timer_list;
 | 
					static list_entry_t timer_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sched_class *sched_class;
 | 
					static struct sched_class *sched_class;
 | 
				
			||||||
@ -98,6 +99,7 @@ schedule(void) {
 | 
				
			|||||||
    local_intr_restore(intr_flag);
 | 
					    local_intr_restore(intr_flag);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// add timer to timer_list
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
add_timer(timer_t *timer) {
 | 
					add_timer(timer_t *timer) {
 | 
				
			||||||
    bool intr_flag;
 | 
					    bool intr_flag;
 | 
				
			||||||
@ -120,6 +122,7 @@ add_timer(timer_t *timer) {
 | 
				
			|||||||
    local_intr_restore(intr_flag);
 | 
					    local_intr_restore(intr_flag);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// del timer from timer_list
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
del_timer(timer_t *timer) {
 | 
					del_timer(timer_t *timer) {
 | 
				
			||||||
    bool intr_flag;
 | 
					    bool intr_flag;
 | 
				
			||||||
@ -139,6 +142,7 @@ del_timer(timer_t *timer) {
 | 
				
			|||||||
    local_intr_restore(intr_flag);
 | 
					    local_intr_restore(intr_flag);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
run_timer_list(void) {
 | 
					run_timer_list(void) {
 | 
				
			||||||
    bool intr_flag;
 | 
					    bool intr_flag;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,17 +5,20 @@
 | 
				
			|||||||
#include <list.h>
 | 
					#include <list.h>
 | 
				
			||||||
#include <skew_heap.h>
 | 
					#include <skew_heap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_TIME_SLICE 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct proc_struct;
 | 
					struct proc_struct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    unsigned int expires;
 | 
					    unsigned int expires;       //the expire time
 | 
				
			||||||
    struct proc_struct *proc;
 | 
					    struct proc_struct *proc;   //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
 | 
				
			||||||
    list_entry_t timer_link;
 | 
					    list_entry_t timer_link;    //the timer list
 | 
				
			||||||
} timer_t;
 | 
					} timer_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define le2timer(le, member)            \
 | 
					#define le2timer(le, member)            \
 | 
				
			||||||
to_struct((le), timer_t, member)
 | 
					to_struct((le), timer_t, member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// init a timer
 | 
				
			||||||
static inline timer_t *
 | 
					static inline timer_t *
 | 
				
			||||||
timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
 | 
					timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
 | 
				
			||||||
    timer->expires = expires;
 | 
					    timer->expires = expires;
 | 
				
			||||||
@ -62,9 +65,9 @@ struct run_queue {
 | 
				
			|||||||
void sched_init(void);
 | 
					void sched_init(void);
 | 
				
			||||||
void wakeup_proc(struct proc_struct *proc);
 | 
					void wakeup_proc(struct proc_struct *proc);
 | 
				
			||||||
void schedule(void);
 | 
					void schedule(void);
 | 
				
			||||||
void add_timer(timer_t *timer);
 | 
					void add_timer(timer_t *timer);     // add timer to timer_list
 | 
				
			||||||
void del_timer(timer_t *timer);
 | 
					void del_timer(timer_t *timer);     // del timer from timer_list
 | 
				
			||||||
void run_timer_list(void);
 | 
					void run_timer_list(void);          // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !__KERN_SCHEDULE_SCHED_H__ */
 | 
					#endif /* !__KERN_SCHEDULE_SCHED_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -65,11 +65,11 @@ sys_pgdir(uint32_t arg[]) {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t
 | 
					static int
 | 
				
			||||||
sys_gettime(uint32_t arg[]) {
 | 
					sys_gettime(uint32_t arg[]) {
 | 
				
			||||||
    return (int)ticks;
 | 
					    return (int)ticks;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static uint32_t
 | 
					static int
 | 
				
			||||||
sys_lab6_set_priority(uint32_t arg[])
 | 
					sys_lab6_set_priority(uint32_t arg[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t priority = (uint32_t)arg[0];
 | 
					    uint32_t priority = (uint32_t)arg[0];
 | 
				
			||||||
 | 
				
			|||||||
@ -211,7 +211,7 @@ trap_dispatch(struct trapframe *tf) {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case IRQ_OFFSET + IRQ_TIMER:
 | 
					    case IRQ_OFFSET + IRQ_TIMER:
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
    LAB3 : If some page replacement algorithm need tick to change the priority of pages, 
 | 
					    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
 | 
				
			||||||
    then you can add code here. 
 | 
					    then you can add code here. 
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        /* LAB1 YOUR CODE : STEP 3 */
 | 
					        /* LAB1 YOUR CODE : STEP 3 */
 | 
				
			||||||
@ -224,7 +224,14 @@ trap_dispatch(struct trapframe *tf) {
 | 
				
			|||||||
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
 | 
					        /* you should upate you lab1 code (just add ONE or TWO lines of code):
 | 
				
			||||||
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
 | 
					         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
  
 | 
					        /* LAB6 YOUR CODE */
 | 
				
			||||||
 | 
					        /* IMPORTANT FUNCTIONS:
 | 
				
			||||||
 | 
						     * run_timer_list
 | 
				
			||||||
 | 
						     *----------------------
 | 
				
			||||||
 | 
						     * you should update your lab5 code (just add ONE or TWO lines of code):
 | 
				
			||||||
 | 
					         *    Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
 | 
				
			||||||
 | 
					         *    You can use one funcitons to finish all these things.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case IRQ_OFFSET + IRQ_COM1:
 | 
					    case IRQ_OFFSET + IRQ_COM1:
 | 
				
			||||||
        c = cons_getc();
 | 
					        c = cons_getc();
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEPTH 4
 | 
					#define DEPTH 4
 | 
				
			||||||
#define SLEEP_TIME 400
 | 
					
 | 
				
			||||||
void forktree(const char *cur);
 | 
					void forktree(const char *cur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -31,8 +31,6 @@ forktree(const char *cur) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main(void) {
 | 
					main(void) {
 | 
				
			||||||
    cprintf("forktree process will sleep %d ticks\n",SLEEP_TIME);
 | 
					 | 
				
			||||||
    sleep(SLEEP_TIME);
 | 
					 | 
				
			||||||
    forktree("");
 | 
					    forktree("");
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -70,7 +70,7 @@ sys_pgdir(void) {
 | 
				
			|||||||
    return syscall(SYS_pgdir);
 | 
					    return syscall(SYS_pgdir);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t
 | 
					int
 | 
				
			||||||
sys_gettime(void) {
 | 
					sys_gettime(void) {
 | 
				
			||||||
    return syscall(SYS_gettime);
 | 
					    return syscall(SYS_gettime);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ int sys_kill(int pid);
 | 
				
			|||||||
int sys_getpid(void);
 | 
					int sys_getpid(void);
 | 
				
			||||||
int sys_putc(int c);
 | 
					int sys_putc(int c);
 | 
				
			||||||
int sys_pgdir(void);
 | 
					int sys_pgdir(void);
 | 
				
			||||||
 | 
					int sys_gettime(void);
 | 
				
			||||||
/* FOR LAB6 ONLY */
 | 
					/* FOR LAB6 ONLY */
 | 
				
			||||||
void sys_lab6_set_priority(uint32_t priority);
 | 
					void sys_lab6_set_priority(uint32_t priority);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main(void) {
 | 
					main(void) {
 | 
				
			||||||
    int pid, ret, i ,j;
 | 
					    int pid, ret;
 | 
				
			||||||
    cprintf("I am the parent. Forking the child...\n");
 | 
					    cprintf("I am the parent. Forking the child...\n");
 | 
				
			||||||
    pid = fork();
 | 
					    pid = fork();
 | 
				
			||||||
    if (pid== 0) {
 | 
					    if (pid== 0) {
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
#include <vmm.h>
 | 
					#include <vmm.h>
 | 
				
			||||||
#include <proc.h>
 | 
					#include <proc.h>
 | 
				
			||||||
#include <kdebug.h>
 | 
					#include <kdebug.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STACKFRAME_DEPTH 20
 | 
					#define STACKFRAME_DEPTH 20
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										132
									
								
								code/lab8/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								code/lab8/kern/debug/kmonitor.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <mmu.h>
 | 
				
			||||||
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					#include <kdebug.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * Simple command-line kernel monitor useful for controlling the
 | 
				
			||||||
 | 
					 * kernel and exploring the system interactively.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct command {
 | 
				
			||||||
 | 
					    const char *name;
 | 
				
			||||||
 | 
					    const char *desc;
 | 
				
			||||||
 | 
					    // return -1 to force monitor to exit
 | 
				
			||||||
 | 
					    int(*func)(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct command commands[] = {
 | 
				
			||||||
 | 
					    {"help", "Display this list of commands.", mon_help},
 | 
				
			||||||
 | 
					    {"kerninfo", "Display information about the kernel.", mon_kerninfo},
 | 
				
			||||||
 | 
					    {"backtrace", "Print backtrace of stack frame.", mon_backtrace},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* return if kernel is panic, in kern/debug/panic.c */
 | 
				
			||||||
 | 
					bool is_kernel_panic(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Kernel monitor command interpreter *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAXARGS         16
 | 
				
			||||||
 | 
					#define WHITESPACE      " \t\n\r"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* parse - parse the command buffer into whitespace-separated arguments */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					parse(char *buf, char **argv) {
 | 
				
			||||||
 | 
					    int argc = 0;
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        // find global whitespace
 | 
				
			||||||
 | 
					        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
 | 
				
			||||||
 | 
					            *buf ++ = '\0';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (*buf == '\0') {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // save and scan past next arg
 | 
				
			||||||
 | 
					        if (argc == MAXARGS - 1) {
 | 
				
			||||||
 | 
					            cprintf("Too many arguments (max %d).\n", MAXARGS);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        argv[argc ++] = buf;
 | 
				
			||||||
 | 
					        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
 | 
				
			||||||
 | 
					            buf ++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return argc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * runcmd - parse the input string, split it into separated arguments
 | 
				
			||||||
 | 
					 * and then lookup and invoke some related commands/
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					runcmd(char *buf, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    char *argv[MAXARGS];
 | 
				
			||||||
 | 
					    int argc = parse(buf, argv);
 | 
				
			||||||
 | 
					    if (argc == 0) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    for (i = 0; i < NCOMMANDS; i ++) {
 | 
				
			||||||
 | 
					        if (strcmp(commands[i].name, argv[0]) == 0) {
 | 
				
			||||||
 | 
					            return commands[i].func(argc - 1, argv + 1, tf);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cprintf("Unknown command '%s'\n", argv[0]);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Implementations of basic kernel monitor commands *****/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					kmonitor(struct trapframe *tf) {
 | 
				
			||||||
 | 
					    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
				
			||||||
 | 
					    cprintf("Type 'help' for a list of commands.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tf != NULL) {
 | 
				
			||||||
 | 
					        print_trapframe(tf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *buf;
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        if ((buf = readline("K> ")) != NULL) {
 | 
				
			||||||
 | 
					            if (runcmd(buf, tf) < 0) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* mon_help - print the information about mon_* functions */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_help(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    for (i = 0; i < NCOMMANDS; i ++) {
 | 
				
			||||||
 | 
					        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 | 
				
			||||||
 | 
					 * print the memory occupancy in kernel.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    print_kerninfo();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *
 | 
				
			||||||
 | 
					 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 | 
				
			||||||
 | 
					 * print a backtrace of the stack.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					mon_backtrace(int argc, char **argv, struct trapframe *tf) {
 | 
				
			||||||
 | 
					    print_stackframe();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								code/lab8/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								code/lab8/kern/debug/kmonitor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#ifndef __KERN_DEBUG_MONITOR_H__
 | 
				
			||||||
 | 
					#define __KERN_DEBUG_MONITOR_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <trap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void kmonitor(struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_backtrace(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_continue(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_step(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					int mon_list_dr(int argc, char **argv, struct trapframe *tf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !__KERN_DEBUG_MONITOR_H__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,132 +0,0 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <mmu.h>
 | 
					 | 
				
			||||||
#include <trap.h>
 | 
					 | 
				
			||||||
#include <monitor.h>
 | 
					 | 
				
			||||||
#include <kdebug.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * Simple command-line kernel monitor useful for controlling the
 | 
					 | 
				
			||||||
 * kernel and exploring the system interactively.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct command {
 | 
					 | 
				
			||||||
    const char *name;
 | 
					 | 
				
			||||||
    const char *desc;
 | 
					 | 
				
			||||||
    // return -1 to force monitor to exit
 | 
					 | 
				
			||||||
    int(*func)(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct command commands[] = {
 | 
					 | 
				
			||||||
    {"help", "Display this list of commands.", mon_help},
 | 
					 | 
				
			||||||
    {"kerninfo", "Display information about the kernel.", mon_kerninfo},
 | 
					 | 
				
			||||||
    {"backtrace", "Print backtrace of stack frame.", mon_backtrace},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* return if kernel is panic, in kern/debug/panic.c */
 | 
					 | 
				
			||||||
bool is_kernel_panic(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NCOMMANDS (sizeof(commands)/sizeof(struct command))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***** Kernel monitor command interpreter *****/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MAXARGS         16
 | 
					 | 
				
			||||||
#define WHITESPACE      " \t\n\r"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* parse - parse the command buffer into whitespace-separated arguments */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
parse(char *buf, char **argv) {
 | 
					 | 
				
			||||||
    int argc = 0;
 | 
					 | 
				
			||||||
    while (1) {
 | 
					 | 
				
			||||||
        // find global whitespace
 | 
					 | 
				
			||||||
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
 | 
					 | 
				
			||||||
            *buf ++ = '\0';
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (*buf == '\0') {
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // save and scan past next arg
 | 
					 | 
				
			||||||
        if (argc == MAXARGS - 1) {
 | 
					 | 
				
			||||||
            cprintf("Too many arguments (max %d).\n", MAXARGS);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        argv[argc ++] = buf;
 | 
					 | 
				
			||||||
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
 | 
					 | 
				
			||||||
            buf ++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return argc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * runcmd - parse the input string, split it into separated arguments
 | 
					 | 
				
			||||||
 * and then lookup and invoke some related commands/
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
runcmd(char *buf, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    char *argv[MAXARGS];
 | 
					 | 
				
			||||||
    int argc = parse(buf, argv);
 | 
					 | 
				
			||||||
    if (argc == 0) {
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    for (i = 0; i < NCOMMANDS; i ++) {
 | 
					 | 
				
			||||||
        if (strcmp(commands[i].name, argv[0]) == 0) {
 | 
					 | 
				
			||||||
            return commands[i].func(argc - 1, argv + 1, tf);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cprintf("Unknown command '%s'\n", argv[0]);
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***** Implementations of basic kernel monitor commands *****/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
monitor(struct trapframe *tf) {
 | 
					 | 
				
			||||||
    cprintf("Welcome to the kernel debug monitor!!\n");
 | 
					 | 
				
			||||||
    cprintf("Type 'help' for a list of commands.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (tf != NULL) {
 | 
					 | 
				
			||||||
        print_trapframe(tf);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *buf;
 | 
					 | 
				
			||||||
    while (1) {
 | 
					 | 
				
			||||||
        if ((buf = readline("K> ")) != NULL) {
 | 
					 | 
				
			||||||
            if (runcmd(buf, tf) < 0) {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* mon_help - print the information about mon_* functions */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_help(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    for (i = 0; i < NCOMMANDS; i ++) {
 | 
					 | 
				
			||||||
        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 | 
					 | 
				
			||||||
 * print the memory occupancy in kernel.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    print_kerninfo();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* *
 | 
					 | 
				
			||||||
 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 | 
					 | 
				
			||||||
 * print a backtrace of the stack.
 | 
					 | 
				
			||||||
 * */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
 | 
					 | 
				
			||||||
    print_stackframe();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,19 +0,0 @@
 | 
				
			|||||||
#ifndef __KERN_DEBUG_MONITOR_H__
 | 
					 | 
				
			||||||
#define __KERN_DEBUG_MONITOR_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <trap.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void monitor(struct trapframe *tf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int mon_help(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_kerninfo(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_backtrace(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_continue(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_step(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_breakpoint(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_watchpoint(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_delete_dr(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
int mon_list_dr(int argc, char **argv, struct trapframe *tf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* !__KERN_DEBUG_MONITOR_H__ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include <defs.h>
 | 
					#include <defs.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <intr.h>
 | 
					#include <intr.h>
 | 
				
			||||||
#include <monitor.h>
 | 
					#include <kmonitor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool is_panic = 0;
 | 
					static bool is_panic = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +27,7 @@ __panic(const char *file, int line, const char *fmt, ...) {
 | 
				
			|||||||
panic_dead:
 | 
					panic_dead:
 | 
				
			||||||
    intr_disable();
 | 
					    intr_disable();
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        monitor(NULL);
 | 
					        kmonitor(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev_disk0.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev_disk0.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdin.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdin.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdout.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/devs/dev_stdout.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/file.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/file.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/file.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/file.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										2
									
								
								code/lab8/kern/fs/fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										2
									
								
								code/lab8/kern/fs/fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -78,7 +78,7 @@ files_closeall(struct files_struct *filesp) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
dup_fs(struct files_struct *to, struct files_struct *from) {
 | 
					dup_files(struct files_struct *to, struct files_struct *from) {
 | 
				
			||||||
//    cprintf("[dup_fs]\n");
 | 
					//    cprintf("[dup_fs]\n");
 | 
				
			||||||
    assert(to != NULL && from != NULL);
 | 
					    assert(to != NULL && from != NULL);
 | 
				
			||||||
    assert(files_count(to) == 0 && files_count(from) > 0);
 | 
					    assert(files_count(to) == 0 && files_count(from) > 0);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										0
									
								
								code/lab8/kern/fs/fs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/fs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/iobuf.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/iobuf.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/iobuf.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/iobuf.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/bitmap.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_fs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_inode.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_inode.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_io.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_io.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_lock.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/sfs/sfs_lock.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								code/lab8/kern/fs/swap/swapfs.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user