《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.1 KiB

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