VMware环境下用kgdb调试内核

VMware环境下用kgdb调试内核
2007-08-12 16:07

一、kgdb安装

1. 系统配置:
VMware Workstation 5.5.4
Fedora Core 3(2.6.9-1.667)
kgdb-2.4(linux-2.6.15.5)

2. 系统安装:
在虚拟机上安装FC3,然后参照后面的文章,将系统的内核升级到2.6.15.5,命名为“FC3-kgdb-client”。Clone一个和预装环境一样的系统,选择"Create a full clone",命名为“FC3-kgdb-server”。
分别为两个系统增加一个串口,以"Output to named pipe"方式,其中:
client端选择"this end is the client", "the other end is a virtual machine"
Server端选择"this end is the server", "the other end is a virtual machine"
这里解释一下client和server的区别:
client(development machine):即开发机,用于输入命令(例如设置断点)控制target machine的运行。
server(target machine):也就是被调试的机器了,其运行受到development machine命令的控制。

3. 文件下载:
进入client系统,从网上下载如下源文件。(之所以选择2.6.15.5版本内核,是因为kgdb的patch目前最高只能支持到这个版本)
linux kernel
http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.15.5.tar.gz
kgdb patch
http://kgdb.linsyssoft.com/downloads/kgdb-2/linux-2.6.15.5-kgdb-2.4.tar.bz2

4. 安装过程:
解压缩各个包,假设最终kernel和patch的路径如下:
/usr/src/linux
/usr/src/linux-2.6.15.5-kgdb-2.4

为内核打上kgdb的支持补丁(具体可以参考patch中README,选择需要得patch):
#cd /usr/src/linux
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/core-lite.patch
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/i386-lite.patch
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/8250.patch
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/eth.patch
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/i386.patch
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/core.patch
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/module.patch
#patch -p1 < ../linux-2.6.15.5-kgdb-2.4/sysrq_bugfix.patch

按正常编译内核流程,进入make menuconfig阶段,除了选择支持vmware中内核编译必须的选项,还需要加上如下内容:

VMware环境下用kgdb调试内核_第1张图片

最关键的一条,就是:
Serial port number for KGDB,默认选项是1,需要改为0。

接下来“make bzImage”,等着完成。

下面要做的工作就相对简单一点:
将/usr/src/linux/arch/i386/boot/bzImage和/usr/src/linux/System.map复制到server上,这里使用scp命令复制,假设server的ip是192.168.6.13:
#scp arch/i386/boot/bzImage [email protected]:/boot/vmlinuz-2.6.15.5-kgdb
#scp System.map [email protected]:/boot/System.map-2.6.15.5-kgdb

在server上创建symbolic链接:
#ln -s /boot/vmlinuz-2.6.15.5-kgdb /boot/vmlinuz
#ln -s /boot/System.map-2.6.15.5-kgdb /boot/System.map

下面就该修改启动项啦:
#vim /boot/grub/grub.conf
给大家做个参考吧:
default=1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Fedora Core (2.6.15.5-kgdb)
          root (hd0,0)
          kernel /boot/vmlinuz-2.6.15.5-kgdb ro root=/dev/hda1 kgdbwait kgdb8250=0,115200
title Fedora Core (2.6.15.5)
          root (hd0,0)
          kernel /boot/vmlinuz-2.6.15.5-secos ro root=LABEL=/ rhgb quiet
          initrd /boot/initrd-2.6.15.5-secos.img
title Fedora Core (2.6.9-1.667)
          root (hd0,0)
          kernel /boot/vmlinuz-2.6.9-1.667 ro root=LABEL=/ rhgb quiet
          initrd /boot/initrd-2.6.9-1.667.img

OK, reboot重启吧。

系统引导到
"Uncompressing Linux... OK, booting the kernel."
所有的资料上都说看到
"Waiting for connection from remote gdb..."
才是等待调试状态,我的安装完之后可以看到这句话。当然也有可能只看到前面一句,我把这个版本的kgdb移植到2.6.20上就只显示前面一句话,不过可以用client正常连接。

