GitHubで公開されているEMLinuxを、QEMUでエミュレートしたRaspberry Piで動かしてみた

# はじめに
サイバートラストが提供する組み込み/IoT機器向けのOSである[EMLinux](https://www.cybertrust.co.jp/iot/emlinux.html)を、[QEMU](https://www.qemu.org/)でエミュレートしたRaspberry Pi上で動かしてみました。

なお、本記事では、[GitHubのリポジトリで公開されているEMLinux](https://github.com/miraclelinux/meta-emlinux/tree/bookworm)を使用しました。

# 参考
## EMLinuxのWebページ
- [EMLinux](https://www.cybertrust.co.jp/iot/emlinux.html)
  - 製品版と同じ機能を利用できる無償評価版の申し込みが可能です。

## EMLinuxのブログ
- [EMLinux 3.0 を Raspberry Pi 3 で動かしてみよう：入門編](https://www.cybertrust.co.jp/blog/iot/techinfo/pi3-emlinux3.html)

## MIRACLE LINUX Users Meetup!!!
- [Raspberry Pi で試す組み込みLinux⼊⾨](https://miraclelinux.connpass.com/event/301828/)
- [動画](https://www.youtube.com/watch?v=x3-498F4YYA&t=835s)

# 構成図
```
+--------------------------------+
| +----------------------------+ |
| | +------------------------+ | |
| | | +--------------------+ | | |
| | | | EMLinux 3.0        | | | |
| | | +--------------------+ | | |
| | | Rapsberry Pi 3         | | |
| | +------------------------+ | |
| | QEMU                       | |
| +----------------------------+ |
| Ubuntu Server 22.04.4 LTS      |
+--------------------------------+
```

# 各ソフトウェアのバージョン
## Ubuntu Server
```
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.4 LTS"
```

## Docker
```
$ docker version 
Client:
 Version:           24.0.5
 API version:       1.43
 Go version:        go1.20.3
 Git commit:        24.0.5-0ubuntu1~22.04.1
 Built:             Mon Aug 21 19:50:14 2023
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          24.0.5
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.3
  Git commit:       24.0.5-0ubuntu1~22.04.1
  Built:            Mon Aug 21 19:50:14 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.2
  GitCommit:        
 runc:
  Version:          1.1.7-0ubuntu1~22.04.2
  GitCommit:        
 docker-init:
  Version:          0.19.0
  GitCommit: 
```

## Docker Compose
```
$ docker compose version 
Docker Compose version 2.20.2+ds1-0ubuntu1~22.04.1
```

## QEMU
```
$ qemu-system-aarch64 --version 
QEMU emulator version 6.2.0 (Debian 1:6.2+dfsg-2ubuntu6.17)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
```

# 前提条件
## 評価環境
|項目|要件|
|-|-|
|OS|Dockerが動作するLinux|
|CPU|Intel 64対応プロセッサまたはAMD64対応プロセッサ (8スレッド以上を推奨)|
|RAM|8GiB以上 (16GiB以上を推奨)|
|Disk|30GiB以上の空き容量|
|その他|インターネットに接続可能であること|
- Proxyサーバがある場合、.bashrcなどに以下を設定し、再ログインしてください。
  ```
  $ cat .bashrc
  (snip)
  PROXY=http://<proxyサーバのIPアドレス>:<ポート番号>
  export http_proxy=${PROXY}
  export https_proxy=${PROXY}
  export ftp_proxy=${PROXY}
  export no_proxy='127.0.0.1'  
  ```

## その他
- 以降の作業は、Ubuntu Serverインストール時に作成したemlinuxユーザを使用しました。
- emlinuxユーザのホームディレクトリは/home/emlinuxです。以降の作業は/home/emlinux上で行いました。

# DockerおよびDocker Composeのインストール
以下のコマンドを実行し、DockerおよびDocker Composeをインストールしてください。
```sh
sudo apt install -y docker.io docker-compose-v2
```

emlinuxユーザをdockerグループに追加してください。
```sh
sudo gpasswd -a emlinux docker
```

ログアウトし、再ログイン後、sudoなしでdockerコマンドを実行できることを確認してください。
```
$ docker ps 
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

Proxyサーバがある場合、Dockerにproxyサーバを設定してください。
```sh
sudo mkdir /etc/systemd/system/docker.service.d
```
```sh
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=<proxyサーバのIPアドレス>:<ポート番号>"
Environment="HTTPS_PROXY=<proxyサーバのIPアドレス>:<ポート番号>"
EOF
```

dockerデーモンを再起動してください。
```sh
sudo systemctl daemon-reload
```
```sh
sudo systemctl restart docker
```

docker searchコマンドを実行し、proxyサーバが正しく設定されていることを確認してください。
```
$ docker search mariadb 
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mariadb                        MariaDB Server is a high performing open sou…   5713      [OK]       
(snip)
```

# qemu-user-staticのインストール
x86_64の環境でarm64のバイナリをクロスビルドするために、qemu-user-staticをインストールしてください。
```sh
sudo apt install -y qemu-user-static
```

# meta-emlinuxリポジトリのクローン
Proxyサーバがある環境の場合、以下のコマンドでproxyサーバの設定を行ってください。
```sh
git config --global http.proxy <proxyサーバのFQDNまたはIPアドレス>:<ポート番号>
```
```sh
git config --global https.proxy <proxyサーバのFQDNまたはIPアドレス>:<ポート番号>
```

リポジトリをクローンするためのディレクトリを作成してください。
```sh
mkdir -p /home/emlinux/github/miraclelinux/emlinux/repos
```

以下のディレクトリに移動してください。   
```sh
cd /home/emlinux/github/miraclelinux/emlinux
```   

git cloneコマンドで、リポジトリをクローンしてください。
```sh
git clone -b bookworm https://github.com/miraclelinux/meta-emlinux.git repos/meta-emlinux
```

以下のディレクトリに移動してください。
```sh
cd /home/emlinux/github/miraclelinux/emlinux/repos/meta-emlinux/docker
```

上記dockerディレクトリ内にあるrun.shを実行してください。初回起動時にはコンテナの作成処理が行われます。コンテナ作成処理後、コンテナにログインした状態になります。
```
$ ./run.sh
(snip)
build@82fa043f8378:~/work$
```

# local.confファイルの編集
以下のコマンドを実行し、ビルドのために必要な環境変数を設定してください。
```sh
source repos/meta-emlinux/scripts/setup-emlinux build 
```

viエディタでlocal.confファイルを開き、ファイルの末尾に以下を追記してください。
```
$ vi conf/local.conf
(snip)
MACHINE = "raspberrypi3bplus-64"
USERS += "emlinux"
USER_emlinux[password] = "emlinux"
USER_emlinux[flags] = "create-home clear-text-password"
USER_emlinux[home] = "/home/emlinux"
USER_emlinux[shell] = "/bin/bash"
IMAGE_INSTALL:append = " sshd-regen-keys"
IMAGE_PREINSTALL:append = " \
    openssh-server \
    connman \
"
```
# EMLinuxのビルド
EMLinuxのビルドを行ってください。
```sh
bitbake emlinux-image-base
```

ビルド完了後、exitコマンドでコンテナからログアウトしてください。
```
build@82fa043f8378:~/work$ exit 
exit
```

# QEMUのインストール
QEMUをインストールしてください。
```sh
sudo apt install -y qemu-system-arm seabios
```

# EMLinuxの起動
以下のディレクトリに移動してください。
```sh
cd /home/emlinux/github/miraclelinux/emlinux/build
```

wicファイルのサイズを変更してください。1GiB, 2GiB, 4GiBのように、2の乗数のサイズとなるように変更してください。以下の例では、1GiBに変更しています。
```sh
qemu-img resize ./tmp/deploy/images/raspberrypi3bplus-64/emlinux-image-base-emlinux-bookworm-raspberrypi3bplus-64.wic 1G
```

viエディタでrun.shファイルを作成してください。
```sh
vi run.sh
```

run.shファイルに以下を記載してください。
```sh
qemu-system-aarch64 \
-m 1024 \
-M raspi3b \
-kernel ./tmp/deploy/images/raspberrypi3bplus-64/Image \
-dtb ./tmp/deploy/images/raspberrypi3bplus-64/bcm2837-rpi-3-b-plus.dtb \
-drive format=raw,file=./tmp/deploy/images/raspberrypi3bplus-64/emlinux-image-base-emlinux-bookworm-raspberrypi3bplus-64.wic \
-append "console=ttyAMA0 root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4 dwc_otg.fiq_fsm_enable=0 bcm2708_fb.fbwidth=1280 bcm2708_fb.fbheight=720" \
-no-reboot \
-device usb-kbd \
-device usb-mouse \
-device usb-net,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-nographic
```

run.shファイルに実行権限を付与してください。
```sh
chmod +x run.sh
```

run.shファイルを実行してください。
```sh
./run.sh
```
```
$ ./run.sh 
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 6.1.75-cip14 (isar-users@googlegroups.com) (aarch64-linux-gnu-gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #1 SMP PREEMPT Thu, 01 Jan 1970 0   1:00:00 +0000
[    0.000000] Machine model: Raspberry Pi 3 Model B+
[    0.000000] efi: UEFI not found.
[    0.000000] Reserved memory: created CMA memory pool at 0x0000000038000000, size 64 MiB
(snip)
```
- FIXME: 現時点では、ログインプロンプトが表示されず、後述のsshでログインする必要があります。

別のターミナルを開き、sshで仮想マシンにアクセスできることを確認してください。
```sh
ssh emlinux@localhost -p 2222
```

# さいごに
GitHubから入手したEMLinuxを、QEMUでエミュレートしたRaspberry Pi上で動かしてみました。Raspberry Piをすぐに入手できない場合の参考になれば幸いです。