oneAPI+Intel PAC(D5005)環境をUbuntu20.04で強引に動かす

こんにちは。

インテルPACカードは、Arria10搭載版・D5005（Stratix10搭載）ともにoneAPIに対応していますが、残念ながら現状Ubuntu18.04のみサポート・RHEL/CentOS7については対応させるためのドキュメントが公式に出ている、という状態になっていて、今多く使われているUbuntu20.04やRHEL8には対応出来ていません。

今回は、とりあえずリグレッションテストとかバリデーションとか置いておいて、Ubuntu20.04上で試しにoneAPIを動かしてみようと思います。

:::note warn
本記事の内容は、基本的にベンダー（この場合はインテル）のサポート外の話になりますので、ご注意ください。
:::

#事前準備

```
$ sudo apt update
$ sudo apt upgrade
```

今回の記事は、上記が前提となってます。ただこれ、やるかどうかは微妙なところで、やっちゃうとKernelが5.11まで上がっちゃうんですよね（記事執筆時点で）。結構なバージョンですよこれ、FPGA屋としては。

#ともあれoneAPI Base Toolkitをインストール

以前の筆者の記事も参考にしてください。

https://qiita.com/yukitaketake/items/68dd7c93439164d615e4

ダウンロードはこちらから。

https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html

今回は色々いじることもあり/optではなくユーザ側にインストールしました。
（実は、なんでかsudoすると微妙にうまく行かなかった。未デバッグ）
原稿執筆時点での最新版はv2021.4のようです。
まずはBase Toolkitをインストールします（FPGA Add-onを一緒にインストールするやり方もあるようですが、今回は別々に）。

```
$ sh ./l_BaseKit_p_2021.4.0.3422_offline.sh
```

# FPGA Add-onをインストール

上のURLからFPGA add-on for Intel® PAC with Intel® Arria® 10 GX FPGA and with Intel® Stratix® 10 SX FPGAもダウンロードしておきます。
で、zipファイルを解凍してインストールするわけですが、ちょっとsetup.shをいじります。
具体的には、PACSignのインストールはスキップさせます。

903行目あたりを下のようにコメントアウト。

```setup.sh
################################################################################
#Installing the OPAE PACSign package
################################################################################
if [ $NO_PREREQS -eq 0 ] ;then
    DCP_BOARD="pac_a10"
    DCP_LOC="${BSPROOTDIR}/${bspnames[0]}/bringup/opae/${DCP_BOARD}"
    # if [ $is_ubuntu -eq 1 ] ;then
    # install_opae_pacsign_package_for_ubuntu
    # else
    # install_opae_pacsign_package_for_centos
    # fi
fi

```

で、実行します。筆者はBase Toolkitをユーザ側に入れたので、install_dirの設定は変更しました。

```
$ ./setup.sh
```

途中、RHEL7とUbuntu18.04しかサポートしてないよと出てきますが、サクッと無視します。

# Board Support Package(BSP)のインストール

ここでも、ちょっとdebファイルをいじる必要があります。
まず、今回インストールするBSPの場所に移動（PATHは各環境に合わせて適当に読み替えてください）。

```
$ cd ~/intel/oneapi/intelfpgadpcpp/2021.4.0/board/intel_s10sx_pac/bringup/opae/pac_s10
```

ここでは、ネットで見つけたvidebcontrolなるdebファイルをいじるツールを使います。

https://gist.github.com/bayyas/fde788520b79ca2a00fc

ではまず、PACSignのパッケージをいじります。

```
$ ./videbcontrol.sh python3-opae.pacsign_1.0.4_all.deb
```

Ubuntu20.04はpython3.8が入っているようです。上記のツールで見ると、python3のバージョンを3.7未満に制限してあるようですが、エイヤでいじって3.8でもOKにしてしまいましょう。

```
Package: python3-opae.pacsign
Source: opae.pacsign
Version: 1.0.4
Architecture: all
Maintainer: The OPAE Development Team, <opae@lists.01.org>
Installed-Size: 6282
Depends: python3 (<< 3.9), python3 (>= 3.6~), python3:any (>= 3.3.2-2~)
Section: python
Priority: optional
Description: PacSign for Intel FPGA PAC devices.
```

