Advertisement
Mysakure

monitor.c

Nov 23rd, 2019
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.41 KB | None | 0 0
  1. // Simple command-line kernel monitor useful for
  2. // controlling the kernel and exploring the system interactively.
  3.  
  4. #include <inc/stdio.h>
  5. #include <inc/string.h>
  6. #include <inc/memlayout.h>
  7. #include <inc/assert.h>
  8. #include <inc/x86.h>
  9.  
  10. #include <kern/console.h>
  11. #include <kern/monitor.h>
  12. #include <kern/kdebug.h>
  13. #include <kern/trap.h>
  14.  
  15. #define CMDBUF_SIZE 80  // enough for one VGA text line
  16.  
  17.  
  18. struct Command {
  19.     const char *name;
  20.     const char *desc;
  21.     // return -1 to force monitor to exit
  22.     int (*func)(int argc, char** argv, struct Trapframe* tf);
  23. };
  24.  
  25. static struct Command commands[] = {
  26.     { "help", "Display this list of commands", mon_help },
  27.     { "kerninfo", "Display information about the kernel", mon_kerninfo },
  28.     { "backtrace", "Display the backtrace of stacks.", mon_backtrace}
  29. };
  30. #define NCOMMANDS (sizeof(commands)/sizeof(commands[0]))
  31.  
  32. /***** Implementations of basic kernel monitor commands *****/
  33.  
  34. int
  35. mon_help(int argc, char **argv, struct Trapframe *tf)
  36. {
  37.     int i;
  38.  
  39.     for (i = 0; i < NCOMMANDS; i++)
  40.         cprintf("%s - %s\n", commands[i].name, commands[i].desc);
  41.     return 0;
  42. }
  43.  
  44. int
  45. mon_kerninfo(int argc, char **argv, struct Trapframe *tf)
  46. {
  47.     extern char _start[], entry[], etext[], edata[], end[];
  48.  
  49.     cprintf("Special kernel symbols:\n");
  50.     cprintf("  _start                  %08x (phys)\n", _start);
  51.     cprintf("  entry  %08x (virt)  %08x (phys)\n", entry, entry - KERNBASE);
  52.     cprintf("  etext  %08x (virt)  %08x (phys)\n", etext, etext - KERNBASE);
  53.     cprintf("  edata  %08x (virt)  %08x (phys)\n", edata, edata - KERNBASE);
  54.     cprintf("  end    %08x (virt)  %08x (phys)\n", end, end - KERNBASE);
  55.     cprintf("Kernel executable memory footprint: %dKB\n",
  56.         ROUNDUP(end - entry, 1024) / 1024);
  57.     return 0;
  58. }
  59.  
  60. int
  61. mon_backtrace(int argc, char **argv, struct Trapframe *tf)
  62. {
  63.     //The ebp value of the program, which calls the mon_backtrace
  64.     int regebp = read_ebp();
  65.     regebp = *((int *)regebp);
  66.     int *ebp = (int *)regebp;
  67.    
  68.     cprintf("Stack backtrace:\n");
  69.     //If only we haven't pass the stack frame of i386_init
  70.     while((int)ebp != 0x0) {
  71.         cprintf("  ebp %08x", (int)ebp);
  72.         cprintf("  eip %08x", *(ebp+1));
  73.         cprintf("  args");
  74.         cprintf(" %08x", *(ebp+2));
  75.         cprintf(" %08x", *(ebp+3));
  76.         cprintf(" %08x", *(ebp+4));
  77.         cprintf(" %08x", *(ebp+5));
  78.         cprintf(" %08x\n", *(ebp+6));
  79.         ebp = (int *)(*ebp);
  80.     }
  81.     return 0;
  82. }
  83.  
  84.  
  85.  
  86. /***** Kernel monitor command interpreter *****/
  87.  
  88. #define WHITESPACE "\t\r\n "
  89. #define MAXARGS 16
  90.  
  91. static int
  92. runcmd(char *buf, struct Trapframe *tf)
  93. {
  94.     int argc;
  95.     char *argv[MAXARGS];
  96.     int i;
  97.  
  98.     // Parse the command buffer into whitespace-separated arguments
  99.     argc = 0;
  100.     argv[argc] = 0;
  101.     while (1) {
  102.         // gobble whitespace
  103.         while (*buf && strchr(WHITESPACE, *buf))
  104.             *buf++ = 0;
  105.         if (*buf == 0)
  106.             break;
  107.  
  108.         // save and scan past next arg
  109.         if (argc == MAXARGS-1) {
  110.             cprintf("Too many arguments (max %d)\n", MAXARGS);
  111.             return 0;
  112.         }
  113.         argv[argc++] = buf;
  114.         while (*buf && !strchr(WHITESPACE, *buf))
  115.             buf++;
  116.     }
  117.     argv[argc] = 0;
  118.  
  119.     // Lookup and invoke the command
  120.     if (argc == 0)
  121.         return 0;
  122.     for (i = 0; i < NCOMMANDS; i++) {
  123.         if (strcmp(argv[0], commands[i].name) == 0)
  124.             return commands[i].func(argc, argv, tf);
  125.     }
  126.     cprintf("Unknown command '%s'\n", argv[0]);
  127.     return 0;
  128. }
  129.  
  130. void
  131. monitor(struct Trapframe *tf)
  132. {
  133.     char *buf;
  134.  
  135.     cprintf("Welcome to the JOS kernel monitor!\n");
  136.     cprintf("Type 'help' for a list of commands.\n");
  137.  
  138.     if (tf != NULL)
  139.         print_trapframe(tf);
  140.  
  141.     while (1) {
  142.         buf = readline("K> ");
  143.         if (buf != NULL)
  144.             if (runcmd(buf, tf) < 0)
  145.                 break;
  146.     }
  147.  
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement