BruceFan's Blog

Stay hungry, stay foolish

0%

VirtualBox上调试Linux Kernel

之前写过用VMware调试Linux Kernel,今天又尝试了一下VirtualBox+gdb的组合。

环境搭建

我的环境,主机:Ubuntu14.04
虚拟机:VirtualBox5.1
客户机:Ubuntu12.04.5 x64
1.首先在VirtualBox上安装客户机
编译安装linux-3.13内核(一般是将源码放到/usr/src中):

1
2
3
4
5
$ sudo apt-get install libncurses5-dev
$ make menuconfig
$ make
$ sudo make install modules_install
$ sudo make install

这里我把编译过的内核源码用tar压缩后,通过共享文件夹(需要安装增强工具)拷贝到主机上再解压,这样就可以进行源码级调试了。
2.安装后关闭客户机,启用串口:

3.启用客户机KGDB:
这里有两种方法,一是在内核启动项中添加参数:

1
kgdboc=ttyS0,115200

或者是在启动内核后执行:

1
# echo ttyS0,115200 > /sys/module/kgdboc/parameters/kgdboc

建议使用第一种,要不每次开机都得输入命令。修改方法是编辑/boot/grub/grub.cfg,在启动的内核项加上参数即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# vim /boot/grub/grub.cfg
==================================================
...
set defualt="2" # 将启动项修改为刚刚编译安装的内核(从0开始,第2个menuentry)
...
submenu "Previous Linux versions" {
menuentry 'Ubuntu, with Linux 3.13.0' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 294b8f76-001b-4367-bead-3053c38b2578
linux /boot/vmlinuz-3.13.0 root=UUID=294b8f76-001b-4367-bead-3053c38b2578 ro quiet splash $vt_handoff kgdboc=ttyS0,115200 # 添加内核启动参数
initrd /boot/initrd.img-3.13.0
}
==================================================

3.客户机上执行:

1
# echo g > /proc/sysrq-trigger

4.主机连接到客户机:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cd linux-3.13
$ socat -d -d /tmp/serial pty &
[1] 7907
2017/07/01 11:56:40 socat[7907] N opening connection to AF=1 "/tmp/serial"
2017/07/01 11:56:40 socat[7907] N successfully connected from local address AF=1 ":\xAD\xEE\x7E"
2017/07/01 11:56:40 socat[7907] N successfully connected via <anon>
2017/07/01 11:56:40 socat[7907] N PTY is /dev/pts/4
2017/07/01 11:56:40 socat[7907] N starting data transfer loop with FDs [3,3] and [4,4]
$ gdb vmlinux
(gdb) target remote /dev/pts/4
Remote debugging using /dev/pts/4
kgdb_breakpoint () at kernel/debug/debug_core.c:1042
1042 wmb(); /* Sync point after breakpoint */
(gdb)

gdb中c继续执行内核,客户机上# echo g > /proc/sysrq-trigger暂停执行。接下来就可以随意调试了!
reference
Debug a running kernel module with GDB and VirtualBox
Debugging the Linux kernel
Debugging the linux kernel using kgdb and VirtualBox