0. 关键词
debug raspberry pi bcm2835 armv6 linux kernel J-Link jtag gdb
1. 摘要
gdb是一款开源debugger,调试的事实标准,gdb可以帮助开发者快速定位问题。
gdb也可以作为阅读源码的工具,可以非常方便的查看运行时上下文,跳转所见即所得。因此,在嵌入式系统或底层开发中,gdb必不可少。
linux内核作为操作系统调试起来有一定特殊性,不能直接在本地gdb调试,需要一个host和一个target远程调试。
远程调试内核主要有三种方式,一种是内置派,通过Kgdb这种内核内置的模块。一种是虚拟派,通过把内核跑在类似qemu的虚拟机上。最后一种是硬件派,这是嵌入式设备上最常用的调试方式,通过连接jtag调试。
前两种多少都会受到软件的限制,而最后一种方式由硬件来实现,最直接。
2. rpi+jlink的优势
成本和流行的平衡,raspberry pi搭载的bcm2835是目前比较流行的soc,且资料较为完善,
armv6架构,比s3c2440要新很多,S3C2440架构是arm9,资料很丰富,但目前好像也只有周立功还在推这个老旧SoC作为学习平台。
而相对比较新的单板计算机例如树莓派3,其架构为a53,只能用昂贵的jlink v11。
我这里选择的jtag为jlink v9 非常便宜daobanchangkuang,由于来自深圳的科技,淘宝才不到100块,不喜欢黑又粗外观的还可以选择定制化的小板。
3. 硬件准备
3.1 清单
- micro sd card
- SEGGER J-Link V9
- pl2303/ch340 usb uart adapter
- raspberry pi 1A (bcm2835)
3.2 接线方式
接线方式可以参考segger官网Interface Description和树莓派specRPi BCM2835 GPIOs,
因为rpi1A只有26个pin,主板上没有引出GPIO26,只得改用GPIO4来替换,rpi1B+则无需改动。
JTAG | J-Link pin | rpi pin (1A) | bcm2835 GPIO |
---|---|---|---|
TRST | 3 | 15 | 22 |
RTCK | 11 | 16 | 23 |
TDO | 13 | 18 | 24 |
TCK | 9 | 22 | 25 |
TDI | 5 | 37 (7) | 26 (4) |
TMS | 7 | 13 | 27 |
4. 环境配置
4.1 buildroot制作Linux镜像
我们需要在 /boot/config.txt 使能jtag,bcm2835的VideoCore读取配置之后,就可以对GPIO作出相应的设置。(否则另一种方式是由arm核配置GPIO,需要改动linux kernel 启动代码)。
配置参数具体参考enable_jtag_gpio
这里可以使用我写好的buildroot recipe,我在这个基础上超级精简了linux kernel,缩短编译时间,同时开启debug选项。
1 | git clone https://github.com/996refuse/rpi_bcm2835_minimal.git |
这样,适配bcm2835的Linux镜像就制作完成了,使用dd写到卡上 dd if=output/images/sdcard.img of=/dev/sdX status=progress
然后就可以启动树莓派了
4.2 安装JLinkGDBServer
1 | dpkg -i JLink_Linux_V618d_x86_64.deb |
我这里用的是618d版本,segger官网可以下,太新的版本(2020年后)在调试过程中隔几分钟J-Link就会丢失jtag的连接,并且gdb报错
Program received signal SIGTRAP, Trace/breakpoint trap
(这个问题我搞了好久,一直以为是linux kernel有关cpu idle实现的问题,Debugging-Linux-Kernel-over-JTAG-with-J-Link 这篇文章误导了我。后来发现其实降版本就可以稳定了)
启动JLinkGDBServer
1 | JLinkGDBServer -select USB -device arm11 |
此时GDB Server 会在监听2331端口,等待gdb连接
4.3 安装和使用gdb
上位机不是arm架构的话,需要交叉编译gdb的时候设置target为arm-linux-gnueabi (顺便加上python支持,后面gdb scripts会用到,不然又要重rebuild一次)。
如果是Ubuntu系统可以直接安装 gdb-multiarch
1 | apt install gdb-multiarch |
linux kernel为了gdb提供了一下helper function,kernel需开启CONFIG_GDB_SCRIPTS gdb-kernel-debugging ,并加入安全路径
1 | echo "add-auto-load-safe-path /path/to/linux-build" >> ~/.gdbinit |
启动gdb
1 | cd output/build/linux-custom |
愉快的开始debug吧!
5. 开源替代
这套方案能极大方便os爱好者尝试和分析系统层的特性和原理,稳定并且很便宜。
缺点在于过度依赖segger的产品。接下来我有时间会尝试openocd和daplink,力图找到完美的开源替代。
- openocd替换JLinkGDBServer,jlink v9 + openocd 调试树莓派3 Debugging Raspberry Pi 3 with JTAG | SUSE Communities
- daplink替换jlink
简单记录一下我的经验,希望对大家有帮助
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章