From e484704ce89a7862ef729a5e369eab870b5f6dda Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 19 Apr 2019 13:19:15 -0700 Subject: [PATCH] Implement the showmappings command --- kern/ansi.h | 6 +++--- kern/monitor.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++--- kern/monitor.h | 1 + 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/kern/ansi.h b/kern/ansi.h index c5df2d5..8869cba 100644 --- a/kern/ansi.h +++ b/kern/ansi.h @@ -6,7 +6,7 @@ #define ACOL_WRAP(s) "\33[" s "m" #define ACOL_BLACK ACOL_WRAP("30") #define ACOL_RED ACOL_WRAP("31") -#define ACOL_GREEM ACOL_WRAP("32") +#define ACOL_GREEN ACOL_WRAP("32") #define ACOL_YELLOW ACOL_WRAP("33") #define ACOL_BLUE ACOL_WRAP("34") #define ACOL_MAGENTA ACOL_WRAP("35") @@ -15,9 +15,9 @@ #define ACOL_CLEAR ACOL_WRAP("0") #define ACOL_TAG(c, s) "[" c s ACOL_CLEAR "] " -#define ACOL_NOTE(s) ACOL_TAG(ACOL_WHITE, "Note ") s +#define ACOL_NOTE(s) ACOL_TAG(ACOL_WHITE, " Note ") s #define ACOL_WARN(s) ACOL_TAG(ACOL_YELLOW, "Warning") s -#define ACOL_ERR(s) ACOL_TAG(ACOL_RED, "Error ") s +#define ACOL_ERR(s) ACOL_TAG(ACOL_RED, " Error ") s struct AttrState { uint8_t cattrs; diff --git a/kern/monitor.c b/kern/monitor.c index c97da78..1e626e2 100644 --- a/kern/monitor.c +++ b/kern/monitor.c @@ -7,9 +7,13 @@ #include #include +#include #include #include #include +#include + +#include #define CMDBUF_SIZE 80 // enough for one VGA text line @@ -25,7 +29,8 @@ struct Command { static struct Command commands[] = { { "help", "Display this list of commands", mon_help }, { "kerninfo", "Display information about the kernel", mon_kerninfo }, - { "backtrace", "Display current backtrace", mon_backtrace } + { "backtrace", "Display current backtrace", mon_backtrace }, + { "showmappings", "Display the physical mappings for range", mon_showmappings } }; /***** Implementations of basic kernel monitor commands *****/ @@ -46,7 +51,7 @@ 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(" _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); @@ -75,7 +80,7 @@ mon_backtrace(int argc, char **argv, struct Trapframe *tf) ebp = (uint32_t*) ebp[0]; debuginfo_eip(eip, &info); - cprintf(" %s:%d: %.*s+%d\n", + cprintf(" %s:%d: %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, eip - info.eip_fn_addr); @@ -84,6 +89,53 @@ mon_backtrace(int argc, char **argv, struct Trapframe *tf) return 0; } +#define EXPECT_ARGS(n, ac) if(ac - 1 != n) { \ + cprintf(ACOL_ERR("Expected %d arguments, " \ + "got %d\n"), n, ac - 1); \ + return 1; } + +#define VA_TXT ACOL_CYAN "VA" ACOL_CLEAR +#define PA_TXT ACOL_GREEN "PA" ACOL_CLEAR + +char* +decode_pte_perms(pte_t pte, char* buffer) { + buffer[0] = (pte & PTE_W) ? 'w' : 'r'; + buffer[1] = (pte & PTE_U) ? 'u' : 'k'; + return buffer; +} + +int +mon_showmappings(int argc, char** argv, struct Trapframe* tf) { + EXPECT_ARGS(2, argc); + long from = strtol(argv[1], NULL, 0); + long to = strtol(argv[2], NULL, 0); + + uintptr_t va_start = ROUNDDOWN(from, PGSIZE); + uintptr_t va_end = ROUNDUP(to, PGSIZE); + if(va_start != from) cprintf(ACOL_WARN("Aligning start address %p down to %p\n"), + from, va_start); + if(va_end != to) cprintf(ACOL_WARN("Aligning end address %p up to %p\n"), + to, va_end); + + char buffer[3] = {0}; + + if(va_start == va_end) va_end += PGSIZE; + while(va_start < va_end) { + pte_t* pte = pgdir_walk(kern_pgdir, (const void*) va_start, 0); + cprintf(VA_TXT " 0x%08p -> ", va_start); + + if(pte && (*pte & PTE_P)) { + cprintf(PA_TXT " 0x%08p (%s)\n", PTE_ADDR(*pte), + decode_pte_perms(*pte, buffer)); + } else { + cprintf(PA_TXT " ------------\n"); + } + + va_start += PGSIZE; + } + + return 0; +} /***** Kernel monitor command interpreter *****/ diff --git a/kern/monitor.h b/kern/monitor.h index 0aa0f26..35d2793 100644 --- a/kern/monitor.h +++ b/kern/monitor.h @@ -15,5 +15,6 @@ void monitor(struct Trapframe *tf); int mon_help(int argc, char **argv, struct Trapframe *tf); int mon_kerninfo(int argc, char **argv, struct Trapframe *tf); int mon_backtrace(int argc, char **argv, struct Trapframe *tf); +int mon_showmappings(int argc, char **argv, struct Trapframe *tf); #endif // !JOS_KERN_MONITOR_H