就可以用client去连接了,在client上:
#cd /usr/src/linux
#gdb ./vmlinux
GNU gdb Red Hat Linux (6.0post-0.20040223.17rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.         Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
breakpoint () at kernel/kgdb.c:1212
1212                   atomic_set(&kgdb_setting_breakpoint, 0);
warning: shared library handler failed to enable breakpoint
(gdb)

上面“1212 atomic_set(&kgdb_setting_breakpoint, 0);”这一行表明已经连接上了。

二、启动过程中的问题:

1. VFS: Unable to mount root fs on unknown-block(3,1)
错误如下:
------------------------------------------------------------------------------
No filesystem could mount root, tried:    iso9660
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(3,1)
------------------------------------------------------------------------------
解决方法:将“Second extended fs support”和下面ext2和ext3相关选项都编入内核。
File systems->
<*> Second extended fs support
[*] Ext2 extended attributes
[*] Ext2 POSIX Access Control Lists
[*] Ext2 Security Labels
[*] Ext2 execute in place support
<M> Ext3 journalling file system support
[*] Ext2 extended attributes
[*] Ext2 POSIX Access Control Lists
[*] Ext2 Security Labels

2.Warning: unable to open an initial console.
解决方法:在2.6.13之前,将“dev file system support”编入内核
File systems->Pseudo filesystems->
[*] dev file system support
2.6.13之后,需要生成“initrd”,在client端:
#mkinitrd /boot/initrd-2.6.15.5-kgdb 2.6.15.5
注意:上面命令最后2.6.15.5指的是“/lib/modules/2.6.15”这个目录,如果上面这个命令出错,你查看一下是否有这个目录。
上面命令将在/boot下面生成initrd-2.6.15.5-kgdb这个文件,将其复制到server端:
#scp /boot/initrd-2.6.15.5-kgdb [email protected]:/boot/ initrd-2.6.15.5-kgdb

修改grub.conf,在“kernel /boot/vmlinuz-2.6.15.5-kgdb ro root=/dev/hda1 kgdbwait kgdb8250=0,115200”这行下面添加“initrd /boot/initrd-2.6.15.5-kgdb”

三、模块调试

1. gdbmod
首先按上面过程配置好kgdb环境。从kgdb的网站下载gdbmod-2.4,将其改名为gdbmod,然后添加x属性,复制到/bin目录。
#mv gdbmod-2.4 gdbmod
#chmod +x gdbmod
#cp gdbmod /bin

2.编写内核模块和makefile

在client机器上,写了个测试用的内核模块orig,如下:

orig.c
------------------------------------------------
void xcspy_func()
{
      printk("<1>xcspy_func/n");
      printk("<1>aaaaaaaaaaa/n");
}

int xcspy_init()
{
      printk("<1>xcspy_init_module/n");
        
      return 0;
}

void xcspy_exit()
{
      printk("<1>xcspy_cleanup_module/n");
}

module_init(xcspy_init);
module_exit(xcspy_exit);
------------------------------------------------

Makefile
------------------------------------------------
# Comment/uncomment the following line to disable/enable debugging
DEBUG = y


# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
    DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
else
    DEBFLAGS = -O2
endif

CFLAGS += $(DEBFLAGS)
CFLAGS += -I$(LDDINC)

ifneq ($(KERNELRELEASE),)
# call from kernel build system

obj-m := orig.o

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD         := $(shell pwd)

modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules

endif


clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

depend .depend dep:
$(CC) $(CFLAGS) -M *.c > .depend


ifeq (.depend,$(wildcard .depend))
include .depend
endif
------------------------------------------------

#make
#scp orig.ko [email protected]:/root

3.开始调试

在client机上:
#cd /usr/src/linux
# gdbmod vmlinux
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.    Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0

设置符号文件的搜索路径(注意:orig后面不能有空格,有空格的话,会搜不到符号,大家都喜欢用tab键,而tab键会自动加空格,一定要记住把空格去掉)
(gdb) set solib-search-path /root/orig

这时在server机器上执行insmod orig.ko,如果正常,在client机上将显示共享库已经加载。

接下来的过程就和用gdb调试应用程序差不多了,大家可以参照gdb user manual。

vmware + kgdb + linux2.6.15内核调试配置

参考文献:
《vmware + kgdb + linux2.6.15内核调试配置》
《Linux 系统内核的调试》
《KGDB Quick Start》
《使用kgdb调试linux内核及内核模块》
《在VmWare Workstation中编译Linux 2.6.20内核》
《RedHat9.0内核升级(从2.4.20-8到2.6.18)》
《RHEL4内核升级(从2.6.9-42.EL到2.6.20.4)》

 

你可能感兴趣的:(VMware环境下用kgdb调试内核)