1.printk
(1)printk打印等级类型如下:
printk(KERN_DEBUG "hello"); //
#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 */
(2)printk开启打印
使用:
cat /proc/sys/kernel/printk
7 4 1 7 4(新版Linux才有)
echo 8 > /proc/sys/kernel/printk //8 > KERN_DEBUG, so KERN_DEBUG will print
分析:
kernel/printk/prink.c有如下定义:
int console_printk[5] = {
CONSOLE_LOGLEVEL_DEFAULT, /*7,console_loglevel, 控制台输出,<7 的才输出 */
MESSAGE_LOGLEVEL_DEFAULT, /*6,default_message_loglevel, 即printk(“hell world”);优先级为4 */
CONSOLE_LOGLEVEL_MIN, /*1,minimum_console_loglevel, 最小支持的打印等级为1,0留给内核严重错误使用 */
CONSOLE_LOGLEVEL_DEFAULT, /*7,default_console_loglevel, 第一个默认的等级*/
MESSAGE_LOGLEVEL_DEFAULT, /*4,default_devkmsg_loglevel, 进入kmesg /dev/kmsg log的等级*/
};
(1)第一个参数7:表示小于7优先级消息才会被输出到控制台。
(2)第二个参数4 :表示默认的printk消息优先级别,即printk(“hell world”);优先级为4, 由于4<7,故可以被打印到控制台。
(3)第三个参数1 :表示可接收的最高优先级,当printk disable控制台输出时,设置第一个参数为1,但是,从内核等级来看,还有优先级0,这个是printk最高级优先级,一般用于内核严重消息打印。比如内存错误或者 watchdog reset.也可以设置第一个和第三个参数为0
(4)第四个参数7: 默认控制台优先级,即第一个参数的默认优先级。
(5)第五个参数4:执行dmesg(/dev/kmsg)输出log,该等级即是消息进入log的等级,<4 的消息都能在dmesg下找到。
2. dev_dbg、 pr_debug、dev_vdbg、dev_printk
dev_dbg定义:
#if defined(CONFIG_DYNAMIC_DEBUG) //如果定义动态调试,执行echo 'file hub.c +p' > /sys/kernel/debug/dynamic_debug/control 开启打印
#define dev_dbg(dev, format, ...) \
do { \
dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
} while (0)
#elif defined(DEBUG) //定义了debug,则 dev_printk(KERN_DEBUG""), 执行 echo 8 > /proc/sys/kernel/printk 开启打印
#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
pr_debug定义:
/* If you are writing a driver, please use dev_dbg instead */
#if defined(CONFIG_DYNAMIC_DEBUG)
#include <linux/dynamic_debug.h>
/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
#define pr_debug(fmt, ...) \
dynamic_pr_debug(fmt, ##__VA_ARGS__) //动态调试
#elif defined(DEBUG)
#define pr_debug(fmt, ...) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) //正常打印
#else
#define pr_debug(fmt, ...) \
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) //不打印
#endif
dev_vdbg定义:
#ifdef VERBOSE_DEBUG //定义了这个才打印
#define dev_vdbg dev_dbg
#else
#define dev_vdbg(dev, format, arg...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, format, ##arg); \
})
#endif
dev_printk定义:
static void __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
{
if (dev) //带个前缀
dev_printk_emit(level[1] - '0', dev, "%s %s: %pV", dev_driver_string(dev), dev_name(dev), vaf);
else
printk("%s(NULL device *): %pV", level, vaf);
}
void dev_printk(const char *level, const struct device *dev,
const char *fmt, ...)
{
struct va_format vaf;
va_list args;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
__dev_printk(level, dev, &vaf);
va_end(args);
}
EXPORT_SYMBOL(dev_printk);
离线