ethernet调试工具_kgdb调试aarch64内核模块

  • 0 开发环境

  • 1 完善被调试终端的KGDB

  • 2 配置内核

    • 2.1 构建开发环境

    • 2.2设置内核选项

    • 2.3 修改对应模块的优化等级

    • 2.4 内核编译

  • 3 代码修改记录总计

  • 4 文件共享

  • 5 串口复用

  • 6 GDB优化

  • 7 开发板配置

  • 8 主机配置

  • 参考博客

0 开发环境

  • 笔记本:ubuntu18.04.5,内核版本为5.3

  • 开发板:imx8mp-evk

  • 内核版本:Linux5.4.24

  • 交叉编译工具链:fsl-imx-xwayland-glibc-x86_64-imx-image-core-aarch64-imx8mpevk-toolchain-5.4-zeus.sh

注:下面的可能会遗漏部分细节,但主要的部分基本都写出来了,应该无大碍。

注:以下步骤虽然针对的imx8mp-evk,但只要是aarch64架构的芯片,大部分操作都通用的。

注:这是个人的踩坑记录,虽然可以解决问题,但估计不是最好的解决方案,欢迎评论区一起探讨。

1 完善被调试终端的KGDB

远端的 gdb 连上 linux 的 kgdb 之后,在断点处执行单步调式(step/next)的时候,调式器并不是执行断点处的语句,而是每次都陷入到下面的代码段:

arch/arm64/kernel/entry.S:356
el1_irq:
kernel_entry 1
enable_dbg

社区也有人碰到这个问题,并提交了如下 patch 来修复这个问题。这个问题并不是在所有的 arm64 平台上都会碰到,patch 还在讨论并没有合进 upstream,Patch 如下:

https://patchwork.kernel.org/patch/9741897/

注:至少我在Linux5.4.24中发现并没有解决这个问题,更不用说大部分嵌入式板子还用的4.x的内核。

diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index b9176b324e5a..fddbc6be3780 100644--- a/arch/arm64/kernel/kgdb.c+++ b/arch/arm64/kernel/kgdb.c@@ -28,6 +28,7 @@ #include debug-monitors.h>#include +#include ptrace.h>#include struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {@@ -111,6 +112,8 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "fpcr", 4, -1 },
};+static DEFINE_PER_CPU(unsigned int, kgdb_pstate);+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
{if (regno >= DBG_MAX_REG_NUM || regno < 0)@@ -200,6 +203,10 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
err = 0;break;case 's':+ /* mask interrupts while single stepping */+ __this_cpu_write(kgdb_pstate, linux_regs->pstate);+ linux_regs->pstate |= PSR_I_BIT;+/*
* Update step address value with address passed
* with step packet.
@@ -242,11 +249,20 @@ NOKPROBE_SYMBOL(kgdb_compiled_brk_fn);
static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
{
+ unsigned int pstate;
+
if (!kgdb_single_step)
return DBG_HOOK_ERROR;
kernel_disable_single_step();
+ /* restore interrupt mask status */+ pstate = __this_cpu_read(kgdb_pstate);+ if (pstate & PSR_I_BIT)+ regs->pstate |= PSR_I_BIT;+ else+ regs->pstate &= ~PSR_I_BIT;+
kgdb_handle_exception(1, SIGTRAP, 0, regs);return 0;
}

2 配置内核  

2.1 构建开发环境

source /opt/fsl-imx-xwayland/5.4-zeus/environment-setup-aarch64-poky-linux
make imx_v8_defconfig
make menuconfig

如果在make menuconfig出现如下问题,具体解决方案可以看,我就不在这里多费口舌了。

  • /usr/bin/ld: cannot find -lxxx的解决办法:https://www.cnblogs.com/zhming26/p/6164131.html

  • 关于curses、ncurses、ncursesw区别及安装方法:https://blog.csdn.net/u013590407/article/details/79119377

HOSTLD  scripts/kconfig/mconf
/usr/bin/ld: cannot find -lncursesw
collect2: error: ld returned 1 exit status
scripts/Makefile.host:116: recipe for target 'scripts/kconfig/mconf' failed
make[1]: *** [scripts/kconfig/mconf] Error 1
Makefile:567: recipe for target 'menuconfig' failed
make: *** [menuconfig] Error 2

注:source /opt/fsl-imx-xwayland/5.4-zeus/environment-setup-aarch64-poky-linux为我yocto编译下载后的交叉编译工具链的安装位置

2.2设置内核选项

配置内核KGDB选项

1a64ff7e43d49eff2dbbc5d2a0693d0f.png

配置dwmac-imx编译为模块

注:这个是我用于调试的模块,其他模块类似的操作

d1460843ea12104d75ef85a52ffe4f75.png

2.3 修改对应模块的优化等级

