码迷,mamicode.com
首页 > 数据库 > 详细

默認打開pr_debug和dev_dbg

时间:2016-08-25 23:38:59      阅读:486      评论:0      收藏:0      [点我收藏+]

标签:

在進行Linux驅動開發時經常見到使用pr_debug和dev_dbg打印驅動的log,如果在內核配置時選擇了CONFIG_DYNAMIC_DEBUG宏,那麼就可以利用類似下面的命令打開對應文件的log:

echo -n "file xxx.c +p" > /sys/kernel/debug/dynamic_debug/control

但是有時候我們需要看到這個文件在內核啓動階段的log,那麼改怎麼辦呢?

這裏有兩種方法:

方法一 修改內核傳參

修改bootloader傳遞給kernel的bootargs,如果使用了設備樹的話,可以修改在chosen節點中bootargs屬性的值,具體方法內核文檔:Documentation/dynamic-debug-howto.txt

這種方案的優點是不需要修改驅動代碼。

 

方法二 在需要開啓log的驅動文件的開頭定義宏DEBUG

這樣該驅動文件中的pr_debug和dev_dbg就可以打開了。

比如驅動文件的名字是tfa98xx.c,那麼就在其第一個非註釋行添加DEBUG宏的定義:

/*
 * tfa98xx.c   tfa98xx codec module
 *
 * Copyright (c) 2015 NXP Semiconductors
 *
 *  Author: Sebastien Jan <sjan@baylibre.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#define DEBUG
#define pr_fmt(fmt) "%s(): " fmt, __func__

#include <linux/module.h>
#include <linux/i2c.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <linux/of_gpio.h>
......

 爲什麼這樣做可以實現呢?下面我們以pr_debug爲例簡單分析。

在內核配置了CONFIG_DYNAMIC_DEBUG後,pr_debug的定義如下:

#define pr_debug(fmt, ...) \
    dynamic_pr_debug(fmt, ##__VA_ARGS__)

dynamic_pr_debug的定義如下:

#define dynamic_pr_debug(fmt, ...)                do {                                    DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);            if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT))            __dynamic_pr_debug(&descriptor, pr_fmt(fmt),                       ##__VA_ARGS__);        } while (0)

這裏用到了宏DEFINE_DYNAMIC_DEBUG_METADATA,定義如下:

#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)            static struct _ddebug  __aligned(8)                __attribute__((section("__verbose"))) name = {                .modname = KBUILD_MODNAME,                    .function = __func__,                        .filename = __FILE__,                        .format = (fmt),                        .lineno = __LINE__,                        .flags =  _DPRINTK_FLAGS_DEFAULT,            }

 __dynamic_pr_debug的定義如下:

void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
{
    va_list args;
    struct va_format vaf;
    char buf[PREFIX_SIZE];

    BUG_ON(!descriptor);
    BUG_ON(!fmt);

    va_start(args, fmt);

    vaf.fmt = fmt;
    vaf.va = &args;

    printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);

    va_end(args);
}

 從上面的代碼可以看到,每一個pr_debug都對應一個名爲descriptor,類型爲struct _ddebug的變量,存放在kernel的__verbose段。決定這個pr_debug能否輸出log的條件就是descriptor.flags & _DPRINTK_FLAGS_PRINT爲true。

在定義descriptor時,將其flags成員賦值爲了_DPRINTK_FLAGS_DEFAULT,下面看一下這兩個宏的定義:

#if defined DEBUG
#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
#else
#define _DPRINTK_FLAGS_DEFAULT 0
#endif

 可以看到,如果定義了宏DEBUG,那麼_DPRINTK_FLAGS_DEFAULT其實就是_DPRINTK_FLAGS_PRINT,所以默認就是可以打印的。如果沒有定義,那麼_DPRINTK_FLAGS_DEFAULT就是0,上面的條件不會成立,也就打印不出來。

 

默認打開pr_debug和dev_dbg

标签:

原文地址:http://www.cnblogs.com/pengdonglin137/p/5808373.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!