RaspberryPi4の活用を見越して QEMU Staticモードによる x86_64 Ubuntu 環境への高速な Debian Buster arm64(aarch64)エミュレーション環境の構築

# １．Introduction
RaspberryPi4の販売が国外でスタートし、Raspbian Buster (armv7l/32bit) が公式にリリースされましたので、あらゆるバイナリを64bitでビルドできる高速な環境の構築方法を模索していました。 今回は QEMUのSTATICモードを使用して x86_64 Ubuntu16.04 上に arm64(aarch64) の高速なエミュレーション環境の構築にトライしました。 **[Raspberry Pi のセルフビルド環境を QEMU で作る - Qiita - autchさん](https://qiita.com/autch/items/c8c9cdc7b8e5821e81a4)** と **[losetupコマンドの使い方 - Qiita - hana shinさん](https://qiita.com/hana_shin/items/90b3c6fb54b59ebba076)** と **[debian stretchで「/etc/resolv.conf」が無い問題を解決する。](http://labunix.hateblo.jp/entry/20180409/1523280068)** の記事を猛烈に参考にさせていただいています。 二番煎じです。 ハードウェアエミュレーションモードと比べると超絶爆速でした。 体感的には１０倍速ほどに感じます。
ちなみに私は、Tensorflow を高速にネイティブビルドすることばかり考えている人間です。

# ２．Environment

- Ubuntu 16.04 x86_64
- Debian Buster arm64 (aarch64) + Python 3.7.3
- QEMU

# ３．Procedure
まず、私のGoogle Driveから、 **`Debian Buster arm64(aarch64)`** のディスクイメージをダウンロードして解凍します。 公式のダウンロード元サイトは **[こちら](https://cdimage.debian.org/cdimage/daily-builds/daily/arch-latest/arm64/iso-cd/)** ですが、とても遅いです。

```bash:Debian_Busterの高速ダウンロードと解凍
$ sudo apt install qemu qemu-user-static curl wget
$ mkdir qemu-debian-arm64;cd qemu-debian-arm64

$ curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id=1mkxiqwDYYJ3OjBNn7rUh3Y-uTuJw1qL0" > /dev/null
$ CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"
$ curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id=1mkxiqwDYYJ3OjBNn7rUh3Y-uTuJw1qL0" -o 20190628_raspberry-pi-3_buster_PREVIEW.img.xz
$ xz -dv 20190628_raspberry-pi-3_buster_PREVIEW.img.xz
```

次に、QEMUによるarm64エミュレーション環境を構築します。

```bash:エミュレーション環境の構築
$ sudo losetup -P -f -r 20190628_raspberry-pi-3_buster_PREVIEW.img
$ sudo fdisk -l
Disk /dev/loop0: 88.5 MiB, 92778496 bytes, 181208 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop1: 88.4 MiB, 92692480 bytes, 181040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop2: 105.5 MiB, 110608384 bytes, 216032 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

　：

Disk /dev/loop8: 1.5 GiB, 1572864000 bytes, 3072000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x36969c21

デバイス     起動  Start 最後から セクタ  Size Id タイプ
/dev/loop8p1        2048   614399  612352  299M  c W95 FAT32 (LBA)
/dev/loop8p2      614400  3071999 2457600  1.2G 83 Linux


$ sudo mount -o ro /dev/loop8p2 /mnt
$ sudo tar cvjf ./debian-buster-arm64.tar.bz2 -C /mnt .

$ sudo umount /mnt
$ sudo losetup -d /dev/loop8

$ mkdir -p debian;cd debian
$ sudo tar xjf ../debian-buster-arm64.tar.bz2

$ sudo update-binfmts --display | grep aarch64

qemu-aarch64 (enabled):
 interpreter = /usr/bin/qemu-aarch64-static

$ cd ..
$ sudo cp /usr/bin/qemu-aarch64-static debian/usr/bin/

$ sudo mount -t sysfs sysfs debian/sys
$ sudo mount -t proc proc debian/proc
$ sudo mount -t devtmpfs udev debian/dev
$ sudo mount -t devpts devpts debian/dev/pts
```

最後に、 **`chroot`** により arm64(aarch64) 環境をエミュレーションします。 起動後の権限設定やパッケージの追加は各自で実施してください。 **`#`** がプロンプト表示されたあとは、Raspbian を使用するときとほぼ同じ操作感です。

```console:起動
$ sudo chroot debian /bin/bash
# mkdir /home/debian
# useradd -g users -d /home/debian debian
# passwd debian
New password: 
Retype new password:  
passwd: password updated successfully

# nano /etc/resolv.conf
nameserver 127.0.1.1

# apt-get update --allow-releaseinfo-change
# apt-get update
# apt-get install sudo
# gpasswd -a debian sudo

# su - debian
```

<details><summary>**【参考】QEMU実行バイナリの一覧表示**</summary><div>

```bash:【参考】QEMU実行バイナリの一覧表示
$ ls -l /usr/bin/qemu-*
-rwxr-xr-x 1 root root 1948160  5月 16 22:41 /usr/bin/qemu-aarch64
-rwxr-xr-x 1 root root 3126560  5月 16 22:41 /usr/bin/qemu-aarch64-static
-rwxr-xr-x 1 root root 1300176  5月 16 22:41 /usr/bin/qemu-alpha
-rwxr-xr-x 1 root root 2490688  5月 16 22:41 /usr/bin/qemu-alpha-static
-rwxr-xr-x 1 root root 1833440  5月 16 22:41 /usr/bin/qemu-arm
-rwxr-xr-x 1 root root 3011840  5月 16 22:41 /usr/bin/qemu-arm-static
-rwxr-xr-x 1 root root 1833440  5月 16 22:41 /usr/bin/qemu-armeb
-rwxr-xr-x 1 root root 3015936  5月 16 22:41 /usr/bin/qemu-armeb-static
-rwxr-xr-x 1 root root 1283856  5月 16 22:41 /usr/bin/qemu-cris
-rwxr-xr-x 1 root root 2486656  5月 16 22:41 /usr/bin/qemu-cris-static
-rwxr-xr-x 1 root root 1589200  5月 16 22:41 /usr/bin/qemu-i386
-rwxr-xr-x 1 root root 3345392  5月 16 22:41 /usr/bin/qemu-i386-static
-rwxr-xr-x 1 root root 1094120  5月 16 22:41 /usr/bin/qemu-img
-rwxr-xr-x 1 root root 1174512  5月 16 22:41 /usr/bin/qemu-io
-rwxr-xr-x 1 root root 1480464  5月 16 22:41 /usr/bin/qemu-m68k
-rwxr-xr-x 1 root root 2613632  5月 16 22:41 /usr/bin/qemu-m68k-static
-rwxr-xr-x 1 root root 1262896  5月 16 22:41 /usr/bin/qemu-microblaze
-rwxr-xr-x 1 root root 2490272  5月 16 22:41 /usr/bin/qemu-microblaze-static
-rwxr-xr-x 1 root root 1258800  5月 16 22:41 /usr/bin/qemu-microblazeel
-rwxr-xr-x 1 root root 2486176  5月 16 22:41 /usr/bin/qemu-microblazeel-static
-rwxr-xr-x 1 root root 2140016  5月 16 22:41 /usr/bin/qemu-mips
-rwxr-xr-x 1 root root 3183072  5月 16 22:41 /usr/bin/qemu-mips-static
-rwxr-xr-x 1 root root 2279312  5月 16 22:41 /usr/bin/qemu-mips64
-rwxr-xr-x 1 root root 3301856  5月 16 22:41 /usr/bin/qemu-mips64-static
-rwxr-xr-x 1 root root 2275216  5月 16 22:41 /usr/bin/qemu-mips64el
-rwxr-xr-x 1 root root 3297760  5月 16 22:41 /usr/bin/qemu-mips64el-static
-rwxr-xr-x 1 root root 2135920  5月 16 22:41 /usr/bin/qemu-mipsel
-rwxr-xr-x 1 root root 3178976  5月 16 22:41 /usr/bin/qemu-mipsel-static
-rwxr-xr-x 1 root root 2279280  5月 16 22:41 /usr/bin/qemu-mipsn32
-rwxr-xr-x 1 root root 3301856  5月 16 22:41 /usr/bin/qemu-mipsn32-static
-rwxr-xr-x 1 root root 2275184  5月 16 22:41 /usr/bin/qemu-mipsn32el
-rwxr-xr-x 1 root root 3297760  5月 16 22:41 /usr/bin/qemu-mipsn32el-static
-rwxr-xr-x 1 root root 1066056  5月 16 22:41 /usr/bin/qemu-nbd
-rwxr-xr-x 1 root root 1214224  5月 16 22:41 /usr/bin/qemu-or32
-rwxr-xr-x 1 root root 2453888  5月 16 22:41 /usr/bin/qemu-or32-static
-rwxr-xr-x 1 root root 2686384  5月 16 22:41 /usr/bin/qemu-ppc
-rwxr-xr-x 1 root root 3626528  5月 16 22:41 /usr/bin/qemu-ppc-static
-rwxr-xr-x 1 root root 2817648  5月 16 22:41 /usr/bin/qemu-ppc64
-rwxr-xr-x 1 root root 3749600  5月 16 22:41 /usr/bin/qemu-ppc64-static
-rwxr-xr-x 1 root root 2821712  5月 16 22:41 /usr/bin/qemu-ppc64abi32
-rwxr-xr-x 1 root root 3753664  5月 16 22:41 /usr/bin/qemu-ppc64abi32-static
-rwxr-xr-x 1 root root 2813552  5月 16 22:41 /usr/bin/qemu-ppc64le
-rwxr-xr-x 1 root root 3745504  5月 16 22:41 /usr/bin/qemu-ppc64le-static
-rwxr-xr-x 1 root root 1480464  5月 16 22:41 /usr/bin/qemu-s390x
-rwxr-xr-x 1 root root 2605440  5月 16 22:41 /usr/bin/qemu-s390x-static
-rwxr-xr-x 1 root root 1300240  5月 16 22:41 /usr/bin/qemu-sh4
-rwxr-xr-x 1 root root 2523520  5月 16 22:41 /usr/bin/qemu-sh4-static
-rwxr-xr-x 1 root root 1304336  5月 16 22:41 /usr/bin/qemu-sh4eb
-rwxr-xr-x 1 root root 2523520  5月 16 22:41 /usr/bin/qemu-sh4eb-static
-rwxr-xr-x 1 root root 1509136  5月 16 22:41 /usr/bin/qemu-sparc
-rwxr-xr-x 1 root root 2584960  5月 16 22:41 /usr/bin/qemu-sparc-static
-rwxr-xr-x 1 root root 1578768  5月 16 22:41 /usr/bin/qemu-sparc32plus
-rwxr-xr-x 1 root root 2642304  5月 16 22:41 /usr/bin/qemu-sparc32plus-static
-rwxr-xr-x 1 root root 1582864  5月 16 22:41 /usr/bin/qemu-sparc64
-rwxr-xr-x 1 root root 2650496  5月 16 22:41 /usr/bin/qemu-sparc64-static
-rwxr-xr-x 1 root root 8873112  5月 16 22:41 /usr/bin/qemu-system-aarch64
-rwxr-xr-x 1 root root 7065768  5月 16 22:41 /usr/bin/qemu-system-alpha
-rwxr-xr-x 1 root root 8705048  5月 16 22:41 /usr/bin/qemu-system-arm
-rwxr-xr-x 1 root root 3671688  5月 16 22:41 /usr/bin/qemu-system-cris
-rwxr-xr-x 1 root root 8411496  5月 16 22:41 /usr/bin/qemu-system-i386
-rwxr-xr-x 1 root root 3636840  5月 16 22:41 /usr/bin/qemu-system-lm32
-rwxr-xr-x 1 root root 6990888  5月 16 22:41 /usr/bin/qemu-system-m68k
-rwxr-xr-x 1 root root 3652424  5月 16 22:41 /usr/bin/qemu-system-microblaze
-rwxr-xr-x 1 root root 3652424  5月 16 22:41 /usr/bin/qemu-system-microblazeel
-rwxr-xr-x 1 root root 8174120  5月 16 22:41 /usr/bin/qemu-system-mips
-rwxr-xr-x 1 root root 8401896  5月 16 22:41 /usr/bin/qemu-system-mips64
-rwxr-xr-x 1 root root 8419560  5月 16 22:41 /usr/bin/qemu-system-mips64el
-rwxr-xr-x 1 root root 8170024  5月 16 22:41 /usr/bin/qemu-system-mipsel
-rwxr-xr-x 1 root root 3578792  5月 16 22:41 /usr/bin/qemu-system-moxie
-rwxr-xr-x 1 root root 3571048  5月 16 22:41 /usr/bin/qemu-system-or32
-rwxr-xr-x 1 root root 8722408  5月 16 22:41 /usr/bin/qemu-system-ppc
-rwxr-xr-x 1 root root 9081928  5月 16 22:41 /usr/bin/qemu-system-ppc64
lrwxrwxrwx 1 root root      17  5月 16 22:41 /usr/bin/qemu-system-ppc64le -> qemu-system-ppc64
-rwxr-xr-x 1 root root 8484328  5月 16 22:41 /usr/bin/qemu-system-ppcemb
-rwxr-xr-x 1 root root 6898792  5月 16 22:41 /usr/bin/qemu-system-sh4
-rwxr-xr-x 1 root root 6902888  5月 16 22:41 /usr/bin/qemu-system-sh4eb
-rwxr-xr-x 1 root root 4032200  5月 16 22:41 /usr/bin/qemu-system-sparc
-rwxr-xr-x 1 root root 7205960  5月 16 22:41 /usr/bin/qemu-system-sparc64
-rwxr-xr-x 1 root root 3704904  5月 16 22:41 /usr/bin/qemu-system-tricore
-rwxr-xr-x 1 root root 3555112  5月 16 22:41 /usr/bin/qemu-system-unicore32
-rwxr-xr-x 1 root root 8466472  5月 16 22:41 /usr/bin/qemu-system-x86_64
-rwxr-xr-x 1 root root 3653224  5月 16 22:41 /usr/bin/qemu-system-xtensa
-rwxr-xr-x 1 root root 3642952  5月 16 22:41 /usr/bin/qemu-system-xtensaeb
-rwxr-xr-x 1 root root 1206032  5月 16 22:41 /usr/bin/qemu-tilegx
-rwxr-xr-x 1 root root 2441600  5月 16 22:41 /usr/bin/qemu-tilegx-static
-rwxr-xr-x 1 root root 1214224  5月 16 22:41 /usr/bin/qemu-unicore32
-rwxr-xr-x 1 root root 2449792  5月 16 22:41 /usr/bin/qemu-unicore32-static
-rwxr-xr-x 1 root root 1597424  5月 16 22:41 /usr/bin/qemu-x86_64
-rwxr-xr-x 1 root root 3353616  5月 16 22:41 /usr/bin/qemu-x86_64-static
```

</div></details>

# ４．Reference articles

**[RaspberryPiの 64bit OS イメージの保管場所](https://people.debian.org/~gwolf/raspberrypi3/)**