# Debug using OpenOCD

OpenOCD is an open-source on-chip debugger that provides debugging, in-system programming, and boundary-scan testing for embedded devices. OpenOCD supports a range of interfaces, such as JTAG and SWD, which make it a versatile debugging tool. OpenOCD supports GDB, LLDB, and other debugging tools, which provide you with a familiar and powerful debugging environment. For more information, see [OpenOCD](https://openocd.org/).

Review the following information before using OpenOCD.

- Use an Ubuntu Linux host computer for the debug setup.
- Qualcomm supports OpenOCD version 0.12.0. For more information, see `openocd/configure.ac`.
- OpenOCD is supported with Qualcomm embedded USB debugger (EUD) solution over USB Type-C, LLDB, and GDB as command line debuggers.
- Keep the Qualcomm Linux build ready. For more information, see [Qualcomm Linux Build Guide](https://docs.qualcomm.com/bundle/publicresource/topics/80-70029-254/flash_images.html#move-to-edl-mode).

## Known limitations

- Qualcomm supports OpenOCD debug for APSS Linux kernel space.
- At present, OpenOCD supports only QCS6490, IQ-9100/IQ-9075 chipset-based device.
- Kernel debug during bootup isn't supported until you manually enable EUD in the console shell or adb.
- When you enable EUD, the system disables the USB Host mode.

## Set up the Ubuntu host

1. Install the following pre-requisite package:

sudo apt-get install libusb-1.0
        
        sudo apt-get install libftdi-dev
        
        sudo apt-get install libftdi1
        
        sudo apt-get install pkg-config
        
        sudo apt-get install build-essential
        
        sudo apt-get install libtool-bin
        
        sudo apt-get install g++
        Copy to clipboard
2. Ensure that the version of `autoconf` is at least v2.71.

autoconf --version
        Copy to clipboard

## Download OpenOCD

- To download the OpenOCD that supports Qualcomm chipsets, run the following commands:

> 
> 
> git clone https://git.codelinaro.org/clo/la/openocd-org/openocd.git -b qcom_changes
>         
>         cd openocd
>         
>         git submodule update --init --recursive
>         Copy to clipboard

## Build OpenOCD

After downloading the source code, do the following to compile the OpenOCD:

1. Go to the OpenOCD directory.

cd openocd
        Copy to clipboard
2. Generate the configuration scripts.

./bootstrap
        Copy to clipboard
3. Configure the build. This step generates the make file required to build OpenOCD, with the options you provide. In the following command, the system incorporates the EUD for debugging.

> 
> 
> ./configure --disable-werror --enable-eud --disable-internal-libjaylink --disable-jlink --disable-ftdi --disable-dummy --disable-rshim --disable-stlink --disable-ti-icdi --disable-ulink --disable-usb-blaster-2 --disable-ft232r --disable-vsllink --disable-xds110 --disable-cmsis-dap-v2 --disable-osbdm --disable-opendous --disable-aice --disable-usbprog --disable-rlink --disable-armjtagew --disable-cmsis-dap --disable-nulink --disable-kitprog --disable-usb-blaster --disable-presto --disable-openjtag --disable-parport --disable-parport-giveio --disable-jtag_vpi --disable-jtag_dpi --disable-amtjtagaccel --disable-zy1000-master --disable-zy1000 --disable-ioutil --disable-bcm2835gpio --disable-imx_gpio --disable-ep93xx --disable-at91rm9200 --disable-gw16012 --disable-oocd_trace --disable-buspirate --disable-sysfsgpio --disable-xlnx-pcie-xvc --disable-minidriver-dummy --disable-remote-bitbang --disable-parport-ppdev --disable-esp-usb-jtag
>         Copy to clipboard

Note

Disable the adapters that aren't required in Qualcomm Linux.

For more information about the build configuration, run the `./configure -help` command.
4. Compile the source code.

make
        Copy to clipboard
5. Clean the build.

make clean
        Copy to clipboard

When the build succeeds, it generates the OpenOCD binary in the `openocd/src/` directory.

## Set up command-line debuggers

Qualcomm supports LLDB, and GDB debuggers on the host computer. For more information about the setup, see the following:

- LLDB

> 
> 
> For installation, go to [LLVM packages](https://apt.llvm.org/). To autoinstall script for the version-19, see the following sample example:
> 
> 
> /# wget https://apt.llvm.org/llvm.sh
>         /# chmod +x llvm.sh
>         /# sudo ./llvm.sh 19
>         /# export PATH=/usr/lib/llvm-19/bin:$PATH
>         /# lldb -version
>         lldb version 19.1.7
>         Copy to clipboard
- GDB

> 
> 
> For installation, go to [GNU toolchain downloads](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads). To install the version-14.2, see the following sample example:
> 
> 
> /# wget https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf.tar.xz
>         /# tar -xf arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf.tar.xz
>         Copy to clipboard

The following are the optional commands:

/# sudo mv arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf /opt/
    
    /# export PATH=/opt/arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-elf/bin:$PATH
    
    /# aarch64-none-elf-gdb -version
    Copy to clipboard

**Sample output:**

GNU gdb (Arm GNU Toolchain **14.2.Rel1** (Build arm-14.52)) 15.2.90.20241130-git
    
    Copyright (C) 2024 Free Software Foundation, Inc.
    
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    
    This is free software: you are free to change and redistribute it.
    
    There is NO WARRANTY, to the extent permitted by law.
    Copy to clipboard

## Set up the APPS kernel build

Qualcomm recommends to use a debug build using the `export DEBUG_BUILD=1` command. For more information, see [Qualcomm Linux Build Guide](https://docs.qualcomm.com/bundle/publicresource/topics/80-70029-254/build_landing_page.html#move-to-edl-mode) and [Qualcomm Linux Kernel Guide](https://docs.qualcomm.com/bundle/publicresource/topics/80-70029-3/kernel_landing_page.html).

To disable SELinux, make the following changes in the debug build:

1. Open the `<root>/layers/meta-qti-bsp/recipes-kernel/linux/linux-qcom-custom_6.6.bb` file and disable the SELinux as mentioned in the following:

# Enable selinux support
        # SELINUX_CFG = "${@oe.utils.vartrue('DEBUG_BUILD', 'selinux_debug.cfg', 'selinux.cfg', d)}"
        # KERNEL_CONFIG_FRAGMENTS:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'selinux', '${WORKDIR}/${SELINUX_CFG}', '', d)}"
        Copy to clipboard
2. Open the `<root>/sources/kernel/kernel_platform/kernel/arch/arm64/configs/qcom_defconfig` file and modify as the following:

# CONFIG_MODULE_SIG=y
        # CONFIG_MODULE_SIG_FORCE=y
        # CONFIG_SLAB_FREELIST_RANDOM=y
        # CONFIG_SLAB_FREELIST_HARDENED=y
        # CONFIG_SHUFFLE_PAGE_ALLOCATOR=y
        # CONFIG_SECURITY=y
        # CONFIG_SECURITY_NETWORK=y
        # CONFIG_HARDENED_USERCOPY=y
        # CONFIG_FORTIFY_SOURCE=y
        # CONFIG_SECURITY_SELINUX=y
        Copy to clipboard

## Set up the target device

For debugging applications, it's required to remove modem binaries from the target device. To remove modem binaries before debugging the OpenOCD, run the following sample commands:

1. For IQ-9075 platform, disable the hardware watchdog using the dip switch setting (SW3-3 switch as LOW).
2. Enable EUD on the host computer. To enable EUD, the host computer doesn't require any extra drivers to detect the EUD target device.
3. Enable EUD on the target device using console shell or adb.

    - For QCS6490, run the following command:

> 
> 
> /# echo 1 >/sys/bus/platform/devices/88e0000.eud/enable
>             Copy to clipboard
    - For IQ-9100/IQ-9075, run the following command:

> 
> 
> /# echo 1 >/sys/bus/platform/devices/88e1000.eud/enable
>             Copy to clipboard

Note

    - After enabling EUD, USB host mode won't work because it doesn't receive the role from Glink on the port connector.
    - With every system restart, it's required to enable the EUD using these adb commands.
4. Disable CPU 1-7. Enable only CPU-0 and run the following command:

adb shell
        echo 0 > /sys/devices/system/cpu/cpu1/online
        echo 0 > /sys/devices/system/cpu/cpu2/online
        echo 0 > /sys/devices/system/cpu/cpu3/online
        echo 0 > /sys/devices/system/cpu/cpu4/online
        echo 0 > /sys/devices/system/cpu/cpu5/online
        echo 0 > /sys/devices/system/cpu/cpu6/online
        echo 0 > /sys/devices/system/cpu/cpu7/online
        Copy to clipboard
5. To disable LPM for core 0, run the following command:

/# echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state0/disable
        
        /# echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state1/disable
        
        /# echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state2/disable
        Copy to clipboard
6. To sign in using UART, run the following command:

/# mount -o remount,rw /
        /# cd /lib/firmware/qcom/qcm6490/ && rm -rf modem*
        /# cd /lib/firmware/qcom/qcm6490/ && ls
        /# cd /lib/firmware/qcom/qcs6490/ && rm -rf modem*
        /# cd /lib/firmware/qcom/qcs6490/ && ls
        /# reboot
        Copy to clipboard

## Debug the Linux kernel

After completing the setup, proceed to debug the Linux kernel. The following are the sample debug commands for QCS6490 (Qualcomm Dragonwing™ RB3 Gen 2 Development Kit) target device:

1. Flash the device with the implemented APPS kernel set up modifications. For more information, see [Set up the APPS kernel build](https://docs.qualcomm.com/doc/80-70029-12/topic/debug_using_openocd.html#set-up-the-apps-kernel-build).
2. Attach the Qualcomm Dragonwing™ RB3 Gen 2 device with the host computer using the USB Type-C cable.
3. Enable the EUD on target by using console shell or adb.

    The following is the expected output on the host computer, when you enable the 9501 EUD port:

/#lsusb

Bus 001 Device 038: ID 05c6:9501 Qualcomm, Inc.

Bus 001 Device 037: ID 05c6:9500 Qualcomm, Inc.
4. Run the OpenOCD on host computer.

cd openocd/src
        Copy to clipboard

    - For QCS6490 (Dragonwing™ RB3 Gen 2 Development Kit), run the following command:

> 
> 
> sudo ./openocd -f ../tcl/interface/eud.cfg -f ../tcl/target/qualcomm/qcs6400.cfg
>             Copy to clipboard
    - For IQ-9100, run the following command:

> 
> 
> sudo ./openocd -f ../tcl/interface/eud.cfg -f ../tcl/target/qualcomm/qcs9100.cfg
>             Copy to clipboard

    The following is the sample output for QCS6490:

Open On-Chip Debugger 0.12.0-01020-g3124da65c (2025-03-21-15:28)
        Licensed under GNU GPL v2
        For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
        Info : only one transport option; autoselect 'swd'
        Warn : Transport "swd" was already selected
        force hard breakpoints
        Info : Listening on port 6666 for tcl connections
        Info : Listening on port 4444 for telnet connections
        Info : Using EUD 2.1.7
        Error: Translation from adapter speed to khz not implemented
        Info : adapter-specific clock speed value 6
        Info : SWD DPIDR 0x5ba02477
        Info : QCS6490.cpu0: hardware has 6 breakpoints, 4 watchpoints
        Info : starting gdb server for QCS6490.cpu0 on 3333
        Info : Listening on port 3333 for gdb connections
        Info : QCS6490.cpu0 cluster 0 core 0 multi core
        QCS6490.cpu0 halted in AArch64 state due to debug-request, current mode: EL0T
        cpsr: 0x60001000 pc: 0xffffffc080010c00
        MMU: enabled, D-Cache: enabled, I-Cache: enabled
        Copy to clipboard

Note

In case of a connection failure with OpenOCD, run the OpenOCD command again.
5. Two debuggers LLDB and GDB support the host computer. For more information, see the following:

    - Using LLDB

> 
> 
> 1. Open new terminal and run the LLDB with the following command:
> 
> 
> /# lldb
>                 Copy to clipboard
>         2. To load the application symbols, run the following command:
> 
> 
> (lldb) target create <vmlinux_path>
>                 Copy to clipboard
>         3. To map the source code, run the following command:
> 
> 
> (lldb) settings set target.source-map <build_path_from_vmlinux> <local_path_to_source_code>
>                 Copy to clipboard
> 
> 
>             In this command, `<build_path_from_vmlinux>` is `/usr/src/kernel/<SUFFIX>`, where `SUFFIX` is the actual code directory in the kernel. For example, `/usr/src/kernel/drivers/usb/gadget`.
>         4. To debug kernel modules, do the following (if not required, ignore this instruction):
> 
> 
> (lldb) target modules add <path_to_.ko>
>                 (lldb) target modules load --file <path_to_.ko> --slide <.ko_start_address>
>                 Copy to clipboard
> 
>             - To get the `<.ko_start_address>` string directly, run the following commands:
> 
> 
> 
> > 
> > 
> > echo 0 > /proc/sys/kernel/kptr_restrict
> >                     cat /proc/modules
> >                     Copy to clipboard
>             - To map the source code, run the following command:
> 
> 
> 
> > 
> > 
> > (lldb) settings set target.source-map <build_path_from_.ko> <local_path_to_source_code>
> >                     Copy to clipboard
>         5. Connect to the OpenOCD.
> 
> 
> (lldb) gdb-remote 3333
>                 Copy to clipboard

> 
> 
> For more LLDB commands, see [Tutorial](https://lldb.llvm.org/use/tutorial.html).

    - Using GDB

> 
> 
> 1. Open new terminal and run the GDB with the following command:
> 
> 
> /# aarch64_none_elf_gdb
>                 Copy to clipboard
>         2. To load application symbols, run the following command:
> 
> 
> (gdb) add-symbol-file <vmlinux_path>
>                 Copy to clipboard
>         3. To map the source code, run the following command:
> 
> 
> (gdb) set substitute-path <build_path_from_vmlinux> <local_path_to_source_code>
>                 Copy to clipboard
> 
> 
>             In this command, `<build_path_from_vmlinux>` is `/usr/src/kernel/<SUFFIX>`, where `SUFFIX` is the actual code directory in the kernel. For example `/usr/src/kernel/drivers/usb/gadget`.
>         4. To debug kernel modules, do the following (if not required, ignore this instruction):
> 
> 
> (gdb) add-symbol-file <path_to_.ko> -o <.ko_start_address>
>                 Copy to clipboard
> 
>             - To get the `<.ko_start_address>` string directly, run the following commands:
> 
> 
> 
> > 
> > 
> > echo 0 > /proc/sys/kernel/kptr_restrict
> >                     cat /proc/modules
> >                     Copy to clipboard
>             - To map the source code, run the following command:
> 
> 
> 
> > 
> > 
> > (gdb) set substitute-path <build_path_from_.ko> <local_path_to_source_code>
> >                     Copy to clipboard
>         5. Connect to OpenOCD.
> 
> 
> (gdb) target remote localhost:3333
>                 Copy to clipboard

> 
> 
> For more GDB commands, see [GDB command reference](https://visualgdb.com/gdbreference/commands/).

Last Published: Mar 15, 2026

[Previous Topic
Debug using the crash utility tool](https://docs.qualcomm.com/bundle/publicresource/80-70029-12/topics/crash_utility.md) [Next Topic
Debug common system issues](https://docs.qualcomm.com/bundle/publicresource/80-70029-12/topics/general_system_debugging.md)