We've been working through getting a working setup for debugging the linux kernel via JTAG, using Segger's J-Link. There's a few hints on this forum and elsewhere, but not a complete guide, so here's what works for us:
First: if you just go and try debugging the kernel, you'll probably find that you either:
- can't connect at all once linux has booted, or
- if you connect at u-boot, and then let linux load, you get disconnected around the time that init runs, or
- if you get lucky and manage to connect when linux is running, you get disconnected shortly afterwards.
This issue is caused by linux going into a low power idle state. In this state, linux will gate the ARM clock domain, causing the JTAG to lose connection whenever the OS is executing the idle task. There are two ways around this. The first is less invasive, but slightly more limited.
Method 1 (easy method): Disable 'clock off' wait state in the cpuidle driver
On the IMX6 you can disable the clock off wait state through sysfs. Navigate to the cpuidle driver for the cpu (cpu0 in this case as we are on the solo lite).
The output of 'cat desc' should be 'Clock off'. If this is not the case, go up a folder and check the other states until you find the one with the 'Clock off' desc. Now, you simply need to disable this wait state
Now you should be able to attach with JTAG and debug to your heart's content.
Method 2 (harder method): Disable gating of the ARM clock domain in the source
The above method is good for most cases of debugging, unless something needs to be debugged during startup. In this case you will need to modify the source to stop the IMX from ever gating the ARM clock domain. You can apply the following patch to disable the clock gating.
We have been using the Segger J-Link to debug ARM platforms from a linux host. Download the Segger J-Link tools for Linux from the Segger website. After you have done one of the two above methods you can now attach the J-Link GDB server. Note that by default your user wont have permissions to access the J-Link USB device. You can either setup a udev rule to set the permissions properly, or simply run the gdb server as root. We will do the latter as we are lazy. Note the noir and noreset options. noir will not init the working register and noreset won't reset the cpu core. See the J-Link documentation included with the download for more info.
Helpful kernel configuration options for debugging
Before diving right into debugging, note there are some useful kernel configuration options that will make your life a lot easier. Below is a list of kernel configuration options you should set:
GDB client connection and debugging!
Finally, with a GDB server running that is connected to your target, you can connect with a GDB client. Note that you can point GDB to your linux binary for the debugging information. Also, you should use your cross compile GDB for this target. If you are using the Yocto Poky SDK (as we are), you can simply source the SDK and use '$GDB' in place of gdb-[CROSS-COMPILE] below. Note that [CROSS-COMPILE] should be replaced with your proper cross compile tuple (e.g. gdb-arm-linux-eabi).
$ gdb-[CROSS-COMPILE] /path/to/linux/build/vmlinux
(gdb) target remote localhost:
Enjoy your debugging session! Any questions or comments, please post them below.