{"id":120,"date":"2018-02-05T15:36:25","date_gmt":"2018-02-05T23:36:25","guid":{"rendered":"https:\/\/sysprogs.com\/tutorials\/?p=120"},"modified":"2023-06-06T09:05:50","modified_gmt":"2023-06-06T16:05:50","slug":"preparing-raspberry-pi-for-jtag-debugging","status":"publish","type":"post","link":"https:\/\/sysprogs.com\/VisualKernel\/tutorials\/raspberry\/jtagsetup\/","title":{"rendered":"Preparing Raspberry PI for JTAG Debugging"},"content":{"rendered":"<p>This tutorial shows how to prepare your\u00a0<a href=\"http:\/\/www.raspberrypi.org\/\">Raspberry PI\u00a0<\/a>board for debugging with JTAG (we have tested this with Raspberry Pi 1, 2, 3 and 4). Using JTAG will allow debugging the Linux kernel using hardware like\u00a0<a href=\"http:\/\/www.segger.com\/debug-probes.html\">Segger J-Link<\/a>. As Raspberry PI board does not have a connector with a normal JTAG layout, preparing the board for JTAG debugging involves finding the correct pins and wiring them in the correct order. Follow the steps below for a complete walkthrough:<\/p>\n<ol>\n<li>Determine the revision of your Raspberry PI board. Connect to it using SSH and run the following command:\n<pre class=\"code\">cat \/proc\/cpuinfo<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/img\/01-cpuinfo.png\" width=\"679\" height=\"441\" \/><\/li>\n<li>Use the\u00a0<a href=\"http:\/\/elinux.org\/RPi_HardwareHistory\">revision table\u00a0<\/a>to look up the board revision. In this tutorial we will use Model B v2.0 (revision 0xe), however\u00a0the same schematics also works for Raspberry Pi 3 and Raspberry Pi 4.<\/li>\n<li>In order to find which pins on the board are JTAG pins we need to first find the GPIO numbers that correspond to them. JTAG requires 4 pins: <strong>TDI<\/strong>, <strong>TDO<\/strong>, <strong>TMS<\/strong> and <strong>TCK<\/strong> plus <strong>TRST<\/strong> and <strong>RTCK<\/strong> pins. You can find the GPIO pins corresponding to these in the datasheet for <a href=\"https:\/\/www.raspberrypi.org\/app\/uploads\/2012\/02\/BCM2835-ARM-Peripherals.pdf\">BCM2835<\/a> (Raspberry Pi 1-3) or <a href=\"https:\/\/datasheets.raspberrypi.com\/bcm2711\/bcm2711-peripherals.pdf\">BCM2711<\/a> (Raspberry Pi 4). Search for &#8220;_TCK&#8221; to find the GPIO number table:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/02-pins.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-460\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/02-pins.png\" alt=\"\" width=\"925\" height=\"635\" \/><\/a><\/li>\n<li>Here are the GPIO numbers for the current revision:\n<div class=\"table_responsive\">\n<table class=\"neat_table\">\n<tbody>\n<tr>\n<td>JTAG pin<\/td>\n<td>&#8220;ALT4&#8221; mode<\/td>\n<td>&#8220;ALT5&#8221; mode<br \/>\n<span style=\"color: red;\">(Raspberry Pi 1-3 only)<\/span><\/td>\n<\/tr>\n<tr>\n<td>TDI<\/td>\n<td>GPIO26<\/td>\n<td>GPIO4<\/td>\n<\/tr>\n<tr>\n<td>TDO<\/td>\n<td>GPIO24<\/td>\n<td>GPIO5<\/td>\n<\/tr>\n<tr>\n<td>TMS<\/td>\n<td>GPIO27<\/td>\n<td>GPIO12<\/td>\n<\/tr>\n<tr>\n<td>TCK<\/td>\n<td>GPIO25<\/td>\n<td>GPIO13<\/td>\n<\/tr>\n<tr>\n<td>RTCK<\/td>\n<td>GPIO23<\/td>\n<td>GPIO6<\/td>\n<\/tr>\n<tr>\n<td>TRST<\/td>\n<td>GPIO22<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/li>\n<li>Download Raspberry PI schematics PDF for the board revision you found out in step 2. Each JTAG pin (except TRST) can be routed to one of 2 GPIO pins. Use the schematics to find GPIO pins that are connected to the GPIO connector:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/03-layout.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-461\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/03-layout.png\" alt=\"\" width=\"699\" height=\"776\" \/><\/a><\/li>\n<li>We will now need to wire the selected pins from the P1 connector to a 20-pin JTAG connector. Use the\u00a0<a href=\"http:\/\/infocenter.arm.com\/help\/topic\/com.arm.doc.dui0499d\/BEHEIHCE.html\">JTAG-20 pinout<\/a> to map the P1 pins to the JTAG-20 pins:\n<div class=\"table_responsive\">\n<table class=\"neat_table\">\n<tbody>\n<tr>\n<td>JTAG-20 pin<\/td>\n<td>JTAG signal<\/td>\n<td>GPIO pin<\/td>\n<td>ALT mode<\/td>\n<td>P1 pin<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>VREF<\/td>\n<td>N\/A<\/td>\n<td>N\/A<\/td>\n<td>1<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>nTRST<\/td>\n<td>GPIO22<\/td>\n<td>ALT4<\/td>\n<td>15<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>GND<\/td>\n<td>N\/A<\/td>\n<td>N\/A<\/td>\n<td>9<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>TDI<\/td>\n<td>GPIO4 <span style=\"color: red;\">(Rpi 1-3)<\/span><br \/>\nGPIO26 <span style=\"color: red;\">(Rpi Pi 4)<\/span><\/td>\n<td>ALT5 <span style=\"color: red;\">(Rpi Pi 1-3)<\/span><br \/>\nALT4 <span style=\"color: red;\">(Rpi Pi 4)<\/span><\/td>\n<td>7 <span style=\"color: red;\">(Rpi 1-3)<\/span><br \/>\n37 <span style=\"color: red;\">(Rpi 4)<\/span><\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>TMS<\/td>\n<td>GPIO27<\/td>\n<td>ALT4<\/td>\n<td>13<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td>TCK<\/td>\n<td>GPIO25<\/td>\n<td>ALT4<\/td>\n<td>22<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td>RTCK<\/td>\n<td>GPIO23<\/td>\n<td>ALT4<\/td>\n<td>16<\/td>\n<\/tr>\n<tr>\n<td>13<\/td>\n<td>TDO<\/td>\n<td>GPIO24<\/td>\n<td>ALT4<\/td>\n<td>18<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/li>\n<li>Now we can make an adapter cable that will connect the pins from the 26-pin P1 connector on Raspberry PI to the 20-pin JTAG connector. This can be done by carefully opening and detaching the 26-pin connector from a 26-pin cable and attaching the wires from the 14-pin cable to it ordered according to the table above:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/img\/04-jtagcable.png\" \/><\/li>\n<li>Each wire can be carefully pushed into the correct position using a pincette:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/img\/05-26pins.png\" \/><\/li>\n<li><span class=\"warning\">Double-triple check your wiring. Wrong wiring\/cable orientation can permanently damage your Raspberry PI, your JTAG programmer and even your PC connected to it!<\/span>\u00a0Test the correctness of each pin. E.g. we can test JTAG pin 3 (nTRST = GPIO22) by connecting a LED between pins 3 and 4 (4 is GND) and running the following commands in your Raspberry PI terminal over SSH:\n<pre class=\"code\">cd \/sys\/class\/gpio\r\necho 22 &gt; export\r\ncd gpio22\r\necho out &gt; direction\r\necho 1 &gt; value<\/pre>\n<p>This will turn on the LED until we run &#8216;echo 0 &gt; value&#8217;:<img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/img\/06-led.png\" width=\"700\" height=\"649\" \/><\/li>\n<li>The easiest way to\u00a0test out the JTAG connection is to <a href=\"https:\/\/sysprogs.com\/VisualKernel\/tutorials\/raspberry\/basicmodule\/\">create a\u00a0kernel module project with VisualKernel<\/a>\u00a0that can configure and\u00a0verify\u00a0the JTAG setup\u00a0automatically:<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-179\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/raspijtag.png\" alt=\"\" width=\"841\" height=\"642\" srcset=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/raspijtag.png 841w, https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/raspijtag-300x229.png 300w, https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2018\/02\/raspijtag-768x586.png 768w\" sizes=\"(max-width: 841px) 100vw, 841px\" \/>Alternatively you can follow the steps below to\u00a0check your\u00a0JTAG connection manually.<\/li>\n<\/ol>\n<h2>Checking the JTAG connection manually<\/h2>\n<ol>\n<li>Now that we have verified that the GPIO pins are connected to correct JTAG pins we need to switch them from the GPIO mode to JTAG mode. The table above summarized the alternative function numbers that we need to select for each pin. On <strong>Raspberry Pi 1-3<\/strong>, this is done by accessing the <strong>GPFSELx<\/strong> registers of the BCM2835 chip. The easiest way to access them from a user-mode Linux program is by using the\u00a0<strong>\/dev\/mem<\/strong>\u00a0device (note that the 0x7E20xxxx addresses mentioned in the BCM2835 reference are the physical addresses. the corresponding virtual addresses are 0x2020xxxx). To do this, upload, the\u00a0<a href=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/JtagEnabler.cpp\">JtagEnabler.cpp<\/a>\u00a0file to your <strong>Raspberry Pi 1-3 (not 4!)<\/strong>, compile and run it:\n<pre class=\"code\">g++ -o JtagEnabler JtagEnabler.cpp\r\nsudo .\/JtagEnabler<\/pre>\n<p>Below is the code responsible for setting the alternative functions for all affected pins:<\/p>\n<pre class=\"code\">GpioFunctionSelector selector;\r\nselector.SetGPIOFunction(22, GPIO_ALT_FUNCTION_4);\r\nselector.SetGPIOFunction(4,\u00a0 GPIO_ALT_FUNCTION_5);\r\nselector.SetGPIOFunction(27, GPIO_ALT_FUNCTION_4);\r\nselector.SetGPIOFunction(25, GPIO_ALT_FUNCTION_4);\r\nselector.SetGPIOFunction(23, GPIO_ALT_FUNCTION_4);\r\nselector.SetGPIOFunction(24, GPIO_ALT_FUNCTION_4);<\/pre>\n<p>Note that if you are using <strong>Raspberry Pi 3<\/strong>, you would need to change the peripheral base address from <strong>0x20000000<\/strong> to\u00a0<strong>0x3f000000<\/strong>.<br \/>\nOn <strong>Raspberry Pi 4 <\/strong>(BCM2711 chip), setting the <strong>GPFSELx<\/strong> registers is not sufficient to enable JTAG debugging. Instead, you need to add the following line to the <strong>\/boot\/config.txt<\/strong> file:<\/p>\n<pre class=\"\">enable_jtag_gpio=1<\/pre>\n<p>This will both configure the pins, and enable the JTAG module on the BCM2711 chip. Make sure it is added before the model-specific sections (e.g. <strong>[pi4]<\/strong>) or inside the <strong>[all]<\/strong> section. You can also add model-specific sections to use GPIO4 for TDI on Raspberry Pi 1-3 and GPIO26 on Raspberry Pi 4:<\/p>\n<pre class=\"\">[all]\r\nenable_jtag_gpio=1\r\ngpio=22-27=a4\r\n\r\n[pi1]\r\ngpio=4=a5\r\n\r\n[pi2]\r\ngpio=4=a5\r\n\r\n[pi3]\r\ngpio=4=a5<\/pre>\n<\/li>\n<li>Now we are ready to start debugging. In this tutorial we will use a Segger J-Link programmer with the OpenOCD tool, however you can use any other supported programmer instead.\u00a0<a href=\"http:\/\/gnutoolchains.com\/arm-eabi\/openocd\/\">Download our OpenOCD package<\/a>\u00a0and the<a href=\"http:\/\/visualgdb.com\/UsbDriverTool\/\">USBDriverTool<\/a>. Connect the J-Link programmer, launch USBDriverTool, select the J-Link device and install the WinUSB drivers for it:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/img\/07-usbtool.png\" \/><\/li>\n<li>We&#8217;re almost ready. Before we can start debugging our Raspberry PI we need to create a target configuration file for OpenOCD. The target configuration file should specify the correct ARM core, set the the JTAG ID and configure multi-core debugging so that GDB doesn&#8217;t break the target. You download configuration files for Raspberry Pi 1-4 boards tested with Linux kernel debugging here:\n<ul>\n<li><a href=\"https:\/\/github.com\/sysprogs\/openocd\/blob\/master\/tcl\/target\/raspberry.cfg\">Raspberry Pi 1<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/sysprogs\/openocd\/blob\/master\/tcl\/target\/raspberrypi3.cfg\">Raspberry Pi 3<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/sysprogs\/openocd\/blob\/master\/tcl\/target\/raspberrypi4.cfg\">Raspberry Pi 4<\/a><\/li>\n<\/ul>\n<\/li>\n<li>Now connect your JTAG programmer to Raspberry PI and run OpenOCD:\n<pre class=\"code\">cd &lt;OpenOCD directory&gt;\\share\\openocd\\scripts\r\n..\\..\\..\\bin\\openocd.exe -f interface\/jlink.cfg -f target\/raspberry.cfg<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/img\/08-openocd.png\" width=\"677\" height=\"342\" \/><\/li>\n<li><span class=\"warning\">There is a bug in OpenOCD that will prevent Raspberry PI from continuing correctly after a stop unless the initialization is done twice. Close OpenOCD with Ctrl-C and re-run it again. Now the debugging will be usable.<\/span><\/li>\n<li>By default OpenOCD opens port 3333 for GDB connections. Start GDB, connect to OpenOCD and test the connection by displaying disassembly and stepping over one instruction:\n<pre class=\"code\">target remote :3333\r\nx\/10i $pc\r\nstepi\r\nx\/2i $pc<\/pre>\n<\/li>\n<li><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/jtagsetup\/img\/09-gdb.png\" \/><\/li>\n<\/ol>\n<p>If stepping over an instruction actually puts you on the next instruction, the JTAG debugging is working. In order to have a meaningful debugging session you will need to rebuild the Raspberry PI kernel and use the symbols obtained during build to debug. Follow the\u00a0<a href=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/raspberry\/buildkernel\/\">kernel build tutorial<\/a>\u00a0to learn about it.<\/p>\n<p><span class=\"warning\">Remember, after you reboot your Raspberry PI you&#8217;ll need to start OpenOCD, exit it with Ctrl-C and then start it again, otherwise the target won&#8217;t be resumed correctly after a stop.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to prepare your\u00a0Raspberry PI\u00a0board for debugging with JTAG (we have tested this with Raspberry Pi 1,<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35],"tags":[38,37],"_links":{"self":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/120"}],"collection":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/comments?post=120"}],"version-history":[{"count":14,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/120\/revisions"}],"predecessor-version":[{"id":567,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/120\/revisions\/567"}],"wp:attachment":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/media?parent=120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/categories?post=120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/tags?post=120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}