I’ve recently released an early version of a GDB remote serial protocol
implementation that runs on bare-metal on a Raspberry Pi that allows you do
debug bare metal applications without the use of a JTAG. Once running you can
connect with GDB as a remote target and perform all of the normal debugging
that you’d expect and you can even single step through interrupt handlers and
The implementation uses the security extensions of the ARM core so that the
target application requires no modification. The security extensions are
present in v6K and later revisions of the ARM architecture and are marketed as
TrustZone. These extensions allow the CPU and peripherals to be partitioned
into secure and non-secure regions so that it is possible to run a small
trusted system and prevent a larger OS like Linux from accessing secret data.
The Broadcom SoC on the Raspberry Pi doesn’t implement enough (or have
sufficient documentation – who knows?) to do any useful security hardening
with these extensions – there would usually be a protection controller (TZPC)
for gating peripheral accesses and a secure memory adapter along with onchip
memory that the non-secure world can’t access such as TCM’s which this SoC
So it’s no good security, but the extra operating modes mean we can create a
debugger. The security extensions introduce a new operating state – secure
monitor mode, and a new set of vectors which the CPU can be configured to
branch to on certain, well defined events. A new CPU instruction SMC (Secure
Monitor Call) provides a way for the CPU to enter the monitor mode, and the
CPU can be configured to branch to the FIQ/IRQ vectors in monitor mode rather
than the normal vectors. So to implement a debugger we can use the FIQ entry
for handling input from the serial port and the SMC entry for breakpoints then
the rest is just glue.
This does impose a couple of limitations though:
- The security extensions can’t be used by the application being debugged –
that’s probably fine as they aren’t useful on this SoC anyway.
- The core can only handle 1 FIQ and that’s used by the debugger for the UART
- the application will have to make do with IRQ’s. The nice thing about
using the FIQ is that this can effectively be turned into an NMI to the
- The UART is used for communication with the debugger – the application
can’t use it.
- The monitor mode can’t really single step the core – GDB is clever enough
to emulate this with breakpoints at the next instruction, but this does mean
that whilst single stepping the core can jump to the IRQ vector and handle a
whole IRQ unlike where a JTAG single steps the whole core in lockstep.
- Watchpoints can’t be configured to branch to the monitor mode without
application support so hardware watchpoints don’t work.
The code is available on my github page, please give it a go – patches are