QEMU を使った Linux のカーネルデバッグ

0 0
QEMU を使った Linux のカーネルデバッグ方法を以下の流れで紹介します。Ubuntu 20.04 で試しています。

1. カーネルのビルド
2. 初期 RAM ディスクの作成
3. QEMU を用いてカーネルの起動
4. GDB を用いてカーネルデバッグ

1. カーネルのビルド
1.1. 必要なモジュールをインストールします。
sudo apt-get install libncurses5-dev gcc make git exuberant-ctags bc libssl-dev flex bison libelf-dev


1.2. カーネルのソースコードをダウンロードします。
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git


1.3. 利用できるカーネルのバージョンを確認します。
cd linux-stable
git tag –l


1.4. 利用できるカーネルのバージョンでチェックアウトします。
git checkout –b <ブランチ名> <上記 1.3. で確認したカーネルのバージョン>


1.5. デフォルトのカーネルの設定ファイルを作成します。
make x86_64_defconfig


1.6. カーネルの設定ファイルを編集します。
make menuconfig


「Kernel hacking」に移動します。


「Compile-time checks and compiler options」に移動します。


以下にチェックを入れます。
「Compile the kernel with debug info」
「Provide GDB scripts for kernel debugging」


「save」を実行し .config ファイルを保存します。




1.7. カーネルをビルドします。
sudo make –j$(nproc)
-j$(nproc) を指定することで、稼働中のマシンの CPU コア使ってビルドします。


1.8. arch/x86_64/boot に bzImage があることを確認します。
ls –l arch/x86_64/boot


2. 初期 RAM ディスクの作成
カーネルを起動させる際に必要になる RAM ディスクを作成します。
mkinitramfs -o ramdisk.img


3. QEMU を用いてカーネルの起動

3.1. QEMU をインストールします。
sudo apt install qemu-system-x86


3.2. カーネルを起動します。
qemu-system-x86_64 -kernel <linux-stable>/arch/x86_64/boot/bzImage -initrd <ramdisk.img のパス> -m 1024M -nographic -append "console=ttyS0 nokaslr" -s -S

引数の意味は以下です。
引数意味
-kernel <linux-stable>/arch/x86_64/boot/bzImageカーネルのパスを指定
-initrd <ramdisk.img のパス>初期 RAM ディスクの指定
-m 1024M1024 Mbyte のメモリを割り当て
-nographicグラフィックな出力を省略
-append “console=ttyS0 nokaslr”出力を ttyS0 に設定し、kernel randomization を使用しない
-sGDB の接続を許可
-SGDB が接続するまで、ブートさせない

GDB からの接続待ちの状態になります。


4. GDB を用いてカーネルデバッグ
4.1. カーネルビルド時に、カーネルデバッグに便利なスクリプトが作成されています。そのスクリプトを読み込めるように設定します。
echo "add-auto-load-safe-path <linux-stable>/vmlinux-gdb.py" >> ~/.gdbinit


4.2. GDB を開始します。
gdb <linux-stable>/vmlinux


4.3. デバッグ対象に接続します。
target remote :1234


4.4. start_kernel にブレークポイントを張ってみます。
break start_kernel


4.5. カーネルの実行を開始します。
c
start_kernel でブレークします。


4.7.「Ctrl + x, a」を押すと、ソースコードも表示されます。


4.8.「lx-」と入力しタブを 2 回押すと、スクリプトを確認できます。


4.9.「lx-version」を実行してみると、カーネルバージョンが表示されます。


4.10.「c」を入力すると、カーネルが実行されます。



情報元
Debugging the Linux Kernel with Qemu and GDB
ページトップ