Skip to content

jwillikers/openocd-image

Repository files navigation

OpenOCD Image

GitHub Workflow Status pre-commit

A container image for {OpenOCD}.

Synopsis

Image

quay.io/jwillikers/openocd

Tags
  • latest

Supported architectures
  • amd64 (x86_64)

  • arm64 (aarch64)

User

The default user inside the container is named user.

Entrypoint

openocd

Labels
io.containers.autoupdate=registry

Enables automatic updates when using Podman and the fully-qualified image name.

Usage

The following instructions and examples will you get you up and running for using OpenOCD and GDB with your on-chip debugger. For these examples, I’m using an ST-LINK, an ST-LINK/V2.1 to be exact, and targeting an STM32F7 microcontroller. All examples and instructions are for rootless containers run with Podman.

USB Device Access

When running OpenOCD from within this container, make sure to provide the appropriate access to the on-chip debugger. To run the container with as few privileges as possible, permit the user access to the on-chip debugger device and pass only this device to container.

udev

To allow access to the on-chip debugger, a udev rule can be created on the host which permits access for unprivileged users. This will allow an unprivileged container to access the device.

  1. Connect the on-chip debugger to the host.

  2. Use lsusb or dmesg to determine the vendor id and product id of the on-chip debugger.

    $ lsusb | grep ST-LINK
    Bus 001 Device 020: ID 0483:374b STMicroelectronics ST-LINK/V2.1

    Here the vendor id is 0483 and the product id is 374b.

  3. Create an appropriately named udev rule to permit access, substituting the vendor id and product id from the last step.

    /etc/udev/rules.d/70-st-link.rules
    # ST-LINK/V2-1
    ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", TAG+="uaccess"
  4. Now reload the udev rules.

    sudo udevadm control --reload-rules

This udev rule grant’s access to the user on the host machine. It’s important to run rootless containers which run with a non-root user, such as this one, with the option --userns keep-id. This ensures that the udev rule is applied to the user running inside the container.

Find the USB Bus and Device Numbers

It’s possible to permit access to the underlying device with by allowing the container to access /dev/bus/usb, but this allows the container access to all USB devices. To restrict this further, it’s necessary to find the device path for the on-chip debugger as shown below.

Use lsusb to determine the USB bus and device numbers assigned to the on-chip debugger.

$ lsusb | grep ST-LINK
Bus 001 Device 020: ID 0483:374b STMicroelectronics ST-LINK/V2.1

The USB bus number here is 001, and the device number is 020. Using this information, the USB device’s path is /dev/bus/usb/001/020. Pass this device in to the container using the --device option like so, --device /dev/bus/usb/001/020.

SELinux

For systems using SELinux, such as Fedora, there is the last hurdle. To enable access to USB devices for rootless containers on systems running SELinux, pass the option --security-opt label=disable to Podman.

Examples

The following examples assume you have allowed the necessary access to the USB devices. In addition, they use the same device information such as the USB bus and device numbers. The examples will enumerate a number of common scenarios when networking between GDB and OpenOCD. To attach the GDB Server hosted by OpenOCD, you’ll need to permit network access to port 3333 of the OpenOCD container. Some of the examples run GDB from within its own container. These use my GDB Image available on Quay.

Flash

The following example flashes an ELF file executable in the current directory to an STM32F7 target board.

podman run \
    --rm \
    --userns keep-id \
    --security-opt label=disable \
    --device /dev/bus/usb/001/020 \
    --volume $PWD:/home/user:Z \
    --name openocd \
    -it quay.io/jwillikers/openocd:latest \
    -f interface/stlink.cfg \
    -f target/stm32f7x.cfg \
    -c "program app.elf verify reset exit"

Background

To run OpenOCD in the background, daemonize the container by using the -d flag in place of the -i flag used in the preceding example.

podman run \
    --rm \
    --userns keep-id \
    --security-opt label=disable \
    --device /dev/bus/usb/001/020 \
    --name openocd \
    -dt quay.io/jwillikers/openocd:latest \
    -f interface/stlink.cfg \
    -f target/stm32f7x.cfg

GDB From the Same Pod

If you wish to run GDB from another container, the easiest method is to place both rootless containers in the same pod and attach to port 3333 on localhost.

  1. Create a pod.

    podman pod create --name openocd-and-gdb
  2. Create and start the OpenOCD container as part of the new pod.

    podman run \
        --rm \
        --pod openocd-and-gdb \
        --userns keep-id \
        --security-opt label=disable \
        --device /dev/bus/usb/001/020 \
        --name openocd \
        -dt quay.io/jwillikers/openocd:latest \
        -f interface/stlink.cfg -f target/stm32f7x.cfg
  3. Run GDB from a container within the same pod.

    podman run \
        --rm \
        --pod openocd-and-gdb \
        --volume $PWD:/home/user:Z \
        --name gdb \
        -it quay.io/jwillikers/gdb:latest \
        -q -ex "target remote :3333" app.elf

GDB on the Host

If you’re using GDB on the host, then it’s possible to access the GDB Server using the host’s network.

  1. Startup OpenOCD in a container using the host’s network stack directly.

    podman run \
        --rm \
        --userns keep-id \
        --security-opt label=disable \
        --device /dev/bus/usb/001/020 \
        --network host \
        --name openocd \
        -dt quay.io/jwillikers/openocd:latest \
        -f interface/stlink.cfg -f target/stm32f7x.cfg
  2. Then just attach to the GDB Server as normal.

    gdb -q -ex "target remote :3333" app.elf

Build

This project uses Buildah and Podman for building and testing the image. A set of pre-commit checks are readily available to ensure your code is up-to-spec at the time it is committed. Instructions for setting up a development environment, building the image, and testing the image follow. These instructions are intended for users of Fedora Silverblue, where the packages buildah, git, and podman are already available. Moreover, I use the fish shell.

  1. Install the fish shell.

    sudo rpm-ostree install fish
  2. Reboot to finish the installation.

    systemctl reboot
  3. Clone this repository.

    git -C ~/Projects clone [email protected]:jwillikers/openocd-image.git
  4. Install pre-commit.

    pip install pre-commit
  5. Change into the project directory.

    cd ~/Projects/openocd-image
  6. Install pre-commit’s Git hooks.

    pre-commit install
  7. Run the shell script to build the image.

    buildah unshare ~/Projects/openocd-image/build.fish
  8. Test the image with the test.fish shell script.

    ~/Projects/openocd-image/test.fish

Contributing

Contributions in the form of issues, feedback, and even pull requests are welcome. Make sure to adhere to the project’s Code of Conduct.

Open Source Software

This project is built on the hard work of countless open source contributors. Several of these projects are enumerated below.

Code of Conduct

Refer to the project’s Code of Conduct for details.

License

This repository is licensed under the GPLv3, a copy of which is provided in the license file.

© 2021 Jordan Williams

Authors

Releases

No releases published

Packages

No packages published

Languages