i.MX6UL Evaluation KitをQEMUで動かしてみた

# はじめに
i.MX6UL Evaluation KitをQEMUで動かした時の作業メモです。

# 参考にしたサイト
- https://www.nxp.com/docs/en/user-guide/IMX_YOCTO_PROJECT_USERS_GUIDE.pdf
- https://github.com/nxp-imx/meta-imx

# 構成図
```
+------------------------------------------+
| +--------------------------------------+ |
| | +----------------------------------+ | |
| | | +------------------------------+ | | |
| | | | Poky 4.2                     | | | |
| | | +------------------------------+ | | |
| | | Freescale i.MX6UL Evaluation Kit | | |
| | +----------------------------------+ | |
| | QEMU                                 | |
| +--------------------------------------+ |
| Ubuntu Server                            |
+------------------------------------------+
```

# 各ソフトウェアのバージョン
## Ubuntu Server
```
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.6 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.6 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

## QEMU
- GitHubのQEMUのレポジトリをcloneしてビルドし、コマンド名をqemu-system-aarch64-6.2.0に変更しました。
  ```
  $ qemu-system-aarch64-6.2.0 --version 
  QEMU emulator version 6.2.0 (v6.2.0)
  Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
  ```
  ```
  $ qemu-system-aarch64-6.2.0 -M help|grep MX
  imx25-pdk            ARM i.MX25 PDK board (ARM926)
  mcimx6ul-evk         Freescale i.MX6UL Evaluation Kit (Cortex-A7)
  mcimx7d-sabre        Freescale i.MX7 DUAL SABRE (Cortex-A7)
  sabrelite            Freescale i.MX6 Quad SABRE Lite Board (Cortex-A9)
  ```
  - 本記事では、上記の __mcimx6ul-evk__ を使います。
  - なお、Ubuntu Server 20.04の場合、apt-get installでインストール可能な最新バージョンは4.2.1です。
    ```
    $ qemu-system-aarch64 --version 
    QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.27)
    Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
    ```

# repoファイルの入手
1. 以下のコマンドを実行し、repoファイル (実体はPythonのスクリプトファイル) を入手します。
   ```sh
   curl -O https://storage.googleapis.com/git-repo-downloads/repo
   ```
1. repoファイルに実行権を付与します。
   ```sh
   chmod +x repo
   ```
1. repoファイルをPATHが通っているディレクトリ (/usr/local/bin) にコピーします。
   ```sh
   sudo cp repo /usr/local/bin
   ```
1. vimなどでrepoファイルを開きます。
   ```sh
   sudo vim repo /usr/local/bin/repo
   ```
   - 先頭の1行を以下のように変更してください。
     - 変更前
       ```python
       #!/usr/bin/env python
       ```
     - 変更後
       ```python
       #!/usr/bin/env python3
       ```
   - proxyサーバがある場合には、以下を追記してください。
     ```python
     # (snip)
     import sys
     
     # 追加部分
     os.environ['http_proxy'] = '<your proxy server name>:<port number>'
     os.environ['https_proxy'] = '<your proxy server name>:<port number>'

     # (snip)
     ```
# OSのビルド
1. repo initで初期化します。
   ```sh
   repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-mickledore -m imx-6.1.22-2.0.0.xml
   ```
1. i.MX6UL Evaluation Kit上で動かすOSをビルドするために必要なファイルをダウンロードします。
   ```sh
   repo sync
   ```
1. OSのビルドが可能な状態にします。
   ```
   MACHINE=imx6ulevk DISTRO=poky source setup-environment build
   ```
1. bitbakeコマンドで、OSをビルドします。
   ```sh
   bitbake core-image-minimal
   ```
1. ビルド完了後、build/tmp/deploy/images/imx6ulevk配下の以下のファイルを任意の場所 (e.g., /home/iotuser/imx6) にコピーします。
   - core-image-minimal-imx6ulevk.wic.gz
   - imx6ul-14x14-evk.dtb
   - zImage

# QEMUでエミュレートしたi.MX6UL Evaluation KitでOSを起動
1. /home/iotuser/imx6に移動します。
   ```sh
   cd /home/iotuser/imx6
   ```
1. core-image-minimal-imx6ulevk.wic.gzを解凍し、ファイルサイズを1Gに変更します。
   ```sh
   gunzip core-image-minimal-imx6ulevk.wic.gz
   ```
   ```sh
   qemu-img resize core-image-minimal-imx6ulevk.wic 1G
   ```
1. 仮想マシンを起動するためのシェルスクリプトrun.shを作成します。
   ```sh
   touch run.sh
   ```
   ```sh
   chmod +x run.sh
   ```
   ```sh
   vim run.sh
   ```
   ```sh
   qemu-system-aarch64-6.2.0 \
   -machine mcimx6ul-evk \
   -m 1G \
   -no-reboot \
   -nographic \
   -dtb ./imx6ul-14x14-evk.dtb \
   -drive if=sd,id=sd0,format=raw,file=./core-image-minimal-imx6ulevk.wic \
   -device sd-card,id=sd0 \
   -kernel ./zImage \
   -append "root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait console=ttymxc0 loglevel=8 earlycon printk" \
   ```
   - FIXME: 上記の場合、ネットワークアダプタが有効にならないため、対処方法を探し中です。
1. run.shを実行してください。
   ```sh
   ./run.sh
   ```
1. 初期設定の場合、ユーザroot、パスワードは無しでログイン可能です。
   ```
   (snip)
   Starting syslogd/klogd: done
   
   Poky (Yocto Project Reference Distro) 4.2 imx6ulevk /dev/ttymxc0
   
   imx6ulevk login:    
   ```
1. Enjoy!
   ```
   root@imx6ulevk:~# dmesg |head
   [    0.000000] Booting Linux on physical CPU 0x0
   [    0.000000] Linux version 6.1.27-fslc+gddc32335b72f (oe-user@oe-host) (arm-poky-linux-gnueabi-gcc (GCC) 12.2.0, GNU ld (GNU Binutils) 2.40.20230119) #1 SMP Tue May  2 19:10:59 UTC 2023
   [    0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
   [    0.000000] CPU: div instructions available: patching division code
   [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
   [    0.000000] OF: fdt: Machine model: Freescale i.MX6 UltraLite 14x14 EVK Board
   [    0.000000] earlycon: ec_imx6q0 at MMIO 0x02020000 (options '')
   [    0.000000] printk: bootconsole [ec_imx6q0] enabled
   [    0.000000] Memory policy: Data cache writealloc
   [    0.000000] cma: Reserved 64 MiB at 0xbc000000
   ```

# さいごに
ネットワークアダプタの有効化ができていませんが、ひとまず、OSの起動まではできました。