diff options
author | Mike J. Chen <mjchen@google.com> | 2012-02-02 10:12:52 -0800 |
---|---|---|
committer | Mike J. Chen <mjchen@google.com> | 2012-03-03 17:29:34 -0800 |
commit | 592fa8103cd61d5b57c99cbb0def322d29ef45ae (patch) | |
tree | 17769c0a0173ff72601207a972251c0d861aa7ef | |
parent | ed563657d787eb1809440de2b92629c7258c0666 (diff) | |
download | uboot-592fa8103cd61d5b57c99cbb0def322d29ef45ae.tar.gz |
FASTBOOT: Add 'fastboot oem kmsg' - dumps kernel log
Change-Id: I68df06a2cab8b288130014fe4b6738a59ab34979
Signed-off-by: Mike J. Chen <mjchen@google.com>
-rw-r--r-- | common/cmd_fastboot.c | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c index e89186de9..ee8dc11fe 100644 --- a/common/cmd_fastboot.c +++ b/common/cmd_fastboot.c @@ -122,7 +122,7 @@ print "%04d/%02d/%02d %02d:%02d\n" % (int(foo[0], 36) + 2001, #define CONFIG_FASTBOOT_LOG_SIZE 4000 #endif static char log_buffer[CONFIG_FASTBOOT_LOG_SIZE]; -static unsigned long log_position; +static uint32_t log_position; #ifdef DEBUG #define FBTDBG(fmt, args...)\ @@ -1466,6 +1466,7 @@ static int fbt_send_raw_info(const char *info, int bytes_left) make sure priv.response is terminated */ priv.response[4 + bytes_left] = '\0'; + break; } } @@ -1477,7 +1478,7 @@ static int fbt_send_raw_info(const char *info, int bytes_left) return 0; } -static void fbt_dump_log(void) +static void fbt_dump_log(char *buf, uint32_t buf_size) { /* the log consists of a bunch of printf output, with * logs of '\n' interspersed. to make it format a @@ -1486,15 +1487,22 @@ static void fbt_dump_log(void) * buffer, break the log into bits that end * with '\n', like replaying the printfs. */ - int bytes_left = log_position; - char *line_start = log_buffer; - while (bytes_left) { + char *line_start = buf; + + if (buf_size == 0) { + printf("%s: unexpected buf size of 0\n", __func__); + return; + } + + /* guarantee null termination for strchr/strlen */ + buf[buf_size - 1] = 0; + while (buf_size) { char *next_line = strchr(line_start, '\n'); if (next_line) { int len = next_line - line_start + 1; fbt_send_raw_info(line_start, len); line_start += len; - bytes_left -= len; + buf_size -= len; } else { fbt_send_raw_info(line_start, strlen(line_start)); break; @@ -1502,6 +1510,39 @@ static void fbt_dump_log(void) } } +struct ram_console_buffer { + uint32_t sig; + uint32_t start; + uint32_t size; + uint8_t data[0]; +}; +#define RAM_CONSOLE_SIG (0x43474244) /* 'DBGC' */ + +static void fbt_dump_kmsg(void) +{ + /* the kmsg log is similar to the log we keep in the bootloader + * except that it has a header, is at an address fixed for + * each board, and starts with a ram_console_buffer structure. + */ + struct ram_console_buffer *buf; +#ifndef CONFIG_FASTBOOT_RAMCONSOLE_START + printf("No ram console start address defined\n"); + strcpy(priv.response, "FAILNo ram console start address defined"); + return; +#else + buf = (struct ram_console_buffer *)CONFIG_FASTBOOT_RAMCONSOLE_START; +#endif + if (buf->sig != RAM_CONSOLE_SIG) { + printf("Ram console signature not found\n"); + strcpy(priv.response, "FAILRam console signature not found\n"); + return; + } + printf("Ram console found (size %d, start %d):\n", + buf->size, buf->start); + fbt_dump_log((char *)&buf->data[0], buf->start); + strcpy(priv.response, "OKAY"); +} + static void fbt_handle_oem(char *cmdbuf) { cmdbuf += 4; @@ -1509,11 +1550,18 @@ static void fbt_handle_oem(char *cmdbuf) /* %fastboot oem log */ if (strcmp(cmdbuf, "log") == 0) { FBTDBG("oem %s\n", cmdbuf); - fbt_dump_log(); + fbt_dump_log(log_buffer, log_position); strcpy(priv.response, "OKAY"); return; } + /* %fastboot oem kmsg */ + if (strcmp(cmdbuf, "kmsg") == 0) { + FBTDBG("oem %s\n", cmdbuf); + fbt_dump_kmsg(); + return; + } + /* %fastboot oem recovery */ if (strcmp(cmdbuf, "recovery") == 0) { FBTDBG("oem recovery\n"); |