Browse Source

update lab1-8 codes and docs. now version is 0.2

main
chyyuu 12 years ago
parent
commit
d537948e30
144 changed files with 1998 additions and 1735 deletions
  1. +387
    -387
      LICENSE
  2. +51
    -27
      README
  3. +2
    -2
      code/lab1/kern/debug/kmonitor.c
  4. +1
    -1
      code/lab1/kern/debug/kmonitor.h
  5. +2
    -2
      code/lab1/kern/debug/panic.c
  6. +2
    -2
      code/lab1/kern/init/init.c
  7. +1
    -1
      code/lab2/kern/debug/kdebug.c
  8. +2
    -2
      code/lab2/kern/debug/kmonitor.c
  9. +1
    -1
      code/lab2/kern/debug/kmonitor.h
  10. +2
    -2
      code/lab2/kern/debug/panic.c
  11. +2
    -1
      code/lab2/kern/init/init.c
  12. +1
    -1
      code/lab3/kern/debug/kdebug.c
  13. +2
    -2
      code/lab3/kern/debug/kmonitor.c
  14. +1
    -1
      code/lab3/kern/debug/kmonitor.h
  15. +2
    -2
      code/lab3/kern/debug/panic.c
  16. +2
    -1
      code/lab3/kern/init/init.c
  17. +3
    -3
      code/lab3/kern/mm/swap.c
  18. +1
    -1
      code/lab4/kern/debug/kdebug.c
  19. +2
    -2
      code/lab4/kern/debug/kmonitor.c
  20. +1
    -1
      code/lab4/kern/debug/kmonitor.h
  21. +2
    -2
      code/lab4/kern/debug/panic.c
  22. +2
    -1
      code/lab4/kern/init/init.c
  23. +2
    -2
      code/lab4/kern/mm/kmalloc.c
  24. +4
    -4
      code/lab4/kern/mm/swap.c
  25. +26
    -5
      code/lab4/tools/grade.sh
  26. +1
    -1
      code/lab5/kern/debug/kdebug.c
  27. +2
    -2
      code/lab5/kern/debug/kmonitor.c
  28. +1
    -1
      code/lab5/kern/debug/kmonitor.h
  29. +2
    -2
      code/lab5/kern/debug/panic.c
  30. +2
    -1
      code/lab5/kern/init/init.c
  31. +2
    -2
      code/lab5/kern/mm/kmalloc.c
  32. +2
    -2
      code/lab5/kern/mm/swap.c
  33. +9
    -0
      code/lab5/kern/mm/vmm.c
  34. +17
    -2
      code/lab5/kern/process/proc.c
  35. +1
    -1
      code/lab5/kern/trap/trap.c
  36. +39
    -0
      code/lab5/tools/grade.sh
  37. +1
    -1
      code/lab5/user/forktree.c
  38. +1
    -1
      code/lab6/kern/debug/kdebug.c
  39. +132
    -0
      code/lab6/kern/debug/kmonitor.c
  40. +19
    -0
      code/lab6/kern/debug/kmonitor.h
  41. +0
    -132
      code/lab6/kern/debug/monitor.c
  42. +0
    -19
      code/lab6/kern/debug/monitor.h
  43. +2
    -2
      code/lab6/kern/debug/panic.c
  44. +2
    -1
      code/lab6/kern/init/init.c
  45. +2
    -2
      code/lab6/kern/mm/kmalloc.c
  46. +2
    -2
      code/lab6/kern/mm/swap.c
  47. +9
    -0
      code/lab6/kern/mm/vmm.c
  48. +27
    -2
      code/lab6/kern/process/proc.c
  49. +5
    -1
      code/lab6/kern/schedule/sched.c
  50. +9
    -6
      code/lab6/kern/schedule/sched.h
  51. +2
    -2
      code/lab6/kern/syscall/syscall.c
  52. +9
    -2
      code/lab6/kern/trap/trap.c
  53. +1
    -1
      code/lab6/user/libs/syscall.c
  54. +1
    -0
      code/lab6/user/libs/syscall.h
  55. +1
    -1
      code/lab7/kern/debug/kdebug.c
  56. +132
    -0
      code/lab7/kern/debug/kmonitor.c
  57. +19
    -0
      code/lab7/kern/debug/kmonitor.h
  58. +0
    -132
      code/lab7/kern/debug/monitor.c
  59. +0
    -19
      code/lab7/kern/debug/monitor.h
  60. +2
    -2
      code/lab7/kern/debug/panic.c
  61. +2
    -1
      code/lab7/kern/init/init.c
  62. +2
    -2
      code/lab7/kern/mm/kmalloc.c
  63. +2
    -2
      code/lab7/kern/mm/swap.c
  64. +9
    -0
      code/lab7/kern/mm/vmm.c
  65. +27
    -2
      code/lab7/kern/process/proc.c
  66. +4
    -0
      code/lab7/kern/schedule/sched.c
  67. +9
    -6
      code/lab7/kern/schedule/sched.h
  68. +2
    -2
      code/lab7/kern/syscall/syscall.c
  69. +9
    -2
      code/lab7/kern/trap/trap.c
  70. +1
    -3
      code/lab7/user/forktree.c
  71. +1
    -1
      code/lab7/user/libs/syscall.c
  72. +1
    -0
      code/lab7/user/libs/syscall.h
  73. +1
    -1
      code/lab7/user/spin.c
  74. +1
    -1
      code/lab8/kern/debug/kdebug.c
  75. +132
    -0
      code/lab8/kern/debug/kmonitor.c
  76. +19
    -0
      code/lab8/kern/debug/kmonitor.h
  77. +0
    -132
      code/lab8/kern/debug/monitor.c
  78. +0
    -19
      code/lab8/kern/debug/monitor.h
  79. +2
    -2
      code/lab8/kern/debug/panic.c
  80. +0
    -0
      code/lab8/kern/fs/devs/dev.c
  81. +0
    -0
      code/lab8/kern/fs/devs/dev.h
  82. +0
    -0
      code/lab8/kern/fs/devs/dev_disk0.c
  83. +0
    -0
      code/lab8/kern/fs/devs/dev_stdin.c
  84. +0
    -0
      code/lab8/kern/fs/devs/dev_stdout.c
  85. +0
    -0
      code/lab8/kern/fs/file.c
  86. +0
    -0
      code/lab8/kern/fs/file.h
  87. +1
    -1
      code/lab8/kern/fs/fs.c
  88. +0
    -0
      code/lab8/kern/fs/fs.h
  89. +0
    -0
      code/lab8/kern/fs/iobuf.c
  90. +0
    -0
      code/lab8/kern/fs/iobuf.h
  91. +0
    -0
      code/lab8/kern/fs/sfs/bitmap.c
  92. +0
    -0
      code/lab8/kern/fs/sfs/bitmap.h
  93. +0
    -0
      code/lab8/kern/fs/sfs/sfs.c
  94. +0
    -0
      code/lab8/kern/fs/sfs/sfs.h
  95. +0
    -0
      code/lab8/kern/fs/sfs/sfs_fs.c
  96. +0
    -0
      code/lab8/kern/fs/sfs/sfs_inode.c
  97. +0
    -0
      code/lab8/kern/fs/sfs/sfs_io.c
  98. +0
    -0
      code/lab8/kern/fs/sfs/sfs_lock.c
  99. +0
    -0
      code/lab8/kern/fs/swap/swapfs.c
  100. +0
    -0
      code/lab8/kern/fs/swap/swapfs.h

