驱动调试之printk

1、printk的基本概念

    阅读过linux内核源码的童鞋肯定知道,内核有很多调用printk函数打印的调试信息。但是在内核启动的时候,这些调试信息是默认不会打印出来的,需要启动之后调用dmesg命令才能查看到内核的打印信息,即便这样,我们还是不能查看到完整的内核打印信息,这是为什么呢?下面我们要引入printk的级别

   1.1 printk 打印级别

   内核通过 printk() 输出的信息具有日志级别,日志级别是通过在 printk() 输出的字符串前加一个带尖括号的整数来控制的,如 printk("<6>Hello, world!\n");。内核中共提供了8种不同的日志级别,在 linux/kernel.h 中有相应的宏对应:
    #define KERN_EMERG   "<0>"   /* system is unusable */
    #define KERN_ALERT   "<1>"   /* action must be taken immediately */
    #define KERN_CRIT     "<2>"   /* critical conditions */
    #define KERN_ERR      "<3>"   /* error conditions */
    #define KERN_WARNING "<4>"   /* warning conditions */
    #define KERN_NOTICE   "<5>"   /* normal but significant */
    #define KERN_INFO     "<6>"   /* informational */

    #define KERN_DEBUG    "<7>"   /* debug-level messages */

    以上8种级别,级别0最高(哈哈,一般来说内核里面数字越小级别越高)。当你直接调用printk函数没有设置打印级别的时候,默认为4级,以下分别为每个级别的意义:

KERN_EMERG
用于突发性事件的消息,通常在系统崩溃之前报告此类消息。 
KERN_ALERT
在需要立即操作的情况下使用此消息。 
KERN_CRIT
用于临界条件下,通常遇到严重的硬软件错误时使用此消息。 
KERN_ERR
用于报告错误条件;设备驱动经常使用KERN_ERR报告硬件难题。 
KERN_WARNING
是关于问题状况的警告,一般这些状况不会引起系统的严重问题。 
KERN_NOTICE 
该级别较为普通,但仍然值得注意。许多与安全性相关的情况会在这个级别被报告。 
KERN_INFO
信息消息。许多驱动程序在启动时刻用它来输出获得的硬件信息。
KERN_DEBUG 
一些内核的调试信息。

    1.2 设置打印级别

    你可以执行:cat  /proc/sys/kernel/printk,查看设置的打印级别,该文件有四个数据,默认是6 4 1 7,这四个数据的含义分别如下:                                                                                                       
        控制台日志级别:优先级高于该值的消息将被打印至控制台
        默认的消息日志级别: 将用该优先级来打印没有设置优先级的消息
        最低的控制台日志级别: 控制台日志级别可被设置的最小值 (其实就是最高优先级)
        默认的控制台日志级别:  控制台日志级别的缺醒值

    现在我们可以执行echo  8 /proc/sys/kernel/printk,这样所有的消息就可以打印出来了

2、printk的实现原理

         一些基本信息,platform:s3c2440        kernel version:2.6     uboot :1.6

        2.1  uboot 传入控制参数,设置串口为输出方式
        console=ttySAC0  console=tty1
        2.2  内核处理uboot传输的参数
                console_setup
                        add_preferred_console    //表示我想用名为"ttySAC0"的控制台,并记录下来
        2.3  printk主要调用过程
                printk
                        vprintk  //先把输出信息放入临时的buffer
                            vscnprintf
                            //把临时buffer的数据进行处理,再写入log_buf
                            //比如printk("abc");这种没有加打印级别的消息,加上默认打印级别,再写入log_buf
                            //调用dmesg命令把log_buf里的数据打印出来重现内核的输出信息(历史信息)
                            //调用硬件的write函数输出信息
                            release_console_sem();
                                call_console_drivers(_con_start,  log_end);
                                    //从log_buf中得到数据,算出打印级别,只输出打印级别高的log信息
                                    if( msg_log_level < consol_loglevel )
                                            __call_console_drivers
                                                  con->write(con, &LOG_BUF(start), end -start);



   

        

            

                                      

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值