2016年11月21日

Windows用QEMUをDockerコンテナを使用してUbuntu Linuxでクロスビルド

お久しぶりです。だいぶ間が空いてしまいました。その間、全身性エリテマトーデス(SLE)という、免疫が狂って自分自身を攻撃してしまう原因不明の難病を発病し、半年ほど休職していたりと色々ありましたが、なんとか職場復帰することができました。またよろしくお願いします。

そんなこんなで浦島太郎状態なのですが、QEMU のサイトを久しぶりに見てみた所、Docker という仮想化技術を使用して QEMU の Windows 用バイナリをビルドできるようになったそうなので、試してみました。


Docker は Linux ホスト上で、別の仮想 Linux ユーザー空間(環境)を軽量高速に動作させることができる技術です。QEMU の開発グループが準備した、Windows 用バイナリのビルド環境を整えた Fedora Linux のイメージ(コンテナ)を、ローカルの Linux ホスト上で動作させて、クロスビルドを行うことになります。この方法のメリットは、QEMU の公式ビルド環境を簡単に使用できるということです。(また、これは直接 Docker とは関係ありませんが、Linux 上でクロスビルドを行うと、Windows 上のネイティブビルドよりもかなり高速というメリットもあります。)

今回は手元にあった Ubuntu 14.04 64bit を使用しました。(16.04 が最新の LTS なので、一つ古いのですが、なにぶん浦島太郎ですので…。)

○ Docker のインストール

以下のサイトの通りに作業しました。
Install Docker on Ubuntu

Docker を動作させるためには、64bit の Linux ホストと、3.10 以降の Linux Kernel が必要です。 Ubuntu 14.04 64bit は条件を満たしています。
$ uname -r
3.13.0-45-generic
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates
(私の環境では、既にインストール済みでした。)
$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee /etc/apt/sources.list.d/docker.list
$ sudo apt-get update
$ sudo apt-get install docker-engine
$ sudo service docker start
(私の環境では、既に起動済みでした。)
ちゃんとインストールできたかどうか、hello-world コンテナを動かして確認。エラーが出ずに終了すれば OK です。
$ sudo docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

○ Windows 版 QEMU のビルド

適当なワーキングディレクトリで QEMU の git リポジトリを clone して root に移動し、make します。
$ git clone git://git.qemu-project.org/qemu.git
$ cd qemu
$ make docker-test-mingw@fedora V=1 DEBUG=1 J=4
イメージのダウンロードやセットアップなどが自動的に行われ、できた仮想 Fedora Linux 環境の中にログインした状態になります。後は通常の QEMU のビルドとなります。今回は AArch64 ターゲットの 64bit バイナリ(x86_64)をビルドしました。

QEMU の公式サイトでは、以下の PATH に移動してビルドを行うとありますが、このソースだとどうも DTC (libfdt) が無いとエラーになり、git リポジトリでも無いので submodule update もできません。
[root@f9a7ae43e8d5 src]# cd $QEMU_SRC
[root@f9a7ae43e8d5 src]# pwd
/tmp/qemu-test/src
[root@f9a7ae43e8d5 src]# ls ..
build  install  src
[root@f9a7ae43e8d5 src]# ./configure --cross-prefix=x86_64-w64-mingw32- --prefix=/tmp/qemu-test/install --target-list=aarch64-softmmu --disable-strip --extra-cflags="-static-libgcc -static-libstdc++"

ERROR: DTC (libfdt) version >= 1.4.0 not present. Your options:
         (1) Preferred: Install the DTC (libfdt) devel package
         (2) Fetch the DTC submodule, using:
             git submodule update --init dtc
[root@f9a7ae43e8d5 src]# git submodule update --init dtc
fatal: Not a git repository (or any of the parent directories): .git
仕方ないので、この仮想 Fedora 環境の中で、再び QEMU の git リポジトリを clone しました。
[root@f9a7ae43e8d5 src]# cd ..
[root@f9a7ae43e8d5 qemu-test]# git clone git://git.qemu-project.org/qemu.git
[root@f9a7ae43e8d5 qemu-test]# cd qemu/
[root@f9a7ae43e8d5 qemu]# git submodule update --init dtc
[root@f9a7ae43e8d5 qemu]# ./configure --cross-prefix=x86_64-w64-mingw32- --prefix=/tmp/qemu-test/install --target-list=aarch64-softmmu --disable-strip --extra-cflags="-static-libgcc -static-libstdc++"
[root@f9a7ae43e8d5 qemu]# make
make は成功しましたが、msgfmt が無くて make install は失敗しました。
この仮想環境は Fedora なので、yum で gettext をインストールしてみた所、上手くいきました。
[root@f9a7ae43e8d5 qemu]# yum install gettext
[root@f9a7ae43e8d5 qemu]# make install
できたバイナリと、必要な dll をホスト Ubuntu にコピーします。(docker cp ではワイルドカード * がどうも使えない感じだったので、とりあえずディレクトリを丸ごとコピーしました。)
以下はホスト Ubuntu での作業となります。
$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
f9a7ae43e8d5        qemu:fedora         "/var/tmp/qemu/run te"   30 minutes ago      Up 29 minutes                           adoring_swartz
$ sudo docker cp f9a7ae43e8d5:/tmp/qemu-test/install .
$ sudo docker cp f9a7ae43e8d5:/usr/x86_64-w64-mingw32/sys-root/mingw/bin/ .
コピーが終わったら、コンテナを終了します。ややこしいですが、以下はコンテナ内部での作業となります。
[root@f9a7ae43e8d5 qemu]# exit
exit すると自動的にコンテナは停止します。このコンテナを再び起動する場合は、ホストで以下のようにします。(docker ps の a オプションは、停止中のコンテナも表示するオプションです。)
$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
f9a7ae43e8d5        qemu:fedora         "/var/tmp/qemu/run te"   About an hour ago   Exited (0) 6 minutes ago                       adoring_swartz
eebee92599b2        hello-world         "/hello"                 2 hours ago         Exited (0) 2 hours ago                         boring_hawking
$ sudo docker start f9a7ae43e8d5
$ sudo docker attach f9a7ae43e8d5

○ 動作確認

以下は Windows 64bit 環境での作業となります。
動作確認には、以下のサイトのビルド済み AArch64 Linux を使用しました。

http://people.linaro.org/~alex.bennee/images/

前述した Ubuntu 内のバイナリと dll を、samba 等を使って Windows にコピーして、コマンドプロンプト上から実行します。
>install\qemu-system-aarch64.exe -machine virt -cpu cortex-a57 -machine type=virt -smp 1 -m 2048 -kernel aarch64-linux-3.15rc2-buildroot.img
Ctrl + Alt + 2 で、シリアルコンソール画面が出ます。
qemu_aarch64_linux


トラックバックURL

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード