【Linux】驱动内核调试,是需要几板斧的

这篇具有很好参考价值的文章主要介绍了【Linux】驱动内核调试,是需要几板斧的。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

一、基础打印工具

 (1)printk---最常用

①Log Buffer:

②Console:

③RAM Console:

(2)动态打印

①动态打印与printk之间的区别联系

②动态打印常用的例子

③动态打印转为printk正常打印

 (3)dump_stack---分析源码的利器

(4)操作寄存器命令---硬件测试

①devmem---系统层面

②ioremap---内核层面

③ /dey/mem---应用层面

二、特殊场景下的打印工具

(1)Oops内核崩溃:

(2)休眠唤醒:

(3)Linux错误码:

(4)Linux kernel中计算代码运行时间:

(5)debugfs


前言:

在VS code编程时我们编写程序时都有输出打印信息,方便查找问题,在驱动开发中,亦有调试的手段和方法,这些是我们解决和排查问题的利器。 

工欲善其事,必先利其器,所以驱动内核调试方法的掌握,是非常有必要的。

参考学习:

https://xuesong.blog.csdn.net/article/details/113062813

https://xuesong.blog.csdn.net/article/details/109522945?spm=1001.2014.3001.5502

Linux内核常用调试手段介绍-Linux笔记

开发环境:

imx6ull pro开发板 

Linux 4.9.88内核 

一、基础打印工具

 (1)printk---最常用

这里它有三个方向去输出,如下图所示:

【Linux】驱动内核调试,是需要几板斧的

①Log Buffer:

  • 该Buffer里面的内容可以存储在/proc/kmsg
  • 示例:https://blog.csdn.net/weixin_42373086/article/details/130545341?spm=1001.2014.3001.5501 在这里,使用了很多printk打印信息,可以使用dmesg命令查看。

【Linux】驱动内核调试,是需要几板斧的

②Console:

  • Console的实现可以很多,目前我们用到的有UART Console(串口)

③RAM Console:

  • 允许将调试日志信息写入一个被称为RAM Console的设备。
  • 这个主要用于解决系统内核崩溃问题,临终时会将一些日志存储在这里方便后续排查。

 这里有很多打印信息,谁优先打印就是一个问题。

这里printk有8个等级,从0到7,优先级依次降低。

通常通过修改/proc/sys/kernel/printk来设置打印。

cat /proc/sys/kernel/printk

//打开所有的内核打印
echo 8> /proc/sys/kernel/printk

 小于阈值的打印信息,都将输出到控制台上。

【Linux】驱动内核调试,是需要几板斧的

(2)动态打印

①动态打印与printk之间的区别联系

  • 在系统运行时,动态打印可以由系统维护者动态打开内核子系统的打印,可以有选择性地打开某些模块的打印。
  • 而printk是全局的,只能设置打印等级。要使用动态打印,必须在内核设置时打开CONFIG_DYNAMIC_DEBUG。
  • 动态打印也有相应的设备节点:/sys/kernel/debug/dynamic_debug。常用于高速设备。

可以打印函数名(f)、行号(l)、模块名字(m)以及线程ID(t)。

②动态打印常用的例子

1.打开一个文件中所有动态打印语句

echo -n "file gadget.c +p">

2.打开一个模块中所有动态打印语句

echo -n "module dwc3 +p">

3.打开一个函数中所有动态打印语句

echo "func svc_process +p">

4.打开文件路径中包含usb的文件里所有的动态打印语句

echo -n "*usb* +p">

③动态打印转为printk正常打印

开机的时候,没法操作这个动态打印的节点,能否把动态打印转换成默认的printk正常打印,这个如何实现?

在c文件开头添加:

//重定义
#undef dev_dbg
#define dev_dbg dev_info
#undef pr_debug
#define pr_debug pr_info

 (3)dump_stack---分析源码的利器

分析一个函数的底层调用,离不开dump_stack,因为它是对内核调用栈的打印;当我们不清楚系统回调函数上下文,使用这个方法是非常好的。

具体demo案例:参照文章

https://xuesong.blog.csdn.net/article/details/113062813

(4)操作寄存器命令---硬件测试

