PICO-PI-IMX8M 環境構築

# 概要
PICO-PI-IMX8 環境構築手順を記載します。
本記事で、開発環境の構築＆PICO-PI Linux上でのログインまでが可能になります。

# 対象
PICO-PIボードを使って組み込みLinux Driver開発の勉強をしたい人

# 基本環境
　Windows 上で動く VirtualBox(Ubuntu16.04) を host OS とします。
　（本物のUbuntuマシンでも構築可能）

# 必要なもの
* Windows PC
* PICO-PI-IMX8
PICO-PI はラズパイライクな開発ボードで、Mouser で ¥23,370 で~~購入できます~~ →　現在、製造中止…　https://www.mouser.jp/ProductDetail/TechNexion/PICO-PI-IMX8M-2G?qs=l7cgNqFNU1iNOyJvrHQ%252BmQ%3D%3D
ラズパイはドライバの一部分がGPUコードで隠蔽されている部分がありますが、PICO-PI はドライバコードがすべて公開されています。
また、公式からツールチェーンが提供されており、カーネルビルドが可能なためドライバの学習に向いています。
* Etherケーブル

# virtual box 導入
以下を参考に、VirtualBox上のUbuntuイメージを作成します。
https://qiita.com/ykawakami/items/4bae371932110b2e25e3

メモリ容量等は以下で十分でした
* 割当メモリ：2048MB
* ハードディスク容量 120GB


# Toolchain の取得
#### i.MX8M ARM Toolchain DL

下記リンクから gcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz　を DL
http://releases.linaro.org/components/toolchain/binaries/6.4-2017.11/aarch64-linux-gnu/gcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz

DL後、VirtualBox上で以下を実行
```bash:
$ sudo tar xvf gcc-linaro-6.4.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz -C /opt/
```

#### Toolchain の確認
VirtualBox上で、
以下を ~/.bashrc に追記。

```bash:~/.bashrc
export ARCH=arm64
export CROSS_COMPILE=/opt/[toolchain directory]/bin/aarch64-linux-gnu-
export CC=/opt/[toolchain directory]/bin/aarch64-linux-gnu-
```

toolchainを適用
```bash:
$ source ~/.bashrc
```

hello world を行う test.c を作成し、ファイル形式がARM64で出来上がることを確認。
```c:test.c
#include<stdio.h>
int main(void) {
    printf("hello");
    return 0;
}
```

コンパイル
```bash:
$ {CC}gcc test.c -o test
```

出力ファイルがARM64 形式であることを確認
```bash:
$ file test
test: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically link
ed, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=0
fd5aa244f4822bdbe6bdbe09dfe513df725c2c1, not stripped
```

# kernel source 取得

任意ディレクトリで以下を実行。
```bash:
$ git clone https://github.com/TechNexion/linux.git
```

# kernel build
先程取得したカーネルソースへ移動、makeを実行。

```bash:
$ cd ~/path/to/work/linux
$ make defconfig
$ make all
```

# rootfs 取得
PICO-PI にインストールする Ubuntu 20.04 file system を取得します。

以下を実行。
```bash:
$ wget -c https://rcn-ee.com/rootfs/eewiki/minfs/ubuntu-20.04-minimal-armhf-2020-05-10.tar.xz
```

# nfs server 構築
PICO-PI-IMX8M は eMMC boot, NFS boot が可能です。
本記事では NFS boot 用の環境構築手順を記載します。接続概要は以下です。

![tftp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146096/8aed1cc3-075d-6a0f-8174-4b6bc9ad5525.png)

/public/nfsroot を作成し、取得した ubuntu-20.04-minimal-armhf-2020-05-10.tar.xz を /public/nfsroot へ展開します。

```bash:
$ ls /public/nfsroot
bin dev home media opt root sbin sys usr
boot etc lib mnt proc run srv tmp var
```

/public/nfsroot 以下は permission=777 に設定しておきます。
```bash:
$ sudo chmod -R 777 /public/nfsroot
```

以下で nfs server をインストールします。
```bash:
$ sudo apt-get install nfs-kernel-server
```
参考：https://qiita.com/salty-vanilla/items/5bc95ad47af6bf051bf7

/etc/exports に以下を追記します。
```text:
/public/nfsroot/ 192.168.4.200(rw,sync,no_subtree_check)
```

ファイヤウォールを無効化します。
```bash:
$ sudo ufw disable
```

# tftp server 構築
以下でTFTP server をインストールします。
```bash:
$ sudo apt install tftpd-hpa tftp-hpa
$ sudo systemctl enable tftpd-hpa
$ sudo systemctl restart tftpd-hpa
```
TFTP server のターゲットディレクトリを作成します。
```bash:
$ sudo mkdir /tftpboot
```

/etc/default/tftpd-hpa に以下を追記
```text:
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--ipv4 --secure --create"
```

tftpserver を restart
```bash:
$ sudo service tftpd-hpa restart
```

# 起動Image の配置
kernel build 成果物である Image, dtb を tftpserver へ配置します。
```bash:
$ cd ~/path/to/work/linux
$ sudo cp arch/arm64/boot/Image /tftpboot
$ sudo cp arch/arm64/boot/dts/freescale/pico-8m.dtb /tftpboot
```

# teraterm install
※teraterm は Windows へ install します
windows 版 teraterm を install
https://forest.watch.impress.co.jp/library/software/utf8teraterm/

# PICO-PI-IMX8 起動

typeB micro USB, USB type C をPC と接続します。
teraterm を起動、Serial 接続で port 3,4 （PC環境による）いずれかを選択してボードのリセットボタンを押下します。
起動ログが流れるportで、ボーレートを115200 に設定。再起動。
文字化けのない起動ログが現れたら成功。
以下でログインします。
```text:
User name: root
password: root
```

# ボード設定を NFS boot へ切り替え
工場出荷状態では eMMC boot 設定となっているため、uboot 環境変数を編集して NFS boot に切り替える必要があります。

また、Virtual box のネットワーク設定を行う必要があります。

#### virtual box ネットワーク設定

Virtual Box を終了
Virtual Box 起動画面 -> 設定 -> ネットワーク ->
割り当て：ブリッジアダプター
名前：Realtek PCIe FE Familiy Controller

とする
名前の部分は環境によって変えること。今回はEther ポートに直接接続。

Virtual box の Ubuntu を起動
Ubuntu 側で network アドレスを 192.168.4.10 に設定

PICO-PI を起動、teraterm 上で以下を実行。
```bash:
# ifconfig eth0 192.168.4.200
```
Ubuntu から ```ping 192.168.4.200``` が通ればOK

#### uboot 環境変数に Ether boot 設定を追加

デフォルトで NFS boot が走るように uboot 環境変数を変更する。
変更前に printenv で工場出荷状態の環境変数を確認、保存しておくこと

環境変数のバックアップ後、以下を実行。

```bash:
setenv ipaddr 192.168.4.200
setenv serverip 192.168.4.10
setenv nfsroot /public/nfsroot
setenv fdt_addr 0x43000000
setenv loadaddr 0x40480000
setenv fdt_file pico-8m.dtb
setenv bootcmd 'run netboot'
setenv netargs 'setenv bootargs root=/dev/nfs rw ip=${ipaddr}:${serverip}:${serverip}:255.255.255.0:hostname::off nfsroot=${serverip}:${nfsroot},nolock,vers=4,tcp'
```

#### ログイン
PICO-PI 電源ON, ログイン画面で以下を入力して、ログインできれば成功。
```bash:
username: ubuntu
pass: temppwd
```

# Driver のカスタム

カーネルソースの任意のドライバにプリント文を仕込み、カスタマイズができることを確認します。
例として linux/drivers/media/platform/mxc/capture/mx6s_capture.c を編集します。

probe()関数の先頭にpr_info()を追記します。
```c:mx6s_capture.c
static int mx6s_csi_probe(struct platform_device *pdev)
{
    struct device *dev = &pdev->dev;
    const struct of_device_id *of_id;
    struct mx6s_csi_dev *csi_dev;
    struct video_device *vdev;
    struct resource *res;
    int ret = 0;
    
    pr_info("20220311 test\n"); // ★追記
```

kernel build を実行し、起動ログに↑のログが現れることが確認できます。

```text:起動ログ
[ 1.787511] input: 30370000.snvs:snvs-powerkey as /devices/platform/30370000.snvs/30370000.snvs:snvs-powerkey/input/input0
[ 1.801515] snvs_rtc 30370000.snvs:snvs-rtc-lp: rtc core: registered 30370000.snvs:snvs- as rtc0
[ 1.811097] i2c /dev entries driver
[ 1.817608] 20220311 test
[ 1.820700] 20220311 test
[ 1.825344] mxc-mipi-csi2_yav 30a70000.mipi_csi1: mipi_csi2_probe
[ 1.831571] CSI: Registered sensor subdevice: mxc-mipi-csi2.0
[ 1.837429] mxc-mipi-csi2_yav 30a70000.mipi_csi: Remote device a
```