diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 1d71df66f3fa7c9027e39742e4fc0680acdde1b6..1aed37b4c564c843fa2d92a145255de45188200f 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -82,7 +82,7 @@ static int kgdb_use_con; int dbg_switch_cpu; /* Use kdb or gdbserver mode */ -static int dbg_kdb_mode = 1; +int dbg_kdb_mode = 1; static int __init opt_kgdb_con(char *str) { diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h index 44cf3de8cf9e515f6524c012b25d166dc48ac470..c5d753d80f6764869512a4884dc717a14c1b1e66 100644 --- a/kernel/debug/debug_core.h +++ b/kernel/debug/debug_core.h @@ -66,9 +66,11 @@ extern void gdbstub_msg_write(const char *s, int len); /* gdbstub functions used for kdb <-> gdbstub transition */ extern int gdbstub_state(struct kgdb_state *ks, char *cmd); +extern int dbg_kdb_mode; #ifdef CONFIG_KGDB_KDB extern int kdb_stub(struct kgdb_state *ks); +extern int kdb_parse(const char *cmdstr); #else /* ! CONFIG_KGDB_KDB */ static inline int kdb_stub(struct kgdb_state *ks) { diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index 3c000490a7dd1938cb20a3f410ab31223bbf8c18..4b17b32695259060260f9748d2c51490397c4888 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c @@ -201,6 +201,9 @@ void gdbstub_msg_write(const char *s, int len) int wcount; int i; + if (len == 0) + len = strlen(s); + /* 'O'utput */ gdbmsgbuf[0] = 'O'; @@ -685,6 +688,25 @@ static void gdb_cmd_query(struct kgdb_state *ks) kgdb_mem2hex(tmpstr, remcom_out_buffer, strlen(tmpstr)); } break; +#ifdef CONFIG_KGDB_KDB + case 'R': + if (strncmp(remcom_in_buffer, "qRcmd,", 6) == 0) { + int len = strlen(remcom_in_buffer + 6); + + if ((len % 2) != 0) { + strcpy(remcom_out_buffer, "E01"); + break; + } + kgdb_hex2mem(remcom_in_buffer + 6, + remcom_out_buffer, len); + len = len / 2; + remcom_out_buffer[len++] = 0; + + kdb_parse(remcom_out_buffer); + strcpy(remcom_out_buffer, "OK"); + } + break; +#endif } } diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 9e3cec7a925c7bfced9ace00b6f90ed551df6d3b..8339b291e8bc23c3acbc434da51df87ce8c796db 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include "kdb_private.h" @@ -669,10 +670,14 @@ int kdb_printf(const char *fmt, ...) * Write to all consoles. */ retlen = strlen(kdb_buffer); - while (c) { - c->write(c, kdb_buffer, retlen); - touch_nmi_watchdog(); - c = c->next; + if (!dbg_kdb_mode && kgdb_connected) { + gdbstub_msg_write(kdb_buffer, retlen); + } else { + while (c) { + c->write(c, kdb_buffer, retlen); + touch_nmi_watchdog(); + c = c->next; + } } if (logging) { saved_loglevel = console_loglevel; diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 69ed2eff3feaa6c988ee9d42be0064e29845f57b..97d3ba69775df3b66120f0e7579fc8fba0d896da 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -254,7 +254,6 @@ extern unsigned long kdb_task_state(const struct task_struct *p, unsigned long mask); extern void kdb_ps_suppressed(void); extern void kdb_ps1(const struct task_struct *p); -extern int kdb_parse(const char *cmdstr); extern void kdb_print_nameval(const char *name, unsigned long val); extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); extern void kdb_meminfo_proc_show(void);