1.准备工具
实现linux2.6.15的调试,需要Vmware workstation9(也可以是其它版本,只要能实现串口通信和虚拟机clone);操作系统选择一个比较简单、比较老的版本就好(新版本对内存要求比较高!);kdgd的补丁;linux2.6.15的内核源代码。
2 创建两台虚拟机,并实现串口通信
vmware workstation安装虚拟机就不赘述,创建串口的的过程:
打开虚拟机属性,点击Add,点击Serial port,然后创建Output to named pipe
第一台虚拟机作为调试机器,它负责调试代码,第二台虚拟机只负责运行linux2.6.15的内核
所以,第一台机器的第一个选项选择“This end is client”
第一台虚拟机创建完毕之后,右键点击第一台虚拟机(我命名为client),在manager里面有一个clone选项,创建一个full clone
依照上面的方法新建一个串口,设置第一个选项“This end is the server”(两个串口的名字是一样的,都为\\.\pipe\com_1)
以root身份登录两台虚拟机的终端,在第一台虚拟机(client)输入cat /dev/ttyS1,在第二虚拟机输入echo CSDN >/dev/ttyS1
这时client虚拟机终端会显示CSDN (有些教程上用ttyS0,但我的调不通,换ttyS1毫无压力)
3 在第一个虚拟机(client),给linux2.6.15的内核打补丁,然后编译2.6.15的内核
将下图中中间两个包包拷贝到第一台虚拟机的/usr/src目录,然后用tar解压
进入linux2.6.15目录,依次打上如下补丁(按照顺序打)
patch -p1 <../linux-2.6.15-kgdb-2.4/core-lite.patch
patch -p1 <../linux-2.6.15-kgdb-2.4/i386-lite.patch
patch -p1 <../linux-2.6.15-kgdb-2.4/8250.patch
patch -p1 <../linux-2.6.15-kgdb-2.4/eth.patch
patch -p1 <../linux-2.6.15-kgdb-2.4/i386.patch
patch -p1 <../linux-2.6.15-kgdb-2.4/core.patch
然后修改makefile
第二行原先为CLFAGS += -Os ,修改为-O
之后在终端输入make menuconfig,第一次运行的时候可能提示缺少某些包,这个时候输入yum install XXXX(XXXX为缺少的包)进行安装就可以了!
进入kernel hacking
将KGDB::kernel debugging with remote gdb
KGDB::Console messages through gdb选上
记住串口的波特率为115200 ,串口端口为1 (有的教程说这个串口要设置为0,其实不设也是可以的)
最后make bzImage && make modules等待内核编译完毕
4 对第二台虚拟机的操作
在第一台虚拟机中,如果内核已编译完毕,将/usr/src/linux2.6.15/arch/boot/bzImage和/usr/src/linux2.6.15/Systemp.map拷贝到第二台虚拟机。可以用scp命令拷贝,我直接用U盘拷的,进入第一台虚拟机,插入U盘,将文件拷入,卸载U盘! 进入第二台虚拟机,插入U盘,将这两文件拷入(我拷到我的主目录/home/gehencai)。然后以root身份登录到终端,将这两文件拷贝到/boot,并重命名(不重命名也可以,不过修改grub.conf时要注意对应),命令如下:
cp /home/gehencai/bzImage /boot/vmlinuz-2.6.15
cp /home/gehencai/System.map /boot/System.map-2.6.15
之后修改启动文件/boot/grub/grub.conf
第19~22行是拷贝的14~17行(在vim的命令模式下在第14行4yy,然后到19行p便可以实现复制)
将21行修改如上,并在22行打上#进行注释!!!root=/dev/sda2(如果不确定系统中是否有sda2,可以ls /dev去看看!!!)
kdgb8250=1,115200 后面的两参数就是make menuconfg中的那两个参数,前面是端口号,如果是0就写0(我的为默认值1);后面是串口波特率。
5 开始调试
在第二台机器终端上输入reboot,选择kernel-debug启动项,出现如下的提示表示成功启动。
接下来的操作全部在调试机(client上实现),以root进入/usr/src/linux-2.6.15目录,输入gdb,等gdb启动以后输入:
file vmlinuz (将要调试的文件调入!说个题外话,所谓调试,调试的对象是已通过编译的可执行文件<可执行文件有错误也可以!但前提是通过编译>)
set remotebaud 115220(设置远程机的波特率)
target remote /dev/ttyS1(设置远程串口端口号,有的教程写的/dev/ttyS0,如果在最先测试串口显示CSDN中可行,就用/dev/ttyS0,我也不大明白为什么!!)
如果显示程序停在breakpoint则表明已经成功!!!!然后就可以进行调试了,可以用可视化调试工具ddd(data display debugger)
这工具真拉风!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PS: gdb调试
首先将断点设在某个你需要查看函数,程序执行后,会将一张函数表保存在backtrace
bt(backtrace)命令用于查看这张表
up查看上级函数
down查看下级函数
b或者tb设置新断点
在你需要查看的函数里面
n(next)或者s(step)单步执行语句
pt(ptype)查看某个变量的类型(比whatis更强大)、也可以查看结构体的内容
p(print)可以打印变量的值、给变量赋值、调用函数(比如sizeof等)
until 当执行到循环语句的时候,用此语句让循环执行完毕
finish 让该函数执行完毕并返回到backtrace表的上一层
以上9个命名就可以完成基本的调试!!!!!