瀏覽代碼

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

main
chyyuu 12 年之前
父節點
當前提交
d537948e30
共有 144 個檔案被更改,包括 1998 行新增1735 行删除
  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 查看文件

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

@ -1,27 +1,51 @@
ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University. INTRODUCTION
The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License. ------------
The codes in the files that constitute OS/161 are written by David A. Holland. ucore is a teaching OS which is derived from xv6&jos in MIT, OS161 in Harvard and Linux and developed by Tsinghua University.
The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License. The codes in the files that constitute xv6&jos are Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox and uses MIT License.
-------------------------------------------------------------- The codes in the files that constitute OS/161 are written by David A. Holland.
lab1: boot/protect mode/stack/interrupt The docs and codes in the files that constitute ucore are Copyright 2012 Yu Chen, Naizheng Wang, Yong Xiang and uses GPL License.
lab2: physical memory management CONTENTS
lab3: virtual memory management --------
lab4: kernel thread management lab1: boot/protect mode/stack/interrupt
lab5: user process management lab2: physical memory management
lab6: scheduling lab3: virtual memory management
lab7: mutex/sync lab4: kernel thread management
lab8: filesystem lab5: user process management
lab6: scheduling
The newest lab codes and docs is in https://github.com/chyyuu/ucore_pub or https://bitbucket.org/chyyuu/ucore_pub lab7: mutex/sync
lab8: filesystem
If you have any questions about ucore labs, EXERCISE STEPS
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. 1 $cd labX
To unsubscribe from this group, send email to oscourse+unsubscribe@googlegroups.com. 2 read codes (specially the modified or added files)
For more options, visit this group at http://groups.google.com/group/oscourse?hl=en. 3 add your code
4 compile your code
If you want to be a developer of ucore or pay attention to the development of ucore, $make
you can subscribe to the Google Groups "ucore_dev" group (http://groups.google.com/group/ucore_dev?hl=en.) 5 check your code
To post to this group, send email to ucore_dev@googlegroups.com. $make qemu
To unsubscribe from this group, send email to ucore_dev+unsubscribe@googlegroups.com. OR
For more options, visit this group at http://groups.google.com/group/ucore_dev?hl=en. $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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick)
cprintf("i %d, swap_out: call swap_out_victim failed\n",i); cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
break; break;
} }
assert(!PageReserved(page)); //assert(!PageReserved(page));
//cprintf("SWAP: choose victim page 0x%08x\n", page); //cprintf("SWAP: choose victim page 0x%08x\n", page);
@ -272,8 +272,8 @@ check_swap(void)
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
count --, total -= p->property; count --, total -= p->property;
} }
cprintf("count is %d, total is %d\n",count,total);
assert(count == 0); //assert(count == 0);
cprintf("check_swap() succeeded!\n"); cprintf("check_swap() succeeded!\n");
} }

+ 1
- 1
code/lab4/kern/debug/kdebug.c 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -92,7 +92,7 @@ swap_out(struct mm_struct *mm, int n, int in_tick)
cprintf("i %d, swap_out: call swap_out_victim failed\n",i); cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
break; break;
} }
assert(!PageReserved(page)); //assert(!PageReserved(page));
//cprintf("SWAP: choose victim page 0x%08x\n", page); //cprintf("SWAP: choose victim page 0x%08x\n", page);
@ -182,7 +182,7 @@ check_swap(void)
list_entry_t *le = &free_list; list_entry_t *le = &free_list;
while ((le = list_next(le)) != &free_list) { while ((le = list_next(le)) != &free_list) {
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
//assert(PageProperty(p)); assert(PageProperty(p));
count ++, total += p->property; count ++, total += p->property;
} }
assert(total == nr_free_pages()); assert(total == nr_free_pages());
@ -272,8 +272,8 @@ check_swap(void)
struct Page *p = le2page(le, page_link); struct Page *p = le2page(le, page_link);
count --, total -= p->property; count --, total -= p->property;
} }
cprintf("count is %d, total is %d\n",count,total);
assert(count == 0); //assert(count == 0);
cprintf("check_swap() succeeded!\n"); cprintf("check_swap() succeeded!\n");
} }

+ 26
- 5
code/lab4/tools/grade.sh 查看文件