①devmem---系统层面

它的原理以及应用场景:

  • 硬件工程师将硬件设计好时,需要进行简单的测试,来查看CPU是否可以正确地读取新硬件系统。
    • 正规的Linux操作方式下,是要有硬件的驱动程序才能完成这个需求。
    • 测试需求只是为了实现简单硬件寄存器读写工作时,devmem命令就非常的适用了。
  • 它的原理就是把硬件的地址空间ioremap映射到用户空间。

具体使用方法,可以参照:

https://xuesong.blog.csdn.net/article/details/113283070

②ioremap---内核层面

实现的核心代码:

#define GPIO0_DDR_BASE       ((uint32_t)0xE7A01014) 

static volatile uint32_t *GPIO0_ddr_vreg;
uint32_t val = 0;
GPIO0_ddr_vreg = (uint32_t *)ioremap(GPIO0_DDR_BASE, 4); 
val = readl(GPIO0_ddr_vreg);
printk("val = %ld\n",val);

③ /dey/mem---应用层面

应用层操作寄存器首先需要将内核映射到核外空间,内核已经提供了一个 /dey/mem 的文件接口,这个文件相当于整个系统内存所在,将该文件打开然后指定需要映射的内存的位置即可。需要注意的是,一般 map 映射的是一段内存地址空间。

具体使用方法:

https://xuesong.blog.csdn.net/article/details/114156170

二、特殊场景下的打印工具

(1)Oops内核崩溃:

当我们遇到内核崩溃,比如空指针异常、内存访问越界。这时我们只能靠崩溃之后打印出来异常调用栈信息来定位Oops的位置和原因。

举个例子: 

【Linux】驱动内核调试,是需要几板斧的

在第三行error:Oops信息 kernel BUG at../drivers/mmc/host/sdhci.c  那一行可以简要告知我们是哪里发生问题触发Oops。

(2)休眠唤醒:

我们使用的多个模块都会使用到休眠唤醒,每个休眠唤醒都会有相应的休眠唤醒锁。如果想知道当前模块休眠唤醒失败是由哪个斥锁导致的,可以应用下面的命令实现:

awk '$6 !=0{print $1""$6}' /sys/kernel/debug/wakeup_sources

(3)Linux错误码:

错误代码由内核或用户空间应用程序(通过error变量)解释。错误处理在软件开发中非常重要,而不仅仅是在内核开发中。幸运的是,内核提供的几种错误,几乎涵盖了可能遇到的所有错误,有时需要把它们打印出来以帮助进行调试。

相应文件的路径:

include/uapi/asm-generic/errno-base.h
include/uapi/sm-generic/error.h

具体如下: 

【Linux】驱动内核调试,是需要几板斧的

相应所有错误码说明,可参考:

Linux错误代码及其含义_linux enxio_wsqyouth的博客-CSDN博客

(4)Linux kernel中计算代码运行时间:

对内核或驱动代码做性能优化时,常常要测量一段代码执行时所消耗的时间。

常用的函数为ktime_get(),在一段代码前后各使用 ktime_get() 获取时间,计算其差值,就是这段代码运行消耗的时间。ktime_get() 能够精确到纳秒级。

(5)debugfs

内核中有三个常用的伪文件系统: procfs, debugfs和sysfs。 

debugfs是内核开发中专门用来调试的文件系统接口,其他的工具或者接口,多数都依赖于debugfs。

具体如何使用,参考文章:

https://xuesong.blog.csdn.net/article/details/124112698文章来源地址https://www.toymoban.com/news/detail-454715.html

