FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(ブートイメージの提供)

## 注意(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編)](http://qiita.com/ikwzm/items/57b28cac4f6857b5a199)でFPGA+SoC+Linux+Device Tree Overlay+FPGA Manager のブートシーケンスの説明をしました。また、[「FPGA+SoC+LinuxでDevice Tree Overlayを試してみた」](http://qiita.com/ikwzm/items/ec514e955c16076327ce)、[「FPGA+SoC+LinuxでFPGA Managerを試してみた」](http://qiita.com/ikwzm/items/9eb4d49545636162057e)で、Device Tree Overay と FPGA Manager を紹介しました。

いずれの記事も単なる紹介と説明だけだったのですが、実際に動作する環境もあった方が良いかと思い、以下の URL に ZYBO と PYNQ-Z1 と DE0-Nano-SoC 用のビルド済みの U-Boot、Linux Kernel、Debian8-rootfs、デバイスドライバ(dtbocfgやfpgacfg等)のパッケージを用意しました。

- [https://github.com/ikwzm/FPGA-SoC-Linux](https://github.com/ikwzm/FPGA-SoC-Linux)

Linux や u-boot のビルドが面倒くさいという方はどうぞ。

また、Readme.md にビルド方法も書いてありますので、自分でビルドしてみたいという方は、なにかの参考にしてください。

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


さらに、以下の記事でこのシステムを使った実例をいくつか紹介しています。合わせてご覧ください。

- [「FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(ZYBO-Examples)」@Qiita](http://qiita.com/ikwzm/items/61ea3c5a037b83006f17)
- [「FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(DE0-Nano-SoC-Examples)」@Qiita](http://qiita.com/ikwzm/items/ca6229d4e32fb421b0a9)

## 追記

* 2017/1/14 に Linux Kernel のバージョンを v4.8.17 に更新しました。
* 2017/1/30 に udmabuf のバージョンを v0.6.0 に更新しました。
* 2017/2/16 に ハードウェアとして PYNQ-Z1 を追加しました。

## 概要

* Hardware
  + ZYBO : Xilinx Zynq-7000 ARM/FPGA SoC Trainer Board by Digilent
  + PYNQ-Z1 : Python Productive for Zynq by Digilent
  + DE0-Nano-SoC : Altera SoC FPGA Development Kit by terasic
* 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)
  + fpgacfg     (FPGA Configuration Interface for Linux FPGA Manager Framework)
  + fclkcfg     (FPGA Clock Configuration Device Driver)
  + udmabuf     (User space mappable DMA Buffer)
  + zptty       (Pseudo TeleTYpewriter for FPGA Device)
  + fpga-bridge (FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices)

## ZYBO へのインストール

### ダウンロード

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

 * tareget/zynq-zybo/
   + boot/
     - boot.bin                                                  : Stage 1 Boot Loader(U-boot-spl)
     - design_1_wrapper.bit                                      : FPGA configuration file (Xilinx Bitstream Format)
     - 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-zybo.dtb                           : Linux Device Tree Blob
     - devicetree-4.8.17-zynq-zybo.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-zybo/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-zybo/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
````

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

基本は ZYBO と同じです。以下の記事に PYNQ-Z1 にインストールする記事を載せました。参考にしてください。

* [「FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(PYNQ-Z1対応)」@Qiita](http://qiita.com/ikwzm/items/d6fdaa859906252fd8b0)

## DE0-Nano-SoCへのインストール

### ダウンロード

github から次のようにダウンロードしてください。
現時点の最新バージョンは v0.3.2 です。チェックアウトしてください。
なお、いくつかのイメージファイルはかなり大きいので、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.0
shell$ git lfs pull
```

### ファイルの説明

target/de0-nano-soc/boot/ および target/de0-nano-soc/u-boot/ 下のファイルの詳細は[「FPGA+SoC+Linuxのブートシーケンス(Altera SoC+EDS編)」](http://qiita.com/ikwzm/items/c22d15803ed98f0e52ab)を参照してください。

 * target/de0-nano-soc/
   + boot/
     - DE0_NANO_SOC.rbf                                          : FPGA configuration file (Raw Binary Format)
     - uEnv.txt                                                  : U-Boot environment variables for linux boot
     - zImage-4.8.17-armv7-fpga                                  : Linux Kernel Image
     - devicetree-4.8.17-socfpga.dtb                             : Linux Device Tree Blob
     - devicetree-4.8.17-socfpga.dts                             : Linux Device Tree Source
   + u-boot/
     - u-boot-spl.sfp                                            : Stage 1 Boot Loader(U-boot-spl)
     - u-boot.img                                                : Stage 2 Boot Loader(U-boot)
 * 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 のパーティション３を 特殊パーティション(パーティションタイプ=0xa2)にします。ファイルシステムは作りません。
フォーマット方法の詳細は省略します。

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

SD-Card のパーティション３(下の例では/dev/sdc3)に target/de0-nano-soc/u-boot/ 下のファイルイメージを dd を使って書き込みます。
SD-Card のパーティション１(下の例では/dev/sdc1)に target/de0-nano-soc/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/de0-nano-soc/boot/* /mnt/usb1
shell# dd if=target/de0-nano-soc/u-boot/u-boot-spl.sfp of=/dev/sdc3 bs=64k seek=0
shell# dd if=target/de0-nano-soc/u-boot/u-boot.img     of=/dev/sdc3 bs=64k seek=4
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
````

## ZYBOとDE0-Nano-SoCのデュアルブート

以下の記事に ZYBOとDE0-Nano-SoCのデュアルブートに対応した SD-Card の作り方を載せました。参考にしてください。

* [「FPGA+SoC+Linux+Device Tree Overlay+FPGA Manager(ZYBOとDE0-Nano-SoCのデュアルブートに対応)」@Qiita](http://qiita.com/ikwzm/items/eee398f2f848dc5fe938)



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

### リブートして 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
Selecting previously unselected package fpga-soc-linux-drivers.
(Reading database ... 17830 files and directories currently installed.)
Preparing to unpack fpga-soc-linux-drivers_0.0.3-1_armhf.deb ...
Unpacking fpga-soc-linux-drivers (0.0.3-1) ...
Setting up fpga-soc-linux-drivers (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.3-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.3-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)
```

## 参考

U-Boot、Linux Kernel、Debian8-rootfs のビルドに関しては下記の資料が大変参考になりました。この場をお借りしてお礼を申し上げます。

* 「FPGA マガジンNo.12」, CQ出版社
* [「Debian Linux on Zynq Setup Flow Version March 2016 for Vivado 2015.4」](http://www.slideshare.net/shtaxxx/debian-linux-on-zynq-setup-flow-vivado-20154)