从2.6.26开始,Linux 主干内核开始内置了代码级调试器 kgdb。通过 kgdb,可以在内核代码中设置断点,单步调试和观察变量。为了使用 kgdb,需要有两个系统。一个作为上位机,一个作为下位机(目标机)。两台机器通过串口线连接。需要调试的内核运行在下位机上。串口线用于kgdb连接远程目标板。
内核配置
使用KGDB之前,需要在内核中将KGDB配置下:
Kernel hacking --->
[*] Kernel debugging
[*] Compile the kernel with debug info
[*] KGDB: kernel debugger --->
<*> KGDB: use kgdb over the serial console
编译出内核之后,我们给上位机使用的是ELF格式的内核vmlinux,可以通过如下命令查看内核是否提供调试信息支持。
$../arm-eabi-4.4.3/bin/arm-eabi-readelf -S ./vmlinux | grep debug
[17] .debug_line PROGBITS 00000000 4d4a3b 229041 00 0 0 1
[18] .debug_info PROGBITS 00000000 6fda7c 1f8538f 00 0 0 1
[19] .debug_abbrev PROGBITS 00000000 2682e0b 10eead 00 0 0 1
[20] .debug_aranges PROGBITS 00000000 2791cb8 009b50 00 0 0 8
[21] .debug_pubnames PROGBITS 00000000 279b808 031751 00 0 0 1
[22] .debug_str PROGBITS 00000000 27ccf59 11fc28 01 MS 0 0 1
[23] .debug_frame PROGBITS 00000000 28ecb84 07e470 00 0 0 4
[24] .debug_loc PROGBITS 00000000 296aff4 26e872 00 0 0 1
[25] .debug_ranges PROGBITS 00000000 2bd9868 0c8368 00 0 0 8
同时要对对i.MX内核UART驱动代码修改:
static struct uart_ops mxc_ops = {
...
#ifdef CONFIG_CONSOLE_POLL
.poll_put_char = mxcuart_poll_put_char,
.poll_get_char = mxcuart_poll_get_char,
#endif
}
主要实现struct uart_ops 中的poll_get_char,pool_put_char这两个成员。实现KGDB所需的poll功能。
如何使用KGDB调试内核
使用之前解释两个三个参数
kgdboc:[KGDB,HW] kgdb over consoles.
Requires a tty driver that supports console polling,or a supported polling keyboard driver (non-usb).
Serial only format: [,baud]
keyboard only format: kbd
keyboard and serial format: kbd,[,baud]
kgdbwait: [KGDB] Stop kernel execution and enter the kernel debugger at the earliest opportunity.
kgdbcon: share console serial port with KGDB
上面的参数通过bootargs传递给内核,启动相应的功能。
(1) .内核初始化时进入gdb调试模式
驱动程序在内核启动的时候,要做很多初始化动作,这个时候可以利用GDB参与调试。
console=ttymxc