あと、どうもlibjson-c3っていうのがいるらしいんですが、Ubuntu18.04までのサポートだったみたいですね。ちょっとこれはやって良いのかよくわからんですが（識者の方教えて下さい…）、無理やりdebファイル持ってきて入れてしまいます。

```
$ wget http://archive.ubuntu.com/ubuntu/pool/main/j/json-c/libjson-c3_0.12.1-1.3_amd64.deb
$ sudo dpkg -i libjson-c3_0.12.1-1.3_amd64.deb
```

では、BSPをインストールしてみましょう。

```
$ aocl install intel_s10sx_pac
```

恐らくDriverのインストールでエラーが出るはずです（少なくともKernelが5.11なら）。

では、ドライバーを何とかするため、ちょこちょこいじります。

:::note warn
筆者はLinux Driverの知識がそれほどあるわけではないので、間違ったことをしている可能性が結構あります。アドバイス等ありましたら是非ください！
:::

まず、ドライバのdebファイルを展開します。PATH名は適当に読み替えてください。

```
$ cd intel/oneapi//intelfpgadpcpp/2021.4.0/board/intel_s10sx_pac/bringup/opae/pac_s10 
$ mkdir temp
$ cd temp
$ ar vx ../opae-intel-fpga-driver_2.0.2_all.deb
$ ls
control.tar.xz  data.tar.xz  debian-binary  _gpgorigin 
```

このdata.tar.xzがドライバコードが入っている圧縮ファイルなので、これを展開して、コードのディレクトリに移動します。

```
$ tar Jxvf data.tar.gz
$ cd usr/src/intel-fpga-2.0.2
```

さて、試しにコンパイルしてみると、色々エラーが出ることがわかると思います。これを解決しないといけません。

```
$ make
```

いじらないといけないのは以下のファイルです。

`・Makefile`
`・drivers/fpga/intel/dma-region.c`
`・drivers/i2c/busses/i2c-altera.c`

また、追加しないといけないファイルもあります。以下は実行しておいてください。

```
$ pushd driver/spi
$ wget https://github.com/torvalds/linux/blob/v5.11/drivers/spi/spi-bitbang.c
$ popd
```

多分、linux-headersも必要。

```
$ sudo apt update
$ sudo apt install linux-headers-$(uname -r)
```

あと、これぐらい新しいカーネルになってくると、DefaultでFPGAのドライバが入ってしまってます。これを取り除かないといけないので、今回はblacklistに入れて読まないようにしました。他のやり方でももちろん大丈夫だと思います。

```
$ sudo vi /etc/modprobe.d/blacklist.conf
```

追加分は以下。あと、これを反映させるために適宜リブート等してください。

```blacklist.conf
blacklist dfl_fme_br
blacklist dfl_fme_region
blacklist dfl_fme_mgr
blacklist dfl_pci
blacklist dfl_afu
blacklist dfl_fme
blacklist dfl
```


では、各ファイルを修正していきます。

まずMakefile。上記でspi-bitbang.cを追加した対応を入れます。

12行目辺り。

```Makefile.
ifeq ($(kerval),3.10)
	obj-m += spi-bitbang-mod.o
	obj-m += regmap-mmio-mod.o
endif
	obj-m += spi-bitbang-mod.o
```

55行目辺り

```Makefile.
#spi-bitbang-mod-y := drivers/spi/spi-bitbang-3-10.o
spi-bitbang-mod-y := drivers/spi/spi-bitbang.o
```
92行目辺り

```Makefile.
DRIVERS=\
spi-nor-mod.ko \
intel-generic-qspi.ko \
intel-on-chip-flash.ko \
altera-asmip2.ko \
3.10regmap-mmio-mod.ko \
i2c-altera.ko \
spi-bitbang-mod.ko \
spi-altera-mod.ko \
```

132行目辺り

```Makefile.
#ifeq ($(kerval),3.10)
	if ! egrep -q '^spi_bitbang_mod ' /proc/modules; then insmod spi-bitbang-mod.ko; fi
#endif
```

