Panic も Oops も出ずに強制リセットがかかるようなバグが出た時、とりあえず死ぬ直前の様子だけでも見たいことがある。もし u-boot を使っているのなら、再起動した時に u-boot の起動プロンプトから残骸を覗き見ることができる。
下準備 (1) __log_buf のアドレスを探す
Linux が printk 用リングバッファをどこに配置しているか調べる。 2 種類の方法があって、ひとつめは Linux 起動後に /proc/kallsyms から「 __log_buf 」シンボルを検索する。
$ sudo cat /proc/kallsyms | grep ‘__log_buf’
c07d4d21 b __log_buf
または Linux Kernel を make した環境で System.map から「 __log_buf 」シンボルを検索する。
$ grep ‘__log_buf’ System.map
c07d4d21 b __log_buf
探し当てたアドレス (この例では共に 0xc07d4d21) は論理アドレスなので、物理アドレスへ変換する。この作業には例えば利用中のアーキテクチャ用の vert_to_phys() 函数 (or マクロ) の実装を参照して手計算すれば良いと思う (この例での計算結果は 0x407d4d21 になった) 。
下準備 (2) __log_buf のサイズを探す
Linux Kernel の CONFIG_LOG_BUF_SHIFT の値から大きさを特定する。多分大抵の環境では (1UL << CONFIG_LOG_BUF_SHIFT) が実際の値だと思う (この例では CONFIG_LOG_BUF_SHIFT = 16 だったので、サイズは 0x10000 バイト (64KB) ) 。
準備完了、 u-boot から __log_buf を覗く
ここまでくれば準備完了なので、 Linux がリセットし再起動したら、Linux へ制御が渡る前に u-boot のプロンプトへ入り、「 md.b addr [size] 」を実行すれば OK 。
#md.b 407d4d21 10000
407d4d21: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
407d4d31: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
:
References