連載
» 2010年08月03日 00時00分 公開

作りながら理解するファイルシステムの仕組み(6):AndroidエミュレータでLinuxカーネルをデバッグ!! (3/3)

[森 崇 株式会社 永和システムマネジメント,@IT MONOist]
前のページへ 1|2|3       

Linuxカーネルをデバッグする

 それでは、先ほどコンパイルしたカーネルモジュールを使用して、Androidを起動してみましょう。

 要領は以下のとおりです。


$ cd ${HOME}/mydroid
$ android-sdk-linux_86/tools/emulator -kernel common/arch/arm/boot/zImage @androidDev -qemu -s 

 emulatorコマンドの引数にあるオプションの意味は、以下のとおりです(表3)。

オプション 意味
-kernel AndroidエミュレータのLinuxカーネルを指定する
@ 仮想デバイス名を指定する
-qemu -s gdbとの通信用ポート(1234)を開く
表3 emulatorコマンドの引数にあるオプションの意味

Android起動直後の状態 図6 Android起動直後の状態

 うまくAndroidが起動できました。それでは、まず画面下のタブをクリックし、「Dev Tools」−「Terminal Emulator」を選択して、コマンドライン上でAndroid環境を確認してみましょう。

ターミナル上でファイルシステムを確認 図7 ターミナル上でファイルシステムを確認

 図7は、ターミナル上で以下のコマンドを実行した結果です。

$ ls -l
$ mount 

 lsの実行結果から、ルート(/)直下には、17個のファイルがあることが分かります。PC Linuxとはだいぶディレクトリ構成は違うようです。特に興味深いのは、「sdcard」というディレクトリがあることです。これは、Android端末のSDカードがマウントされるディレクトリになります。

 さて、気になるAndroidエミュレータで採用されているファイルシステムですが、引数なしでmountコマンドを実行すればその一覧を見ることができます。このうち永続化可能なものとしては、「/sdcard」のvfatと「/system」などのyaffs2があります。

 vfatはWindows用のファイルシステムで、SDカードで使われるファイルシステムですね。一方、yaffs2はNAND専用のファイルシステムです。PC Linuxのファイルシステムの場合、HDDのファイルシステムはext3かext4ですが、携帯端末の場合は、HDDだと衝撃に弱いため、NANDなどのフラッシュメモリが使われている場合が多いです。このため、そのファイルシステムも特殊なものを使用する必要があります(yaffs2はその1つなのですね)。

 それでは、以下のコマンドを実行し、Linuxカーネルのデバッグをしましょう。

$ cd ${HOME}/mydroid/common
$ ddd --debugger ../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gdb 

GUIデバッグツール 図8 GUIデバッグツール

 dddは、“Data Display Debugger”の略で、--debuggerで指定したgdbコマンドをGUI上で操作するためのコマンドです。図8は、dddの初期画面であり、大きく分けて3つの枠があります。1番上はグラフィック表示用のもので、真中がソース表示用、1番下がgdbコマンド実行用のものです。

 それでは、以下の要領でgdbコマンドを実行し、デバッグの準備をしましょう。

(gdb) target remote localhost:1234     ……Androidエミュレータのgdbポート(1234)に接続する
(gdb) file vmlinux     ……gdbにLinuxカーネルイメージを認識させる
(gdb) b vfs_statfs     ……Linuxカーネルの関数vfs_stafs()にブレイクを張る
(gdb) c     ……Linuxカーネルの処理を継続させる

 次に、Androidのターミナル上で、dfコマンドを実行してみます。すると、dfコマンドの延長で実行されるvfs_statfs()というカーネル関数で処理が止まり、図9のように表示されます。

vfs_statfsでデバッグする 図9 vfs_statfsでデバッグする

 この関数では、44行目のdentry->d_sb->s_op->statfs(dentry,buf)を実行している個所が重要であり、dentryという変数からstatfs()という関数ポインタのコールが行われていることが分かります。このdentryという変数は、Linuxカーネル内でファイル名を管理する共通データであり、ここからファイルシステム固有の処理(今回の場合はstatfs())を呼び出すことができる構造になっています。そして、statfs()呼び出し完了後には、bufというデータにdfで表示すべき情報が設定されるようになります。

 それでは、ステップ実行で45行目まで実行し、dentryおよびbufデータの中を表示してみましょう。

LinuxカーネルデータのGUI表示 図10 LinuxカーネルデータのGUI表示

 まず、dentryデータのd_nameというメンバを見てみると(図10)、“/”というファイル名があるのが分かります。つまり、このdentryはルートディレクトリを表しているのです。次に、bufの中をのぞいてみると、特徴的なものとして、f_bsizeが4096bytesで、f_namelenが255となっていますね。f_bsizeは、ファイルシステムのブロックサイズで、f_namelenはこのファイルシステムの最大のファイル名長です。

 このように、カーネルのデバッグができるようになればLinuxカーネル内のすべてのデータを参照できるようになります。また、通常のアプリケーションのデバッグと同様に、変数の値を書き換えてしまうこともできます。興味のある方は、ぜひ、カーネルの中を探検してみてください。



 次回は、Linuxカーネルのファイルシステム・データ構造の概要を解説し、自分が書いたデータがカーネル内のどこにあるのかを確かめていきます。お楽しみに!(次回に続く)


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.