次にdrivers/fpga/intel/dma-region.cです。
54行目あたり

```dma-region.c
	//down_write(&current->mm->mmap_sem);
	down_write(&current->mm->mmap_lock);
```

79行目辺り

```dma-region.c
	//up_write(&current->mm->mmap_sem);
	up_write(&current->mm->mmap_lock);
```

最後にdrivers/i2c/busses/i2c-altera.cです。
636行目辺り。

```i2c-altera.c
		  //i2c_new_device(&idev->adapter, pdata->devices + i);
			i2c_new_client_device(&idev->adapter, pdata->devices + i);
```

これでソースコードの修正は終わりです。一応ちゃんとコンパイル出来るか確認します。

```
$ make unload-hdrs
$ make
```

エラーが出たら、上記の処理の何かが足りてないはず。
（ちなみに、前者のmakeがなぜ必要なのかイマイチわかってない筆者です）
これでOKなので、元通りに固めます。

```
$ rm data.tar.xz
$ tar Jcvf data.tar.xz usr/*
$ rm -r usr
```

ガシガシrmしてますが、随時バックアップ等はとったほうが良いかも。
さて、これで終わりと思いたいところですが、どうも筆者の環境では/lib/modules/5.11.0-27-generic/build/include以下にあるヘッダファイルが悪さをするようです（なので、make前にmake unload-hdrsが必要でした）。
なので、この辺のいらないヘッダを事前に消す処理を追加します。具体的には、debファイルの中にあったcontrol.tar.xzの中身を修正します。

```
$ mkdir temp
$ cd temp
$ tar Jxvf ../control.tar.xz 
$ ls
control  md5sums  postinst  prerm
```

で、prermに色々追加します。以下、prermの全文を掲載します。

```prerm
#!/bin/sh

echo
echo "Uninstall of intel-fpga module (version 2.0.2) beginning:"
dkms remove -m intel-fpga -v 2.0.2 --all --rpm_safe_upgrade

find /lib/modules -type f -name spi-nor-mod.ko -delete
find /lib/modules -type f -name intel-generic-qspi.ko -delete
find /lib/modules -type f -name intel-on-chip-flash.ko -delete
find /lib/modules -type f -name altera-asmip2.ko -delete
find /lib/modules -type f -name regmap-mmio-mod.ko -delete
find /lib/modules -type f -name i2c-altera.ko -delete
find /lib/modules -type f -name spi-bitbang-mod.ko -delete
find /lib/modules -type f -name spi-altera-mod.ko -delete
find /lib/modules -type f -name ifpga-sec-mgr.ko -delete
find /lib/modules -type f -name avmmi-bmc.ko -delete
find /lib/modules -type f -name intel-max10.ko -delete
find /lib/modules -type f -name fpga-mgr-mod.ko -delete
find /lib/modules -type f -name intel-fpga-pci.ko -delete
find /lib/modules -type f -name intel-fpga-afu.ko -delete
find /lib/modules -type f -name intel-fpga-fme.ko -delete
find /lib/modules -type f -name intel-fpga-pac-hssi.ko -delete
find /lib/modules -type f -name intel-fpga-pac-iopll.ko -delete
find /lib/modules -type f -name pac_n3000_net.ko -delete
find /lib/modules -type f -name c827_retimer.ko -delete

UN=`uname -r`
KERNELDIR=/lib/modules/${UN}/build
echo $KERNELDIR
rm -f ${KERNELDIR}/include/linux/avmmi-bmc.h
rm -f ${KERNELDIR}/include/linux/i2c/altera.h
rm -f ${KERNELDIR}/include/linux/spi/altera.h
rm -f ${KERNELDIR}/include/linux/bitfield-intel-pac.h
rm -f ${KERNELDIR}/include/linux/fpga/fpga-mgr-4-12.h
rm -f ${KERNELDIR}/include/linux/iopoll-4-12.h
rm -f ${KERNELDIR}/include/linux/regmap-intel-pac.h
rm -f ${KERNELDIR}/include/linux/libfdt-4-12.h
rm -f ${KERNELDIR}/include/linux/libfdt_env-4-12.h
rm -f ${KERNELDIR}/include/linux/mtd/altera-asmip2.h
rm -f ${KERNELDIR}/include/linux/mtd/intel-generic-qspi.h
rm -f ${KERNELDIR}/include/linux/mtd/intel-on-chip-flash.h
rm -f ${KERNELDIR}/include/linux/mtd/spi-nor-4-12.h
rm -f ${KERNELDIR}/include/uapi/linux/intel-fpga.h
rm -f ${KERNELDIR}/include/uapi/linux/avmmi-bmc.h
rm -f ${KERNELDIR}/include/uapi/linux/intel-pac-iopll.h
rm -f ${KERNELDIR}/include/generated/autoksyms.h

exit 0
```

