linux设备驱动开发,内核使用dev_dbg来控制输出信息,这个函数包含在include/linux/device.h头文件中,但是默认情况下看不到调试信息,该如何打开呢,我们直接上代码:
#if defined(CONFIG_DYNAMIC_DEBUG)
#define dev_dbg(dev, format, ...) \
do { \
dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
} while (0)
#elif defined(DEBUG)
#define dev_dbg(dev, format, arg...) \
dev_printk(KERN_DEBUG, dev, format, ##arg)
#else
#define dev_dbg(dev, format, arg...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, format, ##arg); \
})
#endif
从上面的代码分析dev_dbg可以指向dynamic_dev_dbg()或者系统打印printk(),那么分别从这两中情况进行具体分析:
1、 dev_dbg -> dynamic_dev_dbg 定义的debug log的情况
debugfs 默认路径sys/kernel/debug,官方使用文档参考 kernel/Documentation/dynamic-debug-howto.txt,debugfs 使用必须在kernel的config文件(kernel/arch/arm/configs/xxx_deconfig)中有
CONFIG_DEBUG_FS=y
CONFIG_DYNAMIC_DEBUG=y
如何使用:
mount -t debugfs none /sys/kernel/debug #路径也可以自己选择,这里用系统默认路径
echo -n 'file xxx.c +p' > /sys/kernel/debug/dynamic_debug/control #增加xxx.c文件dynamic debug的输出
echo -n 'file xxx.c -p' > /sys/kernel/debug/dynamic_debug/control #去掉xxx.c文件dynamic debug的输出
2、dev_dbg ->dev_printk定义的debug log的情况
我们先看一下定义在<linux/device.h>里面关于打印级别基本的定义
#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 */
#define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel*/
在来看下kernel/printk.c 中定义的打印级别,如下:
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel 控制台日志级别,优先级高于该值的消息将在控制台显示*/
DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */
MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel 最低的控制台日志级别 */
DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
};
在内核代码include/linux/kernel.h中,定义了控制台的级别:
extern int console_printk[];
#define console_loglevel (console_printk[0])
#define default_message_loglevel (console_printk[1])
#define minimum_console_loglevel (console_printk[2])
#define default_console_loglevel (console_printk[3])
据如上定义printk只会打印小于等于该级别的日志信息,dev_dbg对应的是调试信息,打印级别为KERN_DEBUG = 7,默认情况下自然是无法打印的,所以我们需要调整系统的默认打印级别来显示调试信息。
/proc/sys/kernel # cat printk
1 4 1 7
#echo 7 4 1 7 > /proc/sys/kernel/printk #修改printk对应的打印级别
(1)第一个参数 7表示小于7优先级消息才会被输出到控制台。
(2)第二个参数4 表示默认的printk消息优先级别,即printk(“hell world”);优先级为4, 由于4<7,故可以被打印到控制台。
(3)第三个参数1 表示可接收的最高优先级,当printk disable控制台输出时,设置第一个参数为1,但是,从内核等级来看,还有优先级0,这个是printk最高级优先级,一般用于内核严重消息打印。比如内存错误或者 watchdog reset.也可以设置第一个和第三个参数为0
(4)第四个参数7 默认控制台优先级,即第一个参数的默认优先级。
参考:https://blog.csdn.net/kinzxv/article/details/81944397