+ 387
- 387
LICENSE View File

@ -1,388 +1,388 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
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
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
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
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.
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.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
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
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
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
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
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
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.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
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"
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,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
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
along with the Program.
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.
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
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
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
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
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
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
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
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
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works 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
a storage or distribution medium does not bring the other work under
the scope of this License.
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
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
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
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
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
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
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
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
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
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
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
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
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
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
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
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 promoting the sharing and reuse of software generally.
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
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
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
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
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
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
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
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
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 attach them to the start of each source file to most effectively
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
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.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
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
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
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
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
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
Public License instead of this License.
--------------------------------------------------------------------------------------------
Copyright (c) 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
--------------------------------------------------------------------------------------------
Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
The President and Fellows of Harvard College.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
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
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
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
SUCH DAMAGE.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
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
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
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
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.
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.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
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
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
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
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
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
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.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
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"
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,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
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
along with the Program.
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.
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
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
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
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
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
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
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
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
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works 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
a storage or distribution medium does not bring the other work under
the scope of this License.
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
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
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
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
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
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
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
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
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
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
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
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
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
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
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
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 promoting the sharing and reuse of software generally.
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
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
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
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
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
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
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
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
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 attach them to the start of each source file to most effectively
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
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.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
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
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
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
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
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
Public License instead of this License.
--------------------------------------------------------------------------------------------
Copyright (c) 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
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
THE SOFTWARE.
--------------------------------------------------------------------------------------------
Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
The President and Fellows of Harvard College.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
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
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
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
SUCH DAMAGE.
------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------