stmac目录下的Makefile添加如下编译优化等级

987bd53dacbac425a90ceece64db1c8b.png

O1优化等级会出现如下小问题,不过还好,凑活着用

2e8516ed54ff1a5bf9e64681da440582.png

我想修改为O0,但是编译不成功,只能用O1了 注:这个地方因勉强可以用,就没有深究下去

849ff643d2a171830fc015e6cefc1e28.png

2.4 内核编译

make -j 8

3 代码修改记录总计

$git log --stat -p
commit 56e89cdadaac0ded943486912afc135b7dc46cf5 (HEAD -> imx_5.4.24_2.1.0)
Author: sazczmh
Date: Sat Aug 8 10:24:36 2020 +0800
Modify the dwmac module compilation aptimization level to O1
---
drivers/net/ethernet/stmicro/stmmac/Makefile | 4 ++--1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 413d2104948d..91d55b92ce88 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -1,6 +1,6 @@# SPDX-License-Identifier: GPL-2.0
-# Modify the module compilation aptimization level to O0
-EXTRA_CFLAGS += -O0
+# Modify the module compilation aptimization level to O1
+EXTRA_CFLAGS += -O1
obj-$(CONFIG_STMMAC_ETH) += stmmac.o
stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
commit 550c7b51c425418b8122a834e5236592537a22f9
Author: sazczmh
Date: Sat Aug 8 09:43:29 2020 +0800
Modify the code warning!
---
arch/arm64/kernel/kgdb.c | 2 +-1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index dfe6ffcd71f6..52f5010c1166 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -269,7 +269,7 @@ static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)else
regs->pstate &= ~PSR_I_BIT;
- kgdb_handle_exception(1, SIGTRAP, 0, regs);
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);return DBG_HOOK_HANDLED;}
NOKPROBE_SYMBOL(kgdb_step_brk_fn);
commit c92c9abd0aebdc70f9a97f670cfa61cc1fa8e96e
Author: sazczmh
Date: Sat Aug 8 09:35:38 2020 +0800
To reduce unnecessary compilation warnings, only module compilation optomization level is O0
---
Makefile | 2 +-
drivers/net/ethernet/stmicro/stmmac/Makefile | 3 +++2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 02191761c23f..c32c78cf2fe5 100644
--- a/Makefile
+++ b/Makefile
@@ -700,7 +700,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
-KBUILD_CFLAGS += -O1
+KBUILD_CFLAGS += -O2else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3KBUILD_CFLAGS += -O3else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index ae223ec1b754..413d2104948d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -1,4 +1,7 @@# SPDX-License-Identifier: GPL-2.0
+# Modify the module compilation aptimization level to O0
+EXTRA_CFLAGS += -O0
+
obj-$(CONFIG_STMMAC_ETH) += stmmac.o
stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
commit 11eb493c15b271f00d982985dedca75e98145734
Author: sazczmh
Date: Sat Aug 8 09:21:53 2020 +0800
arm64, kgdb debug: Disable interrupts while a software step is enable
---
arch/arm64/kernel/kgdb.c | 23 ++++++++++++++++++++---1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index 43119922341f..dfe6ffcd71f6 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -19,6 +19,11 @@#include #include
+#include
+
+static DEFINE_PER_CPU(unsigned int, kgdb_pstate);
+
+
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {{ "x0", 8, offsetof(struct pt_regs, regs[0])},{ "x1", 8, offsetof(struct pt_regs, regs[1])},
@@ -206,7 +211,10 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,err = 0;
break;case 's':
- /*
+
+ __this_cpu_write(kgdb_pstate, linux_regs->pstate);
+ linux_regs->pstate |= PSR_I_BIT;
+ /*
* Update step address value with address passed
* with step packet.
* On debug exception return PC is copied to ELR
@@ -249,8 +257,17 @@ NOKPROBE_SYMBOL(kgdb_compiled_brk_fn);
static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr){
- if (!kgdb_single_step)
- return DBG_HOOK_ERROR;
+ unsigned int pstate;
+
+ if (!kgdb_single_step)
+ return DBG_HOOK_ERROR;
+ kernel_disable_single_step();
+
+ pstate = __this_cpu_read(kgdb_pstate);
+ if (pstate & PSR_I_BIT)
+ regs->pstate |= PSR_I_BIT;
+ else
+ regs->pstate &= ~PSR_I_BIT;
kgdb_handle_exception(1, SIGTRAP, 0, regs);return DBG_HOOK_HANDLED;

这个是截图,比较好看些

734327dff561cef6cdf076bf24b665d1.png
1216ee7cb4896b26dc96632b84cc61f4.png

4 文件共享

开发板与PC的文件传输是通过NFS,方便进行开发,具体可以参考

【Linux笔记】挂载网络文件系统:https://zhuanlan.zhihu.com/p/109222258

我的共享文件夹为~/imx8mp_evk_nfs/,共享模块文件,使用如下命令即可,比较方便

cp ~/linux-imx/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.ko ~/imx8mp_evk_nfs/

注:文件夹挂载之前不要在这个文件夹,否则会没法刷新cd /;cd /mnt 即可解决。

注:我的配置环境是开发板与PC的网络是通过一个路由器进行通信的,网线直连会有所不同。

5 串口复用

为了调试方便使用agent-proxy即可,需要进行编译安装

https://git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git

使用如下命令可以将ttyUSB2复用为两个端口,方便调试。

./agent-proxy  5550^5551 0 /dev/ttyUSB2,115200 -s003

其中一个可以用如下命令连接开发板,与板子进行通信

telnet localhost 5550

另一个端口用于KGDB调试使用

2edf9d42996cce597a97e40f936c8846.png

注:这个具体原理我没有深究,大概就是将串口的读取发送数据,通过localhost虚拟出来两个端口来进行使用,很容易上手。

注:这个/dev/ttyUSB2需要具体情况具体设置,对于imx8mp来说是从USB插入开始,识别的第三个串口,具体可以用demsg查看

6 GDB优化

Ubuntu18自带的GDB不太好使,调试不方便,需要gdb的界面增强版CGDB,增加了语法高亮等一系列小功能,可以提高调试效率。

使用如下命令即可进行安装

sudo apt install cgdb

下面是我cgdb的调试界面,相对于默认的gdb单色调试界面,这个语法高亮非常实用。

a3c586e8dfeeb6de278e3475c8955e99.png

注:我也尝试使用eclipse进行调试,可是存在着一些问题,因此就先不说那个了。

7 开发板配置

开发板的连接是通过如下命令进行的

./agent-proxy  5550^5551 0 /dev/ttyUSB2,115200 -s003
telnet localhost 5550

使用如下命令即可进入gdb命令行,然后再执行kgdb即可等待主机的连接

mount -t nfs -o nolock,vers=4 192.168.3.5:/home/sazczmh/imx8mp_evk_nfs /mntecho ttymxc1 > /sys/module/kgdboc/parameters/kgdbocecho g  >  /proc/sysrq-trigger

注:这个192.168.3.5:/home/sazczmh/imx8mp_evk_nfs为我的主机共享文件夹,IP以及目录需要根据具体情况进行修改。

注:ttymxc1为imx8mp的调试串口,不同的把板子可能需要进行相应的修改。

8 主机配置

执行如下命令解析vmlinux,准备开始调试

cd ~/linux-imx
cgdb -d gdb-multiarch vmlinux

设置架构为aarch64,再加载被调试模块的信息

set architecture aarch64
add-symbol-file drivers/net/ethernet/stmicro/stmmac/dwmac-imx.ko 0xffff8000090a0000

注:set architecture aarch64的目的是防止出现Remote 'g' packet reply is too long (expected 168 bytes, got 788 bytes)这个错误,也可以利用交叉编译工具链的gdb工具,就不会出现这个问题,后续文章会略有涉及。

注:0xffff8000090a0000这个可以提前通过insmod加载对应模块,再通过cat /proc/modules 可以查看,查看之后注意要卸载rmmod。

现在要连接开发板,设置对应的断点,c开始执行调试

target remote localhost:5551
b stmmac_dvr_probe
c

开发板同时要加载模块,触发断点,就可以进行单步调试了。

参考博客

  • ARM64 的 Linux 内核 kgdb/kdb调试 :https://www.byteisland.com/arm64-%E7%9A%84-linux-%E5%86%85%E6%A0%B8-kgdb-kdb-%E8%B0%83%E8%AF%95/这个讲解的很全面具体,本文就是大部分是参考这个文章,然后根据个人需求进行魔改优化的。

  • GDB调试利器 :https://tutorial.linux.doc.embedfire.com/zh_CN/latest/linux_debug/gdb_use.html从火哥这个文章知道CGDB这个好东西,对于高效率调试非常有帮助,后面还会有关于它的文章。

注:个人能力有限,欢迎批评指正。

原创不易,严禁剽窃!

9b40b37ff38a8c701dd747901d384813.png

c52ebb51ef7db5ae8f4e391d096521c4.gif

原创经验资料分享:包含但不仅限于FPGA、ARM、RISC-V、Linux、LabVIEW等软硬件开发,另外分享生活中的趣事以及感悟。目的是建立一个平台记录学习过的知识,并分享出来自认为有用的与感兴趣的道友相互交流进步。

c52ebb51ef7db5ae8f4e391d096521c4.gif 7f7d49908635131f3ba5d95a81cb9e17.gif END 7f7d49908635131f3ba5d95a81cb9e17.gif 575b148bdb008ecea5e7a7bba55baea2.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值