From af7ec7b7dac78f445176e8a03e0f8913cdd72c8b Mon Sep 17 00:00:00 2001 From: Yeongjin Jang Date: Tue, 2 Apr 2019 02:49:09 -0700 Subject: [PATCH 1/8] add hint --- kern/kdebug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kern/kdebug.c b/kern/kdebug.c index 9547143..b66ab45 100644 --- a/kern/kdebug.c +++ b/kern/kdebug.c @@ -171,7 +171,8 @@ debuginfo_eip(uintptr_t addr, struct Eipdebuginfo *info) // Search within [lline, rline] for the line number stab. - // If found, set info->eip_line to the right line number. + // If found, set info->eip_line to the correct line number. + // e.g., info->eip_line = stabs[lline].n_desc // If not found, return -1. // // Hint: From 575eb44598a44b4a584356ef52da40b7fc2dcab8 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 2 Apr 2019 12:25:19 -0700 Subject: [PATCH 2/8] Edit student info file --- student.info | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/student.info b/student.info index f3ede52..8a21af1 100644 --- a/student.info +++ b/student.info @@ -1,5 +1,5 @@ -OSU ID (xxx-yyy-zzz) : 933456789 -FLIP ID (e.g., jangye) : jangye -Name : Yeongjin Jang +OSU ID (xxx-yyy-zzz) : 932700867 +FLIP ID (e.g., jangye) : fedorind +Name : Danila Fedorin CS 444/544 ? : 444 Lab Class # : Lab 1 From 62b840a99451d8d040a6c1717c0ca5b88b11a8da Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 2 Apr 2019 12:32:39 -0700 Subject: [PATCH 3/8] Change lab number --- student.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/student.info b/student.info index 8a21af1..7014618 100644 --- a/student.info +++ b/student.info @@ -2,4 +2,4 @@ OSU ID (xxx-yyy-zzz) : 932700867 FLIP ID (e.g., jangye) : fedorind Name : Danila Fedorin CS 444/544 ? : 444 -Lab Class # : Lab 1 +Lab Class # : Lab 2 From b0880daaa332f3cc26d6f6db8a4e63cc8aa01b66 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 4 Apr 2019 20:37:11 -0700 Subject: [PATCH 4/8] Implement octal printing. --- lib/printfmt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/printfmt.c b/lib/printfmt.c index 802adcd..b1de635 100644 --- a/lib/printfmt.c +++ b/lib/printfmt.c @@ -205,11 +205,9 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) // (unsigned) octal case 'o': - // LAB 1: Replace this with your code. - putch('X', putdat); - putch('X', putdat); - putch('X', putdat); - break; + num = getuint(&ap, lflag); + base = 8; + goto number; // pointer case 'p': From 8ef5e2f810a0363e5ee3217982d6faa629f33862 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 4 Apr 2019 20:37:40 -0700 Subject: [PATCH 5/8] Add the needed binary search to find line numbers. --- kern/kdebug.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kern/kdebug.c b/kern/kdebug.c index b66ab45..cc59033 100644 --- a/kern/kdebug.c +++ b/kern/kdebug.c @@ -180,6 +180,12 @@ debuginfo_eip(uintptr_t addr, struct Eipdebuginfo *info) // Look at the STABS documentation and to find // which one. // Your code here. + stab_binsearch(stabs, &lline, &rline, N_SLINE, addr); + if(lline <= rline) { + info->eip_line = stabs[lline].n_desc; + } else { + info->eip_line = -1; + } // Search backwards from the line number for the relevant filename From dd3281aba0121dba7cf565314e60228cb0b6219b Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 4 Apr 2019 20:37:53 -0700 Subject: [PATCH 6/8] Implement the backtrace code. --- kern/monitor.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/kern/monitor.c b/kern/monitor.c index ee25809..c97da78 100644 --- a/kern/monitor.c +++ b/kern/monitor.c @@ -25,6 +25,7 @@ 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 } }; /***** Implementations of basic kernel monitor commands *****/ @@ -61,6 +62,25 @@ mon_backtrace(int argc, char **argv, struct Trapframe *tf) // LAB 1: Your code here. // HINT 1: use read_ebp(). // HINT 2: print the current ebp on the first line (not current_ebp[0]) + uint32_t* ebp; + uint32_t eip; + struct Eipdebuginfo info; + + ebp = (uint32_t*) read_ebp(); + cprintf("Stack backtrace:\n"); + while(ebp) { + eip = ebp[1]; + cprintf(" ebp %08x eip %08x args %08x %08x %08x %08x %08x\n", + ebp, eip, ebp[2], ebp[3], ebp[4], ebp[5], ebp[6]); + ebp = (uint32_t*) ebp[0]; + + debuginfo_eip(eip, &info); + 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); + }; + return 0; } From f00ab71fb54032e3c88578b781b0caff1bdd4d7f Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 4 Apr 2019 21:46:17 -0700 Subject: [PATCH 7/8] Implement very bad state machine to match a subset of ANSI escape codes. --- kern/init.c | 8 ++++++++ lib/printfmt.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/kern/init.c b/kern/init.c index df46700..729fae9 100644 --- a/kern/init.c +++ b/kern/init.c @@ -38,6 +38,14 @@ i386_init(void) // Test the stack backtrace function (lab 1 only) test_backtrace(5); + // Test ANSI color escape codes + cprintf("\33[31m" "C" + "\33[33m" "o" + "\33[32m" "l" + "\33[36m" "o" + "\33[34m" "r" + "\33[0m" " Works!" "\n"); + // Drop into the kernel monitor. while (1) monitor(NULL); diff --git a/lib/printfmt.c b/lib/printfmt.c index b1de635..7535e93 100644 --- a/lib/printfmt.c +++ b/lib/printfmt.c @@ -79,6 +79,54 @@ getint(va_list *ap, int lflag) // Main function to format and print a string. void printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...); +struct AttrState { + uint8_t cattrs; + uint8_t attrs; + enum { + NORMAL, + ESC, + BRACKET, + COLOR_FG, + COLOR + } state; +}; + +void +putchw(void (*putch)(int, void*), int c, void* data, struct AttrState* s) { + switch(s->state) { + case NORMAL: + if(c != 27) putch(c | (s->cattrs << 8), data); + else s->state = ESC; + return; + case ESC: + s->state = (c == '[') ? BRACKET : NORMAL; + return; + case BRACKET: + if(c == '3') { + s->state = COLOR_FG; + } else if(c == '0') { + s->state = COLOR; + s->attrs = 0; + } else { + s->state = NORMAL; + } + return; + case COLOR_FG: + if(c >= '0' && c <= '9') { + s->attrs = (s->attrs & ~(0x07)) | (c - '0'); + c |= ((c - '0') << 8); + s->state = COLOR; + } else { + s->state = NORMAL; + } + return; + case COLOR: + s->state = (c == ';') ? BRACKET : NORMAL; + if(c == 'm') s->cattrs = s->attrs; + return; + } +} + void vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { @@ -87,12 +135,17 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) unsigned long long num; int base, lflag, width, precision, altflag; char padc; + struct AttrState attst; + + attst.state = NORMAL; + attst.cattrs = 0; + attst.attrs = 0; while (1) { while ((ch = *(unsigned char *) fmt++) != '%') { if (ch == '\0') return; - putch(ch, putdat); + putchw(putch, ch, putdat, &attst); } // Process a %-escape sequence From 47a176223bc1630f27d3289afa3c98697596c6ba Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 5 Apr 2019 19:20:33 -0700 Subject: [PATCH 8/8] Fix color support to work everywhere via hacky static variable --- kern/Makefrag | 1 + kern/ansi.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ kern/ansi.h | 20 ++++++++++++++++++ kern/console.c | 15 ++++++++++++-- lib/printfmt.c | 55 +------------------------------------------------- 5 files changed, 84 insertions(+), 56 deletions(-) create mode 100644 kern/ansi.c create mode 100644 kern/ansi.h diff --git a/kern/Makefrag b/kern/Makefrag index 3b2982e..458dd57 100644 --- a/kern/Makefrag +++ b/kern/Makefrag @@ -17,6 +17,7 @@ KERN_SRCFILES := kern/entry.S \ kern/entrypgdir.c \ kern/init.c \ kern/console.c \ + kern/ansi.c \ kern/monitor.c \ kern/pmap.c \ kern/env.c \ diff --git a/kern/ansi.c b/kern/ansi.c new file mode 100644 index 0000000..c90057e --- /dev/null +++ b/kern/ansi.c @@ -0,0 +1,49 @@ +#include + +uint8_t vga_colors[8] = { + [0] = 0, + [1] = 4, + [2] = 2, + [3] = 6, + [4] = 1, + [5] = 5, + [6] = 3, + [7] = 7 +}; + +void +ansi_step(void (*putcf)(int), int c, struct AttrState* s) { + switch(s->state) { + case NORMAL: + if(c != 27) putcf(c | (s->cattrs << 8)); + else s->state = ESC; + return; + case ESC: + s->state = (c == '[') ? BRACKET : NORMAL; + return; + case BRACKET: + if(c == '3') { + s->state = COLOR_FG; + } else if(c == '0') { + s->state = COLOR; + s->attrs = 0; + } else { + s->state = NORMAL; + } + return; + case COLOR_FG: + if(c >= '0' && c <= '9') { + s->attrs = (s->attrs & ~(0x07)) | vga_colors[c - '0']; + c |= ((c - '0') << 8); + s->state = COLOR; + } else { + s->state = NORMAL; + } + return; + case COLOR: + s->state = (c == ';') ? BRACKET : NORMAL; + if(c == 'm') s->cattrs = s->attrs; + return; + } +} + diff --git a/kern/ansi.h b/kern/ansi.h new file mode 100644 index 0000000..970f9c6 --- /dev/null +++ b/kern/ansi.h @@ -0,0 +1,20 @@ +#ifndef _ANSI_H_ +#define _ANSI_H_ + +#include + +struct AttrState { + uint8_t cattrs; + uint8_t attrs; + enum { + NORMAL, + ESC, + BRACKET, + COLOR_FG, + COLOR + } state; +}; + +void ansi_step(void (*putcf)(int), int c, struct AttrState* s); + +#endif diff --git a/kern/console.c b/kern/console.c index 7d312a7..8019dad 100644 --- a/kern/console.c +++ b/kern/console.c @@ -7,6 +7,7 @@ #include #include +#include static void cons_intr(int (*proc)(void)); static void cons_putc(int c); @@ -128,6 +129,7 @@ lpt_putc(int c) static unsigned addr_6845; static uint16_t *crt_buf; static uint16_t crt_pos; +static struct AttrState attst; static void cga_init(void) @@ -136,6 +138,10 @@ cga_init(void) uint16_t was; unsigned pos; + attst.cattrs = 0; + attst.attrs = 0; + attst.state = NORMAL; + cp = (uint16_t*) (KERNBASE + CGA_BUF); was = *cp; *cp = (uint16_t) 0xA55A; @@ -157,10 +163,15 @@ cga_init(void) crt_pos = pos; } - +static void cga_putc_internal(int c); static void -cga_putc(int c) +cga_putc(int c){ + ansi_step(cga_putc_internal, c, &attst); +} + +static void +cga_putc_internal(int c) { // if no attribute given, then use black on white if (!(c & ~0xFF)) diff --git a/lib/printfmt.c b/lib/printfmt.c index 7535e93..b1de635 100644 --- a/lib/printfmt.c +++ b/lib/printfmt.c @@ -79,54 +79,6 @@ getint(va_list *ap, int lflag) // Main function to format and print a string. void printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...); -struct AttrState { - uint8_t cattrs; - uint8_t attrs; - enum { - NORMAL, - ESC, - BRACKET, - COLOR_FG, - COLOR - } state; -}; - -void -putchw(void (*putch)(int, void*), int c, void* data, struct AttrState* s) { - switch(s->state) { - case NORMAL: - if(c != 27) putch(c | (s->cattrs << 8), data); - else s->state = ESC; - return; - case ESC: - s->state = (c == '[') ? BRACKET : NORMAL; - return; - case BRACKET: - if(c == '3') { - s->state = COLOR_FG; - } else if(c == '0') { - s->state = COLOR; - s->attrs = 0; - } else { - s->state = NORMAL; - } - return; - case COLOR_FG: - if(c >= '0' && c <= '9') { - s->attrs = (s->attrs & ~(0x07)) | (c - '0'); - c |= ((c - '0') << 8); - s->state = COLOR; - } else { - s->state = NORMAL; - } - return; - case COLOR: - s->state = (c == ';') ? BRACKET : NORMAL; - if(c == 'm') s->cattrs = s->attrs; - return; - } -} - void vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { @@ -135,17 +87,12 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) unsigned long long num; int base, lflag, width, precision, altflag; char padc; - struct AttrState attst; - - attst.state = NORMAL; - attst.cattrs = 0; - attst.attrs = 0; while (1) { while ((ch = *(unsigned char *) fmt++) != '%') { if (ch == '\0') return; - putchw(putch, ch, putdat, &attst); + putch(ch, putdat); } // Process a %-escape sequence