VirtualBox+linux虚拟机+KGDB

说明1:在目标机上配置和编译内核,然后将编译内核的源代码整个目录(内含vmlinux文件)通过网口传到开发机的/usr/src目录(如scp命令等),开发机可以进入这个目录执行gdb ./vmlinux进行调试。

说明2:在目标机编译的内核模块,需要将代码、ko文件,拷贝到开发机的vmlinux目录下,使模块代码、模块ko、vmlinux在同一个目录下,否则会出现“******.ko: 没有那个文件或目录.”的错误。

说明3:如果你要在开发机上开发内核模块,建议使开发机和目标机的内核版本一致(否则可能会存在开发机编译的内核模块在目标机上insmod时,因内核版本不一致报“disagrees about version of symbol module_layout”的错误),此时不需要拷贝开发机的模块代码到目标机,只需要拷贝块ko即可。

说明4:请参考《http://blog.csdn.net/jie12310/article/details/4564853》,此文是目前最客观和详细的。

我的开发机和目标机的内核版本不一致,开发机的内核是:Linux xumin-VirtualBox 3.2.0-23-generic-pae #36-Ubuntu SMP Tue Apr 10 22:19:09 UTC 2012 i686 i686 i386 GNU/Linux,目标机的内核是:Linux xumin-VirtualBox 3.2.63.ubuntu.xumin.001 #6 SMP Wed Feb 4 16:35:36 CST 2015 i686 i686 i386 GNU/Linux。因此我是在目标机编译好内核模块,然后拷贝到开发机。在实测中,我在开发机编译的内核模块,拷贝到目标机中进行insmod时,出现过“disagrees about version of symbol module_layout”的错误。如果你的开发机和目标机内核版本不一致,建议在目标机上开发模块,然后将开发的模块ko及其代码通过scp命令拷贝到开发机的vmlinux所在的目录。无论怎样,我还是建议使两者内核版本一致!

一、在virtualbox下创建一个虚拟机,作为开发机,以此开发机再Clone另一个虚拟机,作为目标机。

https://ryantrotz.com/2011/12/virtualbox-snapshots-and-vmis/

二、在开发机和目标机之间建立联系通道,如串口/网口等(一般不采用网口,怕调试的代码影响到了网口驱动的功能),以便开发机能控制目标机。

两台虚拟机间的通信可以通过利用主机的命名管道来完成。原理可以简单的这样描述:一台虚拟机在主机中创建的命名管道并其串口相连,另外一台虚拟机也将自己的串口连到主机的命名管道上,这样两个虚拟机的串口就能连起来了。这里两台虚拟机都使用各自的COM1端口,主机的命名管道为同一管道\\.\pipe\com1_115200,在配置时一台创建通道(一般在开发机上创建),另一台不创建(但需要打开!)。启动时先启动创建通道的虚拟机,然后启动另一台虚拟机,分别打开两台虚拟机的终端,通过如下命令将各自的COM1口的输入输出波特率都设为115200: stty ispeed 115200 ospeed 115200 -F /dev/ttyS0 测试过程:

在其中一台虚拟机A终端上执行

cat /dev/ttyS0

在另一台虚拟机B上执行 echo ok > /dev/ttyS0 这时虚拟机A的终端会接受到B发来的ok消息。

三、配置及编译目标机内核,修改目标机的引导文件/etc/default/grub文件:

#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" GRUB_CMDLINE_LINUX_DEFAULT="quiet splash kgdboc=ttyS0,115200 kgdbwait"

详细的KGDB相关配置选项参考: http://blog.chinaunix.net/uid-27717694-id-4051339.html

编译内核参考本博客: http://blog.csdn.net/xumin330774233/article/details/40371603

四、在开发机上,拷贝目标机整个源代码目录(内含vmlinux)到开发机/usr/src目录

cd /usr/src

scp -r 目标机用户名@目标机ip地址:目标机编译内核的整个源代码目录 . //使用scp命令,请先配置开发机/目标机的网络为桥接方式。

五、重启目标机

你会发现这样的界面:

六、在开发机上调试vmlinux

cd /usr/src

gdb ./vmlinux

(gdb)set remotebaud 115200

(gdb)target remote /dev/ttyS0

七、调试内核模块

目标机:

1、insmod 模块.ko

2、cat /sys/module/模块/divs/.text //得到模块代码段地址

3、echo g > /proc/sysrq-trigger

开发机:

0、拷贝目标机的模块.ko及模块代码到vmlinux文件所在目录

1、add-symbol-file 模块.ko模块代码段地址

2、b 模块中的函数名

注意:因在模块insmod之前,开发机无法获取到模块的代码段地址信息,因此,暂不能通过上述方法调试模块的init函数。(网上流行的先卸载后再安装的方法,是错误的。因为下次在目标机安装这个模块时,模块的代码段地址已经变了,而前面在开发机gdb中设置的init函数断点,已经失效!)

八、其他小点:

1、echo g > /proc/sysrq-trigger //系统会中断,进入假死状态,等待远程gdb的连接,直到远程GDB连接后并发送continue命令后才退出假死状态。

2、vim ~/.bashrc 加上alias debug-kernel=’echo g > /proc/sysrq-trigger’,source ~/.bashrc,以后使用debug-kernel命令使系统假死。

自信是一个人的胆,有了这个胆,你就会所向披靡!

VirtualBox+linux虚拟机+KGDB

相关文章:

你感兴趣的文章:

标签云: