LV06-09-调试与优化-02-驱动调试
驱动程序出现bug时,除了printk打印信息,我们还可以怎么调试驱动?若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 | Windows | Windows11 |
Ubuntu | Ubuntu20.04.2的64位版本 | |
VMware® Workstation 17 Pro | 17.6.0 build-24238078 | |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) | |
Win32DiskImager | Win32DiskImager v1.0 | |
Linux开发板环境 | Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04 | |
linux内核 | linux-4.19.71(NXP官方提供) |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.nxp.com.cn/ | NXP官方网站 | |
https://www.nxpic.org.cn/ | NXP 官方社区 | |
https://u-boot.readthedocs.io/en/latest/ | u-boot官网 | |
https://www.kernel.org/ | linux内核官网 |
点击查看相关文件下载
分类 | 网址 | 说明 |
NXP | https://github.com/nxp-imx | NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 |
nxp-imx/linux-imx/releases/tag/v4.19.71 | NXP linux内核仓库tags中的v4.19.71 | |
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 | NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0 | |
I.MX6ULL | i.MX 6ULL Applications Processors for Industrial Products | I.MX6ULL 芯片手册(datasheet,可以在线查看) |
i.MX 6ULL Applications ProcessorReference Manual | I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) | |
Source Code | https://elixir.bootlin.com/linux/latest/source | linux kernel源码 |
kernel/git/stable/linux.git - Linux kernel stable tree | linux kernel源码(官网,tag 4.19.71) | |
https://elixir.bootlin.com/u-boot/latest/source | uboot源码 |
一、相关调试函数
1. dump_stack()
1.1 函数说明
dump_stack()函数声明如下:
1 | extern asmlinkage void dump_stack(void) __cold; |
函数实际定义在 dump_stack.c - lib/dump_stack.c
1 | /** |
这个函数是打印内核调用堆栈, 并打印函数的调用关系。
1.2 使用实例
1.2.1 demo源码
1 | static int scdev_create(_CHAR_DEVICE *p_chrdev) |
1.2.2 开发板测试
如下图所示,在加载驱动的时候会打印出这个函数相关的一些调用关系:

2. WARN_ON()
2.1 函数说明
WARN_ON()函数定义如下:
1 |
在括号中的条件成立时, 内核会抛出栈回溯, 打印函数的调用关系。 通常用于内核抛出一个警告, 暗示某种不太合理的事情发生了。WARN_ON 实际上也是调用 dump_stack, 只是多了参数 condition 判断条件是否成立, 例如 WARN_ON (1)则条件判断成功, 函数会成功执行。
2.2 使用实例
2.2.1 demo源码
1 | static int scdev_create(_CHAR_DEVICE *p_chrdev) |
2.2.2 开发板测试
如下图所示,在加载驱动的时候会打印出这个函数相关的一些调用关系:

3. BUG_ON()
3.1 函数说明
BUG_ON()函数定义如下:
1 |
内核中有许多地方调用类似 BUG_ON()的语句, 它非常像一个内核运行时的断言, 意味着本来不该执行到 BUG_ON()这条语句, 一旦 BUG_ON()执行内核就会立刻抛出 oops, 导致栈的回溯和错误信息的打印。 大部分体系结构把 BUG()和 BUG_ON()定义成某种非法操作, 这样自然会产生需要的 oops。 参数 condition 判断条件是否成立, 例如 BUG_ON (1)则条件判断成功,函数会成功执行。
3.2 使用实例
3.2.1 demo源码
1 | static int scdev_create(_CHAR_DEVICE *p_chrdev) |
3.2.2 开发板测试
如下图所示,在加载驱动的时候会打印出栈相关的信息,并产生一个段错误,但是实际上并没有崩溃:

4. panic()
4.1 函数说明
panic() 函数定义如下:
1 | /** |
该函数输出打印会造成系统死机并将函数的调用关系以及寄存器值都打印出来。
4.2 使用实例
4.2.1 demo源码
1 | static int scdev_create(_CHAR_DEVICE *p_chrdev) |
4.2.2 开发板测试
如下图所示,在加载驱动的时候会打印出栈相关的信息,然后系统崩溃,终端也进不去了:

二、驱动调试demo
demo源码可以看这里:10_driver_debug/02_debug_demo · 苏木/imx6ull-driver-demo - 码云 - 开源中国