linux设备驱动开发,我们经常看到内核使用dev_dbg来控制输出信息,这个函数包含在
#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(),那么分别从这两中情况进行具体分析:
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' > /data/debugfs/dynamic_debug/control #增加xxx.c文件dynamic debug的输出
echo -n 'file xxx.c -p' > /data/debugfs/dynamic_debug/control #去掉xxx.c文件dynamic debug的输出
我们先看一下定义在
#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,默认情况下自然是无法打印的,所以我们需要调整系统的默认打印级别来显示调试信息。
在内核启动阶段的信息可以直接修改printk.c里面的定义(非常不建议这么做),我们可以通过如下操作来动态修改
#cat /proc/sys/kernel/printk #查看printk对应的打印级别
10 4 1 10
#echo 1 4 1 7 > /proc/sys/kernel/printk #修改printk对应的打印级别
那启动阶段怎么办,我们完全可以通过修改init.rc来实现临时修改打印级别,这样能够避免大量的打印刷屏。