4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

QEMU で Raspberry Pi 3 用のバイナリを動かす

Last updated at Posted at 2020-05-21

はじめに

突然ですが、

  • ARM で動く (Type-1) VMM を作りたい
  • –> ARM で OS なしで自分のコードが動かしたい (ベアメタルプログラミング)
  • –> デバッグなどのために QEMU で OS なしに自分のコードを動かしたい
  • –> QEMU で Raspberry Pi エミュレーション環境の構築と動作確認をしたい <– 今ここ

という経緯があり QEMU で Raspberry Pi 3 用のイメージを動かしたくなったのでやってみました。

参考ページ

今回も、ほぼ参考ページの通りやっただけの記事になっております..

環境

  • OS (Distribution): Ubuntu 18.04.4 LTS
  • Linux kernel: Linux uefi-ubuntu 4.15.0-96-generic

QEMU の ビルド

Ubuntu 18.04.4 の apt でインストール可能な QEMU は Raspberry Pi 3 のエミュレーションに未対応のため、自分で QEMU をビルドします。

ビルドの準備

まずは、QEMU のビルドに必要なパッケージを apt でインストールします。
apt build-dep <パッケージ名><パッケージ名> に該当するもののビルドに必要なパッケージをまとめてインストールできるようです (参考にしたページを見て知りました..) 。

ただ、Ubuntu での apt のデフォルト設定では、ビルド時の依存関係に関するレポジトリが設定されていないので、まずはこれを設定します。
以下のページを参考に /etc/apt/sources.list を書き換えてみました。

僕の環境は Ubuntu 16.04 からアップデートしたものなので、参考ページの /etc/apt/sources.list と少し様子が違いましたが、
deb から始まる行をコピペして deb-src にしたものを足していけば大丈夫そうです。

あとは、 apt update して apt build-dep を実行します。
まとめると、実行するコマンドは以下のようになります。

$ sudo vim /etc/apt/sources.list #上記の通り編集
$ sudo apt update
$ sudo apt build-dep qemu

ソースコードのダウンロード & ビルド

次に、QEMU のソースコードを git clone でダウンロードし、 v5.0.0 (執筆時の最新バージョン)タグにチェックアウトしてビルドします。
回線やマシンのスペックによりますが、git clone と make はそこそこ時間がかかると思います。

コマンドは以下の通りです。

$ cd ~
$ git clone git://git.qemu.org/qemu.git
$ cd qemu
$ git checkout -b v5.0.0-release refs/tags/v5.0.0
$ git submodule update --init
$ ./configure --prefix=`pwd`/build --target-list=arm-softmmu,aarch64-softmmu --audio-drv-list=alsa
$ make -j5

(2021.05.09 追記: 最近の QEMU は Ninja というビルドツールを使うらしく、これをセットアップしないと ./configure が失敗するようです。こちらのページが参考になりました。QEMUコンパイルガイド - コードワールド)

ちなみに、make の -j オプションはコンパイル時の並列数を指定するものです。
CPU のコアがたくさんあるなら大きめの数字にすると速くビルドが終わるかもしれないです。
僕は、コア数 + 1 をよく指定します (適切な値については諸説あるらしい)。

システム全体で使えるようにするなら、この後に sudo make install を実行するといいんですが、僕はシステムに入っている QEMU と混ざるのは嫌なので、インストールせずに進めます。
ビルドされた QEMU のバイナリがどこにあるのかわからなかったので、以下のコマンドで見つけます。

$ find . -name 'qemu-system-*'
./aarch64-softmmu/qemu-system-aarch64
./arm-softmmu/qemu-system-arm

qemu-system-aarch64 というのが QEMU の実行ファイルです。

以下のようにして、ビルドした QEMU が raspberry pi 3 のエミュレートに対応していることを確認します。

$ ./aarch64-softmmu/qemu-system-aarch64 -machine help | grep rasp
raspi2               Raspberry Pi 2B
raspi3               Raspberry Pi 3B

サンプルバイナリの準備と実行

今回は 参考ページにあるサンプルコード をビルドして QEMU 上で動かしてみます。

サンプルコードのビルド

次に 参考ページにあるサンプルコード から QEMU 上で試しに動かす ELF バイナリを作ります。
aarch64 向けのクロスコンパイラをインストールし、それを使ってサンプルコードをビルドします。

$ sudo apt install gcc-aarch64-linux-gnu
$ mkdir ~/raspberrypi-baremetal-sample-src
$ cd ~/raspberrypi-baremetal-sample-src
$ # ↑で適当に作ったディレクトリにソースを用意
$ ls
Makefile  boot.S  kernel.c  linker.ld
$ make
aarch64-linux-gnu-gcc -mcpu=cortex-a53 -fpic -ffreestanding -c boot.S -o boot.o
aarch64-linux-gnu-gcc -mcpu=cortex-a53 -fpic -ffreestanding -std=gnu99 -O2 -Wall -Wextra -c kernel.c -o kernel.o
kernel.c: In function 'mmio_write':
kernel.c:6:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   *(volatile uint32_t*)reg = data;
    ^
kernel.c: In function 'mmio_read':
kernel.c:12:11: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   return *(volatile uint32_t*)reg;
           ^
aarch64-linux-gnu-gcc -T linker.ld -o kernel.elf -ffreestanding -O2 -nostdlib boot.o kernel.o
$

ビルドが成功すれば、 kernel.elf というバイナリファイルができます。
(なんか warning 出ていますが、気にせず進めます。)

このサンプルは

  • UART に "Hello kernel World!" を表示する。
  • その後入力待ちになり、入力した文字をそのまま表示する。

という動きをします。

ELF バイナリを QEMU で動かしてみる

では先ほどビルドした ELF バイナリを実際に動かしてみましょう。

$ ~/qemu/aarch64-softmmu/qemu-system-aarch64  -M raspi3 -nographic -kernel ./kernel.elf
HHHHelellello, kernel World!
ello, kernel World!
lo, kernel Woro, kld!
ernel World!
QEMU: Terminated
$

なんだか表示がひどいことになっていますが、これは 4 コアで同時に "Hello kernel World!" を表示した結果です(たぶん)。
上の実行例ではやっていませんが、"Hello kernel World!" (x4 だったはずのなにか) の表示後にキー入力すると、その文字がそのまま表示されます。
Ctrl-a x の順でキー入力をすると、QEMU を終了できます。

ちなみに、表示が崩れるのでコアを1つにしてようと QEMU の -smp オプションを付けてみましたがだめでした。
raspi3 のエミュレーション時はコア数は 4 で固定のようです。
同様にメモリも 1 GiB で固定のようでした(もしかしたら変える方法あるかもしれまんせんが..)

おわりに

というわけで、QEMU 上で Raspberry Pi 3 用のバイナリを動かしてみました。
しばらくこれで ARM のベアメタルプログラミングで遊べるといいですね。

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?