Debug Linux Kernel with OpenOCD & GDB

Hi all,

I’m trying to set up target debug of the Linux kernel using GDB & OpenOCD of the HiFive Unmatched. I’m running an Ubuntu 20.04 host. I’m using the stock build from the SiFive freedom-u-sdk github with just two additions to the build/conf/local.conf:

KERNEL_IMAGETYPES += " vmlinux "
EXTRA_IMAGEDEPENDS += " gdb-cross-${TARGET_ARCH} "

Kernel debug seemed to be enabled when I checked with menuconfig. I built the “demo-coreip-cli” image and wrote to the SD card and booted the system. All seemed to go well. I launched OpenOCD that I built from ‘git clone GitHub - riscv/riscv-openocd: Fork of OpenOCD that has RISC-V support’:

openocd -c ‘bindto 0.0.0.0’ -f ./openocd_hifive_unleashed.cfg

I obtained the openocd_hifive_unleashed.cfg from zephyr/openocd_hifive_unleashed.cfg at main · zephyrproject-rtos/zephyr · GitHub. I did modify one line of the script to add “-rtos linux”:

$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 0x4000 -work-area-backup 1 -rtos linux

I then launched a devshell to get access to the cross-compiled GDB:

MACHINE=unmatched bitbake -c devshell linux-mainline

From the devshell I launch GDB:

riscv64-oe-linux-gdb /…/build/tmp-glibc/deploy/images/unmatched/vmlinux

Once in GDB I attached to OpenOCD:

target extended-remote localhost:3333

At this point I am attached and the target is halted but I am unable to resolve symbols. This is what I see after entering the “target command” above:

Remote debugging using localhost:3333
0x0000000080004aaa in ?? ()

At the OpenOCD console I see this:

Error: Cannot compute linux virt2phys translation

I put most of the above steps together from pieces gathered here and there. Is there some step I’m missing or some web page that tells me the proper way to debug the Linux kernel using OpenOCD & GDB? Or is there some other debugger I should be using?

Thanks,
Michael

$_TARGETNAME.0 is hart 0 which is the MMU-less S core rather than one of the four MMU-capable U cores, and thus parked in M-mode not doing anything. Have you tried switching cores via thread 1 up to 4? When I used OpenOCD to debug FreeBSD on the Unmatched in the past I omitted hart 0 entirely from the config and just started from 1.

That worked - thank you. Is there a way to set a breakpoint and have it survive a reset? I’m trying this:

(gdb) b smp_init (I’ve also tried “b start_kernel”)
(gdb) cont
(telnet) reset

The breakpoint is never hit although GDB remains attached; I’ve tried this with and without SMP enabled. If I halt the processor after boot and insert a breakpoint, that seems to work.

Thanks,
Michael

Would something like this work via gdb:

monitor reset halt (or reset init?)
b smp_init
cont