Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Simple command-line kernel monitor useful for
- // controlling the kernel and exploring the system interactively.
- #include <inc/stdio.h>
- #include <inc/string.h>
- #include <inc/memlayout.h>
- #include <inc/assert.h>
- #include <inc/x86.h>
- #include <kern/console.h>
- #include <kern/monitor.h>
- #include <kern/kdebug.h>
- #include <kern/trap.h>
- #define CMDBUF_SIZE 80 // enough for one VGA text line
- 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", "Display the backtrace of stacks.", mon_backtrace}
- };
- #define NCOMMANDS (sizeof(commands)/sizeof(commands[0]))
- /***** Implementations of basic kernel monitor commands *****/
- 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;
- }
- int
- mon_kerninfo(int argc, char **argv, struct Trapframe *tf)
- {
- extern char _start[], entry[], etext[], edata[], end[];
- cprintf("Special kernel symbols:\n");
- cprintf(" _start %08x (phys)\n", _start);
- cprintf(" entry %08x (virt) %08x (phys)\n", entry, entry - KERNBASE);
- cprintf(" etext %08x (virt) %08x (phys)\n", etext, etext - KERNBASE);
- cprintf(" edata %08x (virt) %08x (phys)\n", edata, edata - KERNBASE);
- cprintf(" end %08x (virt) %08x (phys)\n", end, end - KERNBASE);
- cprintf("Kernel executable memory footprint: %dKB\n",
- ROUNDUP(end - entry, 1024) / 1024);
- return 0;
- }
- int
- mon_backtrace(int argc, char **argv, struct Trapframe *tf)
- {
- //The ebp value of the program, which calls the mon_backtrace
- int regebp = read_ebp();
- regebp = *((int *)regebp);
- int *ebp = (int *)regebp;
- cprintf("Stack backtrace:\n");
- //If only we haven't pass the stack frame of i386_init
- while((int)ebp != 0x0) {
- cprintf(" ebp %08x", (int)ebp);
- cprintf(" eip %08x", *(ebp+1));
- cprintf(" args");
- cprintf(" %08x", *(ebp+2));
- cprintf(" %08x", *(ebp+3));
- cprintf(" %08x", *(ebp+4));
- cprintf(" %08x", *(ebp+5));
- cprintf(" %08x\n", *(ebp+6));
- ebp = (int *)(*ebp);
- }
- return 0;
- }
- /***** Kernel monitor command interpreter *****/
- #define WHITESPACE "\t\r\n "
- #define MAXARGS 16
- static int
- runcmd(char *buf, struct Trapframe *tf)
- {
- int argc;
- char *argv[MAXARGS];
- int i;
- // Parse the command buffer into whitespace-separated arguments
- argc = 0;
- argv[argc] = 0;
- while (1) {
- // gobble whitespace
- while (*buf && strchr(WHITESPACE, *buf))
- *buf++ = 0;
- if (*buf == 0)
- break;
- // save and scan past next arg
- if (argc == MAXARGS-1) {
- cprintf("Too many arguments (max %d)\n", MAXARGS);
- return 0;
- }
- argv[argc++] = buf;
- while (*buf && !strchr(WHITESPACE, *buf))
- buf++;
- }
- argv[argc] = 0;
- // Lookup and invoke the command
- if (argc == 0)
- return 0;
- for (i = 0; i < NCOMMANDS; i++) {
- if (strcmp(argv[0], commands[i].name) == 0)
- return commands[i].func(argc, argv, tf);
- }
- cprintf("Unknown command '%s'\n", argv[0]);
- return 0;
- }
- void
- monitor(struct Trapframe *tf)
- {
- char *buf;
- cprintf("Welcome to the JOS kernel monitor!\n");
- cprintf("Type 'help' for a list of commands.\n");
- if (tf != NULL)
- print_trapframe(tf);
- while (1) {
- buf = readline("K> ");
- if (buf != NULL)
- if (runcmd(buf, tf) < 0)
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement