网站建设页面带声音,网页游戏推荐排行,天河公司网站建设公司,专业网站建设 公司哪家好目录
前言
1 printk消息级别
2 调整内核printk打印级别
3 dev_xxx函数简介
4 配置内核使用动态打印
5 动态调试使用方法
6 动态打印调试的基本原理 #x1f388;个人主页#x1f388;#xff1a;linux_嵌入式大师之路的博客-CSDN博客#x1f389;#x1f389;个人主页linux_嵌入式大师之路的博客-CSDN博客欢迎 点赞✍评论⭐收藏希望本文能对你有所帮助欢迎在评论区交流讨论 前言
在 kernel 驱动代码中使用动态输出是系统内核调试的重要手段之一printk打印是全局的只能设置输出等级。而动态输出可以动态选择打开某个内核子系统的输出可以有选择性地打开某些模块的输出printk被dev_infodev_dbgdev_err之类的函数代替dev_xxx函数的本质还是使用printk打印的只是对printk进行了一层包装。
1 printk消息级别
Linux 内核共提供了八种不同的消息级别分为级别 0~7。数值越大表示级别越低对应的消息越不重要。相应的宏定义在 include/linux/kern_levels.h 文件中。
#define KERN_SOH \001 /* ASCII Start Of Header */
#define KERN_SOH_ASCII \001#define KERN_EMERG KERN_SOH 0 /* system is unusable */
#define KERN_ALERT KERN_SOH 1 /* action must be taken immediately */
#define KERN_CRIT KERN_SOH 2 /* critical conditions */
#define KERN_ERR KERN_SOH 3 /* error conditions */
#define KERN_WARNING KERN_SOH 4 /* warning conditions */
#define KERN_NOTICE KERN_SOH 5 /* normal but significant condition */
#define KERN_INFO KERN_SOH 6 /* informational */
#define KERN_DEBUG KERN_SOH 7 /* debug-level messages */ KERN_ALERT 表示必须立即采取行动的消息KERN_CRIT 表示临界状态通常涉及严重的硬件或软件操作失败KERN_ERR 用于报告错误状态设备驱动程序会经常使用该级别来报告来自硬件的问题KERN_WARNING 对可能出现问题的情况进行警告这类情况通常不会对系统造成严重的问题KERN_NOTICE 表示有必要进行提示的正常情形许多与安全相关的状况用这个级别进行汇报KERN_INFO 表示内核提示信息很多驱动程序在启动的时候用这个级别打印出它们找到的硬件信息KERN_DEBUG 用于调试信息。KERN_EMERG 表示紧急事件一般是系统崩溃之前提示的消息 2 调整内核printk打印级别 通过 /proc/sys/kernel/printk 文件可以调节 printk 的输出等级该文件有 4 个数字值。例如在 Ubuntu 上的值如下
四个数值的含义如下 控制台日志级别优先级高于该值的消息将被打印至控制台 默认的消息日志级别将用该优先级来打印没有优先级的消息即 printk 没有指定消息级别 最低的控制台日志级别控制台日志级别可被设置的最小值最高优先级 默认的控制台日志级别控制台日志级别的缺省值。 通过修改 /proc/sys/kernel/printk 中的值来改变内核打印效果。例如屏蔽掉所有的内核 printk 打印只需要把第一个数值调到最小值1或者0指令如下: echo 1 4 1 7 /proc/sys/kernel/printk 3 dev_xxx函数简介
下面简述下这几个dev_xxx函数的基本使用规则以及动态调试使用方式。 dev_info() 启动过程、或者模块加载过程等 “通知类的” 信息等一般只会通知一次例如 probe 函数dev_dbg() 一般使用在普通错误如-EINVAL、-ENOMEM 等 errno 发生处用于调试dev_err() 一般使用在严重错误尤其是用户无法得到 errno 的地方或者程序员不容易猜测系统哪里出了问题的地方 4 配置内核使用动态打印 打开内核动态调试开关打开内核配置选项CONFIG_DEBUG_FSyCONFIG_DYNAMIC_DEBUGydebugfs默认会挂载到/sys/kernel/debug如果没有挂载可以执行以下命令挂载 mount -t debugfs none /sys/kernel/debug 5 动态调试使用方法 使用下面方式控制你想输出 dev_dbg() 信息 控制某个文件所有 dev_dbg()
echo -n file xxx.c p /mnt/dbg/dynamic_debug/control控制某个函数所有 dev_dbg()
echo -n func xxx p /mnt/dbg/dynamic_debug/control 运行程序使用 dmesg 则可以看到相应 dev_dbg() 的输出信息当调试结束不再想输出 dev_dbg() 信息了使用下面命令关闭即可 echo -n file xxx.c -p /sys/kernel/debug/dynamic_debug/controlecho -n func xxx -p /sys/kernel/debug/dynamic_debug/control 例子
echo -n file ca_dsc_core.c p /sys/kernel/debug/dynamic_debug/control 则打印ca_dsc_core.c所有的 dev_dbg() 信息
echo -n func ca_dsc_read p /sys/kernel/debug/dynamic_debug/control 则打印ca_dsc_read()函数所有 dev_dbg()
上面是打开动态输出语句的例子除了能输出pr_debug()/dev_dbg()函数中定义的输出信息外还能输出一些额外信息如函数名、行号、模块名字以及线程ID等 p打开动态输出语句可以是某个文件某个模块某个函数或者文件路径包含某个关键字的文件里所有的动态打印语句f输出函数名l输出行号m输出模块名字t输出线程ID 另外还可以在各个子系统的Makefile中添加ccflags来打开动态输出语句
Makefile
ccflags-y -DDEBUG
ccflags-y -DVERBOSE_DEBUG
6 动态打印调试的基本原理
当编译选项CONFIG_DYNAMIC_DEBUG打开的时候在编译阶段kernel 会把所有使用 dev_dbg() 的信息记录在一个 table 中这些信息我们可以从/sys/kernel/debug/dynamic_debug/control解析出来
# cat /sys/kernel/debug/dynamic_debug/control