linuxカーネルをビルドしてQEMUで起動

The Linux Kernel Archives

公式のカーネル配布サイトから最新リリース(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