Linux内核如何测试
1. 概述
在本文中,我们将讨论用于测试 Linux 内核的各种框架和工具。首先,我们将从全面的 Linux 测试项目开始。然后,我们将介绍其他测试工具和框架。
最后,我们将讨论测试无法使用常规内核测试工具测试的新 Linux 驱动程序的过程。
2. Linux 测试项目(LTP)
**Linux 测试项目 是一个开源的自动化工具集合,我们可以使用它来创建构建过程、执行自动化测试和调试 Linux 内核。**LTP 项目由 IBM、Cisco、RHEL 和其他组织开发。
2.1.构建系统
**LTP 的构建系统为 Linux 内核项目提供了结构。**不仅如此,它还使用了新的Makefile 系统,该系统提供了增强的构建过程,从而使 Linux 项目的维护更易于管理。
2.2. C 测试用例
我们可以用 C 语言或可移植的 POSIX 兼容的 shell 语言编写 LTP 测试用例。测试用例使用 LTP 测试 API,它完全用 C 语言编写。此外,我们可以为glibc 和musl C 库编写测试用例。
3. 自检
Autotest 是一个专门为测试 Linux 内核而设计的测试框架。它提供了用于设置完全自动化的测试网格的模块。
自动测试模块包括:
- 一个客户端模块,用于在项目目录中执行测试的实际执行
- 一个服务器模块,让我们可以轻松管理多台远程机器上的测试客户端
- 存储测试网格结果的自动测试数据库模块
- 执行与测试网格相关的 cron 作业的调度程序
- 用于使用 Autotest 的命令行界面
- 用于可视化测试结果和调度作业的 Web 前端
对于严格的测试,我们还可以将 LTP 测试用例与 Autotest 调度程序结合起来,因为 Autotest 不提供用于测试 Linux 内核的 C 测试 API。
4. Kmemleak
Kmemleak 是主线 Linux 内核的一个开发特性。内核分配的内存有时不会被释放。因此,它可能成为性能问题和安全风险。
使用 Kmemleak,我们可以检查内核产生的内存泄漏。但是,它并没有解决问题,而是跟踪可能的泄漏并将它们报告给/sys/kernel/debug/memleak。**在某种程度上,Kmemleak 非常类似于Java 和 C# 等高级语言中的垃圾收集器 。
此外,如果我们正在使用 Linux 内核,我们可以通过在内核配置中启用“CONFIG_DEBUG_KMEMLEAK”来使用此功能。在大多数流行的发行版中,默认情况下会禁用此功能:
$ zgrep "CONFIG_DEBUG_KMEMLEAK" /proc/config.gz
# CONFIG_DEBUG_KMEMLEAK is not set
这是有道理的,因为我们在生产中不需要它。
5.Kmemcheck
和 Kmemleak 一样,Kmemcheck 也是 Linux 内核的一个开发特性。但是,它们都执行不同的任务。
**Kmemcheck 负责检查内核代码是否访问了内存中未初始化的结构。**例如,内核分配内存块但不填充它们,然后尝试访问该位置。这可能会导致严重的错误和性能问题。
我们应该注意到这个特性只适用于 x86 系统。
6. LAVA
**LAVA (Linaro 自动化和验证架构)是一种持续集成,用于将操作系统部署到物理和虚拟硬件上以运行测试。**这些测试包括引导、引导加载程序和系统级测试。它是专门为 ARM 系统设计的。
我们可以使用 LAVA 来检查我们对内核代码所做的更改的有效性。不仅如此,我们还可以检查内核是否针对速度和大小进行了优化。然后 LAVA 会将这些指标写入一个我们可以进一步分析的文件。
LAVA 框架主要用于测试移动操作系统,因为大多数手机都使用 ARM 或某种形式的 ARM 架构。
7. 单步调试器
**单步调试器是一种允许我们逐行执行程序代码的工具。**它为我们提供了一种简单的方法来监控程序流程并找出难以理解的错误。但是,我们应该知道单步调试器不执行单元测试。
7.1. GDB
在 Linux 上,我们有GDB (GNU 调试器)和 KGDB(内核 GDB)。**GDB 是一个通用调试器,允许我们调试包括 C 在内的多种编程语言的代码。**虽然我们不能直接用 GDB 调试内核代码,但我们可以使用 GDB 设置 QEMU,以便在执行中轻松地遍历内核代码。
7.2. KGDB
另一方面,KGDB 是 BSD 操作系统和 Linux 的调试器。为了使用 KGDB,我们需要两台通过串行连接或火线链接连接的机器。一台机器将运行内核,而另一台机器将运行调试器。这两台机器通过 GDB 远程协议进行通信。
8. 设备驱动测试
**测试 Linux 的设备驱动程序可能会变得非常乏味,因为没有用于测试 Linux 设备驱动程序的灵丹妙药。因此,所有测试都必须在物理硬件上手动完成。**尽管我们可以在虚拟机上测试驱动程序,但由于虚拟机添加了抽象层,它可能无法正常工作。
为了测试驱动程序,我们需要在启动 Linux 后手动加载驱动程序以检查任何初始化错误。之后,我们可以使用步进调试器,在某些情况下,还可以执行自动化测试。