《操作系统》的实验代码。
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.2 KiB

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <mmu.h>
  4. #include <trap.h>
  5. #include <kmonitor.h>
  6. #include <kdebug.h>
  7. /* *
  8. * Simple command-line kernel monitor useful for controlling the
  9. * kernel and exploring the system interactively.
  10. * */
  11. struct command {
  12. const char *name;
  13. const char *desc;
  14. // return -1 to force monitor to exit
  15. int(*func)(int argc, char **argv, struct trapframe *tf);
  16. };
  17. static struct command commands[] = {
  18. {"help", "Display this list of commands.", mon_help},
  19. {"kerninfo", "Display information about the kernel.", mon_kerninfo},
  20. {"backtrace", "Print backtrace of stack frame.", mon_backtrace},
  21. };
  22. /* return if kernel is panic, in kern/debug/panic.c */
  23. bool is_kernel_panic(void);
  24. #define NCOMMANDS (sizeof(commands)/sizeof(struct command))
  25. /***** Kernel monitor command interpreter *****/
  26. #define MAXARGS 16
  27. #define WHITESPACE " \t\n\r"
  28. /* parse - parse the command buffer into whitespace-separated arguments */
  29. static int
  30. parse(char *buf, char **argv) {
  31. int argc = 0;
  32. while (1) {
  33. // find global whitespace
  34. while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
  35. *buf ++ = '\0';
  36. }
  37. if (*buf == '\0') {
  38. break;
  39. }
  40. // save and scan past next arg
  41. if (argc == MAXARGS - 1) {
  42. cprintf("Too many arguments (max %d).\n", MAXARGS);
  43. }
  44. argv[argc ++] = buf;
  45. while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
  46. buf ++;
  47. }
  48. }
  49. return argc;
  50. }
  51. /* *
  52. * runcmd - parse the input string, split it into separated arguments
  53. * and then lookup and invoke some related commands/
  54. * */
  55. static int
  56. runcmd(char *buf, struct trapframe *tf) {
  57. char *argv[MAXARGS];
  58. int argc = parse(buf, argv);
  59. if (argc == 0) {
  60. return 0;
  61. }
  62. int i;
  63. for (i = 0; i < NCOMMANDS; i ++) {
  64. if (strcmp(commands[i].name, argv[0]) == 0) {
  65. return commands[i].func(argc - 1, argv + 1, tf);
  66. }
  67. }
  68. cprintf("Unknown command '%s'\n", argv[0]);
  69. return 0;
  70. }
  71. /***** Implementations of basic kernel monitor commands *****/
  72. void
  73. kmonitor(struct trapframe *tf) {
  74. cprintf("Welcome to the kernel debug monitor!!\n");
  75. cprintf("Type 'help' for a list of commands.\n");
  76. if (tf != NULL) {
  77. print_trapframe(tf);
  78. }
  79. char *buf;
  80. while (1) {
  81. if ((buf = readline("K> ")) != NULL) {
  82. if (runcmd(buf, tf) < 0) {
  83. break;
  84. }
  85. }
  86. }
  87. }
  88. /* mon_help - print the information about mon_* functions */
  89. int
  90. mon_help(int argc, char **argv, struct trapframe *tf) {
  91. int i;
  92. for (i = 0; i < NCOMMANDS; i ++) {
  93. cprintf("%s - %s\n", commands[i].name, commands[i].desc);
  94. }
  95. return 0;
  96. }
  97. /* *
  98. * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
  99. * print the memory occupancy in kernel.
  100. * */
  101. int
  102. mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
  103. print_kerninfo();
  104. return 0;
  105. }
  106. /* *
  107. * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
  108. * print a backtrace of the stack.
  109. * */
  110. int
  111. mon_backtrace(int argc, char **argv, struct trapframe *tf) {
  112. print_stackframe();
  113. return 0;
  114. }