Help us understand the problem. What is going on with this article?

Linux を(わりと)シンプルな構成でビルドして Qemu で起動する

More than 3 years have passed since last update.

はじめに

  • 唐突に小さいカーネルを何となく作りたくなりました(。>﹏<。)
  • そこで(わりと)シンプルな kernel config で Linux カーネルを作れるか試してみました
  • まったり進行です

前提

  • ビルド環境は Ubuntu 14.04 64 bit を使っています
    • 64 bit 環境で 32 bit のカーネルをビルドする、とか需要あるのかしら。
    • あれば書こうかなぁ。
  • init は自作の Hello, world で代用します
  • ディスクイメージ(qcow2とか)に焼く方法は書いてません。qemu の -kernel オプションと -initrd オプションを使ってビルドしたカーネルを起動します
    • そのうち書くかも

ざっくりとした流れ

  1. qemu をインストールして
  2. カーネルを設定して、ビルドして
  3. initramfs を作って
  4. qemu で起動(∩´∀`)∩

下準備

使うツールのインストール

  • qemu と カーネルの設定をする際に使う make menuconfig で利用される libcurses 群を入れます
$ sudo apt-get install qemu
$ sudo apt-get install libncurses5 libncurses5-dev

カーネルのダウンロードと解凍

$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.4.tar.xz
$ tar Jxvf linux-4.4.4.tar.xz
$ cd linux-4.4.4

カーネルの設定

カーネルに必要最低限なコンフィグのみ残す

$ make allnoconfig
  • どれくらい行数があるか気になったのでカウントしてみました
$ egrep -v "(^#|^$)" .config | wc -l
234
  • 結構ありますね(* ´﹃` *)

qemu で起動するために必要なコンフィグを有効にする

  • make menuconfig を使います。
$ make menuconfig
  • 下の項目を有効にしていきます。
[*] 64-bit kernel

-> General setup
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
-> General setup
  -> Configure standard kernel features
[*] Enable support for printk

-> Executable file formats / Emulations
[*] Kernel support for ELF binaries

-> Device Drivers
  -> Character devices
[*] Enable TTY

-> Device Drivers
  -> Character devices
    -> Serial drivers
[*] 8250/16550 and compatible serial support
[*]   Console on 8250/16550 and compatible serial port
設定項目 何に使うか
64-bit kernel 今回は 64 bit kernel をビルドするので必要です
Initial RAM filesystem and RAM disk (initramfs/initrd) support initramfs/initrd を有効にします。qemu から -initrd オプションで起動させるためです。これを有効にしないでやるケースってどんなときなんでしょうね。
Enable support for printk printk 出力を有効にします。カーネルの起動ログをコンソールに出すようにするためです。
Kernel support for ELF binaries ELF を読み込めるようにします。initrd に指定するプログラムが ELF binary なためです。
Enable TTY TTY を有効にします。ターミナルに文字を出力させるためです。
Console on 8250/16550 and compatible serial port シリアルポートを有効にします。カーネルの出力を見られるようにするために必要です
  • ここでコンフィグの行数をカウントしてみます。
$ egrep -v "(^#|^$)" .config | wc -l
311
  • make allnoconfig が 234 だったので、思ったより増えてますね。

カーネルのビルド

  • -j オプションはマルチコアの場合に並列ビルドをします。任意で指定してくださいませ。
$ make -j4 bzImage
  • ビルドを待ちます。この時にビルド対象のコード一覧を見てみるのも楽しいかもしれません
  • bzImage ができていることを確認します。今回は 64 bit kernel なので  ./arch/x86/boot/bzImage を使います
$ find ./ -name bzImage
./arch/i386/boot/bzImage
./arch/x86/boot/bzImage
  • カーネルができあがったので、次に initramfs を作ります。

initramfs の作成

下準備(作業ディレクトリの作成とか)

$ mkdir ~/work
$ cd ~/work
$ cp ~/linux-4.4.4/arch/x86/boot/bzImage bzImage

init で実行するプログラムの作成

  • おもむろに vim を立ち上げて init.c ファイルを作ります
$ vim init.c
  • 以下のようなコードを書きます
#include <stdio.h>

int main(void) {
  printf("-----------HELLO------------\n");
  return 0;
}
  • libc をプログラム本体に含めるために static ビルドをします
$ gcc -static -o init init.c

プログラムを gzip 圧縮の initramfs 形式にする

  • cpio コマンドがパイプでプログラム名を受け取れるため、以下のようなコマンドを実行して、initramfs を作ります
$ echo init | cpio -o -H newc | gzip > initramfs.cpio.gz

カーネルの起動

  • これですべての準備が整いました。以下のコマンドを実行してカーネルを立ち上げてみてください
$ qemu-system-x86_64 -kernel ./bzImage -initrd ./initramfs.cpio.gz -append "console=ttyS0" -nographic
  • 以下のような感じでカーネルの起動ログが出て、作成したプログラムの HELLO という文字が出力されていると思います
    • panic してますが、とりあえずここまで。
(省略)
mousedev: PS/2 mouse device common for all mice
input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input0
Freeing unused kernel memory: 440K (ffffffff81175000 - ffffffff811e3000)
-----------HELLO------------
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000

Kernel Offset: disabled
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
kaishuu0123
プログラミング(C, Ruby, Java, Python etc) も DB (MySQL, PostgreSQL, sqlite, MongoDB, Berkeley DB etc)も、ネットワーク(Cisco, Juniper etc ) もインフラ(色々) もやっていて、何をやる人なんだか一言で言いにくいので、結局「システムエンジニア」を名乗っています。
https://www.saino.me/
weseek
WESEEK, Inc. はシステム開発のプロフェッショナル集団です。UIデザインからサービス運用のためのネットワーク・インフラ構築まで全てを自社で行います。
https://weseek.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした