i.mx6ull用のLinuxをWSL2+Yoctoでコンパイルする

#はじめに
Windows10のバージョン2004からWSL2が使用可能になりました。Win10 proではなく、Win10 homeでも使用可能です。今までVirtualBoxを使ってWindows上に仮想環境を作成していましたが、WSLを使用すれば同様のことがWindowsだけで可能になるわけです。WSL2からはWindows自身がLinuxカーネルを持っていて仮想環境を提供してくれます。

ではさっそく、WSL2をインストールしてみましょう。

#WSL2のインストール

①まず、**PowerShellを管理者モードで立ち上げて**以下を入力します。

```:PowerShell（管理者モード）
> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
②次に**[コントロールパネル] > [プログラム] > [プログラムと機能] >  [Windowsの機能の有効化または無効化]**を選択して、その中にある **[Linux用Windowsサブシステム]**にチェックを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681483/9869146a-9000-5d45-f79a-250464a6a288.png)

③多分最初はLinux Kernelが入ってないので、これを以下からダウンロードします。

　https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel

④**PowerShellを管理者モードで立ち上げて**以下を入力します。（①で立ち上げていたらそのままでいいです）

```:PowerShell（管理者モード）
> wsl --set-default-version 2
```

⑤Microsoft StoreからLinuxのディストリビューションをダンロード・インストールします。今回はUbuntu18.04 LTSをインストールします。ストアアプリで**Ubuntu**を検索すればすぐに出てきます。

　※Ubuntuの最新は20.04 LTSですが、引き続き実施するYoctoのコンパイルで18.04を使いたかったのでこちらを選択しています。

⑥インストールが完了すると、スタートメニューにUbuntuのアイコンが出てきます。これをクリックすると仮想環境が走り出します。一番最初はユーザー名とパスワードを聞かれるので、これを入力すれば完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681483/a91d58d5-6e96-88f4-c756-e13d5a9e286e.png)

#VHDXファイルの移動
上記でディストリビューションをインストールすると、この仮想環境用のディスクイメージが作成されます。作成される場所は
デフォルトでは以下の通り。

　***C:\Users\\\<username\>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx***

インストール時に場所の変更はできません。サイズは可変で、仮想環境中でディスクを使用すると、このファイルがどんどん肥大化していきます。特に以下でYoctoのコンパイルなど実施した際は20GBを超えてきます。なのでC:\ドライブを圧迫しないために、別の場所にこのファイルを移動しておきたいと思います。

```:PowerShell（管理者モード）
> wsl --export Ubuntu-18.04 ubuntu.tar
> wsl --unregister Ubuntu-18.04
> wsl --import Ubuntu-18.04 E:\wsl\Ubuntu\ ubuntu.tar
```

最初のコマンドでtarファイルにexportして、次のコマンドでWSL2からディストリビューションを削除し、最後のコマンドで再度ディストリビューションをインポートします。ちなみにtarファイルはPowerShellを立ち上げたカレンドディレクトリに作成されますので、作業が終わったら消して大丈夫です。

※PowerShellは管理者モードで立ち上げましたが、ひょっとすると通常のモードでも大丈夫かも知れません。管理者モードで立ち上げた場合、ファイルが管理者権限で作成されるので、エクスプローラの設定によってはtarファイルが見えないです。

以上でファイルが（上記のコマンド実施例の場合）**E:\WSL\Ubuntu**以下に生成されます。この状態でスタートメニューからUbuntuのアイコンをクリックすれば、この仮想環境用ファイルを使用してUbuntuが立ち上がります。ただし、これをやった直後はユーザーが**root**になってしまいます。これでは不便なので、再度自分のログイン名に変更します。

```:PowerShell（管理者モード）
> ubuntu1804 config --default-user <username>
```

**\<username\>**は一番最初にUbuntuを起動したときにプロンプトで入力したユーザー名です。ストアアプリでディストリビューションを選択した際、Ubuntuを選択した場合は**ubuntu**が実行ファイルになります。またUbuntu20.04を選択した場合は**ubuntu2004**が実行ファイルです。

#対象プロセッサ/ボード
今回はプロセッサとしてNXP社製のi.MX6ULL、開発用ボードとして同社の[i.MX6ULL EVK](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-6ull-and-6ulz-applications-processor:MCIMX6ULL-EVK)を使用したいと思います。（今回はとりあえずコンパイルできるところまでを目指します。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681483/327768d7-41b1-8a41-d008-3bbe70134f3a.png)

#Yoctoのインストール
NXP社製のi.MXシリーズは旧Freescale時代からYocto用のBSPパッケージが提供されていて、これをダウンロードして自前でボード用のLinuxディストリビューション一式をコンパイルします。

①作業するにあたり、必要なパッケージ類を予めインストールしておく必要があります。

```:Ubuntu
> sudo apt-get install repo gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath \
socat cpio python python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git \
python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm
```

Ubuntu18.04では一番最初の**repo**をapt-getでインストールできます。Ubuntu20.04ではできませんでした。その場合はcurlかなにか使って取ってくる必要があります。

②次に、gitの設定です。

```:Ubuntu
> git config --global user.name "Your Name"
> git config --global user.email "Your Email"
```
③repoを使ってYoctoのレシピを取ってきます。

```:Ubuntu
> mkdir yocto
> cd yocto
> repo init -u https://source.codeaurora.org/external/imx/imx-manifest  -b imx-linux-zeus -m imx-5.4.24-2.1.0.xml
> repo sync
```
作業用ディレクトリとして**yocto**を作成し、その下に移動して**repo**コマンドを実行しています。

#Build(bitbake)
これで準備が整ったので、いよいよコンパイルです！

```:Ubuntu
> DISTRO=fsl-imx-fb MACHINE=imx6ull14x14evk source imx-setup-release.sh -b build
> time bitbake core-image-base
```

ディストリビューションとして*fsl-imx-fb*を、マシン名として**imx6ull14x14evk**を設定して、シェルスクリプトを実行します。これを実行すると、各実行バイナリにパスが通るみたいです。

コンパイルする場合は**bitbake**コマンドを使用します。その前の**time**はbitbakeにかかった時間を表示するために付けておきます。プロジェクト名は**core-image-base**を指定しました。このプロジェクトはコンソールのみのイメージを生成し、対象デバイスのすべてのハードウェアを使用可能になります。**core-image-minimal**を指定した場合は、もっと小さいイメージが出来上がります。

で、ここまでやってなんですが、上記のプロジェクトをコンパイルすると、最後の方でERRORが出て止まります。

```:ErrorLog
ERROR: nxp-wlan-sdk-git-r0 do_compile: oe_runmake failed
ERROR: nxp-wlan-sdk-git-r0 do_compile: Execution of '/home/furukawa/develop/yocto/imx6ullevk/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/nxp-wlan-sdk/git-r0/temp/run.do_compile.3825' failed with exit code 1:
make -C /lib/modules/4.19.104-microsoft-standard/build M=/home/furukawa/develop/yocto/imx6ullevk/build/tmp/work/cortexa7t2hf-neon-poky-linux-gnueabi/nxp-wlan-sdk/git-r0/git/mxm_wifiex/wlan_src modules
make[1]: *** /lib/modules/4.19.104-microsoft-standard/build: No such file or directory.  Stop.
Makefile:412: recipe for target 'default' failed
make: *** [default] Error 2
WARNING: exit code 1 from a shell command.
```
**nxp-wlan-sdk**パッケージのmake中に

 ***/lib/modules/4.19.104-microsoft-standard/build***

を参照するみたいなんですが、これがどうもダメみたいです。ネイティブなLinuxでコンパイルした場合はここは問題なく、/lib/modulesの下には4.19.104-genericと言うフォルダがありｋました。microsoft-standardというのはWSL2のKernelのバージョン名についてるものらしいのですが…どうもこれが引っかかるみたい。回避方法として、今回は

 ***yocto\sources\meta-imx\meta-sdk\recipes-connectivity\nxp-wlan-sdk\nxp-wlan-sdk_git.bb***

の中に記述してある**do_compile ()**と**do_inistall ()**の記述部分を全部コメントアウトしました。これで無事コンパイルが通りますが、4時間ぐらいかかります。イメージは

 ***yocto\build\tmp\deploy\images\imx6ull14x14evk***

以下にできてますので、これらをSDカードに書いてボードに挿せば、ブートして動作するハズ。

#bitbake時のCPU負荷など
**bitbake**はgitなどのサーバからソースコードを落としてきてコンパイルして…という一連の作業を実施してくれますので上記**core-image-base**プロジェクトだと、3100程度の工程があります。make時はデフォルトで使っているCPUのコア数（Intel HTの場合は仮想コア数）だけ並列にmakeされるので、私の環境の場合は4並列でmakeが進みました。ちなみに今回は以下の環境で実施してます。

| 項目 | 種別/値 |
|:--:|:----------------:|
|CPU|Intel Core i5-3340M(2コア/4スレッド) 2.7～3.4GHz|
|メモリ|8GB|
|OS|Windows 10 Home 64bit|

コンパイル時は、4つの（論理）CPUが95%前後で使用されて、少しだけ余裕を残してます。おそらくWindowsが動作するためだと思います。VirtualBoxで4コア全部を仮想環境側に振ると、100%使い切ります（結果、Windowsが動作できなくなって、途中で止まったりします）。ネイティブLinux環境では100%使い切りでも問題ないので、コンパイルは若干早い感じです。コンパイル時に効いてくるのはCPUのコア数とクロック。なので、最新のCPUと使うか、Intelの第4世代ぐらいだとCore i7 4770/4790あたりは欲しいところです（4コア/8スレッド）。

例えば論理4コアの場合、並列で8～9スレッドぐらいは動作させても問題ありません。コンパイルしてる間に別スレッドでネットからダウンロードしたりしてやれば、若干時間短縮になります。（論理コア数 x 2 + 1が目安と、どこかで読んだ気がする）。その場合、**imx-setup-release.sh**を実施した直後、**bitbake**を走らせる前に

***yocto/build/conf/local.conf***

に以下の行を追加すると、並列動作するスレッド数を増やすことが可能です。

```:local.conf
BB_NUMBER_THREADS = '9'
PARALLEL_MAKE = '-j 9'
```

これで**bitbake**を開始すると、9並列でコンパイルが始まります。