> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 内核调试器（KGDB）

KGDB（Kernel GNU Debugger）为运行中的 Qualcomm<sup>®</sup> Linux 内核提供实时的源代码级调试。运行 GDB 的主机通过串行端口连接到目标设备，可以设置断点、检查寄存器并单步执行内核代码，包括动态加载的模块。

## **必需的内核配置**

启用以下 Kconfig 选项并重新构建内核：

```text theme={null}
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_CONSOLE_POLL=y
CONFIG_MAGIC_SYSRQ=y
```

在运行中的系统上验证：

```bash theme={null}
zcat /proc/config.gz | grep -E "CONFIG_KGDB|CONFIG_MAGIC_SYSRQ|CONFIG_FRAME_POINTER"
```

## **串行设置**

KGDB 使用 `kgdboc`（KGDB over console）驱动通过串行端口进行通信。

### 内核命令行参数

将以下内容添加到 `meta-qcom/conf/machine/include/qcom-<SoC>.conf` 中的 `KERNEL_CMDLINE_EXTRA`：

```text theme={null}
kgdboc=ttyMSM0,115200n8 kgdbwait nokaslr
```

| **参数**                    | **效果**                                                 |
| :------------------------ | :----------------------------------------------------- |
| `kgdboc=ttyMSM0,115200n8` | 将 115200 波特率的 `ttyMSM0` 注册为 KGDB I/O 通道                |
| `kgdbwait`                | 在启动期间暂停内核，等待 GDB 连接后再继续。如果希望稍后通过 SysRq 连接 GDB，可以省略此参数。 |
| `nokaslr`                 | 禁用内核地址空间布局随机化。GDB 符号匹配所必需。                             |

### 禁用看门狗

如果内核停止响应，Qualcomm SoC 看门狗会重置设备。请在启动 KGDB 会话之前禁用它，以防止意外重置：

```bash theme={null}
echo 1 > /sys/bus/platform/devices/hypervisor:qcom,gh-watchdog/disable
```

## **进入调试模式**

选择以下方法之一暂停内核并激活 KGDB stub。

### 方法 1：kgdbwait（启动时）

当内核命令行中包含 `kgdbwait` 时，内核会在启动期间停止，并在串行控制台上打印以下消息：

```text theme={null}
[    0.239669] printk: console [ttyMSM0] enabled
[    1.541411] KGDB: Registered I/O driver kgdboc
[    2.224804] KGDB: Waiting for connection from remote gdb...
```

在内核继续之前，从主机连接 GDB。

### 方法 2：Magic SysRq（运行时）

在目标设备的 shell 中：

```bash theme={null}
echo g > /proc/sysrq-trigger
```

内核会立即挂起并等待 GDB。

### 方法 3：编译时断点

在驱动源代码中插入硬断点：

```c theme={null}
#include <linux/kgdb.h>
kgdb_breakpoint();   /* kernel breaks here when this line is reached */
```

重新构建并刷写内核。当代码路径执行到该行时断点触发。

### 方法 4：内核 panic（异常驱动）

当发生未处理的异常或 panic 时，内核会自动进入 KGDB 模式。要为测试目的故意触发崩溃：

```bash theme={null}
echo c > /proc/sysrq-trigger   # kernel panic → enters KGDB
```

## **从主机连接 GDB**

在主机上安装 `gdb-multiarch`：

```bash theme={null}
# Debian / Ubuntu
sudo apt install gdb-multiarch

# MSYS2 (Windows)
pacman -S mingw-w64-x86_64-gdb-multiarch
```

### Linux 主机

```bash theme={null}
gdb-multiarch -b 115200 <path_to_vmlinux>
(gdb) target remote /dev/ttyUSB0
```

### Windows 主机

在 Windows 上，请在设备管理器中将 COM 端口号设置为 16 以上，并使用 `\\.\comN` 路径语法：

```text theme={null}
gdb-multiarch.exe -b 115200 <path_to_vmlinux>
(gdb) target remote \\.\com17
```

连接后的预期输出：

```text theme={null}
Remote debugging using \\.\com17
[Switching to Thread -2]
arch_kgdb_breakpoint () at arch/arm64/include/asm/kgdb.h:21
```

## **GDB 调试会话**

### 基本 GDB 命令

**表：GDB 命令参考**

| **命令**                | **描述**                             |
| :-------------------- | :--------------------------------- |
| `bt`                  | 打印当前调用栈的回溯                         |
| `break <function>`    | 在函数起始处设置断点                         |
| `break <file>:<line>` | 在特定源代码行设置断点                        |
| `info break`          | 列出所有当前断点                           |
| `info reg`            | 显示所有 CPU 寄存器                       |
| `x/<n>x <addr>`       | 以十六进制检查地址 `addr` 处的 `n` 个字（word）内存 |
| `p <expression>`      | 打印 C 表达式或变量的值                      |
| `s`                   | 单步执行一行源代码（进入函数调用）                  |
| `n`                   | 执行下一行源代码（跳过函数调用）                   |
| `c`                   | 继续执行，直到下一个断点或中断                    |
| `finish`              | 运行至当前函数返回                          |
| `detach`              | 从目标分离（内核继续运行）                      |

### 加载模块符号

要调试动态加载的内核模块，请从目标设备获取 `.text` 段地址：

```bash theme={null}
# On the target device
cat /sys/module/<module_name>/sections/.text
# Example output: 0xffff800008800000
```

然后在 GDB 中加载符号文件：

```gdb theme={null}
(gdb) add-symbol-file <path_to_module.ko> 0xffff800008800000
```

示例：

```gdb theme={null}
(gdb) add-symbol-file drivers/net/ethernet/my_driver.ko 0xffff800008800000
(gdb) break my_driver_probe
(gdb) c
```

有关完整的上游 KGDB 文档，请参阅 [Debugging kernel and modules via gdb](https://docs.kernel.org/process/debugging/gdb-kernel-debugging.html)。
