How to Debug with a BDI2000 or BDI3000 JTAG Debugger using TimeStorm

Kernel projects can be debugged with TimeStorm using either JTAG devices such as the Abatron BDI2000 and BDI3000 on-chip debugging device, or kernel debuggers such as KGDB. This document demonstrates the necessary steps to debug with BDI2000 and BDI3000 debuggers using TimeStorm.

This document assumes that TimeStorm is already loaded on the host computer and the BDI2000 or BDI3000 debugger has successfully been connected to the target board as described in JTAG’s manufacturer’s manual.

NOTES: Some additional command-line steps outside of TimeStorm are required for controlling the JTAG device, loading appropriate firmware on the JTAG device, and downloading kernels to the board.

Details for using the BDI2000/BDI3000 debugger without TimeStorm can be found in How To Debug a Board with the BDI2000/BDI3000 from the Command Line (https://linuxlink.timesys.com/docs/bdi2000_command_line).

Step 1. Linux kernel preparation

  1. Run Linux kernel configuration, using the Linux kernel’s standard tools at the Factory’s top level directory:
    make kernel-menuconfig
  2. Enable the following options:
    Kernel hacking->Kernel debugging and ->Compile the kernel with debug info and ->Enable run-time debugging

Step 2. Creating a TimeStorm Linux kernel project

  1. Create a new Makefile project within TimeStorm: New->Project->C Project.
  2. Provide the name for the project, and select the following options in the wizard: go to Executable->Empty Project, select TimeStorm Cross-Compile Toolchain, and select Next.
  3. Bring up Advanced Settings for the project, navigate to C/C++ Build options
    1. Builder Settings:
      1. Uncheck Generate Makefiles automatically
      2. Uncheck Use default build command, and modify it according to the following rule:
        make ARCH=<target architecture> CROSS_COMPILE=<fully qualified path to cross-toolchain>
        e.g.
        make ARCH=mips CROSS_COMPILE=/home/user/timesys-sdk/toolchain/bin/mips64-timesys-linux-gnu-
    2. Behavior:
      1. Place a check next to Build on resource save (Auto build), remove All option, and uncheck the box.
      2. Remove the All option under Build (incremental build).
        NOTE: If you plan on building a specific Linux kernel image (for example, uImage), put uImage in place of All in the above Behavior options.
  4. Pick a cross-toolchain and Finish the project.
  5. Import the existing Linux kernel source tree into TimeStorm. This is important as it enables you to see the sources during a kernel debug session. Using the C/C++ Project or Navigator view, select the newly created project, right-click to bring up a context menu and select Import... option.
  6. Choose General->File System and click Next.
  7. Put the path of the Linux kernel top level directory in the From: field. In the left pane below, put a check on the top-level directory and Finish the import process.
  8. Build a Linux kernel in TimeStorm by selecting a project in the C/C++ Project view and using a context menu run the Build Project command.

Step 3. Preparing a Linux kernel image

With all the debug options enabled in the Linux kernel, the resulting image will be very large (a couple hundred MB). Transferring such large images into the target systems’ memory often times is not supported or at best, takes a long time, making it very inconvenient.

Fortunately, the target system does not require all the symbols for debugging. It needs to have all the symbols in sync with a debugged image (on your host), but we can strip unneeded symbols from the image that runs on the target.

Host vmlinux (large file) Target vmlinux (stripped binary)

  1. Using a command line, copy a vmlinux image from the top level directory of your TimeStorm Linux project to /tftpboot directory. Strip unneeded symbols:
    <cross-toolchain directory>-strip --strip-unneeded /tftpboot/vmlinux
    e.g.
    /home/user/timesys-sdk/toolchain/bin/mips64-timesys-linux-gnu-strip --strip-unneeded /tftpboot/vmlinux

    Now, the /tftpboot/vmlinux copy should be back to the typical Linux image size for your target.

Step 4. Setting up a debug session

  1. If you are booting the kernel directly,transfer the kernel to the board or use TFTP to boot the board.
  2. Rename the vmlinux file in your kernel tree. This file is a statically linked executable version of the kernel; it is created as an intermediate step in the kernel build. However, when a file named vmlinux is passed to GDB as the program to be debugged, GDB attempts to use the KGDB kernel debugging interface. KGDB is incompatible with the BDI2000/BDI3000, which uses standard GDB commands.
    1. To change the filename, use the C/C++ Projects or Navigator view to locate the vmlinux file. It typically is created in the kernel/ directory. Select the vmlinux file, right-click, and choose Rename from the context menu. Any name other than "vmlinux#" is acceptable (for example, @vmlinux1 or my_vmlinux).
  3. Find a suitable breakpoint inside the kernel. Timesys suggests using the start_kernel symbol. To find this, search the System.map file in your kernel's root directory for the proper hexadecimal address:
    # grep start_kernel System.map
    c00085d4 T start_kernel

    The proper breakpoint address, therefore, is 0xc00085d4.
  4. Boot the board with the BDI. Follow these general steps — they are specifically for an EP8260, but with some minor changes, the procedures will work on all boards.
    1. Open a serial console connection to the board.
    2. Telnet to the BDI2000/BDI3000.
    3. On the BDI2000/BDI3000 Telnet session: Issue the go command:
      go
    4. On the target serial console: Transfer the kernel to the bootloader, and answer the questions presented:
      tftp
    5. On the BDI2000/BDI3000 Telnet session: Stop the board using the debugger, and issue a breakpoint at the kernel start:
      halt
      bi 0xc00085d4
    6. On the BDI2000/BDI3000 Telnet session: Start the board again using the debugger:
      go
    7. On the target serial console: Use the "go" command to boot the kernel:
      go

      The bootloader will load the kernel and stop at the breakpoint.
    8. On the BDI2000/BDI3000 Telnet session: Clear the breakpoint in the debugger:
      ci

      NOTE: At this point, the debugger is connected and the kernel is loaded, but the board has been stopped. The debugger can now be controlled with TimeStorm.
  5. Follow this procedure to use the debugger from TimeStorm:
    1. Start TimeStorm and select your kernel project.
    2. Choose Run -> Debug Configurations. Double click on C/C++ Local Configurations. This will create a new debug configuration.
    3. In the main tab, the application to be debugged is the vmlinux file inside your kernel tree.
    4. Click on the Debugger tab and select the gdbserver Debugger under Debugger option.
    5. Change the Stop on startup at: option to start_kernel symbol
    6. Changes for the Debugger Options:
      1. Main:
        1. Under GDB Debugger: specify a fully qualified path to the cross-compiler's GDB
          e.g.
          /home/user/timesys-sdk/toolchain/bin/mips64-timesys-linux-gnu-gdb
      2. Connection:
        1. Since the BDI2000/BDI3000 is connected via Ethernet, select TCP as a connection type
        2. Enter the debugger’s IP address and port in appropriate fields:
          e.g.
          Host name or IP address:    192.168.99.118
          Port number:                2001
    7. Click the Apply button to save the configuration, and then click Debug to open the Debug perspective and start the debug launch configuration.

More information about how to use the debugging features in TimeStorm can be found in the C/C++ Development Users Guide inside TimeStorm's online Help (choose Help > Help Contents).