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
串口连接拓扑:
3.2.2 网络配置
网络调试使用 kgdboe(KGDB over Ethernet),通过 UDP 端口 2159(默认)通信。配置方式:
# 内核启动参数
kgdboe=eth0@192.168.1.100:192.168.1.200@eth0
# 参数格式:<本地网卡>@<本地IP>:<调试机IP>@<调试机网卡>
网络连接拓扑:
网络调试注意事项: 网络调试依赖 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 环境是否正常工作:
- 检查内核配置: 确认
/proc/config.gz或/boot/config-$(uname -r)中包含CONFIG_KGDB=y和CONFIG_KGDB_SERIAL_CONSOLE=y。 - 确认调试符号: 编译内核时生成的
vmlinux文件应包含 DWARF 调试信息(file vmlinux | grep -i dwarf)。 - 测试串口/网络连通性: 调试机使用
minicom或screen连接目标机串口,或使用nc -u 192.168.1.100 2159测试 UDP 端口。 - 启动 GDB 会话: 在调试机执行
gdb vmlinux,输入target remote /dev/ttyUSB0(串口)或target remote 192.168.1.100:2159(网络),观察是否成功连接。 - 设置断点并继续: 在 GDB 中设置断点(如
b start_kernel),输入c继续执行,验证断点是否命中。
常见问题排查:
- 连接超时: 检查串口线是否为交叉线,或网络防火墙是否放行 UDP 2159。
- 断点无法命中: 确认
nokaslr已启用,且vmlinux与运行内核版本一致。 - GDB 报错 "Remote 'g' packet reply is too long": 通常因架构不匹配,需在 GDB 中执行
set architecture i386:x86-64(x86_64 架构)。