debugfsの使用

8160 ワード

Linuxドライバ開発ではpr_の使用がよく見られますdebugとdev_dbg印刷ドライバのロゴ、カーネル構成時にCONFIG_を選択した場合DYNAMIC_DEBUGマクロでは、次のようなコマンドで対応するファイルのロゴを開くことができます.
echo -n “file xxx.c +p” >/sys/kernel/debug/dynamic_debug/controlしかし、カーネル起動段階におけるこのファイルのロゴを見る必要がある場合があります.では、どうすればいいですか.
ここには2つの方法があります.
メソッド1カーネルパラメータを変更する
bootloaderがkernelに渡すbootargsを変更し、デバイスツリーを使用する場合はchosenノードのbootargsプロパティの値を変更できます.具体的な方法カーネルドキュメント:Documentation/dynamic-debug-howto.txt
このスキームの利点は、ドライバコードを変更する必要がないことである.
例えば、電源を入れるカーネルが起動する必要があるときにtfa 98 xxを開きます.c、wcd-mbhc-v2.cとq 6 asm.cのロゴは、まずこの2つのファイルに対応するKBUILD_を見ることができます.MODNAME、この値を表示するには2つの方法があります.
対応するMakefileを表示ドライバで上の3つのファイルに対応するMakefileを表示します.次のようにします.
snd-soc-tfa98xx-objs := tfa98xx.o tfa_container.o tfa_dsp.o tfa9887B_init.o tfa9887_init.o tfa9888_init.o tfa9890_init.o tfa9891_init.o tfa9897_init.o obj-$(CONFIG_SND_SOC_TFA98XX) += snd-soc-tfa98xx.o
snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o
obj-y += audio_calibration.o audio_cal_utils.o q6adm.o q6afe.o q6asm.o q6audio-v2.o q6voice.o q6core.o rtac.o q6lsm.o audio_slimslave.oそのうち、tfa 98 xx.c対応KBUILD_MODNAMEはsnd-soc-tfa 98 xx,wcd-mbhc-v 2である.c対応KBUILD_MODNAMEはsnd-soc-wcd-mbhc,q 6 asmである.c対応KBUILD_MODNAMEはq 6 asm
2つ目の方法は、以下のコマンドで3つのファイルのlogを開くと、この3つのファイルがlogを出力すると同時に対応するKBUILD_MODNAMEもadb shell'echo-n"file tfa 98 xx.c+pmflt">/sys/kernel/debug/dynamic_を出力debug/control’ adb shell ‘echo -n “file wcd-mbhc-v2.c +pmflt” >/sys/kernel/debug/dynamic_debug/control’ adb shell ‘echo -n “file q6asm.c +pmflt” >/sys/kernel/debug/dynamic_debug/control’に含まれる記号の意味は以下の通りである.
The flags specification comprises a change operation followed by one or more flag characters. The change operation is one of the characters:
- remove the given flags + add the given flags = set the flags to the given flags
The flags are:
p enables the pr_debug() callsite. f Include the function name in the printed message l Include line number in the printed message m Include module name in the printed message t Include thread ID in messages not generated from interrupt context _ No flags are set. (Or’d with others on input)その後、関連する操作を実行し、これらのファイルにlogを出力させ、logに次のように表示されます.
[ ] snd_soc_tfa98xx:tfa98xx_mute::tfa98xx -: state: [ : q6asm_callback: nowait_cmd_cnt
[]snd_soc_wcd_mbhc:wcd_correct_swch_plug::wcd_correct_swch_plug:hs_comp_res:上のlogから分かるように、最初のコロンの前の文字列が対応するKBUILD_MODNAMEである.
KBUILD_MODNAMEを取得すると、デバイスツリーファイルを変更できます.以下は、既存のbootargsに追加した結果です.
chosen {
    bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1 snd_soc_wcd_mbhc.dyndbg=\"file wcd-mbhc-v2.c +p\" snd_soc_tfa98xx.dyndbg=\"file tfa98xx.c +p; file tfa_dsp.c +p\"";
};

snd_soc_tfa 98 xx.dyndbg="file tfa 98 xx.c+p;file tfa_dsp.c+p"を例に説明します.
等号の前の命名規則は「KBUILD_MODNAME.dyndbg」であり、等号の後ろの方が分かりやすく、二重引用符の変換が必要であることに注意が必要である.
このセクションをデバッグするときにkernel/params.cのlogを開くことができます.ファイルの先頭にDEBUGマクロを定義すると、このファイルのpr_debugとdev_dbgが開きます.
これによりkernelが起動すると、コマンドラインの解析プロセスが表示されます.
<>[ 0.015794] doing dyndbg params, parsing ARGS: ‘sched_enable_hmp=1 sched_enable_power_aware=1 snd_soc_wcd_mbhc.dyndbg=“file wcd-mbhc-v2.c +p” snd_soc_tfa98xx.dyndbg=“file tfa98xx.c +p; file tfa_dsp.c +p” console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0 androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x237 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 zswap.enabled=1 cma=32M@0-0xffffffff loglevel=0 androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=orange androidboot.veritymode=logging androidboot.serialno=d94b873f androidboot.fingerprint.id=fpc androidboot.hardware.id=0x1c uart_enable=0 ro.housing.color=black pmode=0 androidboot.baseband=msm mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_nt35597_dsc_wqxga_cmd:config2:1:none:cfg:single_dsi fpsimd.fpsimd_settings=0’ <>[ ’ <>[ ’ <>[ 0.015824] doing dyndbg params: snd_soc_wcd_mbhc.dyndbg=‘file wcd-mbhc-v2.c +p’ <>[ 0.015901] doing dyndbg params: snd_soc_tfa98xx.dyndbg=‘file tfa98xx.c +p; file tfa_dsp.c +p’ <>[ 0.015975] doing dyndbg params: console=‘ttyHSL0,115200,n8’ <>[ 0.015980] doing dyndbg params: androidboot.console=‘ttyHSL0’ <>[ 0.015986] doing dyndbg params: androidboot.hardware=‘qcom’ <>[ ’ <>[ 0.015996] doing dyndbg params: msm_rtb.filter=‘0x237’ <>[ ’ <>[ ’ <>[ ’ <>[ 0.016016] doing dyndbg params: cma=‘32M@0-0xffffffff’ <>[ ’ <>[ 0.016026] doing dyndbg params: androidboot.bootdevice=‘624000.ufshc’ <>[ 0.016031] doing dyndbg params: androidboot.verifiedbootstate=‘orange’ <>[ 0.016036] doing dyndbg params: androidboot.veritymode=‘logging’ <>[ 0.016041] doing dyndbg params: androidboot.serialno=‘d94b873f’ <>[ 0.016046] doing dyndbg params: androidboot.fingerprint.id=‘fpc’ <>[ 0.016051] doing dyndbg params: androidboot.hardware.id=‘0x1c’ <>[ ’ <>[ 0.016061] doing dyndbg params: ro.housing.color=‘black’ <>[ ’ <>[ 0.016070] doing dyndbg params: androidboot.baseband=‘msm’ <>[ 0.016075]doing dyndbg params:mdss_mdp.panel=‘1:dsi:0:qcom,mdss_dsi_nt 35597_dsc_wqxga_cmd:config 2:1:none:cfg:single_dsi’<>[’メソッド2 logを開く必要があるドライバファイルの先頭にマクロDEBUGを定義する
これにより、ドライバファイルのpr_debugとdev_dbgが開きます.
例えば、ドライバファイルの名前がtfa 98 xx.cである場合、最初のコメント行にDEBUGマクロの定義を追加します.
/*
  • tfa98xx.c tfa98xx codec module

  • Copyright © 2015 NXP Semiconductors

  • Author: Sebastien Jan [email protected]

  • 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#include#include#include#include#include#include...なぜ実現できるのでしょうか?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); } ) ここではマクロDEFINE_DYNAMIC_DEBUG_METADATAが用いられ、定義は以下の通りである.
    #define DEFINE_DYNAMIC_DEBUG_METADATA(name,fmt))attribute((section("_verbose"))name={.modname=KBUILD_MODNNAME,.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として割り当てます.次に、2つのマクロの定義を見てみましょう.
    #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であり、上記の条件は成立しません.印刷できません.
    dynamic debugが初期化されると__verboseセグメントを巡回し、struct_ddebugタイプごとの変数を処理します.DEBUGマクロを定義すると、起動後にcontrolノードを読み取ることができ、すでに「p」パラメータがあることがわかります.
    root@colombo:/# cat/d/dynamic_debug/control | grep tfa sound/soc/codecs/tfa98xx.c: [snd_soc_tfa98xx]tfa98xx_mute =p “state: %d\012” sound/soc/codecs/tfa98xx.c: [snd_soc_tfa98xx]tfa98xx_digital_mute =p “%s enter, mute: %d\012” sound/soc/codecs/tfa98xx.c: [snd_soc_tfa98xx]tfa98xx_info_vstep =p “vsteps count: %d [prof=%d]\012”...もちろん、次のコマンドを使用して閉じることもできます.
    echo-n「file xxx.c-p」>/sys/kernel/debug/dynamic_debug/control完了.