1 .. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
10 Texas Instrument's K3 family of SoCs utilize a heterogeneous multicore
11 and highly integrated device architecture targeted to maximize
12 performance and power efficiency for a wide range of industrial,
13 automotive and other broad market segments.
15 Typically the processing cores and the peripherals for these devices are
16 partitioned into three functional domains to provide ultra-low power
17 modes as well as accommodating application and industrial safety systems
18 on the same SoC. These functional domains are typically called the:
20 * Wakeup (WKUP) domain
21 * Micro-controller (MCU) domain
24 For a more detailed view of what peripherals are attached to each
25 domain, consult the device specific documentation.
44 K3 SoC based boards in other sections
46 * :doc:`../beagle/am62x_beagleplay`
47 * :doc:`../beagle/j721e_beagleboneai64`
48 * :doc:`../phytec/phycore-am62x`
49 * :doc:`../phytec/phycore-am62ax`
50 * :doc:`../toradex/verdin-am62`
55 For all K3 SoCs the first core started will be inside the Security
56 Management Subsystem (SMS) which will secure the device and start a core
57 in the wakeup domain to run the ROM code. ROM will then initialize the
58 boot media needed to load the binaries packaged inside `tiboot3.bin`,
59 including a 32bit U-Boot SPL, (called the wakeup SPL) that ROM will jump
60 to after it has finished loading everything into internal SRAM.
62 .. image:: img/boot_flow_01.svg
63 :alt: Boot flow up to wakeup domain SPL
65 The wakeup SPL, running on a wakeup domain core, will initialize DDR and
66 any peripherals needed to load the larger binaries inside the `tispl.bin`
67 into DDR. Once loaded the wakeup SPL will start one of the 'big'
68 application cores inside the main domain to initialize the main domain,
69 starting with Trusted Firmware-A (TF-A), before moving on to start
70 OP-TEE and the main domain's U-Boot SPL.
72 .. image:: img/boot_flow_02.svg
73 :alt: Boot flow up to main domain SPL
75 The main domain's SPL, running on a 64bit application core, has
76 virtually unlimited space (billions of bytes now that DDR is working) to
77 initialize even more peripherals needed to load in the `u-boot.img`
78 which loads more firmware into the micro-controller & wakeup domains and
79 finally prepare the main domain to run Linux.
81 .. image:: img/boot_flow_03.svg
82 :alt: Complete boot flow up to Linux
84 This is the typical boot flow for all K3 based SoCs, however this flow
85 offers quite a lot in the terms of flexibility, especially on High
91 All K3 SoCs will generally use the above boot flow with two main
92 differences depending on the capabilities of the boot ROM and the number
93 of cores inside the device. These differences split the bootflow into
94 essentially 4 unique but very similar flows:
96 * Split binary with a combined firmware: (eg: AM65)
97 * Combined binary with a combined firmware: (eg: AM64)
98 * Split binary with a split firmware: (eg: J721E)
99 * Combined binary with a split firmware: (eg: AM62)
101 For devices that utilize the split binary approach, ROM is not capable
102 of loading the firmware into the SoC, requiring the wakeup domain's
103 U-Boot SPL to load the firmware.
105 Devices with a split firmware will have two firmwares loaded into the
106 device at different times during the bootup process. TI's Foundational
107 Security (TIFS), needed to operate the Security Management Subsystem,
108 will either be loaded by ROM or the WKUP U-Boot SPL, then once the
109 wakeup U-Boot SPL has completed, the second Device Management (DM)
110 firmware can be loaded on the now free core in the wakeup domain.
112 For more information on the bootup process of your SoC, consult the
113 device specific boot flow documentation.
118 K3 HS-SE (High Security - Security Enforced) devices enforce an
119 authenticated boot flow for secure boot. HS-FS (High Security - Field
120 Securable) is the state of a K3 device before it has been eFused with
121 customer security keys. In the HS-FS state the authentication still can
122 function as in HS-SE, but as there are no customer keys to verify the
123 signatures against, the authentication will pass for certificates signed
129 1) Public ROM loads the tiboot3.bin (R5 SPL, TIFS)
130 2) R5 SPL loads tispl.bin (ATF, OP-TEE, DM, SPL)
131 3) SPL loads u-boot.img (U-Boot)
132 4) U-Boot loads fitImage (Linux and DTBs)
134 Steps 1-3 are all authenticated by either the Secure ROM or TIFS as the
135 authenticating entity and step 4 uses U-boot standard mechanism for
138 All the authentication that are done for ROM/TIFS are done through x509
139 certificates that are signed.
144 1) Secure ROM comes up and sets up firewalls that are needed by itself
145 2) TIFS will setup it's own firewalls to protect core system resources
146 3) R5 SPL will remove any firewalls that are leftover from the Secure ROM stage
147 that are no longer required.
148 4) Each stage beyond this: such as tispl.bin containing TFA/OPTEE uses OIDs to
149 set up firewalls to protect themselves (enforced by TIFS)
150 5) TFA/OP-TEE can configure other firewalls at runtime if required as they
151 are already authenticated and firewalled off from illegal access.
152 6) All later stages can setup or remove firewalls that have not been already
153 configured by previous stages, such as those created by TIFS, TFA, and OP-TEE.
155 Futhur, firewalls have a lockdown bit in hardware that enforces the setting
156 (and cannot be over-ridden) until the full system is reset.
161 All scripts and code needed to build the `tiboot3.bin`, `tispl.bin` and
162 `u-boot.img` for all K3 SoCs can be located at the following places
165 .. k3_rst_include_start_boot_sources
169 | **source:** https://source.denx.de/u-boot/u-boot.git
172 * **Trusted Firmware-A (TF-A)**
174 | **source:** https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/
177 * **Open Portable Trusted Execution Environment (OP-TEE)**
179 | **source:** https://github.com/OP-TEE/optee_os.git
182 * **TI Firmware (TIFS, DM, SYSFW)**
184 | **source:** https://git.ti.com/git/processor-firmware/ti-linux-firmware.git
185 | **branch:** ti-linux-firmware
189 The TI Firmwares required for functionality of the system are (see
190 platform specific boot diagram for further information as to which
191 component runs on which processor):
193 .. k3_rst_include_end_boot_sources
195 .. k3_rst_include_start_boot_firmwares
197 * **TIFS** - TI Foundational Security Firmware - Consists of purely firmware
198 meant to run on the security enclave.
199 * **DM** - Device Management firmware also called TI System Control Interface
200 server (TISCI Server) - This component purely plays the role of managing
201 device resources such as power, clock, interrupts, dma etc. This firmware
202 runs on a dedicated or multi-use microcontroller outside the security
205 .. k3_rst_include_end_boot_firmwares
206 .. k3_rst_include_start_tifsstub
208 * **TIFS Stub** - The TIFS stub is a small piece of binary designed to help
209 restore the required security context and resume the TIFS firmware when
210 the system resumes from low-power modes such as suspend-to-RAM/Deep
211 Sleep. This stub uses the same encryption and customer key signing model
212 as TIFS and is loaded into the ATCM (Tightly Coupled Memory 'A' of the
213 DM R5) during DM startup. Due to the independent certificate signing
214 process, the stub is maintained separately from DM.
216 .. k3_rst_include_end_tifsstub
220 .. k3_rst_include_start_boot_firmwares_sysfw
222 * **SYSFW** - System firmware - consists of both TIFS and DM both running on
223 the security enclave.
225 .. k3_rst_include_end_boot_firmwares_sysfw
232 Make sure you have installed all necessary host package dependencies
233 before proceeding. See :ref:`build/gcc:Building with GCC`.
235 Depending on the specifics of your device, you will need three or more
236 binaries to boot your SoC.
238 * `tiboot3.bin` (bootloader for the wakeup domain)
239 * `tispl.bin` (bootloader for the main domain)
242 During the bootup process, both the 32bit wakeup domain and the 64bit
243 main domains will be involved. This means everything inside the
244 `tiboot3.bin` running in the wakeup domain will need to be compiled for
245 32bit cores and most binaries in the `tispl.bin` will need to be
246 compiled for 64bit main domain CPU cores.
248 All of that to say you will need both a 32bit and 64bit cross compiler
249 (assuming you're using an x86 desktop)
251 .. k3_rst_include_start_common_env_vars_desc
252 .. list-table:: Generic environment variables
261 - Cross compiler for ARMv7 (ARM 32bit), typically arm-linux-gnueabihf-
264 - Cross compiler for ARMv8 (ARM 64bit), typically aarch64-linux-gnu-
267 - Path to TI Linux firmware repository
270 - Path to source of Trusted Firmware-A
273 - Path to source of OP-TEE
274 .. k3_rst_include_end_common_env_vars_desc
276 .. k3_rst_include_start_common_env_vars_defn
279 export CC32=arm-linux-gnueabihf-
280 export CC64=aarch64-linux-gnu-
281 export LNX_FW_PATH=path/to/ti-linux-firmware
282 export TFA_PATH=path/to/trusted-firmware-a
283 export OPTEE_PATH=path/to/optee_os
284 .. k3_rst_include_end_common_env_vars_defn
286 We will also need some common environment variables set up for the various
287 other build sources. we shall use the following, in the build descriptions below:
289 .. k3_rst_include_start_board_env_vars_desc
290 .. list-table:: Board specific environment variables
299 - Defconfig for Cortex-R (Boot processor).
302 - Defconfig for Cortex-A (MPU processor).
303 * - Trusted Firmware-A
305 - Platform name used for building TF-A for Cortex-A Processor.
306 * - Trusted Firmware-A
308 - Any extra arguments used for building TF-A.
311 - Platform name used for building OP-TEE for Cortex-A Processor.
314 - Any extra arguments used for building OP-TEE.
315 .. k3_rst_include_end_board_env_vars_desc
320 1. To generate the U-Boot SPL for the wakeup domain, use the following
321 commands, substituting :code:`{SOC}` for the name of your device (eg:
322 am62x) to package the various firmware and the wakeup UBoot SPL into
323 the final `tiboot3.bin` binary. (or the `sysfw.itb` if your device
324 uses the split binary flow)
326 .. _k3_rst_include_start_build_steps_spl_r5:
328 .. k3_rst_include_start_build_steps_spl_r5
331 # inside u-boot source
332 make $UBOOT_CFG_CORTEXR
333 make CROSS_COMPILE=$CC32 BINMAN_INDIRS=$LNX_FW_PATH
334 .. k3_rst_include_end_build_steps_spl_r5
336 At this point you should have all the needed binaries to boot the wakeup
337 domain of your K3 SoC.
339 **Combined Binary Boot Flow** (eg: am62x, am64x, ... )
341 `tiboot3-{SOC}-{gp/hs-fs/hs}.bin`
343 **Split Binary Boot Flow** (eg: j721e, am65x)
345 | `tiboot3-{SOC}-{gp/hs-fs/hs}.bin`
346 | `sysfw-{SOC}-{gp/hs-fs/hs}-evm.itb`
350 It's important to rename the generated `tiboot3.bin` and `sysfw.itb`
351 to match exactly `tiboot3.bin` and `sysfw.itb` as ROM and the wakeup
352 UBoot SPL will only look for and load the files with these names.
357 The `tispl.bin` is a standard fitImage combining the firmware need for
358 the main domain to function properly as well as Device Management (DM)
359 firmware if your device using a split firmware.
361 2. We will first need TF-A, as it's the first thing to run on the 'big'
362 application cores on the main domain.
364 .. k3_rst_include_start_build_steps_tfa
367 # inside trusted-firmware-a source
368 make CROSS_COMPILE=$CC64 ARCH=aarch64 PLAT=k3 SPD=opteed $TFA_EXTRA_ARGS \
369 TARGET_BOARD=$TFA_BOARD
370 .. k3_rst_include_end_build_steps_tfa
372 Typically all `j7*` devices will use `TARGET_BOARD=generic` or `TARGET_BOARD
373 =j784s4` (if it is a J784S4 device), while typical Sitara (`am6*`) devices
374 use the `lite` option.
376 3. The Open Portable Trusted Execution Environment (OP-TEE) is designed
377 to run as a companion to a non-secure Linux kernel for Cortex-A cores
378 using the TrustZone technology built into the core.
380 .. k3_rst_include_start_build_steps_optee
383 # inside optee_os source
384 make CROSS_COMPILE=$CC32 CROSS_COMPILE64=$CC64 CFG_ARM64_core=y $OPTEE_EXTRA_ARGS \
385 PLATFORM=$OPTEE_PLATFORM
386 .. k3_rst_include_end_build_steps_optee
388 4. Finally, after TF-A has initialized the main domain and OP-TEE has
389 finished, we can jump back into U-Boot again, this time running on a
390 64bit core in the main domain.
392 .. _k3_rst_include_start_build_steps_uboot:
394 .. k3_rst_include_start_build_steps_uboot
397 # inside u-boot source
398 make $UBOOT_CFG_CORTEXA
399 make CROSS_COMPILE=$CC64 BINMAN_INDIRS=$LNX_FW_PATH \
400 BL31=$TFA_PATH/build/k3/$TFA_BOARD/release/bl31.bin \
401 TEE=$OPTEE_PATH/out/arm-plat-k3/core/tee-raw.bin
404 It is also possible to pick up a custom DM binary by adding TI_DM argument
405 pointing to the file. If not provided, it defaults to picking up the DM
406 binary from BINMAN_INDIRS. This is only applicable to devices that utilize
409 .. k3_rst_include_end_build_steps_uboot
411 At this point you should have every binary needed initialize both the
412 wakeup and main domain and to boot to the U-Boot prompt
414 **Main Domain Bootloader**
416 | `tispl.bin` for HS devices or `tispl.bin_unsigned` for GP devices
417 | `u-boot.img` for HS devices or `u-boot.img_unsigned` for GP devices
422 Most K3 boards have support for UEFI capsule update via capsule-on-disk
423 functionality. Check the ``CONFIG_EFI_CAPSULE_ON_DISK`` config option for
424 the board under question to verify. If configured, capsules for each of the
425 binaries above are automatically generated as part of the binary's build.
426 They are named `<binary>-capsule.bin`. For example, the capsule for
427 `u-boot.img` would be called `uboot-capsule.bin`.
429 See :ref:`uefi_capsule_update_ref` for more information on U-Boot's support
430 for capsule update and how they are applied.
432 Each board defines the capsules generated, including where those capsules
433 are applied. See the ``update_info`` definition for a board, typically
434 found at `board/ti/<board>/evm.c`. For example, `board/ti/am62x/evm.c`.
435 Usually, if the board has OSPI flash, the capsules will be applied there,
436 else the boot partition of the eMMC device.
438 Once applied, the board will have U-Boot binaries in on-board non-volatile
439 storage. To start booting from that storage, set the bootmode pins
440 accordingly. Future updates can be performed by using the capsules
441 generated from the corresponding U-Boot builds.
443 FIT signature signing
444 ---------------------
446 K3 platforms have FIT signature signing enabled by default on their primary
447 platforms. Here we'll take an example for creating FIT Image for J721E platform
448 and the same can be extended to other platforms
452 * U-boot build (:ref:`U-boot build <k3_rst_include_start_build_steps_spl_r5>`)
453 * Linux Image and Linux DTB prebuilt
455 Describing FIT source
456 ^^^^^^^^^^^^^^^^^^^^^
458 FIT Image is a packed structure containing binary blobs and configurations.
459 The Kernel FIT Image that we have has Kernel Image, DTB and the DTBOs. It
460 supports packing multiple images and configurations that allow you to
461 choose any configuration at runtime to boot from.
468 description = "FIT Image description";
469 #address-cells = <1>;
480 [conf-1: image-1,fdt-1]
481 [conf-2: image-2,fdt-1]
490 description = "Linux kernel";
491 data = /incbin/("linux.bin");
495 compression = "gzip";
497 entry = <0x81000000>;
502 fdt-ti_k3-j721e-common-proc-board.dtb {
503 description = "Flattened Device Tree blob";
504 data = /incbin/("arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dtb");
507 compression = "none";
514 fdt-ti_k3-j721e-evm-virt-mac-client.dtbo {
515 description = "Flattened Device Tree blob";
516 data = /incbin/("arch/arm64/boot/dts/ti/k3-j721e-evm-virt-mac-client.dtbo");
519 compression = "none";
528 Change the path in data variables to point to the respective files in your
529 local machine. For e.g change "linux.bin" to "<path-to-kernel-image>".
531 For enabling usage of FIT signature, add the signature node to the
532 corresponding configuration node as follows.
534 * Sample Configurations
538 conf-ti_k3-j721e-common-proc-board.dtb {
539 description = "Linux kernel, FDT blob";
540 fdt = "fdt-ti_k3-j721e-common-proc-board.dtb";
543 algo = "sha512,rsa4096";
544 key-name-hint = "custMpk";
545 sign-images = "kernel", "fdt";
548 # Optional configurations
549 conf-ti_k3-j721e-evm-virt-mac-client.dtbo {
550 description = "FDTO blob";
551 fdt = "fdt-ti_k3-j721e-evm-virt-mac-client.dtbo";
554 algo = "sha512,rsa4096";
555 key-name-hint = "custMpk";
560 Specify all images you need the signature to authenticate as a part of
561 sign-images. The key-name-hint needs to be changed if you are using some
562 other key other than the TI dummy key that we are using for this example.
563 It should be the name of the file containing the keys.
567 Generating new set of keys:
572 openssl genpkey -algorithm RSA -out keys/dev.key \
573 -pkeyopt rsa_keygen_bits:4096 -pkeyopt rsa_keygen_pubexp:65537
574 openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt
576 Generating the fitImage
577 ^^^^^^^^^^^^^^^^^^^^^^^
581 For signing a secondary platform like SK boards, you'll require
584 - Change the CONFIG_DEFAULT_DEVICE_TREE
590 diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
591 index a5c1df7e0054..6d0126d955ef 100644
592 --- a/configs/j721e_evm_a72_defconfig
593 +++ b/configs/j721e_evm_a72_defconfig
594 @@ -13,7 +13,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000
595 CONFIG_ENV_SIZE=0x20000
598 -CONFIG_DEFAULT_DEVICE_TREE="k3-j721e-common-proc-board"
599 +CONFIG_DEFAULT_DEVICE_TREE="k3-j721e-sk"
600 CONFIG_SPL_TEXT_BASE=0x80080000
604 - Change the binman nodes to package u-boot.dtb for the correct set of platform
610 diff --git a/arch/arm/dts/k3-j721e-binman.dtsi b/arch/arm/dts/k3-j721e-binman.dtsi
611 index 673be646b1e3..752fa805fe8d 100644
612 --- a/arch/arm/dts/k3-j721e-binman.dtsi
613 +++ b/arch/arm/dts/k3-j721e-binman.dtsi
615 #define SPL_J721E_SK_DTB "spl/dts/k3-j721e-sk.dtb"
617 #define UBOOT_NODTB "u-boot-nodtb.bin"
618 -#define J721E_EVM_DTB "u-boot.dtb"
619 -#define J721E_SK_DTB "arch/arm/dts/k3-j721e-sk.dtb"
620 +#define J721E_EVM_DTB "arch/arm/dts/k3-j721e-common-proc-board.dtb"
621 +#define J721E_SK_DTB "u-boot.dtb"
623 This step will embed the public key in the u-boot.dtb file that was already
624 built during the initial u-boot build.
628 mkimage -r -f fitImage.its -k $UBOOT_PATH/board/ti/keys -K $UBOOT_PATH/build/$ARMV8/dts/dt.dtb fitImage
632 If you have another set of keys then change the -k argument to point to
633 the folder where your keys are present, the build requires the presence
634 of both .key and .crt file.
639 The updated u-boot.dtb needs to be packed in u-boot.img for authentication
640 so rebuild U-boot ARMV8 without changing any parameters.
641 Refer (:ref:`U-boot ARMV8 build <k3_rst_include_start_build_steps_uboot>`)
645 The devices now also have distroboot enabled so if the FIT image doesn't
646 work then the fallback to normal distroboot will be there on HS devices.
647 This will need to be explicitly disabled by changing the boot_targets to
648 disallow fallback during testing.
653 SAVEENV is disabled by default and for the new flow uses Uenv.txt as the default
654 way for saving the environments. This has been done as Uenv.txt is more granular
655 then the saveenv command and can be used across various bootmodes too.
657 **Writing to MMC/EMMC**
661 env export -t $loadaddr <list of variables>
662 fatwrite mmc ${mmcdev} ${loadaddr} ${bootenvfile} ${filesize}
664 **Reading from MMC/EMMC**
666 By default run envboot will read it from the MMC/EMMC partition ( based on
667 mmcdev) and set the environments.
669 If manually needs to be done then the environment can be read from the
670 filesystem and then imported
674 fatload mmc ${mmcdev} ${loadaddr} ${bootenvfile}
675 env import -t ${loadaddr} ${filesize}
677 .. _k3_rst_refer_openocd:
679 Common Debugging environment - OpenOCD
680 --------------------------------------
682 This section will show you how to connect a board to `OpenOCD
683 <https://openocd.org/>`_ and load the SPL symbols for debugging with
684 a K3 generation device. To follow this guide, you must build custom
685 u-boot binaries, start your board from a boot media such as an SD
686 card, and use an OpenOCD environment. This section uses generic
687 examples, though you can apply these instructions to any supported K3
690 The overall structure of this setup is in the following figure.
692 .. image:: img/openocd-overview.svg
693 :alt: Overview of OpenOCD setup.
697 If you find these instructions useful, please consider `donating
698 <https://openocd.org/pages/donations.html>`_ to OpenOCD.
700 Step 1: Download and install OpenOCD
701 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
703 To get started, it is more convenient if the distribution you
704 use supports OpenOCD by default. Follow the instructions in the
705 `getting OpenOCD <https://openocd.org/pages/getting-openocd.html>`_
706 documentation to pick the installation steps appropriate to your
707 environment. Some references to OpenOCD documentation:
709 * `OpenOCD User Guide <https://openocd.org/doc/html/index.html>`_
710 * `OpenOCD Developer's Guide <https://openocd.org/doc/doxygen/html/index.html>`_
712 Refer to the release notes corresponding to the `OpenOCD version
713 <https://github.com/openocd-org/openocd/releases>`_ to ensure
715 * Processor support: In general, processor support shouldn't present
716 any difficulties since OpenOCD provides solid support for both ARMv8
718 * SoC support: When working with System-on-a-Chip (SoC), the support
719 usually comes as a TCL config file. It is vital to ensure the correct
720 version of OpenOCD or to use the TCL files from the latest release or
722 * Board or the JTAG adapter support: In most cases, board support is
723 a relatively easy problem if the board has a JTAG pin header. All
724 you need to do is ensure that the adapter you select is compatible
725 with OpenOCD. Some boards come with an onboard JTAG adapter that
726 requires a USB cable to be plugged into the board, in which case, it
727 is vital to ensure that the JTAG adapter is supported. Fortunately,
728 almost all TI K3 SK/EVMs come with TI's XDS110, which has out of the
729 box support by OpenOCD. The board-specific documentation will
730 cover the details and any adapter/dongle recommendations.
738 OpenOCD version 0.12.0 is usually required to connect to most K3
739 devices. If your device is only supported by a newer version than the
740 one provided by your distribution, you may need to build it from the source.
742 Building OpenOCD from source
743 """"""""""""""""""""""""""""
745 The dependency package installation instructions below are for Debian
746 systems, but equivalent instructions should exist for systems with
747 other package managers. Please refer to the `OpenOCD Documentation
748 <https://openocd.org/>`_ for more recent installation steps.
752 # Check the packages to be installed: needs deb-src in sources.list
753 sudo apt build-dep openocd
754 # The following list is NOT complete - please check the latest
755 sudo apt-get install libtool pkg-config texinfo libusb-dev \
756 libusb-1.0.0-dev libftdi-dev libhidapi-dev autoconf automake
757 git clone https://github.com/openocd-org/openocd.git openocd
762 ./configure --prefix=/usr/local/
768 The example above uses the GitHub mirror site. See
769 `git repo information <https://openocd.org/doc/html/Developers.html#OpenOCD-Git-Repository>`_
770 information to pick the official git repo.
771 If a specific version is desired, select the version using `git checkout tag`.
773 Installing OpenOCD udev rules
774 """""""""""""""""""""""""""""
776 The step is not necessary if the distribution supports the OpenOCD, but
777 if building from a source, ensure that the udev rules are installed
778 correctly to ensure a sane system.
782 # Go to the OpenOCD source directory
784 Copy the udev rules to the correct system location
785 sudo cp ./contrib/60-openocd.rules \
786 ./src/jtag/drivers/libjaylink/contrib/99-libjaylink.rules \
788 # Get Udev to load the new rules up
789 sudo udevadm control --reload-rules
790 # Use the new rules on existing connected devices
796 Most systems come with gdb-multiarch package.
800 # Install gdb-multiarch package
801 sudo apt-get install gdb-multiarch
803 Though using GDB natively is normal, developers with interest in using IDE
804 may find a few of these interesting:
806 * `gdb-dashboard <https://github.com/cyrus-and/gdb-dashboard>`_
807 * `gef <https://github.com/hugsy/gef>`_
808 * `peda <https://github.com/longld/peda>`_
809 * `pwndbg <https://github.com/pwndbg/pwndbg>`_
810 * `voltron <https://github.com/snare/voltron>`_
811 * `ddd <https://www.gnu.org/software/ddd/>`_
812 * `vscode <https://www.justinmklam.com/posts/2017/10/vscode-debugger-setup/>`_
813 * `vim conque-gdb <https://github.com/vim-scripts/Conque-GDB>`_
814 * `emacs realgud <https://github.com/realgud/realgud/wiki/gdb-notes>`_
815 * `Lauterbach IDE <https://www2.lauterbach.com/pdf/backend_gdb.pdf>`_
818 LLDB support for OpenOCD is still a work in progress as of this writing.
819 Using GDB is probably the safest option at this point in time.
821 Step 3: Connect board to PC
822 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
823 There are few patterns of boards in the ecosystem
825 .. k3_rst_include_start_openocd_connect_XDS110
827 **Integrated JTAG adapter/dongle**: The board has a micro-USB connector labelled
828 XDS110 USB or JTAG. Connect a USB cable to the board to the mentioned port.
832 There are multiple USB ports on a typical board, So, ensure you have read
833 the user guide for the board and confirmed the silk screen label to ensure
834 connecting to the correct port.
836 .. k3_rst_include_end_openocd_connect_XDS110
838 .. k3_rst_include_start_openocd_connect_cti20
840 **cTI20 connector**: The TI's `cTI20
841 <https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_JTAG_connectors.html#cti-20-pin-header-information>`_ connector
842 is probably the most prevelant on TI platforms. Though many
843 TI boards have an onboard XDS110, cTI20 connector is usually
844 provided as an alternate scheme to connect alternatives such
845 as `Lauterbach <https://www.lauterbach.com/>`_ or `XDS560
846 <https://www.ti.com/tool/TMDSEMU560V2STM-U>`_.
848 To debug on these boards, the following combinations is suggested:
850 * `TUMPA <https://www.diygadget.com/JTAG-cables-and-microcontroller-programmers/tiao-usb-multi-protocol-adapter-JTAG-spi-i2c-serial>`_
851 or `equivalent dongles supported by OpenOCD. <https://openocd.org/doc/html/Debug-Adapter-Hardware.html#Debug-Adapter-Hardware>`_
852 * Cable such as `Tag-connect ribbon cable <https://www.tag-connect.com/product/20-pin-cortex-ribbon-cable-4-length-with-50-mil-connectors>`_
853 * Adapter to convert cTI20 to ARM20 such as those from
854 `Segger <https://www.segger.com/products/debug-probes/j-link/accessories/adapters/ti-cti-20-adapter/>`_
855 or `Lauterbach LA-3780 <https://www.lauterbach.com/ad3780.html>`_
856 Or optionally, if you have manufacturing capability then you could try
857 `BeagleBone JTAG Adapter <https://github.com/mmorawiec/BeagleBone-Black-JTAG-Adapters>`_
860 XDS560 and Lauterbach are proprietary solutions and is not supported by
862 When purchasing an off the shelf adapter/dongle, you do want to be careful
863 about the signalling though. Please
864 `read for additional info <https://software-dl.ti.com/ccs/esd/xdsdebugprobes/emu_JTAG_connectors.html>`_.
866 .. k3_rst_include_end_openocd_connect_cti20
868 .. k3_rst_include_start_openocd_connect_tag_connect
870 **Tag-Connect**: `Tag-Connect <https://www.tag-connect.com/>`_
871 pads on the boards which require special cable. Please check the documentation
872 to `identify <https://www.tag-connect.com/info/legs-or-no-legs>`_ if "legged"
873 or "no-leg" version of the cable is appropriate for the board.
875 To debug on these boards, you will need:
877 * `TUMPA <https://www.diygadget.com/JTAG-cables-and-microcontroller-programmers/tiao-usb-multi-protocol-adapter-JTAG-spi-i2c-serial>`_
878 or `equivalent dongles supported by OpenOCD <https://openocd.org/doc/html/Debug-Adapter-Hardware.html#Debug-Adapter-Hardware>`_.
879 * Tag-Connect cable appropriate to the board such as
880 `TC2050-IDC-NL <https://www.tag-connect.com/product/TC2050-IDC-NL-10-pin-no-legs-cable-with-ribbon-connector>`_
881 * In case of no-leg, version, a
882 `retaining clip <https://www.tag-connect.com/product/tc2050-clip-3pack-retaining-clip>`_
883 * Tag-Connect to ARM20
884 `adapter <https://www.tag-connect.com/product/tc2050-arm2010-arm-20-pin-to-tc2050-adapter>`_
887 You can optionally use a 3d printed solution such as
888 `Protective cap <https://www.thingiverse.com/thing:3025584>`_ or
889 `clip <https://www.thingiverse.com/thing:3035278>`_ to replace
893 With the Tag-Connect to ARM20 adapter, Please solder the "Trst" signal for
896 .. k3_rst_include_end_openocd_connect_tag_connect
898 Debugging with OpenOCD
899 ^^^^^^^^^^^^^^^^^^^^^^
901 Debugging U-Boot is different from debugging regular user space
902 applications. The bootloader initialization process involves many boot
903 media and hardware configuration operations. For K3 devices, there
904 are also interactions with security firmware. While reloading the
905 "elf" file works through GDB, developers must be mindful of cascading
906 initialization's potential consequences.
908 Consider the following code change:
912 --- a/file.c 2023-07-29 10:55:29.647928811 -0500
913 +++ b/file.c 2023-07-29 10:55:46.091856816 -0500
920 Re-running the elf file with the above change will result in the
921 register setting 0x3 instead of the intended 0x1. There are other
922 hardware blocks which may not behave very well with a re-initialization
923 without proper shutdown.
925 To help narrow the debug down, it is usually simpler to use the
926 standard boot media to get to the bootloader and debug only in the area
929 In general, to debug u-boot spl/u-boot with OpenOCD there are three steps:
931 * Modify the code adding a loop to allow the debugger to attach
932 near the point of interest. Boot up normally to stop at the loop.
933 * Connect with OpenOCD and step out of the loop.
934 * Step through the code to find the root of issue.
936 Typical debugging involves a few iterations of the above sequence.
937 Though most bootloader developers like to use printf to debug,
938 debug with JTAG tends to be most efficient since it is possible to
939 investigate the code flow and inspect hardware registers without
945 * **start.S**: Adding an infinite while loop at the very entry of
946 U-Boot. For this, look for the corresponding start.S entry file.
947 This is usually only required when debugging some core SoC or
948 processor related function. For example: arch/arm/cpu/armv8/start.S or
949 arch/arm/cpu/armv7/start.S
953 diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
954 index 69e281b086..744929e825 100644
955 --- a/arch/arm/cpu/armv7/start.S
956 +++ b/arch/arm/cpu/armv7/start.S
963 /* Allow the board to save important registers */
965 save_boot_params_ret:
967 * **board_init_f**: Adding an infinite while loop at the board entry
968 function. In many cases, it is important to debug the boot process if
969 any changes are made for board-specific applications. Below is a step
970 by step process for debugging the boot SPL or Armv8 SPL:
972 To debug the boot process in either domain, we will first
973 add a modification to the code we would like to debug.
974 In this example, we will debug ``board_init_f`` inside
975 ``arch/arm/mach-k3/{soc}_init.c``. Since some sections of U-Boot
976 will be executed multiple times during the bootup process of K3
977 devices, we will need to include either ``CONFIG_ARM64`` or
978 ``CONFIG_CPU_V7R`` to catch the CPU at the desired place during the
979 bootup process (Main or Wakeup domains). For example, modify the
980 file as follows (depending on need):
984 void board_init_f(ulong dummy)
988 /* Code to run on the R5F (Wakeup/Boot Domain) */
989 if (IS_ENABLED(CONFIG_CPU_V7R)) {
994 /* Code to run on the ARMV8 (Main Domain) */
995 if (IS_ENABLED(CONFIG_ARM64)) {
1003 Connecting with OpenOCD for a debug session
1004 """""""""""""""""""""""""""""""""""""""""""
1006 Startup OpenOCD to debug the platform as follows:
1008 * **Integrated JTAG interface**: If the evm has a debugger such as
1009 XDS110 inbuilt, there is typically an evm board support added and a
1010 cfg file will be available.
1012 .. k3_rst_include_start_openocd_cfg_XDS110
1016 openocd -f board/{board_of_choice}.cfg
1018 .. k3_rst_include_end_openocd_cfg_XDS110
1020 .. k3_rst_include_start_openocd_cfg_external_intro
1022 * **External JTAG adapter/interface**: In other cases, where an
1023 adapter/dongle is used, a simple cfg file can be created to integrate the
1024 SoC and adapter information. See `supported TI K3 SoCs
1025 <https://github.com/openocd-org/openocd/blob/master/tcl/target/ti_k3.cfg#L59>`_
1026 to decide if the SoC is supported or not.
1030 openocd -f openocd_connect.cfg
1032 .. k3_rst_include_end_openocd_cfg_external_intro
1034 For example, with BeaglePlay (AM62X platform), the openocd_connect.cfg:
1039 # http://www.tiaowiki.com/w/TIAO_USB_Multi_Protocol_Adapter_User's_Manual
1040 source [find interface/ftdi/tumpa.cfg]
1042 transport select jtag
1044 # default JTAG configuration has only SRST and no TRST
1045 reset_config srst_only srst_push_pull
1047 # delay after SRST goes inactive
1048 adapter srst delay 20
1050 if { ![info exists SOC] } {
1051 # Set the SoC of interest
1055 source [find target/ti_k3.cfg]
1057 ftdi tdo_sample_edge falling
1059 # Speeds for FT2232H are in multiples of 2, and 32MHz is tops
1060 # max speed we seem to achieve is ~20MHz.. so we pick 16MHz
1063 Below is an example of the output of this command:
1065 .. code-block:: console
1067 Info : Listening on port 6666 for tcl connections
1068 Info : Listening on port 4444 for telnet connections
1069 Info : XDS110: connected
1070 Info : XDS110: vid/pid = 0451/bef3
1071 Info : XDS110: firmware version = 3.0.0.20
1072 Info : XDS110: hardware version = 0x002f
1073 Info : XDS110: connected to target via JTAG
1074 Info : XDS110: TCK set to 2500 kHz
1075 Info : clock speed 2500 kHz
1076 Info : JTAG tap: am625.cpu tap/device found: 0x0bb7e02f (mfg: 0x017 (Texas Instruments), part: 0xbb7e, ver: 0x0)
1077 Info : starting gdb server for am625.cpu.sysctrl on 3333
1078 Info : Listening on port 3333 for gdb connections
1079 Info : starting gdb server for am625.cpu.a53.0 on 3334
1080 Info : Listening on port 3334 for gdb connections
1081 Info : starting gdb server for am625.cpu.a53.1 on 3335
1082 Info : Listening on port 3335 for gdb connections
1083 Info : starting gdb server for am625.cpu.a53.2 on 3336
1084 Info : Listening on port 3336 for gdb connections
1085 Info : starting gdb server for am625.cpu.a53.3 on 3337
1086 Info : Listening on port 3337 for gdb connections
1087 Info : starting gdb server for am625.cpu.main0_r5.0 on 3338
1088 Info : Listening on port 3338 for gdb connections
1089 Info : starting gdb server for am625.cpu.gp_mcu on 3339
1090 Info : Listening on port 3339 for gdb connections
1093 Notice the default configuration is non-SMP configuration allowing
1094 for each of the core to be attached and debugged simultaneously.
1095 ARMv8 SPL/U-Boot starts up on cpu0 of a53/a72.
1097 .. k3_rst_include_start_openocd_cfg_external_gdb
1099 To debug using this server, use GDB directly or your preferred
1100 GDB-based IDE. To start up GDB in the terminal, run the following
1107 To connect to your desired core, run the following command within GDB:
1109 .. prompt:: bash (gdb)
1111 target extended-remote localhost:{port for desired core}
1117 SPL and U-Boot does a re-location of address compared to where it
1118 is loaded originally. This step takes place after the DDR size is
1119 determined from dt parsing. So, debugging can be split into either
1120 "before re-location" or "after re-location". Please refer to the
1121 file ''doc/README.arm-relocation'' to see how to grab the relocation
1124 * Prior to relocation:
1126 .. prompt:: bash (gdb)
1128 symbol-file {path to elf file}
1132 .. prompt:: bash (gdb)
1134 # Drop old symbol file
1136 # Pick up new relocaddr
1137 add-symbol-file {path to elf file} {relocaddr}
1139 .. k3_rst_include_end_openocd_cfg_external_gdb
1141 In the above example of AM625,
1143 .. prompt:: bash (gdb)
1145 target extended-remote localhost:3338 <- R5F (Wakeup Domain)
1146 target extended-remote localhost:3334 <- A53 (Main Domain)
1148 The core can now be debugged directly within GDB using GDB commands or
1149 if using IDE, as appropriate to the IDE.
1151 Stepping through the code
1152 """""""""""""""""""""""""
1155 <https://sourceware.org/gdb/onlinedocs/gdb/TUI-Commands.html>`_ can
1156 help set up the display more sensible for debug. Provide the name
1157 of the layout that can be used to debug. For example, use the GDB
1158 command ``layout src`` after loading the symbols to see the code and
1159 breakpoints. To exit the debug loop added above, add any breakpoints
1160 needed and run the following GDB commands to step out of the debug
1161 loop set in the ``board_init_f`` function.
1163 .. prompt:: bash (gdb)
1168 The platform has now been successfully setup to debug with OpenOCD
1169 using GDB commands or a GDB-based IDE. See `OpenOCD documentation for
1170 GDB <https://openocd.org/doc/html/GDB-and-OpenOCD.html>`_ for further
1175 On the K3 family of devices, a watchdog timer within the DMSC is
1176 enabled by default by the ROM bootcode with a timeout of 3 minutes.
1177 The watchdog timer is serviced by System Firmware (SYSFW) or TI
1178 Foundational Security (TIFS) during normal operation. If debugging
1179 the SPL before the SYSFW is loaded, the watchdog timer will not get
1180 serviced automatically and the debug session will reset after 3
1181 minutes. It is recommended to start debugging SPL code only after
1182 the startup of SYSFW to avoid running into the watchdog timer reset.
1184 Miscellaneous notes with OpenOCD
1185 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1187 Currently, OpenOCD does not support tracing for K3 platforms. Tracing
1188 function could be beneficial if the bug in code occurs deep within
1189 nested function and can optionally save developers major trouble of
1190 stepping through a large quantity of code.