@ -304,8 +304,11 @@ quick_check() {
## kernel image ## kernel image
osimg=$(make_print ucoreimg) osimg=$(make_print ucoreimg)
## swap image
swapimg=$(make_print swapimg)
## set default qemu-options ## set default qemu-options
qemuopts="-hda $osimg" qemuopts="-hda $osimg -drive file=$swapimg,media=disk,cache=writeback"
## set break-function, default is readline ## set break-function, default is readline
brkfun=readline brkfun=readline
@ -316,7 +319,7 @@ quick_run 'Check VMM'
pts=5 pts=5
quick_check 'check pmm' \ quick_check 'check pmm' \
'memory management: buddy_pmm_manager' \ 'memory management: default_pmm_manager' \
'check_alloc_page() succeeded!' \ 'check_alloc_page() succeeded!' \
'check_pgdir() succeeded!' \ 'check_pgdir() succeeded!' \
'check_boot_pgdir() succeeded!' 'check_boot_pgdir() succeeded!'
@ -340,11 +343,29 @@ quick_check 'check vmm' \
'check_pgfault() succeeded!' \ 'check_pgfault() succeeded!' \
'check_vmm() succeeded.' 'check_vmm() succeeded.'
pts=20
quick_check 'check swap page fault' \
'page fault at 0x00001000: K/W [no page found].' \
'page fault at 0x00002000: K/W [no page found].' \
'page fault at 0x00003000: K/W [no page found].' \
'page fault at 0x00004000: K/W [no page found].' \
'write Virt Page e in fifo_check_swap' \
'page fault at 0x00005000: K/W [no page found].' \
'page fault at 0x00001000: K/W [no page found]' \
'page fault at 0x00002000: K/W [no page found].' \
'page fault at 0x00003000: K/W [no page found].' \
'page fault at 0x00004000: K/W [no page found].' \
'check_swap() succeeded!'
pts=5 pts=5
quick_check 'check ticks' \ quick_check 'check ticks' \
'++ setup timer interrupts' \ '++ setup timer interrupts'
'100 ticks' \ pts=30
'End of Test.' 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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -5,17 +5,20 @@
#include <list.h> #include <list.h>
#include <skew_heap.h> #include <skew_heap.h>
#define MAX_TIME_SLICE 20
struct proc_struct; struct proc_struct;
typedef struct { typedef struct {
unsigned int expires; unsigned int expires; //the expire time
struct proc_struct *proc; struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
list_entry_t timer_link; list_entry_t timer_link; //the timer list
} timer_t; } timer_t;
#define le2timer(le, member) \ #define le2timer(le, member) \
to_struct((le), timer_t, member) to_struct((le), timer_t, member)
// init a timer
static inline timer_t * static inline timer_t *
timer_init(timer_t *timer, struct proc_struct *proc, int expires) { timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
timer->expires = expires; timer->expires = expires;
@ -62,9 +65,9 @@ struct run_queue {
void sched_init(void); void sched_init(void);
void wakeup_proc(struct proc_struct *proc); void wakeup_proc(struct proc_struct *proc);
void schedule(void); void schedule(void);
void add_timer(timer_t *timer); void add_timer(timer_t *timer); // add timer to timer_list
void del_timer(timer_t *timer); void del_timer(timer_t *timer); // del timer from timer_list
void run_timer_list(void); void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
#endif /* !__KERN_SCHEDULE_SCHED_H__ */ #endif /* !__KERN_SCHEDULE_SCHED_H__ */

+ 2
- 2
code/lab6/kern/syscall/syscall.c 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -5,17 +5,20 @@
#include <list.h> #include <list.h>
#include <skew_heap.h> #include <skew_heap.h>
#define MAX_TIME_SLICE 20
struct proc_struct; struct proc_struct;
typedef struct { typedef struct {
unsigned int expires; unsigned int expires; //the expire time
struct proc_struct *proc; struct proc_struct *proc; //the proc wait in this timer. If the expire time is end, then this proc will be scheduled
list_entry_t timer_link; list_entry_t timer_link; //the timer list
} timer_t; } timer_t;
#define le2timer(le, member) \ #define le2timer(le, member) \
to_struct((le), timer_t, member) to_struct((le), timer_t, member)
// init a timer
static inline timer_t * static inline timer_t *
timer_init(timer_t *timer, struct proc_struct *proc, int expires) { timer_init(timer_t *timer, struct proc_struct *proc, int expires) {
timer->expires = expires; timer->expires = expires;
@ -62,9 +65,9 @@ struct run_queue {
void sched_init(void); void sched_init(void);
void wakeup_proc(struct proc_struct *proc); void wakeup_proc(struct proc_struct *proc);
void schedule(void); void schedule(void);
void add_timer(timer_t *timer); void add_timer(timer_t *timer); // add timer to timer_list
void del_timer(timer_t *timer); void del_timer(timer_t *timer); // del timer from timer_list
void run_timer_list(void); void run_timer_list(void); // call scheduler to update tick related info, and check the timer is expired? If expired, then wakup proc
#endif /* !__KERN_SCHEDULE_SCHED_H__ */ #endif /* !__KERN_SCHEDULE_SCHED_H__ */

+ 2
- 2
code/lab7/kern/syscall/syscall.c 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件

@ -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 查看文件


+ 0
- 0
code/lab8/kern/fs/devs/dev.h 查看文件


+ 0
- 0
code/lab8/kern/fs/devs/dev_disk0.c 查看文件


+ 0
- 0
code/lab8/kern/fs/devs/dev_stdin.c 查看文件


+ 0
- 0
code/lab8/kern/fs/devs/dev_stdout.c 查看文件


+ 0
- 0
code/lab8/kern/fs/file.c 查看文件


+ 0
- 0
code/lab8/kern/fs/file.h 查看文件


+ 1
- 1
code/lab8/kern/fs/fs.c 查看文件

@ -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 查看文件


+ 0
- 0
code/lab8/kern/fs/iobuf.c 查看文件


+ 0
- 0
code/lab8/kern/fs/iobuf.h 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/bitmap.c 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/bitmap.h 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/sfs.c 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/sfs.h 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_fs.c 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_inode.c 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_io.c 查看文件


+ 0
- 0
code/lab8/kern/fs/sfs/sfs_lock.c 查看文件


+ 0
- 0
code/lab8/kern/fs/swap/swapfs.c 查看文件


+ 0
- 0
code/lab8/kern/fs/swap/swapfs.h 查看文件


部分文件因文件數量過多而無法顯示

||||||
x
 
000:0
Loading…
取消
儲存