驱动中如何打印调试信息?用哪个宏替代 printf?
在Linux内核驱动中,不能使用标准C库的printf函数,因为内核运行在内核空间,无法直接使用用户空间的库函数。内核提供了专门的打印函数:
1. 基本打印函数
printk(KERN_LEVEL "format string", ...);
2. 推荐的替代宏
现代内核代码更推荐使用pr_系列宏,它们会自动包含适当的日志级别:
#include <linux/printk.h> pr_emerg("Emergency message\n"); // KERN_EMERG pr_alert("Alert message\n"); // KERN_ALERT pr_crit("Critical message\n"); // KERN_CRIT pr_err("Error message\n"); // KERN_ERR pr_warn("Warning message\n"); // KERN_WARNING pr_notice("Notice message\n"); // KERN_NOTICE pr_info("Informational message\n");// KERN_INFO pr_debug("Debug message\n"); // KERN_DEBUG
3. 日志级别
级别 | 宏 | 描述 |
---|---|---|
0 | KERN_EMERG | 系统不可用 |
1 | KERN_ALERT | 需要立即采取行动 |
2 | KERN_CRIT | 紧急情况 |
3 | KERN_ERR | 错误条件 |
4 | KERN_WARNING | 警告条件 |
5 | KERN_NOTICE | 正常但重要的情况 |
6 | KERN_INFO | 信息性消息 |
7 | KERN_DEBUG | 调试级消息 |
4. 设备特定打印
对于设备驱动,可以使用dev_系列宏,它们会自动包含设备信息:
dev_emerg(dev, "Device emergency\n"); dev_err(dev, "Device error: %d\n", err);
5. 动态调试
对于更灵活的调试,可以使用动态调试:
#define DEBUG #include <linux/dynamic_debug.h> pr_debug("Debug message with dynamic control\n");
然后可以通过/sys/kernel/debug/dynamic_debug/control文件动态启用/禁用特定调试信息。
扩展知识
控制printk行为
可以通过以下方式控制printk行为:
/proc/sys/kernel/printk
:控制控制台日志级别dmesg
命令:查看内核环形缓冲区CONFIG_PRINTK
:内核编译选项
性能考虑
printk可能会影响性能,特别是在高速路径中:
- 避免在中断上下文中频繁打印
- 生产代码中减少不必要的打印
- 考虑使用tracepoints或ftrace替代频繁的printk