今天加载wifi驱动的时候居然直接造成linux内核崩溃,重启PC后在/var/run/dmesg.0中找不到错误信息。我要如何在我的这台Ubuntu上调试这个驱动呢?答案是KGDB,以前也尝试过,但是最后都放弃了。今天决定再攻关一次,不想居然最后基本成功了。下面的内容基本上都是从网上东拼西凑的,重点参考了优快云上dndxhej的博客, http://blog.youkuaiyun.com/dndxhej/article/details/7171805, 在此谢过。
我的步骤:
1.除了崩溃的Ubuntu 11.10 Linux PC外(叫目标机),还需要一个Linux 环境来远程通过串口线调试(叫开发机)。
2.交叉串口线一根。需要说明一下,本来我想通过网线来远程调试的,但是尝试很多下,最后放弃了。如果哪位成功了,可以告诉我。在先此谢过。
我只有一根两头都是母头的串口线,用万用表量了一下,发现是直连的(1和1通,2和2通,往下一样)。现在需要把这根串口线喀嚓两半后照着下面的链接上的图重新接好。
http://kgdb.linsyssoft.com/quickstart.htm
我把图片复制过来贴在这里:

这个工作需要的就是一个万用表和一点耐心。
3.检查串口线是否工作正常。参照http://kgdb.linsyssoft.com/quickstart.htm。由于我的笔记本上没有串口,所以还串了一个USB转串口的线,这样我的开发机的串口是ttyUSB0。
http://kgdb.linsyssoft.com/quickstart.htm
在目标机上:
stty ispeed 115200 ospeed 115200 -F /dev/ttyS0
cat /dev/ttyS0
有人建议把第一行加到 /etc/rc.local 中,我是这么做了。
在开发机上 :
stty ispeed 115200 ospeed 115200 -F /dev/ttyUSB0
cat testfile.txt > /dev/ttyUSB0
testfile.txt中的内容如果能在目标机上显示,说明串口线已经好了。该编译内核了。
4.由于调试内核需要用到目标机上内核的vmlinux文件,所以重编内核是无法避免的。在目标机上先通过synaptic安装内核源代码linux-source,下面的工作都是在目标机上操作的。
5.把内核源代码复制到自己的home目录,解压,从/boot目录下复制一个config文件到内核源代码的根目录,改名.config。
6.用vim打开Makefile, 修改EXTRAVERSION = -kgdb
7. 配置内核, make menuconfig, 选择如下选项
Kernel Hacking -->
选中 Compile the kernel with debug info
选中 Compile the kernel with frame pointers
选中 KGDB:kernel debugging with remote gdb
其中,KGDB:kernel debugging with remote gdb下全部选上。
也有几项需要去掉:
Processor type and features 中去掉 Para virtualized guest support
Kernel Hacking 中去掉 Write protect kernel read-only data structures(否则不能用软件断点)
8.编译和安装新编译的内核到启动配置文件
make
sudo make modules_install
sudo make install
9.修改启动配置文件来启用kgdb
sudo vim /boot/grub/grub.cfg
找到新增加的选项的linux开头的一行,后面加上 kgdboc=ttyS0,115200
有人说要加上kgdbwait,这样目标机启动后会显示"kgdb: Waiting for connection from remote gdb...",但是我的目标机是Ubuntu, 没有显示这句话,而是像死机一样的停留在启动界面,我就没加。
10. 我把源代码的压缩包scp了一份到开发机上,并解压,又把目标机上编译得到的vmlinux scp到刚解开的linux源代码的根目录并执行 gdb ./vmlinux运行gdb
11 重启目标机,正常启动后在终端里输入"echo g > /proc/sysrq-trigger", 以后每次想要让目标机停下来都要输入这条命令触发kgdb
12 在开发机的gdb命令行输入
(gdb) set remotebaud 115200
到这里已经可以调试内核和编入内核的驱动了,问题是我们更多的工作是调试动态加载的驱动,而不是内核。为了调试动态驱动,还有几步要完成。
13. 在目标机上编译驱动并把整个驱动的目录都复制到开发机上,而且保持目录一样,这样会让生活更简单一点。
14. 目标机上insmod驱动,"cat /sys/module/driver_name/sections/.text" 得到text的地址。
15. "echo g > /proc/sysrq-trigger"停下目标机,gdb也显示命令行了,add-symbol-file
/full/directory/to/driver.ko
16. 这样也可以给驱动下断点了。
目前为止就会这些,还要在实践中提高。