initial commit
[mit-jos.git] / kern / monitor.c
blob374eae88ab5d46302df53ea13882d47f31923695
1 // Simple command-line kernel monitor useful for
2 // controlling the kernel and exploring the system interactively.
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>
10 #include <kern/console.h>
11 #include <kern/monitor.h>
13 #define CMDBUF_SIZE 80 // enough for one VGA text line
16 struct Command {
17 const char *name;
18 const char *desc;
19 // return -1 to force monitor to exit
20 int (*func)(int argc, char** argv, struct Trapframe* tf);
23 static struct Command commands[] = {
24 { "help", "Display this list of commands", mon_help },
25 { "kerninfo", "Display information about the kernel", mon_kerninfo },
27 #define NCOMMANDS (sizeof(commands)/sizeof(commands[0]))
29 unsigned read_eip();
31 /***** Implementations of basic kernel monitor commands *****/
33 int
34 mon_help(int argc, char **argv, struct Trapframe *tf)
36 int i;
38 for (i = 0; i < NCOMMANDS; i++)
39 cprintf("%s - %s\n", commands[i].name, commands[i].desc);
40 return 0;
43 int
44 mon_kerninfo(int argc, char **argv, struct Trapframe *tf)
46 extern char _start[], etext[], edata[], end[];
48 cprintf("Special kernel symbols:\n");
49 cprintf(" _start %08x (virt) %08x (phys)\n", _start, _start - KERNBASE);
50 cprintf(" etext %08x (virt) %08x (phys)\n", etext, etext - KERNBASE);
51 cprintf(" edata %08x (virt) %08x (phys)\n", edata, edata - KERNBASE);
52 cprintf(" end %08x (virt) %08x (phys)\n", end, end - KERNBASE);
53 cprintf("Kernel executable memory footprint: %dKB\n",
54 (end-_start+1023)/1024);
55 return 0;
58 int
59 mon_backtrace(int argc, char **argv, struct Trapframe *tf)
61 // Your code here.
62 return 0;
67 /***** Kernel monitor command interpreter *****/
69 #define WHITESPACE "\t\r\n "
70 #define MAXARGS 16
72 static int
73 runcmd(char *buf, struct Trapframe *tf)
75 int argc;
76 char *argv[MAXARGS];
77 int i;
79 // Parse the command buffer into whitespace-separated arguments
80 argc = 0;
81 argv[argc] = 0;
82 while (1) {
83 // gobble whitespace
84 while (*buf && strchr(WHITESPACE, *buf))
85 *buf++ = 0;
86 if (*buf == 0)
87 break;
89 // save and scan past next arg
90 if (argc == MAXARGS-1) {
91 cprintf("Too many arguments (max %d)\n", MAXARGS);
92 return 0;
94 argv[argc++] = buf;
95 while (*buf && !strchr(WHITESPACE, *buf))
96 buf++;
98 argv[argc] = 0;
100 // Lookup and invoke the command
101 if (argc == 0)
102 return 0;
103 for (i = 0; i < NCOMMANDS; i++) {
104 if (strcmp(argv[0], commands[i].name) == 0)
105 return commands[i].func(argc, argv, tf);
107 cprintf("Unknown command '%s'\n", argv[0]);
108 return 0;
111 void
112 monitor(struct Trapframe *tf)
114 char *buf;
116 cprintf("Welcome to the JOS kernel monitor!\n");
117 cprintf("Type 'help' for a list of commands.\n");
120 while (1) {
121 buf = readline("K> ");
122 if (buf != NULL)
123 if (runcmd(buf, tf) < 0)
124 break;
128 // return EIP of caller.
129 // does not work if inlined.
130 // putting at the end of the file seems to prevent inlining.
131 unsigned
132 read_eip()
134 uint32_t callerpc;
135 __asm __volatile("movl 4(%%ebp), %0" : "=r" (callerpc));
136 return callerpc;