准备条件
GDB调试Linux内核需要准备两台机器,目标机器上需要支持kernel debug (KGDB),调试机器上运行GDB,同时调试机器上需要有带符号表的vmlinux
这里用的两台机器都是CentOS虚拟机,跑在VirtualBox里面,两台机器之间需要支持串口通信,具体可以参考 VirtualBox虚拟机串口通信-CSDN博客
调试需要符号表,这里选择从源码开始编译带符号表的linux内核。
在目标机器上执行如下操作,重新编译安装linux内核。
1. 安装依赖库
sudo dnf install gcc make elfutils-libelf-devel openssl-devel bc flex bison
2. 源码下载
从linux内核网站下载: The Linux Kernel Archives
这里使用的是5.10.216 版本 linux-5.10.216.tar.xz
2. 内核配置
解压以后,进入源码目录,执行 make menuconfig 进行内核配置,主要的配置项有:
To use KGDB, it is necessary to build the kernel with a few configuration options enabled:
- CONFIG_KGDB: this is the main option to enable KGDB support.
- CONFIG_KGDB_SERIAL_CONSOLE: enables the KGDB serial port driver.
- CONFIG_KDB_KEYBOARD: enable keyboard support for the Kernel Debugger (KDB)
- CONFIG_MAGIC_SYSRQ: enables the Magic SysRq key feature, used to enter the kernel debugger (i.e. start KGDB).
- CONFIG_DEBUG_INFO: compiles the kernel with debugging symbols.
- CONFIG_FRAME_POINTER: frame pointers improve the debugging experience (this option is usually enabled by default if supported by the architecture).
Also, it is recommended to disable a few configuration options:
- CONFIG_DEBUG_INFO_REDUCED: this should be disabled so debugging information for structure types is generated in the kernel ELF image.
- CONFIG_RANDOMIZE_BASE: if the architecture you are working on supports KASLR (Kernel Address Space Layout Randomization), you might want to disable this option. KASLR is a feature that enhances security by randomizing the memory address layout of the kernel but can affect the debugging experience. Alternatively, you can also pass nokaslr as a boot parameter to the Linux kernel.
配置完成后会在当前目录生成.config配置文件。
3. 编译安装
执行:
make
make modules_install
make install
完成以后会在当前源码目录生成vmlinux,通过命令 file vmlinux 查看已经包含符号表:
[root@localhost linux-5.10.216]# file vmlinux
vmlinux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=b25953d1bc5ee29de5b6a86c1d56f21ddfccea11, with debug_info, not stripped
同时,在/boot目录下已经生成vmlinuz
4. 更新引导管理器
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
5. 系统重启
6. 目标机器KGDB设置
有两种方式:
1) 启动阶段就开启debug模式,有两种方法。
第一种方法,在系统启动显示Grub菜单时通过按键e进入grub设置,例如添加下面的配置:
kgdboc=ttyS0,115200 kgdbwait
第二种方法:直接修改/etc/default/grub
比如
GRUB_CMDLINE_LINUX="... kgdboc=ttyS0,115200 kgdbwait ..."
改完之后需要更新grub引导:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
2)运行阶段开启debug模式,这里采用的是这种模式。
这种模式分两步:
第一步:
运行时Enable kgdboc on ttyS0:
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
运行时Disable kgdboc: echo "" > /sys/module/kgdboc/parameters/kgdboc
第二步:
echo g > /proc/sysrq-trigger
7. 调试机器GDB远程调试
将目标机器上源码目录编译以后的vmlinux 传到调试机器上,在调试机器上执行:
gdb vmlinux
然后:
(gdb) set serial baud 115200
(gdb) target remote /dev/ttyS0
此时可以开启调试。
参考:
Debugging the Linux kernel with GDB - sergioprado.blog
Using kgdb, kdb and the kernel debugger internals — The Linux Kernel documentation