aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike J. Chen <mjchen@google.com>2012-02-02 10:12:52 -0800
committerMike J. Chen <mjchen@google.com>2012-03-03 17:29:34 -0800
commit592fa8103cd61d5b57c99cbb0def322d29ef45ae (patch)
tree17769c0a0173ff72601207a972251c0d861aa7ef
parented563657d787eb1809440de2b92629c7258c0666 (diff)
downloaduboot-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.c62
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");