第10章:嵌入式Linux的调试技术
对于复杂的Linux驱动及HAL等程序库, 需要使用各种方法对其进行调试。例如, 设置断点、逐步跟踪代码、输出调试信息等。
一、打印内核调试信息:printk
printk函数在前面的章节己多次使用过。该函数的用法与printf函数类似,只不过printk函数运行在内核空间,printf函数运行在用户空间。也就是说,像Linux驱动这样的Linux内核程序只能使用printk函数输出凋试信息。
二、防止printk函数降低Linux驱动性能
虽然使用printk函数可以很方便地将消息写入日志文件或控制台。但大量使用printk函数频繁操作日志文件或控制台设备文件(/dev/console)会严重影响Linux驱动的性能(因为写磁盘的速度远没有读写内存的速度快),因此,这就要求Linux驱动只在开发阶段使用printk函数输出消息, 在正式友布Linux驱动时将可能影响性能的printk函数去掉。当然,最容易想到的方法就是挨个删除printk函数, 或注释printk函数。但这样做很麻烦,而且以后想加上printk函数也是同样麻烦。 要想按制prrintk函数的输出, 而且实现起来很方便,最好的方法无疑是利用C语言中的编译指令 (#if、#else、#endif等)。
三、通过虚拟文件系统(/proc)进行数据交互
在 Linux 文件系统中,/proc 经常被用来作为内核空间与用户空间进行数据交互的工具。/proc 文件系统的行为方式与设备文件系统(/dev )类似。/proc 是虚拟文件系统, 也就是说了/proc 并不是真正的文件系统, 而是内存映射。 所有读写/proc 如操作都是对内存的读写。所以读写/proc 文件系统的速度要远比读写/dev 文件系统的速度快。 因此,/proc 文件系统也可作为 Linux 驱动与用户空间程序交互的工具。
有很多系统信息就是通过/proc 文件系统由内核空间的程序向外界提供的。 例如, 当前系统的内存资源就是通过/proc/meminfo 文件就取的,可以使用如下的命令查看/proc/meminfo 文件的内容。
常用的几种函数:
proc_mkdir
create_poce_entry
create_poce_read_entry
remove_proc_entry
四、调试工具
前面介绍的调试方法都是输出相应的调试消息, 然后开发人员通过这些消息判断错误出在哪里。但这种方式需要不断修改程序, 不断输出各种消息, 比较麻烦。 在 Linux 系统中提供了一类工具. 通过这些工具可以逐行跟踪程序的代码, 就好像可视化开发工具的 step into 和 step over 一样。 这些工具包含用于调试用户空间程序的 gdb、 gdbserver 和调试内核空间程序的 kgdb。
- 用gdb调试用户空间程序
- 用 gdbserver 远程调试用户空间程序
- 用kgdb远程调试内核程序
Linux 内核调试一直被很多人认为是非常困难的。大多数人宁愿直接使用 printk 函数输出调试信息,也不愿意使用各种命令. (gdb 、 gdbserver、kgdb 等)进行调试.因为这样做并不一定能换来更多的好处。·