1. get and unzip src
# mkdir /usr/src/debug
# cd /usr/src/debug
# wget ftp://ftp.gnu.org/pub/gnu/gdb/gdb-6.3.tar.bz2
# tar -jxvf gdb-6.3.tar.bz2
2. apply gdb patch for ARM
# cp [PATCH_PATH]/gdb-6.3-tango-20050204.patch /usr/src/debug/gdb-6.3
# patch -p1 < gdb-6.3-tango-20050204.patch
replace [PATCH_PATH] to your patch path.
use patch-gdb-5.2.1-arm7tdmi-20020920 in the reference document is another choice, it's more complexity which need modify some code before compile.
3. build gdb
# mkdir /usr/src/debug/build_gdb
# cd /usr/src/debug/build_gdb
# ../gdb-6.3/configure --target=arm-linux --host=i386-pc-linux --prefix=/opt/gdebug
# make
# make install
4. build gdbserver
# mkdir /usr/src/debug/build_gdbserver
# cd /usr/src/debug/build_gdbserver
# export PATH=[TOOLCHAIN_PATH]:$PATH
# CC=arm-elf-gcc LDFLAGS='-Wl,-elf2flt' ../gdb-6.3/gdb/gdbserver/configure --target=arm-elf-linux --host=arm-elf-linux --prefix=/opt/gdebug/arm-linux
# make
# make install
set [TOOLCHAIN_PATH] to your toolchain patch.
after build, deploy the gdbserver binary to your target filesystem.
5.use gdb and gdbserve(command line or eclipse):
examples:
host pc ip:192.168.1.45
board ip:192.168.1.180
copy program and gdbserver to host/tftpboot/
and then in Target borad:
# mount 192.168.1.108:/tftpboot /mnt/nfs
# cd /mnt/nfs
# ./gdbserver 192.168.1.45:1234 gdbtest
In host pc:
# cd /usr/local/arm-gdb/bin/
# copy gdbtest /usr/local/arm-gdb/bin/
# ./arm-linux-gdb gdbtest
(gdb)target remote 192.168.1.180:1234
(gdb)list or l
(gdb)break func
(gdb)break 22
(gdb)info br
(gdb)continue or c
(gdb)next or n
(gdb)print or p result
(gdb) finish
(gdb) next
(gdb) quit
Appendix:
1). reference: http://www.uclinux.org/pub/uClinux/archive/10734.html
2). gdb-6.3-tango-20050204.patch:
/* start of gdb-6.3-tango-20050204.patch */
diff -Nur gdb-6.3/gdb/arm-tdep.c gdb-6.3.patched/gdb/arm-tdep.c
--- gdb-6.3/gdb/arm-tdep.c 2004-08-02 19:02:20.000000000 -0700
+++ gdb-6.3.patched/gdb/arm-tdep.c 2005-02-04 10:14:11.000000000 -0800
@@ -1925,10 +1925,12 @@
/* NOTE rearnsha 2002-02-18: for now we allow a non-multi-arch gdb to
override these definitions. */
#ifndef ARM_LE_BREAKPOINT
-#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7}
+//#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7}
+#define ARM_LE_BREAKPOINT {0x01,0x00,0x9f,0xEF}
#endif
#ifndef ARM_BE_BREAKPOINT
-#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE}
+//#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE}
+#define ARM_BE_BREAKPOINT {0xEF,0x9f,0x00,0x01}
#endif
#ifndef THUMB_LE_BREAKPOINT
#define THUMB_LE_BREAKPOINT {0xfe,0xdf}
diff -Nur gdb-6.3/gdb/config/arm/tm-embed.h gdb-6.3.patched/gdb/config/arm/tm-embed.h
--- gdb-6.3/gdb/config/arm/tm-embed.h 2004-04-30 13:52:16.000000000 -0700
+++ gdb-6.3.patched/gdb/config/arm/tm-embed.h 2005-02-04 10:14:11.000000000 -0800
@@ -27,7 +27,7 @@
/* The remote stub should be able to single-step. */
#undef SOFTWARE_SINGLE_STEP_P
-#define SOFTWARE_SINGLE_STEP_P() 0
+#define SOFTWARE_SINGLE_STEP_P() 1
/* The first 0x20 bytes are the trap vectors. */
#undef LOWEST_PC
diff -Nur gdb-6.3/gdb/gdbserver/linux-arm-low.c gdb-6.3.patched/gdb/gdbserver/linux-arm-low.c
--- gdb-6.3/gdb/gdbserver/linux-arm-low.c 2004-02-29 08:43:49.000000000 -0800
+++ gdb-6.3.patched/gdb/gdbserver/linux-arm-low.c 2005-02-04 10:14:11.000000000 -0800
@@ -23,7 +23,7 @@
#include "linux-low.h"
#ifdef HAVE_SYS_REG_H
-#include <sys/reg.h>
+//#include <sys/reg.h>
#endif
#define arm_num_regs 26
diff -Nur gdb-6.3/gdb/gdbserver/linux-low.c gdb-6.3.patched/gdb/gdbserver/linux-low.c
--- gdb-6.3/gdb/gdbserver/linux-low.c 2004-10-16 10:42:00.000000000 -0700
+++ gdb-6.3.patched/gdb/gdbserver/linux-low.c 2005-02-04 10:14:11.000000000 -0800
@@ -78,6 +78,24 @@
/* FIXME: Delete eventually. */
#define inferior_pid (pid_of (get_thread_process (current_inferior)))
+void send_area(char* buf) {
+
+ unsigned int x;
+ unsigned int code_start = ptrace (PTRACE_PEEKUSER, inferior_pid,
+ (PTRACE_ARG3_TYPE) 49*4, 0);
+ unsigned int data_start = ptrace (PTRACE_PEEKUSER, inferior_pid,
+ (PTRACE_ARG3_TYPE) 50*4, 0);
+ unsigned int bss_start = data_start;
+ unsigned int code_end = ptrace(PTRACE_PEEKUSER, inferior_pid,
+ (PTRACE_ARG3_TYPE) 51*4, 0);
+
+ printf("code at %p - %p, data at %p/n", code_start, code_end, data_start);
+
+ x = data_start - (code_end - code_start);
+ sprintf(buf,"Text=%x;Data=%x;Bss=%x;", code_start, x, x);
+};
+
+
/* This function should only be called if the process got a SIGTRAP.
The SIGTRAP could mean several things.
@@ -139,7 +157,7 @@
void *new_process;
int pid;
- pid = fork ();
+ pid = vfork ();
if (pid < 0)
perror_with_name ("fork");
diff -Nur gdb-6.3/gdb/gdbserver/server.c gdb-6.3.patched/gdb/gdbserver/server.c
--- gdb-6.3/gdb/gdbserver/server.c 2004-03-04 19:44:27.000000000 -0800
+++ gdb-6.3.patched/gdb/gdbserver/server.c 2005-02-04 10:14:11.000000000 -0800
@@ -89,6 +89,12 @@
handle_query (char *own_buf)
{
static struct inferior_list_entry *thread_ptr;
+
+ if (strcmp ("qOffsets", own_buf) == 0)
+ {
+ send_area(own_buf);
+ return;
+ }
if (strcmp ("qSymbol::", own_buf) == 0)
{
/* end of gdb-6.3-tango-20050204.patch */
如果有错误的话,还需要打上另外一个补丁:
--- gdb-6.3/sim/arm/iwmmxt~old.c 2003-03-27 12:13:33.000000000 -0500
+++ gdb-6.3/sim/arm/iwmmxt.c 2006-09-18 15:26:05.000000000 -0400
@@ -2114,7 +2114,7 @@
s = (signed long) a * (signed long) b;
- (signed long long) t += s; + t += (signed long long)s; } else { @@ -2130,7 +2130,7 @@ wR [BITS (12, 15)] = 0;
if (BIT (21)) /* Signed. */ - (signed long long) wR[BITS (12, 15)] += (signed long long) t; + wR[BITS (12, 15)] += (signed long long) t; else wR [BITS (12, 15)] += t;
@@ -2166,7 +2166,7 @@ b = wRHALF (BITS (0, 3), i * 2); b = EXTEND16 (b);
- (signed long) s1 = a * b; + s1 = (signed long)a * (signed long)b;
a = wRHALF (BITS (16, 19), i * 2 + 1); a = EXTEND16 (a); @@ -2174,7 +2174,7 @@ b = wRHALF (BITS (0, 3), i * 2 + 1); b = EXTEND16 (b);
- (signed long) s2 = a * b; + s2 = (signed long)a * (signed long)b; } else /* Unsigned. */ { @@ -2183,12 +2183,12 @@ a = wRHALF (BITS (16, 19), i * 2); b = wRHALF (BITS ( 0, 3), i * 2);
- (unsigned long) s1 = a * b; + s1 = (unsigned long)a *(unsigned long) b;
a = wRHALF (BITS (16, 19), i * 2 + 1); b = wRHALF (BITS ( 0, 3), i * 2 + 1);
- (signed long) s2 = a * b; + s2 = (signed long)a * (signed long)b; }
r |= (ARMdword) ((s1 + s2) & 0xffffffff) << (i ? 32 : 0);
如果生成的gdbserver无法使用的话我也没有办法了,呵呵。我也没有搞定,不好意思!