linuxカーネルをビルドしてQEMUで起動
公式のカーネル配布サイトから最新リリース(6.3.8)をダウンロードしました。
解凍して移動します。※kaishuu0123さんの記事では 4.4.4 を使用していたので、私も 4.4.4 でやろうとビルドを試みたのですが、makefileにパッチを当てた影響かqemuで上手く起動できませんでした。
tar xf linux-6.3.8.tar.xz cd linux-6.3.8
※ビルド時に必要な依存関係はインストールしておいてください
ビルドしたいので必要最低限のコンフィグのみ残します。
make allnoconfig
以下のコンフィグを設定します。
make menuconfig
設定項目 | 用途 |
---|---|
64-bit kernel | 64ビット向けになる? |
Initial RAM filesystem and RAM disk (initramfs/initrd) support | 初期RAMディスクの有効化 |
Enable support for printk | カーネルの起動ログをコンソールに出せるようにする |
Kernel support for ELF binaries | 実行ファイルを読み込めるようにする |
Enable TTY | ttyを有効にする |
Console on 8250/16550 and compatible serial port | シリアルポートを有効にしてカーネルの出力を見れるようにする ttys0 |
ビルドします
make -j$(nproc) bzImage
./archにアーキテクチャ別にカーネルが出来ます。
今回はx86の方を使います。
作業用ディレクトリを作成し、そこで cpio でアーカイブし gzip で圧縮して使うinitramfsを作ります。 以下のようなコードを書いて静的ビルドして実行ファイルをinitramfs形式にします。
// init.c #include <stdio.h> int main() { printf("--------------------Hello------------------------\n"); return 0; }
echoで実行ファイル名をcpioにパイプで渡し、-Hパラメータでアーカイブ形式を指定し、更にパイプし gzip は initramfs.cpio.gz にリダイレクトさせてます。
gcc -static -o init init.c echo init | cpio -o -H newc | gzip > initramfs.cpio.gz
起動してみます。-initrdパラメータがなくてもカーネルは起動しましたが、ここら辺はよく理解していないので今後の課題です。
qemu-system-x86_64 -kernel ./bzImage -initrd ./initramfs.cpio.gz -append "console=ttyS0" -nographic
Freeing unused kernel image (rodata/data gap) memory: 1520K Run /init as init process --------------------Hello------------------------ Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
pkill qemu
- 参考文献(ありがとうございます) qiita.com