到了这里,关于【Linux】驱动内核调试,是需要几板斧的的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux驱动开发】013 与gpio相关的OF函数 一、前言

    在上节,我们提供了驱动中gpio子系统相关的API函数,主要用来申请释放gpio、设置gpio输入输出、获取设置gpio的值。 我们进行上述设置的前提是:在驱动程序中需要读取 gpio 属性内容。为此,Linux 内核提供了几个与 GPIO 有关的 OF 函数。 用于统计设备树某个属性里面定义了几个

    2024年02月14日
    浏览(40)
  • 【驱动】TI AM437x(内核调试-06):网卡(PHY和MAC)、七层OSI

    第一层:物理层。 1)需求: 两个电脑之间如何进行通信? 具体就是一台发比特流,另一台能够收到。于是就有了物理层:主要是定义设备标准,如网线的额接口类型、管线的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流,就是从1/0转化为电流强弱来进

    2024年01月17日
    浏览(51)
  • Linux内核8. Linux内核的经典调试方式

    内核总是那么捉摸不透, 内核也会犯错, 但是调试却不能像用户空间程序那样, 为此内核开发者为我们提供了一系列的工具和系统来支持内核的调试. 内核的调试, 其本质是内核空间与用户空间的数据交换, 内核开发者们提供了多样的形式来完成这一功能. 内核中有三个常用的伪

    2024年02月07日
    浏览(43)
  • Ubuntu目录和linux内核文件用途

    1./:根目录,是整个文件系统的起点 2./bin:binary 二进制可执行文件目录,包含用于系统启动和运行的基本命令 3./boot: 启动加载器目录,包含用于系统启动的内核和引导程序文件。 4./dev: device 设备文件目录,包含系统中使用的所有设备文件,如硬盘、光驱、键盘、鼠标等5./etc

    2024年02月10日
    浏览(41)
  • linux内核调试工具记录

    Linux性能测试使用的工具在github网站可见,网址如下: slides: http://www.slideshare.net/brendangregg/linux-performance-analysis-new-tools-and-old-secrets video: https://www.usenix.org/conference/lisa14/conference-program/presentation/gregg 也可通过git下载,可以看到相关脚本的试下: git clone --depth 1 https://github.com/br

    2024年02月16日
    浏览(39)
  • VScode 调试 linux内核

    这里调试的 linux 内核是通过 Linux+SD卡(rootfs)运行的内核 编辑 /home/tyustli/.gdbinit 文件,参考 【GDB】 .gdbinit 文件 在 linux 源码项目的根目录新建 .gdbinit 文件 先启动 linux 内核,让其等待 GDB 连接 在编译 linux 的当前路径输入 如果没有设置 /home/tyustli/.gdbinit 文件,那么对应的命令为

    2024年02月07日
    浏览(32)
  • Linux内核的编译、安装、调试

    Linux内核下载The Linux Kernel Archives 打开 .config 更改 CONFIG_SYSTEM_TRUSTED_KEYS 和 CONFIG_SYSTEM_REVOCATION_KEYS 更改 CONFIG_DEBUG_INFO_BTF 注释掉CONFIG_X86_X32 首先安装模块 这里加上 INSTALL_MOD_STRIP=1 是为了避免内核启动时卡在 loading initial ramdisk 安装内核 更改引导 更改 grub 修改文件 更新 重启 在

    2024年02月11日
    浏览(33)
  • 内核实验(四):Qemu调试Linux内核,实现NFS挂载

    在文章《内核实验(三)……》中,通过挂载虚拟分区,解决了Host和虚拟机文件交换的问题,但依旧比较麻烦。为了提升效率,必须解决NFS挂载共享文件夹的问题。如能实现,则直接在虚拟机上挂载服务端的NFS目录,即可实时交换文件,大大提升效率! 关于Qemu虚拟机挂载

    2024年02月02日
    浏览(25)
  • 修改linux的/sys目录下内核参数、模块...

    ① /sys/devices 该目录下是全局设备结构体系,包含所有被发现的注册在各种总线上的各种物理设备。一般来说,所有的物理设备都按其在总线上的拓扑结构来显示,但有两个例外,即platform devices和system devices。platform devices一般是挂在芯片内部的高速或者低速总线上的各种控制

    2024年02月05日
    浏览(44)
  • linux内核网络驱动框架(linux驱动开发篇)

    网络驱动的核心: 1、就是初始化 net_device 结构体中的各个成员变量, 2、然后将初始化完成以后的 net_device 注册到 Linux 内核中 1、网络设备(用net_device结构体) 2、网络设备的操作集( net_device_ops结构体 ) 3、sk_buff结构体 网络是分层的,对于应用层而言不用关系具体的底层是

    2023年04月08日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包