FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)

## 注意(2017年9月20日追記)

この記事は Linux Kernel 4.4 時点に投稿したものであり、古い内容が含まれています。Linux Kernel 4.10 以降、FPGA 関連は大きく進歩しました。詳しくは[「Linux Kernel 4.10 でのFPGAのサポート事情」](http://qiita.com/ikwzm/items/2ff7d5429da8ace7c0bd)を参照してください。

## 参考(2017年11月2日追記)

FPGA Region を含んだ Linux 4.12.14 のブートイメージを提供しています。詳しくは[「FPGA+SoC+Linux+Device Tree Overlay+FPGA Region(ブートイメージの提供)」](https://qiita.com/ikwzm/items/7e90f0ca2165dbb9a577)を参照してください。

## はじめに

[「FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(ブートイメージの提供) @Qiita」](http://qiita.com/ikwzm/items/cdeb3c9c352776eac683)で、ZYBO と DE0-Nano-SoC 用の Device Tree Overay と FPGA Manager に対応した Linux Kernel と Debian8 RootFS を紹介しました。

今回は新たにプラットフォームとして PYNQ-Z1 を追加しました。PYNQ-Z1 に関しては次の URL を参照してください。

 - [http://www.pynq.io](http://www.pynq.io)

なお、現時点での Linux の FPGA Manager と Device Tree Overlay のサポートは暫定的かつ限定的なもので、将来どうなるかは未だ不明な部分があることをご了承ください。ここで紹介している dtbocfg や fpgacfg と言ったデバイスドライバは、現時点で Linux が提供していないユーザー側とのインターフェースを私が勝手に追加したものです。

## 概要

* Hardware
  + PYNQ-Z1 : Python Productive for Zynq by Digilent
* U-Boot v2016.03 (customized)
  + Build for ZYBO, PYNQ-Z1 and DE0-Nano-SoC
  + Customized boot by uEnv.txt
  + Customized boot by boot.scr
* Linux Kernel Version v4.8.17
  + Available in both Xilinx-Zynq-7000 and Altera-SoC in a single image
  + Enable Device Tree Overlay
  + Enable FPGA Manager
* Debian8(jessie) Root File System
  + Installed build-essential
  + Installed device-tree-compiler
  + Installed ruby ruby-msgpack ruby-serialport
  + Installed u-boot-tools
* FPGA Device Drivers
  + [dtbocfg    (Device Tree Blob Overlay Configuration File System)](https://github.com/ikwzm/dtbocfg)
  + [fpgacfg    (FPGA Configuration Interface for Linux FPGA Manager Framework)](https://github.com/ikwzm/fpgacfg)
  + [fclkcfg    (FPGA Clock Configuration Device Driver)](https://github.com/ikwzm/fclkcfg)
  + [udmabuf    (User space mappable DMA Buffer)](https://github.com/ikwzm/udmabuf)
  + [zptty      (Pseudo TeleTYpewriter for FPGA Device)](https://github.com/ikwzm/PTTY_AXI4)

## PYNQ-Z1 へのインストール

### ダウンロード

github から次のようにダウンロードしてください。
現時点の最新バージョンは v0.3.3 です。チェックアウトしてください。
なお、いくつかのイメージファイルはかなり大きいので、Git LFS(Large File Storage)を使っています。
お使いの環境に git-lfs がインストールされている必要があります。

```
shell$ git clone git://github.com/ikwzm/FPGA-SoC-Linux
shell$ cd FPGA-SoC-Linux
shell$ git checkout v0.3.3
shell$ git lfs pull
```

### ファイルの説明

target/zynq-pynqz1/boot ディレクトリの各ファイルの詳細は、[「FPGA+SoC+Linuxのブートシーケンス(ZYNQ+U-Boot-SPL編)」](http://qiita.com/ikwzm/items/efacec8d8e0744e17d45)を参照してください。

 * tareget/zynq-pynqz1/
   + boot/
     - boot.bin                                                  : Stage 1 Boot Loader(U-boot-spl)
     - u-boot.img                                                : Stage 2 Boot Loader(U-boot)
     - uEnv.txt                                                  : U-Boot environment variables for linux boot
     - zImage-4.8.17-armv7-fpga                                  : Linux Kernel Image       
     - devicetree-4.8.17-zynq-pynqz1.dtb                         : Linux Device Tree Blob   
     - devicetree-4.8.17-zynq-pynqz1.dts                         : Linux Device Tree Source
 * debian8-rootfs-vanilla.tgz                                    : Debian8 Root File System (use Git LFS)
 * linux-image-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb   : Linux Image Package      (use Git LFS)
 * linux-headers-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb : Linux Headers Package    (use Git LFS)
 * fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.3-1_armhf.deb    : Device Drivers Package   (use Git LFS)

### SD-Card のフォーマット

SD-Card のパーティション１を FAT File System でファイルシステムを作ります。
SD-Card のパーティション２を ext3 File System でファイルシステムを作ります。
フォーマット方法の詳細は省略します。

### SD-Card への書き込み

SD-Card のパーティション１(下の例では/dev/sdc1)に target/zynq-pynqz1/boot/ 下のファイルをコピーします。
SD-Card のパーティション２(下の例では/dev/sdc2)に debian8-rootfs-vanilla.tgz の中身を展開します。
また、展開したルートファイルシステムの home/fpga に fpga-soc-linux-drivers パッケージをあらかじめコピーしておくと良いでしょう。後から network 経由でコピーしてもかまいません。

````
shell# mount /dev/sdc1 /mnt/usb1
shell# mount /dev/sdc2 /mnt/usb2
shell# cp target/zynq-pynqz1/boot/*                                     /mnt/usb1
shell# tar xfz debian8-rootfs-vanilla.tgz -C                            /mnt/usb2
shell# cp linux-image-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb   /mnt/usb2/home/fpga
shell# cp linux-headers-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb /mnt/usb2/home/fpga
shell# cp fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.3-1_armhf.deb    /mnt/usb2/home/fpga
shell# umount mnt/usb1
shell# umount mnt/usb2
````

## デバイスドライバパッケージのインストール

### リブートして fpga または root でログイン

fpga　のパスワードは "fpga"　です。

```
debian-fpga login: fpga
Password:
fpga@debian-fpga:~$
```

root のパスワードは "admin" です。

```
debian-fpga login: root
Password:
root@debian-fpga:~#
```

### Linux ヘッダ/イメージ パッケージのインストール

デバイスドライバパッケージのインストールに先立って、デバイスドライバのインストールに必要な Linux ヘッダ/イメージパッケージをインストールします。デバイスドライバのインストールには、対応する Linux カーネルのバージョンのヘッダ/イメージが必要です。

```
fpga@debian-fpga:~$ sudo dpkg -i linux-image-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb
fpga@debian-fpga:~$ sudo dpkg -i linux-headers-4.8.17-armv7-fpga_4.8.17-armv7-fpga-1_armhf.deb
```

### デバイスドライバ パッケージのインストール

dpkg を使って fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.3-1_armhf.deb をインストールします。

```
fpga@debian-fpga:~$ sudo dpkg -i fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.3-1_armhf.deb
sudo: unable to resolve host debian-fpga
Selecting previously unselected package fpga-soc-linux-drivers-4.8.17-armv7-fpga.
(Reading database ... 37627 files and directories currently installed.)
Preparing to unpack fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.3-1_armhf.deb ...
Unpacking fpga-soc-linux-drivers-4.8.17-armv7-fpga (0.0.3-1) ...
Setting up fpga-soc-linux-drivers-4.8.17-armv7-fpga (0.0.3-1) ...
Created symlink from /etc/systemd/system/multi-user.target.wants/device-tree-overlay.service to /etc/systemd/system/device-tree-overlay.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/fpga-manager.service to /etc/systemd/system/fpga-manager.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/udmabuf.service to /etc/systemd/system/udmabuf.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/zptty.service to /etc/systemd/system/zptty.service.
```

なお、v0.1.3(Linux Kernel Version 4.4.7版) の fpga-soc-linux-drivers-4.4.7-armv7-fpga_0.0.2-1_armhf.deb がインストール済みの RootFS に fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.2-1_armhf.deb をインストールしようとするとコンフリクトしてインストールに失敗します。これは私のパッケージ作成ミスです。申し訳ありませんが、次の様に先に fpga-soc-linux-drivers-4.4.7-armv7-fpga_0.0.2-1_armhf.deb を削除してから、fpga-soc-linux-drivers-4.8.17-armv7-fpga_0.0.2-1_armhf.deb をインストールしてください。

```
fpga@debian-fpga:~$ sudo dpkg --purge fpga-soc-linux-drivers-4.4.7-armv7-fpga
```


### デバイスドライバパッケージがインストールされたかチェックする

```
fpga@debian-fpga:~$ sudo lsmod
Module                  Size  Used by
zptty                   8529  0
udmabuf                10177  0
fpgacfg                12287  0
dtbocfg                 3200  2
fpga@debian-fpga:~$ sudo systemctl status device-tree-overlay.service
● device-tree-overlay.service - Device Tree Overlay Service.
   Loaded: loaded (/etc/systemd/system/device-tree-overlay.service; enabled)
   Active: active (exited) since Sat 2016-04-30 07:50:08 JST; 1min 22s ago
  Process: 1461 ExecStart=/sbin/modprobe dtbocfg (code=exited, status=0/SUCCESS)
 Main PID: 1461 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/device-tree-overlay.service

Apr 30 07:50:08 debian-fpga systemd[1]: Started Device Tree Overlay Service..
fpga@debian-fpga:~$ sudo systemctl status fpga-manager.service
● fpga-manager.service - FPGA Manager Service.
   Loaded: loaded (/etc/systemd/system/fpga-manager.service; enabled)
   Active: active (exited) since Sat 2016-04-30 07:50:09 JST; 2min 46s ago
  Process: 1477 ExecStart=/sbin/modprobe fpgacfg (code=exited, status=0/SUCCESS)
  Process: 1467 ExecStartPre=/usr/bin/fpgacfg_load_overlay.rb (code=exited, status=0/SUCCESS)
 Main PID: 1477 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/fpga-manager.service

Apr 30 07:50:09 debian-fpga systemd[1]: Started FPGA Manager Service..
fpga@debian-fpga:~$ sudo systemctl status udmabuf.service
● udmabuf.service - User space mappable DMA Buffer Service.
   Loaded: loaded (/etc/systemd/system/udmabuf.service; enabled)
   Active: active (exited) since Sat 2016-04-30 07:50:09 JST; 3min 50s ago
  Process: 1484 ExecStart=/sbin/modprobe udmabuf (code=exited, status=0/SUCCESS)
 Main PID: 1484 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/udmabuf.service

Apr 30 07:50:09 debian-fpga systemd[1]: Started User space mappable DMA Buff....
Hint: Some lines were ellipsized, use -l to show in full.
fpga@debian-fpga:~$ sudo systemctl status zptty.service
● zptty.service - Pseudo TTY Driver for communication with FPGA.
   Loaded: loaded (/etc/systemd/system/zptty.service; enabled)
   Active: active (exited) since Sat 2016-04-30 07:50:09 JST; 4min 40s ago
  Process: 1491 ExecStart=/sbin/modprobe zptty (code=exited, status=0/SUCCESS)
 Main PID: 1491 (code=exited, status=0/SUCCESS)
```

## 使用例

### PYNQ祭り

2017年3月4日に開催された [「FPGAエクストリーム・コンピューティング 番外編：PYNQ祭り」](https://fpgax.connpass.com/event/48848/) にて、[「PythonでFPGAプログラミング」](https://www.slideshare.net/ssuser941451/pynq-72804195)という題で発表しました。ここで紹介した環境上に、Python で fibonacci 関数を記述して FPGA に実装して、Juptyer Notebook から動かしてみました。
この環境一式も次の URL に置いてあります。参考にしてください。

 - [https://github.com/ikwzm/PYNQ-Festival](https://github.com/ikwzm/PYNQ-Festival)



## 参考

 - [https://github.com/ikwzm/FPGA-SoC-Linux](https://github.com/ikwzm/FPGA-SoC-Linux)
 - [https://github.com/ikwzm/PYNQ-Festival](https://github.com/ikwzm/PYNQ-Festival)
 - [「FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(ブートイメージの提供) @Qiita」](http://qiita.com/ikwzm/items/cdeb3c9c352776eac683)
 - [「FPGAエクストリーム・コンピューティング 番外編：PYNQ祭り」](https://fpgax.connpass.com/event/48848/)
 - [「PythonでFPGAプログラミング」](https://www.slideshare.net/ssuser941451/pynq-72804195)