修正後、元に戻します。

```
$ rm ../control.tar.xz
$ tar Jcvf ../control.tar.xz control md5sums postinst prerm 
$ cd ..
```

これで修正終了なので、debファイルを生成します。

```
$ ar r ../opae-intel-fpga-driver_2.0.2_all.mod.deb debian-binary control.tar.xz data.tar.xz
$ cd ..
```

では、インストールしてみましょう。

```
$ sudo dpkg -i opae-intel-fpga-driver_2.0.2_all.mod.deb
```

うまく行かない場合は、オリジナルのドライバをインストール→アンインストールしてから、再度試してみてください。

```
$ sudo dpkg -i opae-intel-fpga-driver_2.0.2_all.deb 
$ sudo dpkg -r opae-intel-fpga-driver
$ sudo dpkg -i opae-intel-fpga-driver_2.0.2_all.mod.deb
```

どうでしょう。うまくインストール出来ましたか？
一応以下を実行して、ドライバが入っていそうか確認してみてください。

```
$ lsmod|grep fpga
```

一応、pac_s10_usmのほうも対応したほうが良いと思うので、上で作ったdebをコピーして、

```
$ cp opae-intel-fpga-driver_2.0.2_all.mod.deb ../pac_s10_usm
```

両方のubuntu1804.pkgsを修正しておきます。

```ubuntu1804.pkgs
opae-intel-fpga-driver_2.0.2_all.deb
opae-libs-1.1.4-8.x86_64.deb
opae-devel-1.1.4-8.x86_64.deb
opae-tools-1.1.4-8.x86_64.deb
opae-tools-extra-1.1.4-8.x86_64.deb
opae-ase-1.1.4-8.x86_64.deb
python-opae.admin_1.0.2_all.deb
python3-opae.pacsign_1.0.4_all.modified.deb
opae-d5005-fpgaotsu-base_2.0.1_all.deb
opae-d5005-super-rsu-base_2.0.1_all.deb
```


# 何かコンパイルしてみる。

準備として、まだやってない人は、下のフローでjsonschema含め、諸々のインストールも必要です。
これ、source intel/oneapi/setvars.shをやったあとに実行するとおかしなことになるので、気をつけましょう。

```
$ sudo apt-add-repository universe
$ sudo apt update
$ sudo apt install python2.7 python2.7-dev curl libncurses5
$ curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
$ python2.7 get-pip.py
$ pip2 install jsonschema
```

あとは、いつものoneapi-cliツールで、好きなサンプルを取得します。ここではgzipあたりを取得したと仮定。下のコマンド群は、PATH名は単なる例です。

```
$ source ~/intel/oneapi/setvars.sh
$ cd work
$ oneapi-cli
```

あとは、

```
$ cd gzip
$ mkdir build
$ cd build
$ cmake .. -DFPGA_BOARD=intel_s10sx_pac:pac_s10_usm
$ make fpga
```

で試します。cmake時にBSPを指定するのを忘れないように！
これで多分動くはずです。
動かない場合、findコマンド等で、生成されたgbsファイルを探して、fpgaconfコマンドでgbsファイルを書き込んでから再実行してみてください。

```
$ find . -name "*.gbs"
./gzip.fpga.prj/build/output_files/afu_import.gbs
$ fpgaconf ./gzip.fpga.prj/build/output_files/afu_import.gbs
```

ではでは。