【Nerves】ElixirからFPGAをゴリゴリ使える環境を作ろう。EBAZ4205への移植


関連記事
- [EBAZ4205を使って、FPGAを使ったシステム開発の環境を構築する](https://qiita.com/GeekMasahiro/items/6bdb8886fb5c32c332cb)
- [EBAZ4205でLinuxを動かして見る](https://qiita.com/GeekMasahiro/items/bb411ab40bb2e80e4c2a)
- [petalinuxをBuildrootでビルドする](https://qiita.com/GeekMasahiro/items/7ce3d4fe108f2cfe49a3)

# 始めに

[petalinuxをBuildrootでビルドする](https://qiita.com/GeekMasahiro/items/7ce3d4fe108f2cfe49a3) に引き続き、Zynqを使ったボードでNervesを動作させることを目指してみます。

# Nervesのポーティング

Nervesのポーティングは、以前、M5Stack Core MP135へのポーティングを行ったことがあります。

- [準備編](https://qiita.com/GeekMasahiro/items/dd214725bc1849b355ef)
- [設定ファイル作成編](https://qiita.com/GeekMasahiro/items/17242bf1f030de91ed75)
- [KernelのBuild編](https://qiita.com/GeekMasahiro/items/e1bb049144b314e0c413)
- [試行錯誤編](https://qiita.com/GeekMasahiro/items/e26a185bf858b0b149df)

これで作成した`nerves_system_m5stack_core_mp135`を元に、Zynqのボードに合わせた設定を作成してみます。

ターゲットにするボードは、EBAZ4205とします。

`nerves_system_ebaz4205`という名前で、新しいNervesのシステムを作成してみます。
EBAZ4205は、Zynq-7000搭載のボードです。マイニングマシーンに使われていたコントローラの中古販売品でaliexpress等で、低価格で販売されてます。評価boardと違い、開発環境を自分で環境を構築する必要がありますが、見方を変えると、このボードで動作できれば、自分でボードを開発した場合でも、同様の手順でNervesを動作させることができると思います。

# 変更点

変更点は、大きく分けて以下の2点です。

### nerves_defconfigの変更

BR2_LINUX_KERNELとBR2_TARGET_UBOOTを[この記事](https://qiita.com/GeekMasahiro/items/7ce3d4fe108f2cfe49a3)で動作確認しているものに変更しました。

```
BR2_arm=y
BR2_cortex_a9=y
BR2_ARM_ENABLE_NEON=y
BR2_ARM_ENABLE_VFP=y
BR2_TARGET_GENERIC_GETTY_PORT="ttyPS0"
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
BR2_TOOLCHAIN_EXTERNAL_URL="https://github.com/nerves-project/toolchains/releases/download/v13.2.0/nerves_toolchain_armv7_nerves_linux_gnueabihf-linux_${shell uname -m}-13.2.0-BE3EA83.tar.xz"
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="armv7-nerves-linux-gnueabihf"
BR2_TOOLCHAIN_EXTERNAL_GCC_13=y
BR2_TOOLCHAIN_EXTERNAL_HEADERS_5_4=y
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
# BR2_TOOLCHAIN_EXTERNAL_INET_RPC is not set
BR2_TOOLCHAIN_EXTERNAL_CXX=y
BR2_TOOLCHAIN_EXTERNAL_FORTRAN=y
BR2_TOOLCHAIN_EXTERNAL_OPENMP=y
BR2_TAR_OPTIONS="--no-same-owner"
BR2_BACKUP_SITE="http://dl.nerves-project.org"
BR2_ENABLE_DEBUG=y
BR2_GLOBAL_PATCH_DIR="${BR2_EXTERNAL_NERVES_PATH}/patches"
BR2_REPRODUCIBLE=y
BR2_ROOTFS_SKELETON_CUSTOM=y
BR2_ROOTFS_SKELETON_CUSTOM_PATH="${BR2_EXTERNAL_NERVES_PATH}/board/nerves-common/skeleton"
BR2_INIT_NONE=y
BR2_ROOTFS_DEVICE_TABLE="${BR2_EXTERNAL_NERVES_PATH}/board/nerves-common/device_table.txt"
BR2_ENABLE_LOCALE_WHITELIST="locale-archive"
BR2_GENERATE_LOCALE="en_US.UTF-8"
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_NERVES_PATH}/board/nerves-common/rootfs_overlay ${NERVES_DEFCONFIG_DIR}/rootfs_overlay"
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_NERVES_PATH}/board/nerves-common/post-build.sh ${NERVES_DEFCONFIG_DIR}/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${NERVES_DEFCONFIG_DIR}/post-createfs.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_REPO_URL="https://github.com/Xilinx/linux-xlnx.git"
BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="xlnx_rebase_v5.15_LTS"
BR2_LINUX_KERNEL_USE_ARCH_DEFAULT_CONFIG=y
BR2_LINUX_KERNEL_UIMAGE=y
BR2_LINUX_KERNEL_UIMAGE_LOADADDR="0x8000"
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_USE_CUSTOM_DTS=y
BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="${NERVES_DEFCONFIG_DIR}/ebaz4205/dts/ebaz4205-zynq7.dts ${NERVES_DEFCONFIG_DIR}/ebaz4205/dts/ebaz4205-board.dtsi ${NERVES_DEFCONFIG_DIR}/ebaz4205/dts/ebaz4205-pl.dtsi"
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="${NERVES_DEFCONFIG_DIR}/ebaz4205/linux/linux.config"
BR2_PACKAGE_BUSYBOX_CONFIG="${BR2_EXTERNAL_NERVES_PATH}/board/nerves-common/busybox.config"
BR2_PACKAGE_F2FS_TOOLS=y
BR2_PACKAGE_LINUX_FIRMWARE=y
BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y
BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX=y
# BR2_PACKAGE_RNG_TOOLS_JITTERENTROPY_LIBRARY is not set
BR2_PACKAGE_CA_CERTIFICATES=y
BR2_PACKAGE_LIBP11=y
BR2_PACKAGE_UNIXODBC=y
BR2_PACKAGE_LIBMNL=y
BR2_PACKAGE_WIRELESS_REGDB=y
BR2_PACKAGE_WPA_SUPPLICANT=y
BR2_PACKAGE_WPA_SUPPLICANT_WIRED=y
BR2_PACKAGE_WPA_SUPPLICANT_AP_SUPPORT=y
BR2_PACKAGE_WPA_SUPPLICANT_HOTSPOT=y
BR2_PACKAGE_WPA_SUPPLICANT_DEBUG_SYSLOG=y
BR2_PACKAGE_WPA_SUPPLICANT_WPA3=y
BR2_PACKAGE_WPA_SUPPLICANT_CTRL_IFACE=y
# BR2_TARGET_ROOTFS_TAR is not set
BR2_TARGET_UBOOT=y
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
BR2_TARGET_UBOOT_CUSTOM_GIT=y
BR2_TARGET_UBOOT_CUSTOM_REPO_URL="https://github.com/embed-me/u-boot.git"
BR2_TARGET_UBOOT_CUSTOM_REPO_VERSION="v2019.07-ebaz4205"
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="zynq_ebaz4205"
BR2_TARGET_UBOOT_NEEDS_DTC=y
BR2_TARGET_UBOOT_NEEDS_OPENSSL=y
BR2_TARGET_UBOOT_FORMAT_IMG=y
BR2_TARGET_UBOOT_SPL=y
BR2_TARGET_UBOOT_SPL_NAME="spl/boot.bin"
BR2_NERVES_SYSTEM_NAME="nerves_system_stm32mp135d"
BR2_PACKAGE_NBTTY=y
BR2_PACKAGE_NERVES_CONFIG=y
```

### fwup.confの変更

U-Bootのイメージを保存するパーティションがCore MP135と異なるので、fwup.confを変更しました。

この変更は、Nervesの`Zybo Z7-10`へのポーティングを参考にしました。

https://github.com/zeam-vm/nerves_system_zybo_z7_10

# build

`nerves_system_ebaz4205`を使用するテストプロジェクトを作成してビルドしてみます。

Build成功したら、SDカードに書き込んで、EBAZ4205で起動してみます。

# 起動結果

U-Boot関係でいくつかの問題点があったのですが、修正して、起動することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/39ad8e37-7aef-63a6-6d9e-cd04c446e82f.png)

Nervesが動作することを確認できました。

## まとめ

NervesをEBAZ4205で動作させることができました。
Buildrootでの構築の実績があったのと、fwup.confの記述方法については、以前のポーティング作業での経験が活かせたので、それほど難しい作業ではありませんでした。

しかし、以下の問題点があります。
- FPGAのプログラムの書き込みができておらず、EthernetのPHYが認識されていません。
- U-Bootの環境変数が、uEnv.txtに保存する形になっていて、Nervesのfwup.confで指定している環境変数と共用できていません。

U-Boot周りを見直す必要がありそうです。
このあたりを見直して、EBAZ4205でNervesを動作させることができるようにしたいと思います。