3. KGDB 环境搭建:内核配置选项与启动参数设置

KGDB 是 Linux 内核源码级调试的核心机制,允许开发者通过串口或网络连接远程 GDB 调试器,对运行中的内核进行断点、单步、变量查看等操作。本章聚焦 KGDB 环境搭建的完整流程,涵盖内核配置选项、串口/网络配置以及启动参数设置,确保调试环境稳定可靠。

前置条件: 调试机(运行 GDB)与目标机(被调试内核)之间需建立物理连接。串口调试推荐使用交叉串口线(Null Modem),网络调试需确保目标机与调试机在同一二层网络或可路由。

3.1 内核配置选项详解

KGDB 功能通过内核编译选项启用,以下为关键配置项及其作用:

配置选项 依赖关系 功能说明
CONFIG_KGDB 无 KGDB 核心支持,必须启用
CONFIG_KGDB_SERIAL_CONSOLE CONFIG_KGDB 通过串口与 GDB 通信,支持中断信号(Ctrl+C)
CONFIG_KGDB_KDB CONFIG_KGDB 启用 KDB 内核调试器,可在无 GDB 时直接调试
CONFIG_KGDB_LOW_LEVEL_TRAP CONFIG_KGDB 捕获早期异常(如 CPU 异常),用于启动阶段调试
CONFIG_KGDB_HONOUR_BLOCKLIST CONFIG_KGDB 遵守内核模块黑名单,避免调试被禁止的模块
CONFIG_MAGIC_SYSRQ 无 启用 SysRq 魔术键,用于触发 KGDB 中断
CONFIG_DEBUG_INFO 无 生成 DWARF 调试符号,GDB 断点/变量查看必需
CONFIG_FRAME_POINTER 无 保留栈帧指针,提升回溯准确性
配置建议: 调试内核时,建议同时启用 CONFIG_DEBUG_INFO 和 CONFIG_FRAME_POINTER,否则 GDB 可能无法正确解析函数调用栈。

3.2 串口配置与网络配置

KGDB 支持两种通信通道:串口(UART)和网络(UDP)。串口配置简单、延迟低,适合早期调试;网络配置灵活、带宽高,适合远程调试。

3.2.1 串口配置

串口调试需指定物理串口设备(如 ttyS0)和波特率。常见配置如下:

# 内核启动参数(GRUB 或 U-Boot)
kgdboc=ttyS0,115200

# 或通过 sysfs 动态设置
echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc

串口连接拓扑:

串口 KGDB 连接拓扑 目标机 Linux 内核 (KGDB) 串口: ttyS0 调试机 GDB (远程调试) 串口: ttyUSB0 交叉串口线 波特率: 115200, 8N1

3.2.2 网络配置

网络调试使用 kgdboe(KGDB over Ethernet),通过 UDP 端口 2159(默认)通信。配置方式:

# 内核启动参数
kgdboe=eth0@192.168.1.100:192.168.1.200@eth0

# 参数格式:<本地网卡>@<本地IP>:<调试机IP>@<调试机网卡>

网络连接拓扑:

网络 KGDB 连接拓扑 目标机 Linux 内核 (KGDB) eth0: 192.168.1.100 交换机/路由器 二层网络 调试机 GDB (远程调试) eth0: 192.168.1.200 UDP 端口: 2159 (默认) 需确保防火墙允许 UDP 2159 双向通信
网络调试注意事项: 网络调试依赖 UDP 协议,丢包可能导致 GDB 会话中断。建议在专用调试网络或低负载环境下使用。若目标机有多个网卡,需在 kgdboe 参数中明确指定。

3.3 启动参数设置

KGDB 的启动参数通过内核命令行传递,常见引导加载器包括 GRUB、U-Boot 和 EFI stub。以下为典型配置:

3.3.1 GRUB 配置(x86/ARM64)

# 编辑 /etc/default/grub
GRUB_CMDLINE_LINUX="kgdboc=ttyS0,115200 kgdbwait nokaslr"

# 更新 GRUB 配置
grub-mkconfig -o /boot/grub/grub.cfg

3.3.2 U-Boot 配置(嵌入式)

# U-Boot 环境变量
setenv bootargs 'console=ttyS0,115200 kgdboc=ttyS0,115200 kgdbwait nokaslr'
bootm 0x82000000

3.3.3 关键启动参数说明

参数 作用 推荐场景
kgdboc=<device>,<baud> 指定串口设备和波特率 串口调试
kgdboe=<iface>@<ip>:<debug_ip> 指定网络接口和 IP 网络调试
kgdbwait 内核启动后立即等待 GDB 连接 早期启动阶段调试
nokaslr 禁用内核地址空间布局随机化 确保断点地址稳定
kgdbcon 将内核日志输出到 KGDB 通道 调试时查看内核打印
kgdb_earlycon 早期控制台支持(需内核 4.10+) 极早期启动调试
调试技巧: 使用 kgdbwait 时,目标机启动后会暂停在 KGDB 入口,等待调试机执行 gdb vmlinux 并输入 target remote /dev/ttyUSB0(串口)或 target remote 192.168.1.100:2159(网络)建立连接。

3.4 动态启用与切换

KGDB 支持运行时动态启用,无需重启内核。通过 sysfs 接口可随时切换调试通道:

# 动态启用串口 KGDB
echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc

# 动态启用网络 KGDB
echo eth0@192.168.1.100:192.168.1.200 > /sys/module/kgdboe/parameters/kgdboe

# 触发 KGDB 中断(需 SysRq 支持)
echo g > /proc/sysrq-trigger
动态切换限制: 串口和网络通道不能同时激活。切换前需确保当前通道已释放,否则可能导致内核崩溃。

3.5 环境验证流程

搭建完成后,通过以下步骤验证 KGDB 环境是否正常工作:

  1. 检查内核配置: 确认 /proc/config.gz 或 /boot/config-$(uname -r) 中包含 CONFIG_KGDB=y 和 CONFIG_KGDB_SERIAL_CONSOLE=y。
  2. 确认调试符号: 编译内核时生成的 vmlinux 文件应包含 DWARF 调试信息(file vmlinux | grep -i dwarf)。
  3. 测试串口/网络连通性: 调试机使用 minicom 或 screen 连接目标机串口,或使用 nc -u 192.168.1.100 2159 测试 UDP 端口。
  4. 启动 GDB 会话: 在调试机执行 gdb vmlinux,输入 target remote /dev/ttyUSB0(串口)或 target remote 192.168.1.100:2159(网络),观察是否成功连接。
  5. 设置断点并继续: 在 GDB 中设置断点(如 b start_kernel),输入 c 继续执行,验证断点是否命中。
KGDB 环境验证流程 检查内核配置 CONFIG_KGDB=y 确认调试符号 vmlinux + DWARF 测试连通性 串口/UDP GDB 连接 设置断点并继续 b start_kernel; c 若断点命中,说明 KGDB 环境搭建成功 若连接失败,检查串口线/网络防火墙/内核参数
常见问题排查:
  • 连接超时: 检查串口线是否为交叉线,或网络防火墙是否放行 UDP 2159。
  • 断点无法命中: 确认 nokaslr 已启用,且 vmlinux 与运行内核版本一致。
  • GDB 报错 "Remote 'g' packet reply is too long": 通常因架构不匹配,需在 GDB 中执行 set architecture i386:x86-64(x86_64 架构)。