+ 51
- 27
README View File

@ -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.
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.
The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License.
--------------------------------------------------------------
lab1: boot/protect mode/stack/interrupt
lab2: physical memory management
lab3: virtual memory management
lab4: kernel thread management
lab5: user process management
lab6: scheduling
lab7: mutex/sync
lab8: filesystem
The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub
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.
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.
INTRODUCTION
------------
ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University.
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.
The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License.
CONTENTS
--------
lab1: boot/protect mode/stack/interrupt
lab2: physical memory management
lab3: virtual memory management
lab4: kernel thread management
lab5: user process management
lab6: scheduling
lab7: mutex/sync
lab8: filesystem
EXERCISE STEPS
--------------
1 $cd labX
2 read codes (specially the modified or added files)
3 add your code
4 compile your code
$make
5 check your code
$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.

code/lab1/kern/debug/monitor.c → code/lab1/kern/debug/kmonitor.c View File

@ -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");

code/lab1/kern/debug/monitor.h → code/lab1/kern/debug/kmonitor.h View File

@ -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);

+ 2
- 2
code/lab1/kern/debug/panic.c View File

@ -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);
} }
} }

+ 2
- 2
code/lab1/kern/init/init.c View File

@ -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

+ 1
- 1
code/lab2/kern/debug/kdebug.c View File

@ -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

code/lab5/kern/debug/monitor.c → code/lab2/kern/debug/kmonitor.c View File

@ -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");

code/lab3/kern/debug/monitor.h → code/lab2/kern/debug/kmonitor.h View File

@ -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);

+ 2
- 2
code/lab2/kern/debug/panic.c View File

@ -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);
} }
} }

+ 2
- 1
code/lab2/kern/init/init.c View File

@ -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

+ 1
- 1
code/lab3/kern/debug/kdebug.c View File

@ -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

code/lab3/kern/debug/monitor.c → code/lab3/kern/debug/kmonitor.c View File

@ -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");

code/lab4/kern/debug/monitor.h → code/lab3/kern/debug/kmonitor.h View File

@ -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);

+ 2
- 2
code/lab3/kern/debug/panic.c View File

@ -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);
} }
} }

+ 2
- 1
code/lab3/kern/init/init.c View File

@ -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

+ 3
- 3
code/lab3/kern/mm/swap.c View File

@ -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;
} }
assert(count == 0);
cprintf("count is %d, total is %d\n",count,total);
//assert(count == 0);
cprintf("check_swap() succeeded!\n"); cprintf("check_swap() succeeded!\n");
} }

+ 1
- 1
code/lab4/kern/debug/kdebug.c View File

@ -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

code/lab2/kern/debug/monitor.c → code/lab4/kern/debug/kmonitor.c View File

@ -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");

code/lab5/kern/debug/monitor.h → code/lab4/kern/debug/kmonitor.h View File

