220 likes | 420 Views
第 9 章 内核调试技术. 本章介绍了各种 Linux 内核调试方法。内核的调试需要从内核源码本身、调试工具等方面做好准备。通过本章的学习,可以了解不同调试方式的特点和使用方法,根据需要选择不同的内核调试方式。. 本章目标. 内核调试方法 内核打印函数 获取内核信息 处理出错信息 内核源码调试. 9.1 内核调试方法. 对于庞大的 Linux 内核软件工程,单靠阅读代码查找问题已经非常困难,需要借助调试技术解决 BUG 。通过合适的调试手段,可以有效地查找和判断 BUG 的位置和原因。. 9.1.1 内核调试概述.
E N D
本章介绍了各种Linux内核调试方法。内核的调试需要从内核源码本身、调试工具等方面做好准备。通过本章的学习,可以了解不同调试方式的特点和使用方法,根据需要选择不同的内核调试方式。本章介绍了各种Linux内核调试方法。内核的调试需要从内核源码本身、调试工具等方面做好准备。通过本章的学习,可以了解不同调试方式的特点和使用方法,根据需要选择不同的内核调试方式。 www.farsight.com.cn
本章目标 • 内核调试方法 • 内核打印函数 • 获取内核信息 • 处理出错信息 • 内核源码调试
9.1 内核调试方法 • 对于庞大的Linux内核软件工程,单靠阅读代码查找问题已经非常困难,需要借助调试技术解决BUG。通过合适的调试手段,可以有效地查找和判断BUG的位置和原因。
9.1.1 内核调试概述 • 调试内核很难,实际上内核不同于其他软件工程。内核有操作系统独特的问题,例如:时间管理和条件竞争,这可以使多个线程同时在内核中执行。 • 因此,调试BUG需要有效的调试手段。几乎没有一种调试工具或者方法能够解决全部问题。即使在一些集成测试环境中,也要划分不同测试调试功能,例如:跟踪调试、内存泄漏测试、性能测试等。掌握的调试方法越多,调试BUG就越方便。Linux有很多开放源代码的工具,每一个工具的调试功能专一,所以这些工具的实现一般也比较简单。
9.1.2 学会分析内核源程序 • 按书上进行学习,并在机器上实验
9.1.3 调试方法介绍 • 内核调试方法很多,主要有以下4类。 • 通过打印函数 • 获取内核信息 • 处理出错信息 • 内核源码调试
9.2 内核打印函数 • 嵌入式系统一般都可以通过串口与用户交互。大多数Bootloader可以向串口打印信息,并且接收命令。内核同样可以向串口打印信息。但是在内核启动过程中,不同阶段的打印函数不同。分析这些打印函数的实现,可以更好地调试内核。
9.2.1 内核映像解压前的串口输出函数 • decompresss_kernel()函数调用了putstr()函数,直接向串口打印内核解压的信息。 • 9.2.2 内核错误报告子程序 • 怎样才能报告这种错误信息呢?可以通过printascii子程序来向串口打印。 • printascii、printhex8等子程序包含在arch/arm/kernel/debug.S文件中。 • 9.2.3 内核打印函数 • Linux内核标准的系统打印函数是printk。printk函数具有极好的健壮性,不受内核运行条件的限制,在系统运行期间都可以使用。
9.3 获取内核信息 • Linux内核提供了一些与用户空间通信的机制,大部分驱动程序与用户空间的接口都可以作为获取内核信息的手段。另外内核也有专门的调试机制。
9.3.2 通过/proc接口 • proc文件系统是一种伪文件系统。实际上,它并不占用存储空间,而是系统运行时在内存中建立的内核状态映射,可以瞬时地提供系统的状态信息。
9.3.3 通过/sys接口 • Sysfs文件系统是Linux 2.6内核新增加的文件系统。它也是一种伪文件系统,是在内存中实现的文件系统。它可以把内核空间的数据、属性、链接等东西输出到用户空间。 • 在Linux 2.6内核中,sysfs和kobject是紧密结合的,成为驱动程序模型的组成部分。
9.3.4 通过ioctl方法 • ioctl是对一个文件描述符响应的系统调用,它可以实现特殊命令操作。ioctl可以替代/proc文件系统,实现一些调试的命令。 • 使用ioctl获取信息比/proc麻烦一些,因为通过应用程序的ioctl函数调用并且显示结果必须编写、编译一个应用程序,并且与正在测试的模块保持一致。反过来,驱动程序代码比实现/proc文件相对简单一点。
9.4 处理出错信息 • 当系统出现错误时,内核有两个基本的错误处理机制:oops和panic。 • 9.4.1 oops信息 • (1)oops消息包含系统错误的详细信息 • stem.map,完全可以分析一下的。不过,还有一个更好的工具来辅助分析。 • (2)使用ksymoops转换oops信息 • (3)内核kallsyms选项支持符号信息 • 9.4.2 panic • 当系统发生严重错误的时候,将调用panic()函数。
9.5 内核源码调试 • 因为Linux内核程序是GNU GCC编译的,所以对应地使用GNU GDB调试器。Linux应用程序需要gdbserver辅助交叉调试。那么内核源代码调试时,谁来充当gdbserver的角色呢?
9.5.1 KGDB调试内核源代码 • KGDB是Linux内核调试的一种机制。它使用远程主机上的GDB调试目标板上的Linux内核。 • 准确地说,KGDB是内核的功能扩展,它在内核中使用插桩(Stub)的机制。
遵循下面的步骤来设置KGDB调试环境。 • (1)配置编译Linux内核映像 • (2)在目标板上启动内核 • (3)启动gdb,建立连接 • (4)使用gdb的调试命令设置断点,跟踪调试
9.5.2 BDI2000调试内核源代码 • 下面说明一下BDI2000调试Linux内核的操作步骤。 • (1)主机/目标机设置 • (2)准备要调试的内核 • (3)通过BDI2000控制硬件开发板 • (4)设置BDI2000断点 • (5)下载内核 • (6)gdb连接BDI2000 • (7)设置gdb断点 • (8)重新控制调试过程 • (9)调试内核模块
Q&A www.farsight.com.cn
谢谢! www.farsight.com.cn