![b507d9e256924c3f126700bdb69a159c.png](https://img-blog.csdnimg.cn/img_convert/b507d9e256924c3f126700bdb69a159c.png)
- 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 如下:
[v3,2/4] arm64: kgdb: disable interrupts while a software step is enabledpatchwork.kernel.org注:至少我在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 <asm/debug-monitors.h>
#include <asm/insn.h>
+#include <asm/ptrace.h>
#include <asm/traps.h>
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_