RaspberryPi向けLinuxをQEMUでエミュレートする

この投稿では、以下のLinuxをホストOS上でエミュレータQEMUを実行して動かしてみたときの備忘録になる。

QEMUのインストール

備忘録で必要なのは、qemuのほうでstatic版の説明はしない。

> sudo apt install qemu
> sudo apt install qemu-user-static

ARM用コンパイラでビルドしたCソースの実行

ARM用のGCCコンパイラをインストールする

> sudo apt install gcc-arm-linux-gnueabihf 

お約束のHelloWorldソース。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  printf("Hello World !!\n");
  return 0;
}

コンパイルと実行

> arm-linux-gnueabi-gcc sample.c -o sample
> sudo qemu-arm -L /usr/arm-linux-gnueabi/ sample
Hello World !!

QEMUエミュレータ

通常版(qemu-system-arm)は、完全なエミュレートの時に使用する。スタティック版(qemu-arm-static)は、イメージをホストOS上にマウントしてソフトウェアのみのエミュレートする。

通常版はそれなりのマシンスペックがないともっさりした動作になる。スタティック版は、実装するソフトウェアの確認程度なら十分使用できるとのこと。

エミュレータ   Raspberry Piモデル
qemu-system-arm
qemu-arm-static 
RaspberryPi 1、Zero向けのARM1176
qemu-system-aarch64
qemu-aarch64-static
RaspberryPi 2、3向けのCortex-A53

qemu-system-armを使ってYocto ProjectのLinuxを起動する。

前回のブログで作成したRaspberryPi向けのrpi-basic-imageビルドで作成した最小構成のLinuxイメージを実行してみる。

qemu-system-armでは、実行時に引数でカーネルを指定する必要がある。qemu用のカーネルは以下でダウンロードした。ソースからビルドすることも可能。

dhruvvyas90/qemu-rpi-kernel

kernel-qemu

任意の場所にビルドしたsdimgを配置して、実行する。
引数でマシンタイプ-machineを指定する必要がある。ここでは一番構成が近いversatilepbを指定する。また、引数の最後にエミュレートするLinuxイメージファイルを指定する。

> qemu-system-arm  -cpu arm1176 -m 256 -machine versatilepb -kernel kernel-qemu -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw init=/bin/bash" -hda raspi.sdimg

ちなみにqemu-rpi-kernelを使用した場合、GPIO関連のモジュールを追加していないと、起動時できなかった。どれが起因しているかは不明だが、以下の行がレシピに追加したイメージで起動できた。

IMAGE_INSTALL += " pi-blaster rpio rpi-gpio userland"