Navigation Menu
Nuclei-Software/nuclei-linux-sdk
Type / to search
Debug Linuxsdk using NucleiStudio
Huaqi Fang edited this page on Nov 12, 2024 · 16 revisions
How to Debug Linux SDK on NucleiStudio
关于Nuclei Linux SDK的编译开发使用, 参见 https://github.com/Nuclei-Software/nuclei-linux-sdk
本文档主要说明如何调试在板子上运行的程序,调试原理是用pc端openocd做gdb server,接收pc端gdb发送过来的命令,通过jtag与板子进行通信,完成相应命令的处理。 关于openocd的具体工作原理不在本文介绍之列,可以网上自行查阅相关资料。
下面以调试Linux Kernel 为例子,说明如何使用NucleiStudio IDE来单步调试程序, 其他程序调试可以参考此文档。
关于基本的Nuclei Studio IDE的调试功能参见 2.9. Nuclei Studio 调试运行工程 — Nuclei Development Tool Guide 2025.02 documentation
而Nuclei Studio IDE是基于Eclipse Embedded CDT项目,因此很多界面上的功能是一致的,所以搜索Eclipse CDT界面上相关调试使用技巧也基本适用,和具体硬件打交道的可能需要自行辨别下。
1.New Debug Configuration
和arm 调试工具类似,使用前需要配置调试参数。
添加Debug Configuration
双击NucleiStudio程序,进入如下界面,点击Run 可以看到有Debug Configurations的选项。 点击Debug Configurations,在左边界面找到GDB OpenOCD Debugging,双击GDB OpenOCD Debugging, 或者右键可以创建新配置New_configuration。右边选项卡
Main
,Debugger
,Startup
是需要配置的。如需要映射路径,Source
也需要配置。Common
,SVD Path
暂未用到。配置Main 选项卡
配置Debugger 选项卡
如果openocd 与gdb 不是同一台pc,则需要设置remote target 的IP地址。一般NucleiStudio IDE安装目录下有openocd与gdb这两个工具
cfg文件在Linux SDK中
conf/$SOC/
目录下,例如 evalsoc 方案的cfg路径:nuclei-linux-sdk\conf\evalsoc\openocd.cfg
下图中openocd 是修改过的,所以没有使用IDE中自带的openocd。
配置Startup 选项卡
如果需要加载符号表,需要选上Load Symbol
配置Source 选项卡
-
下图中有两项path mapping 映射,理论上说,第一项就够了,但是本人电脑上需要创建第二个映射,原因未知。第一次使用时可以不配置path mapping,调试器会提示你找不到汇编对应的文件,这个时候再编辑路径映射。
其他选项卡
Common,SVD Path 没有用到。Debug Config 编写完成后,可以点击Apply 来保存配置,点击Debug 则可以开始调试。
2.Debug Program
软件调试的一切前提是务必先排查FPGA SoC原型是否是稳定的,例如如果有DDR,务必确认DDR 8/16/32/64位读写执行(随机,按序)是PASS的没有任何错误的,在一个出错的环境上调试只会错上加错,一团乱麻,其他的外设也是如此,有条件先通过裸机都验证完毕再上Linux内核调试,且我们的原型环境是日常CI回归跑Linux的,所以一般而言不会有问题的。
IDE上调试和gdb 调试原理上是一样的,只是gdb 输入的是命令,IDE上是以图形化呈现功能,人机交互IDE界面会更友好一些。
如果想通过gdb加载opensbi/uboot/kernel/rootfs
到DDR上,而不是freeloader
的方式,请参见 https://github.com/Nuclei-Software/nuclei-linux-sdk/issues/23
Nuclei Studio IDE里面的 Debugger Console Tab里面是可以直接输入gdb命令的,关于gdb命令的使用参见 gdb手册 Top (Debugging with GDB) , 也可以网上查看gdb相关的使用方法,这里网上有很多教程,不予赘述。
Note
可以在Nuclei Studio IDE里面使能Instruction Step Mode来使能按指令单步,这样方便定位具体异常出错点
启动调试功能
方法1:在刚配置完debug configure之后直接点击右下角Debug 按钮,
方法2:点击IDE主界面上靠右边的小虫子按钮,会弹出所有debug 配置项,选择对应配置项启动调试。
修改PC指针
下图Linux内核代码中加入了死循环
asm volatile("j .")
指令,让cpu运行到此处时停下来,jtag调试器连上开发板就可以从断点位置开始调试了,调试前需要将pc值加4,让cpu从下一条指令开始执行。可以在下一条汇编代码上,右击鼠标选择Move to Line 来完成pc+4的功能。如没有加死循环指令,jtag 调试器连接开发板就是连上那一刻pc指向的指令,这个时候不需要改pc值。设置断点
-
单步跟踪时,需要切换到按指令单步模式,就是i->
这个图标点击一下。在指令前双击可设置断点 查看函数调用栈,寄存器,变量,断点,表达式,汇编
查看内存
内存地址可以是物理地址,也可以是虚拟地址(前提是系统开了MMU)
如Memory 标签没有显示,可以在界面上选Window->Show View->Memory
手动输入gdb 命令
3.QA
1.单步调试出现断点异常提示
出现这个错误提示,一般是跨image 调试时,出现此地址不在当前调试镜像内存范围内,所以跨镜像调试前,需要把断点删掉,以免出现错误调试。
2.调试过程中重新加载符号表
注意: 调试符号表使用的时候,请务必确保相关的代码编译的时候开启了
-g
选项,最好调试优化等级能调整到-Og
这样更方便源码对照。关于opensbi/uboot/linux kernel
如果开启调试选项,请自行搜索查找,这个和ARM基本一致。如果需要调试过程中,手动加载符号,可在Debugger Console框中用
symbol-file
命令来更新符号表。
symbol-file Y:\\home\\guibing\\nuclei-linux-sdk\\work\\evalsoc\\linux\\vmlinux
3.调试过程中没有源码对应
可能的情况:
- 1.编译,链接时没有加
-g
选项 - 2.加载elf和源码不是同一个工程
- 1.编译,链接时没有加
4.uboot 重定位后符号对不上如何调试
可以先按键中断uboot的自动启动,使其停在uboot 控制台界面,然后在Debugger Console中,输入如下命令获取符号偏移, 并使用
-o
参数重新加载符号表,加载完成后,单步跟踪代码就可以对上。
# 获取符号偏移 p /x ((gd_t*)$gp)->reloc_off $2 = 0x7dd8e000 # 用-o 参数重新加载符号表 symbol-file Y:\\home\\guibing\\nuclei-linux-sdk\\work\\evalsoc\\u-boot\\u-boot -o 0x7dd8e000 Load new symbol table from "Y:\home\guibing\nuclei-linux-sdk\work\evalsoc\u-boot\u-boot"? (y or n) [answered Y; input not from terminal] Reading symbols from Y:\home\guibing\nuclei-linux-sdk\work\evalsoc\u-boot\u-boot...
- 5.怎么定位具体异常是啥
根据当前程序所在模式,通过执行 info reg priv
获取当前模式。
- 例如 Machine(M) 模式,就查看CSR
mepc mcause mtval
来分别获取异常出错前的位置,异常原因,异常出错信息 - 而 Supervisor(S) 模式,就查看CSR
sepc scause stval
相关寄存器来定位 - 通过查看CSR
mtvec
和stvec
寄存器的值可以获知异常入口基地址,关于标准RISC-V异常CSR详细解析参见手册 riscv-privileged.pdf - Nuclei RISC-V处理器里面还额外定义了
mdcause/sdcause
来获知进一步异常的原因,详细参见 Nuclei_RISC-V_ISA_Spec.pdf
通过逐步分析异常出错的位置,反推上一级出错点,在对应的位置打断点,结合gdb 按指令单步(si
)来具体定位出错点。
标准RISC-V CSR的详细解析请参见 riscv-privileged.pdf
Pages 4
Clone this wiki locally
Footer
© 2025 GitHub, Inc.