LeavaTailの日記

LeavaTailの日記

Linuxエンジニアを目指した技術者の備忘録

QEMUでx86_64用Linuxカーネルを起動する

はじめに

x86Intelが開発したマイクロプロセッサの命令セットアーキテクチャであり、x86_64はx86を64ビットに拡張した命令セットアーキテクチャである。 x86はパーソナルコンピュータやサーバなど幅広く使われている。

一方、プロセッサエミュレータQEMUは、ブートローダの再設定などせずにカーネルramdiskを直接ロードすることができる。 そこで、プロセッサエミュレータでもあるQEMUを用いてx86用にビルドされたLinuxカーネルを動かす方法を解説する。

本記事では、以下の動作をする環境を目指す。

f:id:LeavaTail:20201214213716p:plain
カーネル起動ワークフローとメモリマップイメージ図

変更履歴

  • 2020/05/26: 記事公開
  • 2020/12/11: ブログタイトルを "x86_64用" に訂正
  • 2020/12/14: GDBスタブの手順を削除

環境構成

ホスト環境x86_64アーキテクチャに構築する。

f:id:LeavaTail:20200524170044p:plain
実施環境

起動対象のLinuxカーネルは、ホストOS(Ubuntu 18.04)上にインストールしたQEMUから動作させる。 また、今回はクロスコンパイラ環境をDockerで構築した。

ルートファイルシステムとして、Buildrootで生成したルートファイルシステムの非圧縮のcpio形式のアーカイブを利用する。

本記事は、下記の環境とソフトウェアバージョンに基づいて説明する。

環境 パラメータ
ホスト環境 x86_64
ホストOS Ubuntu 20.04
Buildroot buildroot-2020.02.8
QEMU QEMU emulator version 4.2.1
linux 5.7
Docker version 19.03.13
Docker image ubuntu:20.04

ロスコンパイラ環境の構築手順

  1. ホスト環境にDockerをインストールする。 docs.docker.com

  2. ロスコンパイラ環境を構築する。(作成が億劫な人は、著者自作Dockerfile(https://github.com/LeavaTail/kernel-build)を使用してほしい)

     leava@ubuntu-bionic:~$ docker run --rm --name=kbuild -h "kbuild" -v /srv:/work -it ubuntu:20.04 /bin/bash 
    
  3. コンテナ環境下にカーネルのビルドに必要なパッケージをインストールする。(今回はUbuntuコンテナを利用する)

     root@kbuild:/# apt install git bc bison flex libssl-dev make libncurses-dev libelf-dev file wget cpio unzip rsync build-essential
    
  4. カーネルソースの取得

     root@kbuild:/# cd /work
     root@kbuild:/work# git clone https://github.com/torvalds/linux.git
     root@kbuild:/work# cd linux
     root@kbuild:/work/linux# git checkout -b v5.7 refs/tags/v5.7
    
  5. ロスコンパイラ環境用の環境変数を設定する。

     root@kbuild:/work/linux# export ARCH="x86"
    
  6. x86Linuxカーネル用のコンフィグを生成する。

     root@kbuild:/work/linux# make x86_64_defconfig
    
  7. カーネルをビルドする。

     root@kbuild:/work/linux# make -j `getconf _NPROCESSORS_ONLN` bzImage
    

ルートファイルシステムの構築

Buildrootを用いてrootfsを構築する。

  1. Buildrootをインターネットからダウンロード、ファイルを解凍する。

     leava@ubuntu-bionic:~$ wget https://buildroot.org/downloads/buildroot-2020.02.8.tar.gz
     leava@ubuntu-bionic:~$ tar zxvf  buildroot-2020.02.8.tar.gz && cd buildroot-2020.02.8
    
  2. x86_64専用のデフォルトコンフィグqemu_x86_64_defconfigを利用する。

     leava@ubuntu-bionic:~/buildroot-2020.02.8$ make qemu_x86_64_defconfig
    
  3. Buildrootのビルド

     leava@ubuntu-bionic:~/buildroot-2020.02.8$ make
    
  4. ルートファイルシステムの確認

     leava@ubuntu-bionic:~/buildroot-2020.02.8$ ls -l output/images/rootfs.ext4
     lrwxrwxrwx 1 root root 11 Sep  8 15:45 output/images/rootfs.ext4 -> rootfs.ext2
    

カーネルの起動

  1. x86QEMUをインストールする。

     leava@ubuntu-bionic:~$ sudo apt install qemu-system-x86
    
  2. 作成したカーネルQEMUで実行する。

     leava@ubuntu-bionic:~$ qemu-system-x86_64 \
         -kernel /srv/linux/arch/x86/boot/bzImage \
         -drive file=/srv/buildroot-2020.02.8/output/images/rootfs.ext2,if=ide,format=raw
         -nographic \
         -append "root=/dev/sda console=ttyS0"
    

おわりに

本記事では、QEMUx86_64用Linuxカーネルを起動させる手順を説明した。
Buildrootで構築した場合、自動でセットアップしてくれるため非常に使いやすく便利である。

参考

QEMULinuxカーネルを起動する

linuxカーネルデバッグ