进行内核开发调试
在进行驱动开发的过程中往往要打印一些信息来查看是否正确类似于printf,以下将介绍在内核开发常用的调试方法。.(第一次写文章,内容可能不咋样勿喷呀)
内容
一、printk介绍
二、如何查看并修改消息级别
在应用程序采用printf打印调试、内核驱动采用printk打印调试。
printk函数打印数据到console缓冲区,打印的格式方类似printf。
printk函数说明
头文件:<linux/kernel.h>
int printk(KERN_XXX const char *fmt , …)
@param[in] fmt 格式化参数,如:%d
@return 打印出来的字符个数
例子:
printk(“hello_init\n”);
printk(“hello_init = %d\n”,i);
printk(KERN_ALERT"hello_init=%d\n",i);
printk("<1>"“hello_init=%d”,i);
KERN_ALERT 等效于“<1>”
通过修改KERN_ALERT来修改优先级
优先级打印级别 0最高,7最低
0、 KERN_EMERG “<0>” 用于紧急消息, 常常是那些崩溃前的消息
1、 KERN_ALERT “<1>” 需要立刻动作的情形
2、 KERN_CRIT “<2>” 严重情况, 常常与严重的硬件或者软件失效有关
3、 KERN_ERR “<3>” 用来报告错误情况; 设备驱动常常使用 KERN_ERR 来报告硬件故障
4、 KERN_WARNING “<4>” 有问题的情况的警告, 这些情况自己不会引起系统的严重问题
5、 KERN_NOTICE “<5>” 正常情况, 但是仍然值得注意. 在这个级别一些安全相关的情况会报告
6、 KERN_INFO “<6>” 信息型消息. 在这个级别, 很多驱动在启动时打印它们发现的硬件的信息
7、 KERN_DEBUG “<7>” 用作调试消息
格式化符
符合 | 说明 |
---|---|
%d | 十进制打印 |
%x | 十六进制 |
%u | 无符号整数 |
%lu | 无符号长整数 |
%lx | 十六进制无符号长整数 |
%lld | 64bit整数值 |
%llx | 64bit16进制整数值 |
%zu | size_t 10进制打印 |
%zx | size_t 16进制打印 |
%zd | ssize_t 10进制打印 |
%p | 指针原值输出 |
日志守护进程
【klogd&syslogd】
klogd 内核日志守护进程,将内核消息放入/var/log/messages中
syslogd 系统日志守护进程,将程序消息放入/var/log/messages中
通过命令#dmesg 可以查看消息
也可以通过命令cat /var/log/messages查看消息
【console_loglevel】
if (打印消息级别 < console_loglevel)
打印到当前控制台
可以通过读/proc/sys/kernel/printk来查看控制台消息级别
如,# cat /proc/sys/kernel/printk 出现 4 4 1 7
该文件有四个数字值,它们根据日志记录消息的重要性,定义将其发送到何处。上面显示的4个数据分别对应:
1、控制台日志级别:优先级高于该值的消息将被打印至控制台
2、默认的消息日志级别:将用该优先级来打印没有优先级的消息(未指定日志级别的printk() 采用的默认级别 )
3、最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)
4、默认的控制台日志级别:控制台日志级别的缺省值
可以通过写 /proc/sys/kernel/printk 来修改控制台消息级别
了解了上面的这些知识后,我们就应该知道如何手动控制printk打印了。
例如,我想屏蔽掉所有的内核printk打印,那么我只需要把第一个数值调到最小值1或者0。
方法一:
#echo 1 4 1 7 > /proc/sys/kernel/printk
方法二:
#klogd -c 1
…写得很乱