QEMUを使ってカーネルのデバッグを勉強しようとしていました。最初に試しましたが、仮想ファイルシステムがなかったため失敗しました。 この投稿 への回答は、仮想ファイルシステムが必要であることを示唆しています。ただし、カーネルデバッグ用に仮想FSを作成する方法と、それをqemuに渡す方法については説明していません。手伝ってくれませんか?
使用するディストリビューションに応じて、ファイルシステムイメージを作成するさまざまな方法があります。 この記事 "Linux from Scratch"システムへの面倒な方法を説明します。
一般的に、どちらかqemu-img
を使用してQEMUイメージを作成し、いくつかをフェッチしますディストリビューションのインストールメディアとインストールメディアでQEMUを使用してイメージを準備します( このページではDebian GNU/Linuxのプロセスについて説明します )または他の誰かが作成した画像を使用します。
QEMU Wikibookのこのセクション 必要なすべての情報が含まれています。
編集:リンクされた質問に対するGillesの回答が示唆するように、テストに本格的なルートファイルシステムは必要ありません。 initrd
image(たとえば、Arch Linuxのinitrdはここにあります)
Ubuntu 16.10ホストでテストされたQEMU + GDBのステップバイステップの手順
ゼロからすばやく始めるために、最小限の完全に自動化されたQEMU + Buildrootの例を次の場所で作成しました: https://github.com/cirosantilli/linux-kernel-module-cheat 主な手順を以下に示します。
まず、ルートファイルシステムrootfs.cpio.gz
を取得します。必要な場合は、次のことを検討してください。
init
-実行可能イメージのみ: 1つのプログラムのみを実行するカスタムLinuxディストリビューション|他には何も実行しない| Unix&Linux Stack Exchange次に、Linuxカーネルで:
git checkout v4.9
make mrproper
make x86_64_defconfig
cat <<EOF >.config-fragment
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_GDB_SCRIPTS=y
EOF
./scripts/kconfig/merge_config.sh .config .config-fragment
make -j"$(nproc)"
qemu-system-x86_64 -kernel Arch/x86/boot/bzImage \
-initrd rootfs.cpio.gz -S -s
別の端末で、start_kernel
からデバッグを開始するとします。
gdb \
-ex "add-auto-load-safe-path $(pwd)" \
-ex "file vmlinux" \
-ex 'set Arch i386:x86-64:intel' \
-ex 'target remote localhost:1234' \
-ex 'break start_kernel' \
-ex 'continue' \
-ex 'disconnect' \
-ex 'set Arch i386:x86-64' \
-ex 'target remote localhost:1234'
完了です!!
カーネルモジュールについては、以下を参照してください。 QEMUを使用してLinuxカーネルモジュールをデバッグする方法?|スタックオーバーフロー
Ubuntu 14.04、GDB 7.7.1の場合、hbreak
が必要であり、break
ソフトウェアブレークポイントは無視されました。 16.10ではもうそうではありません。参照: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
厄介なdisconnect
とその後のエラーを回避するには、次のようにします。
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
関連スレッド:
参照:
既知の制限:
-O0
をサポートしていません(パッチなしでコンパイルすることもできません): Linuxカーネルを最適化解除して-O0でコンパイルする方法は?| Stack Overflowmax-completions
の修正後でも、一部の種類のタブ補完でメモリを消費します: 大きなバイナリのタブ補完割り込み|スタックオーバーフロー そのパッチでカバーされなかったコーナーケースの可能性があります。したがって、ulimit -Sv 500000
はデバッグ前の賢明なアクションです。 file<tab>
のfilename
引数に対して次のようにタブ完了sys_execve
を実行すると、特に爆発しました。 Linuxカーネルのsys_execve()システムコールは絶対または相対の両方を受信できますか?パス?|スタックオーバーフロー