@ -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);

+ 2
- 2
code/lab4/kern/debug/panic.c View File

@ -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);
} }
} }

+ 2
- 1
code/lab4/kern/init/init.c View File

@ -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

+ 2
- 2
code/lab4/kern/mm/kmalloc.c View File

@ -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");
} }

+ 4
- 4
code/lab4/kern/mm/swap.c View File

@ -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;
} }
assert(count == 0);
cprintf("count is %d, total is %d\n",count,total);
//assert(count == 0);
cprintf("check_swap() succeeded!\n"); cprintf("check_swap() succeeded!\n");
} }

+ 26
- 5
code/lab4/tools/grade.sh View File

@ -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' \
'100 ticks' \
'End of Test.'
'++ setup timer interrupts'
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

+ 1
- 1
code/lab5/kern/debug/kdebug.c View File

@ -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

code/lab4/kern/debug/monitor.c → code/lab5/kern/debug/kmonitor.c View File

@ -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");

code/lab2/kern/debug/monitor.h → code/lab5/kern/debug/kmonitor.h View File

@ -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);

+ 2
- 2
code/lab5/kern/debug/panic.c View File

@ -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);
} }
} }

+ 2
- 1
code/lab5/kern/init/init.c View File

@ -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

+ 2
- 2
code/lab5/kern/mm/kmalloc.c View File

@ -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");
} }

+ 2
- 2
code/lab5/kern/mm/swap.c View File

@ -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");

+ 9
- 0
code/lab5/kern/mm/vmm.c View File

@ -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;
//(1According to the mm AND addr, try to load the content of right disk page //(1According to the mm AND addr, try to load the content of right disk page

+ 17
- 2
code/lab5/kern/process/proc.c View File

@ -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;
} }

+ 1
- 1
code/lab5/kern/trap/trap.c View File

@ -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 */

+ 39
- 0
code/lab5/tools/grade.sh View File

@ -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

+ 1
- 1
code/lab5/user/forktree.c View File

@ -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);

+ 1
- 1
code/lab6/kern/debug/kdebug.c View File

@ -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
- 0
code/lab6/kern/debug/kmonitor.c View 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
- 0
code/lab6/kern/debug/kmonitor.h View 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__ */

+ 0
- 132
code/lab6/kern/debug/monitor.c View File

@ -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;
}

+ 0
- 19
code/lab6/kern/debug/monitor.h View File

@ -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__ */

+ 2
- 2
code/lab6/kern/debug/panic.c View File

@ -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);
} }
} }

+ 2
- 1
code/lab6/kern/init/init.c View File

@ -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

+ 2
- 2
code/lab6/kern/mm/kmalloc.c View File

@ -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");
} }

+ 2
- 2
code/lab6/kern/mm/swap.c View File

@ -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");

+ 9
- 0
code/lab6/kern/mm/vmm.c View File

@ -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;
//(1According to the mm AND addr, try to load the content of right disk page //(1According to the mm AND addr, try to load the content of right disk page

+ 27
- 2
code/lab6/kern/process/proc.c View File

@ -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;
} }

+ 5
- 1
code/lab6/kern/schedule/sched.c View File

@ -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;

+ 9
- 6
code/lab6/kern/schedule/sched.h View File

@ -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;
struct proc_struct *proc;
list_entry_t timer_link;
unsigned int expires; //the expire time
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; //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 del_timer(timer_t *timer);
void run_timer_list(void);
void add_timer(timer_t *timer); // add timer to timer_list
void del_timer(timer_t *timer); // del timer from timer_list
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__ */

+ 2
- 2
code/lab6/kern/syscall/syscall.c View File

@ -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];

+ 9
- 2
code/lab6/kern/trap/trap.c View File

@ -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();

+ 1
- 1
code/lab6/user/libs/syscall.c View File

@ -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);
} }

+ 1
- 0
code/lab6/user/libs/syscall.h View File

@ -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);

