概要:使用kgdb调试内核需要两台机器,为方便叙述,我们称一个为target,一个为develop。kgdb的调试过程是在target端使用魔法键让本机处于假死状态,然后develop端通过串口连到target端,进行调试。我们可以编译好develop,然后使用vmware的clone功能clone一个虚拟机作为target。
(一)使用环境
虚拟机 Workstation 10.0
(二)编译内核
1、下载最新linux内核源码。地址 http://www.kernel.org/;我下载的是 linux-3.13.6的版本,其他版本方法类似
2、解压下载的源码。源码放在哪个目录都能编,为了方便叙述,在/usr/src下创建一个目录叫做linux-kgdb,将源码cp到该目录下,然后解压。
3、配置内核。linux-3.13.6的默认配置包含了调试内核的大多数选项,仅需要去掉一个选项(Writeprotect kernel read-only data structures),该选项设置了某些内存区域为只读,需要去掉,否则可能无法设置断点。
配置内核命令:make menuconfig 。这里可能会遇到一个错误,说某个库,然后建议你install一个库,然后try again。我想在ubuntu下编过内核的朋友都遇到过这个问题。此时就升级该库。
升级库的命令:sudo apt-get insatll ncurses-dev
需要去掉一项:Writeprotect kernel read-only data structures(选住该项,然后敲n)
4、保存退出编译内核
按住tab键,选中exit,保存退出
5、制作内核镜像
这里可以选择的方法不止一种,我所使用的方法可能是比较笨的。顺序如下
make //编译内核源码,这个过程会很长
make_modules //编译内核模块
make_moduesl install //安装模块
make install //安装内核
6、修改内核的启动参数。
在修改grub.cfg的修改曾阅读过很多资料,但在grub.cfg这一步都做得稍显罗嗦,笔者暂未领会其意图。
编辑 /boot/grup/grub.cfg
注意光标所在那一行。在后面添加一句 kgdboc=1,9600。改完的结果图所示。
kgdboc=1,9600的意思是 kgdb over console。console使用ttyS1,波特率为9600。如果次是你要调试开机过程的话,可以加上kgdbwait选项。
至此我们编译内核部分的工作就完成了。接下来要做的就是clone一个虚拟机,然后将它们之间用vmware提供的虚拟串口连接起来。这里我想如果是实机的话,可能就需要用串口线将两台机器连接起来。
(三)clone虚拟机
(1)、关闭虚拟机,并制作一个clone。
关闭虚拟机后,选择虚拟机-->管理-->clone-->下一步-->虚拟机的当前状态-->创建完整的clone
(2)、设置develop和target的串口
待clone完成以后,分别设置两台虚拟机的串口
develop端:编辑此虚拟机设置-->硬件-->添加-->串行端口-->下一步-->输出到命令管道-->完成
target端:编辑此虚拟机设置-->硬件-->添加-->串行端口-->下一步-->输出到命令管道-->该端是客户端(在下拉框中心选择)-->完成
(3)、启动虚拟机检查串口是否设置成功。
这里要非常注意的一点是,在ubuntu下ttyS0被占用了,我们要使用ttyS1。这一点和suse并不相同。笔者曾在suse下成功搭建kgdb环境,后来在ubuntu下搭建卡壳卡了很久,就在于此。另外还有一点需要注意的是,在suse下使用的串口通信的波特率是115200,但在ubuntu下使用的串口的波特率是9600。
在devlop端执行 cat /dev/ttyS1
在target 端执行 echo aa > /dev/ttyS1
如果在develop端看到aa,说明串口通了。当然为确保万无一失,在target端执行cat命令,在develop端执行echo 命令再次是一次。在两端都执行成功才能使kgdb。
ok!如果串口已经调试成功,那么我们就可以进行调试了
(四)测试gdb调试环境是否搭建成功
1、在target端执行echo g > /proc/sysrq
然后target进入假死状态,就是敲任何键都无反应。如果target没有进入假死状态,则需要检查内核启动参数是否设置正确。
2、在develop端执行gdb vmlinux (vmlinux,是我们刚刚编译内核生成的,位于/usr/src/linux-kgdb/linux-3.13.6目录下)
3、gdb启动后,执行下列命令
set remotebaud 9600
target remote /dev/ttyS1
如果次是你看到下面的打印结果的话,说明gdb环境已经搭建成功,那就给自己倒一杯咖啡庆祝下吧!
(五)后记
1、本文中所有命令均使用root权限执行
2、搭建kgdb最初的需求是为了看内核代码,而非调试使用。笔者经常使用gdb来调试用户态程序,阅读代码等。因此想阅读内核代码的时候,自然想到了搭建kgdb调试环境。
3、曾在CSDN上两篇文章使用kgdb + qemu来调试。笔者按照其方法来实验,但未成功,以内CPU不支持虚拟化。但笔者的CPU实际是支持虚拟化的。后来某高人告知,因为我使用的虚拟机,虚拟机已经使用了CPU的虚拟化功能,而其写文章的作者可能使用的实际的机器,所以还可以使用其CPU的虚拟化功能
4、在网上看到一些资料说搭建kgdb环境要修改Makefile,将代码优化级别调低,否则可能无法设置断点。笔者暂未遇到此问题,但希望大家注意。如果笔者在使用过程中遇到此问题,第一时间上来更新。如有朋友遇到过这个问题也请告知我。
5、笔者在搭建kgdb环境过程中网上找到了很多资料,在此真诚感谢每一位作者。
6、本文难免有不足甚至是错误的地方,如果发现请提醒我改正,以免误导他人。谢谢!!
参考资料:
1、http://blog.chinaunix.net/uid-25819644-id-4081100.html
2、http://www.kgdb.info/
3、http://blog.csdn.net/fantasy_wxe/article/details/17175525