声明:
1.本文章在注明引用出处的前提下可以随意引用。
2.因为环境有差异,不能保证在您的机器上可以得到同样的结果。
最近在研究linux module的调试技术,看了一些文章,最后决定采用kgdb来进行调试,两台主机互联,一台跑调试内核,一台跑测试系统。
运行环境:
1.vmware virtual machine 7.1.3 linux edition2.host machine: redhat enterprise linux 6 server edition 3.guest:A. development machine:redhat enterprise linux 6 server editionB. target machine: redhat enterprise linux 6 server editon4.编译内核版本:2.6.32
配置过程:
1.虚拟机安装,这个比较简单,因为使用vmware的,只有编译好的,所以按照最简单的办法,在root帐号下执行./ 执行就可以了。2.安装好以后就可以安装redhat系统。这个系统可以进行快速安装,但是唯一不好的就是这个安装只给/boot目录分类47M的空间,一旦编译内核,安装的时候势必空间是不够的,但是没有什么关系。你可以把/boot目录下的一些文件删除掉。比如initrd*, initram*之类的文件,就有空间了。这个以后再说。让vmware自动安装完了就可以了。3.因为是vmware自动安装的,默认是没有安装gdb的,我个人认为在linux下有虚拟机虚拟linux是最方便不过的了。自己可以搭建个yum本地升级源。然后可以将这个升级源通过共享文件夹,或者是nfs系统之类的进行文件共享那将会非常节省空间,并且也非常方便,当然如果是windows的话,我想也是可以在windows里面把yum的源数据文件搭建起来然后与linux共享了。我是用我host machine中的yum源来安装了gdb.当然以后也可以很方便的安装一些其他的软件,因为自动安装只是将最少的软件装了进去。4.最基本的系统搭建好以后就可以来准备编译内核了。下载2.6.32内核。这个是为了配置方便,直接用系统/boot文件夹下的config文件,版本相同的时候出现异常的风险比较小。编译内核如果简单起来是很容易的。步骤如下
A.make menuconfig
B.make && make module && make module_install
其实很重要的是在于配置.config文件。要注意的是make menuconfig的时候,自动安装的时候缺少一定的库。menuconfig打不开。可以用yum的方法将缺少的库安装进去。
配置的时候保证
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_INFO=y
另外就是保证CONFIG_DEBUG_RODATA不被选上
个人认为最好还是在make menuconfig中进行配置,因为很多配置项是相关的关掉了一些别的一些也会被关掉,如果直接修改.config文件容易漏掉一些。
还有就是有人说要关掉Makefile中的O2优化选项,这个看似是很正确的,不过年轻的人估计都没有那个本领。因为如果关掉了这个在内核编译的时候就会出现一些错误。因为内核里面有些函数是只能在优化选项打开的情况下才会正确编译,如果你想取消优化的话,你可以先修改一下内核的代码。我现在是没有这个能力:-)
然后就是B中的那些命令了。可以直接用&&来进行命令直接的相与操作。然后你可以干点别的事情了。比如说看一下我为什么没有直接把make install也一并加进去。其实我没有加进去是因为我要用clone的方法来产生一样的系统,因为我们调试的时候还是要看代码的。还是需要源文件的支持的,要不然你在一个机器上配置好了,你还的把相同的文件再拷贝的另一台机器的相同的地方。用clone就可以省去这些麻烦。你可以看一下你安装好之后的/lib/modules/$(shell uname -r)/bulid文件夹在哪里。以及source文件夹。这就是跟你编译的时候有关了。
5.上面的做完以后就可以clone一个同样的虚拟主机了。克隆以后就是要进行内核的安装了。其实这个时候就可一把/boot文件夹下的目录里面的原有的内核文件给删除掉了。我们知道这些文件其实都是常驻内存的,从boot开始直至shutdown这个期间我们就算把这些文件删除掉系统也一样运行。删除以后我们可以进行编译的最后一步make install。
6.编译以后就是要看一下新编译的内核是否可以启动了。restart看看结果。如果可以启动,你就可以先庆祝一下了。7.这时候就可以弄一下串口了。vmware下的串口设置是很容易的。
其实就是配置一个有名管道,虽然vmware使用socket来指示的。具体的就是点击配置机器,在器件那个栏目下选中添加串口,vmware这个串口很诡异的,直接就是串口2,不过这个串口对应的/dev目录下的ttyS1,已经分配的串口1应该是给了打印机。vmware是从1-4,而linux是从0-3,自己把握清楚了。然就就是选择socket,接着直接在socket下面那个地方输入一个文件名就可一了。比如/tmp/serial_socket。启动的时候就会产生这个socket文件可以用file命令来查看的。串口设置的另一个问题就是那个client to virtual machine,server to virtual machine的东西。两个机器各用其一就可以了,没有别的限制。只是定义了方向。两个机器都配置完毕以后就可以进行测试了。都进入root模式。都用用stty ispeed 115200 ospeed 115200 -F /dev/ttyS1来进行串口速率的设置。具体的ttyS*要与虚拟机的串口对应好。设置好以后就是看能传数据不能。A主机执行cat /dev/ttyS1 B主机执行echo "hello world">/dev/ttyS1如果A主机可以看到hello world那么恭喜你。要先执行cat等待数据的流入,然后echo。因为如果先echo的话,你是看不到的。我也不知的为什么了。估计是没有缓存了:-)
8.如果你能走到现在这一步其实你已经基本上成功了。我们现在可以直接更改/boot/grub/grub.conf文件了。在你自己编译内核的地方就是那个kernel /boot/vmlinuz-----------------的最后加上ro kgdb=ttyS1,115200 kgdboc=ttyS1,115200 kgdbwait的话,这个是最新的,kgdb, kgdboc两个都要有。并且ttyS1,115200中间不能有空格出现,自己把握了。呵呵。然后我们就可以把这个拥有自己编译内核的主机重启了。应该很快会出现类似kgdb:waiting for remote gdb之类的东西。我们到另外一台主机上面在root模式下,转到编译内核的地方。输入gdb vmlinuz就会启动gdb进行调试了。首先gdb是要载入vmliunz的符号。这个东西太大了,因为有info的缘故。之后就是到了gdb等待输入了。我们要与远程主机进行连接,虽然也就是另一个虚拟机。好输入如下set remotebaude 115200 target remote /dev/ttyS1.这个时候如果不出先问题的话就会出现调试的信息,就是kgdb的断点。gdb等待输入。可以用list命令看一下当前代码哦。9.这个以后的事情就看自己的造化了。基本的通信是完成了。我写了好长时间了。虽然linux下的中文输入法不是很强大,但是现在用多了,也没什么感觉了。输入的速度还是大大的提高了啊。
后记:
本人也是刚开始关注kgdb调试,并且也是第一次写博客。不足之处还请各位见谅。也请各位多多指教。
虚拟机这个东西有时候很怪异。同样的配置我晚上弄到半夜,也没有把串口设置好,但是第二天早上起来直接就可一用了。不得不说这是很恐怖的一件事情。