+ 1
- 1
code/lab7/kern/debug/kdebug.c View File

@ -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
- 0
code/lab7/kern/debug/kmonitor.c View 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
- 0
code/lab7/kern/debug/kmonitor.h View 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__ */

+ 0
- 132
code/lab7/kern/debug/monitor.c View File

@ -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;
}

+ 0
- 19
code/lab7/kern/debug/monitor.h View File

@ -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__ */

+ 2
- 2
code/lab7/kern/debug/panic.c View File

@ -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);
} }
} }

+ 2
- 1
code/lab7/kern/init/init.c View File

@ -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

+ 2
- 2
code/lab7/kern/mm/kmalloc.c View File

@ -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");
} }

+ 2
- 2
code/lab7/kern/mm/swap.c View File

@ -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");

+ 9
- 0
code/lab7/kern/mm/vmm.c View File

@ -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;
//(1According to the mm AND addr, try to load the content of right disk page //(1According to the mm AND addr, try to load the content of right disk page

+ 27
- 2
code/lab7/kern/process/proc.c View File

@ -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;
} }

+ 4
- 0
code/lab7/kern/schedule/sched.c View File

@ -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;

+ 9
- 6
code/lab7/kern/schedule/sched.h View File

@ -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;
struct proc_struct *proc;
list_entry_t timer_link;
unsigned int expires; //the expire time
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; //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 del_timer(timer_t *timer);
void run_timer_list(void);
void add_timer(timer_t *timer); // add timer to timer_list
void del_timer(timer_t *timer); // del timer from timer_list
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__ */

+ 2
- 2
code/lab7/kern/syscall/syscall.c View File

@ -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];

+ 9
- 2
code/lab7/kern/trap/trap.c View File

@ -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();

+ 1
- 3
code/lab7/user/forktree.c View File

@ -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;
} }

+ 1
- 1
code/lab7/user/libs/syscall.c View File

@ -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);
} }

+ 1
- 0
code/lab7/user/libs/syscall.h View File

@ -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);

+ 1
- 1
code/lab7/user/spin.c View File

@ -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) {

+ 1
- 1
code/lab8/kern/debug/kdebug.c View File

@ -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
- 0
code/lab8/kern/debug/kmonitor.c View 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
- 0
code/lab8/kern/debug/kmonitor.h View 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__ */

+ 0
- 132
code/lab8/kern/debug/monitor.c View File

@ -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;
}

+ 0
- 19
code/lab8/kern/debug/monitor.h View File

@ -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__ */

+ 2
- 2
code/lab8/kern/debug/panic.c View File

@ -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
- 0
code/lab8/kern/fs/devs/dev.c View File


+ 0
- 0
code/lab8/kern/fs/devs/dev.h View File


+ 0
- 0
code/lab8/kern/fs/devs/dev_disk0.c View File


+ 0
- 0
code/lab8/kern/fs/devs/dev_stdin.c View File


+ 0
- 0
code/lab8/kern/fs/devs/dev_stdout.c View File


+ 0
- 0
code/lab8/kern/fs/file.c View File


+ 0
- 0
code/lab8/kern/fs/file.h View File


+ 1
- 1
code/lab8/kern/fs/fs.c View 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
- 0
code/lab8/kern/fs/fs.h View File


+ 0
- 0
code/lab8/kern/fs/iobuf.c View File


+ 0
- 0
code/lab8/kern/fs/iobuf.h View File


+ 0
- 0
code/lab8/kern/fs/sfs/bitmap.c View File


+ 0
- 0
code/lab8/kern/fs/sfs/bitmap.h View File


+ 0
- 0
code/lab8/kern/fs/sfs/sfs.c View File


+ 0
- 0
code/lab8/kern/fs/sfs/sfs.h View File


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_fs.c View File


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_inode.c View File


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_io.c View File


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_lock.c View File


+ 0
- 0
code/lab8/kern/fs/swap/swapfs.c View File


+ 0
- 0
code/lab8/kern/fs/swap/swapfs.h View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save