Debugging the free_ecb_at91 board using JTAG

For a school project early 2007 (a study of embedded Linux on the AT91RM9200 ARM9 processor) I got familiar with the GNU development tools and setup required to run a Linux based operating system.
Using the setup described here I was able to inspect the inner workings of Darrell loader in real time, set hardware breakpoints, step through the program flow and inspect values of program variables while the CPU core was halted.
Hardware
I constructed a JTAG connector cable to connect the 6 pin JTAG header on the ecb_at91 board to a standard 20-pin ARM JTAG header as they are used in many boards and JTAG dongles with ARM cores. As JTAG interface I used a arm-usb-ocd dongle manufactured by Olimex.
The connections are as follows:
1 2 GREEN VREF 3 4 BLUE GND 5 BROWN TDI 6 7 YELLOW TMS 8 9 ORANGE TCK 10 11 12 13 RED TDO 14 ... 20
I soldered a 1x6 pinheader connector to the board, and a 3 pin jumper header to manipulate the processor's JTAGSEL signal.
Software
I used a cross compiling toolchain of GCC, built using crosstool. The JTAG interfacing software side was done by OpenOCD, which speaks the GDB debug protocol.
OpenOCD configuration file
#daemon configuration telnet_port 4444 gdb_port 3333 #interface interface ft2232 ft2232_device_desc "Olimex OpenOCD JTAG A" ft2232_layout "olimex-jtag" ft2232_vid_pid 0x15BA 0x0003 jtag_speed 2 #use combined on interfaces or targets that can't set TRST/SRST separately #reset_config trst_and_srst reset_config none #srst_pulls_trst #jtag scan chain #format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) jtag_device 4 0x1 0xf 0xe #target configuration daemon_startup reset #target <type> <endianess> <reset mode> target arm920t little run_and_halt 0 arm920t working_area 0 0x200000 0x4000 backup run_and_halt_time 0 30
GDB init
When invoking the GNU Debugger (gdb), some routine configuration steps have to be made. I put these in a file named 'gdbinit', which I source right after I invoked arm-softfloat-linux-gnu-gdb, or by starting gdb with the arguments -x gdbinit.
target remote localhost:3333 set remote hardware-watchpoint-limit 2 monitor arm7_9 force_hw_bkpts enable
This configuration has the following effect: Since the ARM9 core has support for but two hardware breakpoints, gdb has to be made aware of this, if not gdb reports an error when resuming the core after it has been halted.
Result
Behold a short summary transcript of some of the things I was able to do:
(gdb) l 280 puts("4: Start u-boot\n"); 281 puts("5: Upload Filesystem image\n"); 282 puts("6: Memory test\n"); 283 dispmenu = 0; 284 } 285 if(tstc()){ 286 key = getc(); 287 autoboot = 0; 288 } 289 else (gdb) b 282 Breakpoint 2 at 0x898: file src/board.c, line 282. (gdb) i b Num Type Disp Enb Address What 2 breakpoint keep y 0x00000898 in start_armboot at src/board.c:282 (gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. start_armboot () at src/board.c:282 282 puts("6: Memory test\n"); (gdb) (gdb) l 139 140 puts ("Writing... "); 141 142 ptr = (int *) base; 143 for (i = 0; i < len / sizeof(int); i++) 144 *(ptr++) = i; 145 146 puts ("Reading... "); 147 148 ptr = (int *) base; (gdb) b 140 Breakpoint 70 at 0x534: file src/board.c, line 140. (gdb) c Continuing. Breakpoint 70, memory_test (base=536870912, len=16777216) at src/board.c:140 140 puts ("Writing... "); (gdb) p ptr $5 = (int *) 0x1000000 (gdb) d b Delete all breakpoints? (y or n) y (gdb) l 135 int memory_test(int base, int len) 136 { 137 int *ptr; 138 int i; 139 140 puts ("Writing... "); 141 142 ptr = (int *) base; 143 for (i = 0; i < len / sizeof(int); i++) 144 *(ptr++) = i; (gdb) b 144 Breakpoint 71 at 0x550: file src/board.c, line 144. (gdb) c Continuing. Breakpoint 71, memory_test (base=536870912, len=4194304) at src/board.c:144 144 *(ptr++) = i; (gdb) p i $6 = 0 (gdb) c Continuing. Breakpoint 71, memory_test (base=536870912, len=4194304) at src/board.c:144 144 *(ptr++) = i; (gdb) p i $7 = 1 (gdb) c Continuing. Breakpoint 71, memory_test (base=536870912, len=4194304) at src/board.c:144 144 *(ptr++) = i; (gdb) p i $8 = 2 (gdb)
Liked something? Worked on something similar? Let me know what you think on Mastodon!
You can direct-message me, or mention me @thouters@hsnl.social