SoC FPGA: LinuxからFPGAをお手軽に?コンフィグレーションしたい: DebugFS を介して

# はじめに

この記事は、Arm® processor が搭載された Cyclone® V SoC FPGA で、Arm Linux から FPGA の再コンフィグレーションを行う場合の話です。

Linux から FPGA をコンフィグレーションするには、DeviceTree Overlay という機能を使うというのが Linux Community での正統な方法ということのようですが、DeviceTree Overlay のスクリプト(.dts)を書いて dtc でコンパイルして .dtb に変換して... というのは、必要な手数も多く、気軽に使うには敷居が高く感じられます（と思うのは私だけ？）。
幸いにも、Linux Kernel には、DebugFS を介してFPGAを再コンフィグレーションする仕組みも用意されているので、この仕組みを使ってFPGA の再コンフィグレーションをする方法について、手順と注意点などを書かせていただきます。

実際のところ、組み込みで使われる SoC FPGA においては、Linux を生かしたまま FPGA をコンフィグレーションしたい、という場合はそれほど多くないかもしれませんが、Intel Advent Calender 2020 中盤の「箸休め」的な読み物として御覧いただければと思います。

 
# 仕組み

DebugFS を介した FPGA のコンフィグレーションの仕組みについてです。まず、今回の話に登場する役者たちをザクっと図にしたものが Fig.1 になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175992/131693cd-d430-e35c-552a-0d8d66b5bfc8.png)



User SpaceとKernel Space 内の箱(含むオレンジ系の箱)は CPU で実行される Software、青色系と緑色は FPGA Hardware というイメージです。紫色の矢印はデータの流れで、上から下に流れるのは、コンフィグレーションデータとなります。fpga control block から fpga-mgr に行っている矢印は、FPGA の状態を監視できるといった意味です。
Kernel ドライバとしては、オレンジ系で示した DebugFS と FPGA manager (fpga-mgr) が使われます。fpga-mgr-debugfs という濃いオレンジの箱は、FPGA manager の機能の一部（拡張機能といった位置づけ）です。
濃い青色の fpga control block は、FPGA のコンフィグレーションをコントロールするハードウェアブロックで、FPGA manager はこれにアクセスし、FPGA コンフィグレーションを実行できるようになっています。

動作は、

- ユーザアプリが、debugfs 下の FPGA コンフィグレーション用の path(後述) に コンフィグレーションデータ(.rbf ファイル) を書き込む
- FPGA manager がコンフィグレーションデーを受け取り、FPGA コンフィグレーションを実行する

という流れになります。


ちなみに、DebugFS とは、ですが、[debugfs Wikipedia page](https://en.wikipedia.org/wiki/Debugfs) によりますと(かなりの意訳ですが)
>ユーザプログラムが、Kernel(driver)とデータや情報のやり取りができるファイルシステムで、同様の機能を持つ sysfs や /proc と比べ 使い方に特に制約はなく、自由な使い方をしてよい

とのことです。大量のデータの転送が必要なコンフィグレーションの機能を実装するには適した "ユーザ <-> Kernel" interface となるのだと思います（というか、sysfs では実現できないので debugfs を使っているって感じ.名前も用途に合ってるし）。

# DebugFS を介したFPGAコンフィグレーションを 可能にするには

Fig.1 の Kernel space の３つの箱、debugfs、 fpga-mgr-debugfs、 fpga-mgr を enable にしてやる必要があります。SoC FPGA をサポートする[ linux-socfpga リポジトリ](https://github.com/altera-opensource/linux-socfpga)  の Kernel のデフォルトの構成 (=socfpga_defconfg) では、debugfs と fpga-mgr の基本部分は enable になっていますが、 fpga-mgr-debugfs (濃いオレンジの部分) は、enable になってません。この機能を enable にし、Kernel を作る必要があります[^1]。

[^1]: ”お手軽に” と行きたかったところですが、Kernel を自分でリビルドすることは必要でした...

具体的な方法については、後述の "実践" セクションで書きます。

# 使い方

DebugFS を介した FPGA コンフィグレーションの実際の使い方は、Kernel Source の Documentation/fpga/debugfs.txt に記載されています。これによると、この仕組みが enable になった Kernel では、\<debugfs>/fpga_manager/fpga0 というディレクトリが生成され (具体的には `/sys/kernel/debug/fpga_manager/fpga0`）、さらにその下に、
　`flags,  config_complete_timeout_us, firmware_name , image `
という4つのファイルが作られます 。これらのうち、CycloneV SoC のコンフィグレーションに使えるのは、firmware_name と image です[^2]。firmware_name, image のどちらかを使って、 FPGA コンフィグレーションを実行することができます。

[^2]: 関連のドライバ source (driver/fpga/socfpga.c) を読んでみたのですが、flags, config_complete_timeout_us に渡された情報は、CycloneV SoC のコンフィグレーションでは使われてませんでした.

__firmware_name:__
>あらかじめ firmware ディレクトリ(/lib/firmware) に RBF ファイルをコピーしておき、RBF ファイル名を このpathに書き込むことでコンフィグレーションが実行される。

例：```echo image.rbf > /sys/kernel/debug/fpga_manager/fpga0/firmware_name```


__image:__
>このファイルに、RBF ファイルの内容を Write すれば FPGA コンフィグレーションが実行される。ただし、全 RBF data を 1回の write() 関数で書き込む必要がある。

例：```dd bs=10M if=./image.rbf of=/sys/kernel/debug/fpga_manager/fpga0/image```
この dd コマンドで、bs オプションでバッファサイズを指定しているのは、1回の write() 関数で書き込むためで、RBF ファイルサイズより大きな値を bs に指定してやる必要があります。この場合は、image.rbf が 10MByte 以下である場合の例です。

もし、自分の C プログラムからコンフィグレーションを実行する場合なら、おおよそこんな感じの流れになるかと思います(エラーチェック省いてまーす）。

```c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define MAX_SZ (8*1024*1024)
....
int fd_rbf;
void *buf;
size_t count;

buf = malloc(MAX_SZ);

fd_rbf = open("./image.rbf", O_RDONLY);
count = read(fd_rbf, buf, MAX_SZ); /* RBF ファイル読み込み */
....
int fd_dbgfs;
fd_dbgfs = open("/sys/kernel/debug/fpga_manager/fpga0/image", O_WRONLY);
write(fd_dbgfs, buf, count); /* RBF ファイル書き込み、コンフィグレーション実行 */
....
```


# 実践

では、実際にDebugFS を介したFPGAコンフィグレーションを試してみます。
動作確認に使用したボードは、Terasic Inc. 製の [DE10-nano kit](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=167&No=1046) となります。

## SD card の準備

まずは、ボードを起動するための、SD card を作ります。ボード(DE10-nano)用の Linux SD card image をダウンロードし、SD card に書き込みます。自分の使っているボード用の Linux image であれば、何でも構わないと思います。（私は、 Terasic サイトの [DE10-Nano Kit Resourcesページ](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=167&No=1046&PartNo=4) の中の"Linux LXDE Desktop (kernel 4.5)" を使いました。） 手持ちの SD card に ダウンロードした Image を書き込んだら、無事に Linux が起動することを確認しておいてください。

## Default Kernel のビルド

次に、SoC FPGA 用 Linux のポータルサイト [RocketBoards のドキュメントページ](https://rocketboards.org/foswiki/Documentation/CycloneVSoCGSRD) や ["DE10nano 向けLinux Kernel Build"](https://qiita.com/eofz/items/3413cbdf804154bc150e) 等を参考に、デフォルトの zImage, .dtb のビルド(make zImage; make dtbs) を行ってください。私は、タグ ACDS20.1STD_REL_GSRD_PR  (v5.4.23-lts 系) をチェックアウトしました。
`git checkout refs/tags/ACDS20.1STD_REL_GSRD_PR -b tag_ACDS20.1STD_REL_GSRD_PR`

## Kernel 設定変更 &リビルド

 Fig.1 の濃いオレンジの部分 (fpga-mgr-debugfs) を enable にします。そのためには、Kernel の設定を変更し、 Kernel をビルドし直します。（どんな CONFIG_* を変更をすればよいかは、driver/fpga/ の下の Makefileおよび Kconfig の中身を見て、それらしい名前のものを見つける、という方法で調べました。）

コマンド
 `make menuconfig`
を実行し、
　　-> Device Drivers
　　　　-> FPGA Configuration Framework 
　　　　　　　[*] FPGA Manager DebugFS
と設定し save して exit します。

（もしくは、.config ファイルをテキストエディターで開いて、`CONFIG_FPGA_MGR_DEBUG_FS=y` の一行を最終行に加えるということでもOKです。)
その後 
`make zImage`
で zImage を再ビルドします。

出来上がった zImage を SD card の FAT partition に書き込みます。また、先の "Default Kernel のビルド" のステップで生成した socfpga_cyclone5_de0_sockit.dtb は、soc_system.dtb とリネームして、同じく FAT partition に書き込みます。 どちらも既存のファイルを置き換える形になります[^3]。

[^3]: 正式には、zImage を入れ替える際には、SD card の Kernel module も update してやる必要があるのですが、今回の作業の範疇では、Kernel module は使っていないので作業としては省略しています。Kernel module の update もやっておきたい、という場合は、例えば こちら["DE10nano 向けLinux Kernel Build"](https://qiita.com/eofz/items/3413cbdf804154bc150e) の "Kernel modules も" のセクションをご参照ください. 

## 動作確認

まずは、上の手順で書き換えた SC card で Linux が起動し、root でログインできることを確認します。

```
...
[  OK  ] Started Update UTMP about System Runlevel Changes.
[  OK  ] Started Authenticate and Authorize Users to Run Privileged Tasks.

Ubuntu 16.04.1 LTS DE10_NANO ttyS0

DE10_NANO login: root
Password:
Last login: Sun Dec 13 10:48:30 UTC 2020 from 192.168.1.9 on pts/1
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 5.4.23-03461-gb6dad2fd8d54 armv7l)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
root@DE10_NANO:~#
```

"Welcome to Ubuntu ..." の行を見ると、Kernel が、5.4.23 になっていることも確認できます。

次に、作り直した Kernel に debugfs 経由で FPGA コンフィグレーションができるようになっているか確認してみましょう。/sys/kernel/debug/fpga_manager ディレクトリの下に fpga0 というディレクトリがあるかを確認します。

```
root@DE10_NANO:~# ls -l /sys/kernel/debug/fpga_manager/
total 0
drwxr-xr-x 2 root root 0 Jan  1  1970 fpga0
root@DE10_NANO:~#
```

無事に確認できたら、さらにその下のファイルを見てみます。

```
root@DE10_NANO:~# ls -l /sys/kernel/debug/fpga_manager/fpga0/
total 0
-rw------- 1 root root 0 Jan  1  1970 config_complete_timeout_us
-rw------- 1 root root 0 Jan  1  1970 firmware_name
-rw------- 1 root root 0 Jan  1  1970 flags
--w------- 1 root root 0 Nov 28 15:18 image
root@DE10_NANO:~#
```

このように４つのファイルがあればOKです。
（もし、"fpga0 が存在しない" という場合は、自分で生成した zImage と .dtb が正しく SD card に書き込まれて、起動時に読み込まれているか、確認してみてください。起動時のシリアルターミナルのログの先頭部分に、読み込んだ zImage と dtb のファイルサイズも表示されているので、正しいものか確認できます。）

いよいよ、コンフィグレーションを試してみましょう。コンフィグレーションデータが必要なのですが、手っ取り早く、起動に使った .rbf ファイルを使ってみます。fat partition (partition 1) を /mnt にマウントします。（もちろん、既存の RBF を SD card に書くなり、scp で転送するなりして 持ってきても構いません。）

```
root@DE10_NANO:~# mount /dev/mmcblk0p1 /mnt
root@DE10_NANO:~# ls /mnt
soc_system.dtb  soc_system.rbf  u-boot.scr  zImage
root@DE10_NANO:~#
```

/mnt/soc_system.rbf が コンフィグレーションデータです。これを使ってコンフィグレーションしてみます。

```
root@DE10_NANO:~# dd bs=5M if=/mnt/soc_system.rbf　of=/sys/kernel/debug/fpga_manager/fpga0/image
0+1 records in
0+1 records out
2202852 bytes (2.2 MB, 2.1 MiB) copied, 0.316385 s, 7.0 MB/s
root@DE10_NANO:~#
```

この様に、エラーメッセージが表示されず、無事に dd 終了すれば成功です。また、dd コマンドの実行中に、ボードの conf LED が一旦消えてから再度点灯する、という動作になると思いますが、これもコンフィグレーションが開始され(LED消灯)、その後 正常にコンフィグレーションが成功した(LED点灯)ことを示しています。

また、sysfs を通して fpga manager にアクセスし、fpga manager の動作状況を確認することもできます。
コマンドは、 `cat /sys/class/fpga_manager/fpga0/state` です[^4]。

[^4]: /sys/class/fpga_manager/fpga0/state は、FPGA manager のコンフィグレーション動作がうまくいったかを表す state で、現在の FPGA のコンフィグレーション状態を表す fpga control block の Register(物理アドレス 0xff706000)の値ではありません.

```
root@DE10_NANO:~# cat /sys/class/fpga_manager/fpga0/state
operating
root@DE10_NANO:~#
```
コンフィグレーションが完了し、FPGA が User mode に入った場合には、"operating" という文字列が返ってきます。

__以上、RBF ファイルを、規定の path に dd するだけで FPGA のコンフィグレーションができる、お手軽 FPGA コンフィグレーションが確認できました。__

******
もう一つの方法、firmware_name を使った方法も試してみます。RBF ファイルを予め /lib/firmware フォルダにコピーし (test.rbf という名前にしています)、そのファイル名を /sys/kernel/debug/fpga_manager/fpga0/firmware_name に echo します。

```
root@DE10_NANO:~# cp /mnt/soc_system.rbf /lib/firmware/test.rbf
root@DE10_NANO:~# echo "test.rbf" > /sys/kernel/debug/fpga_manager/fpga0/firmware_name
root@DE10_NANO:~#
```

こちらの方法でもコンフィグレーション動作が行われたこと（ボードの conf LED が一旦消えてから再度点灯するという動作）が確認できるはずです。


__こちらでも、RBF ファイルを /lib/firmware にコピーし、規定の path に RBFファイル名を echo するだけで FPGA のコンフィグレーションができることが確認できました。__


#  注意点

Linux から FPGA 書き換える際の注意点を書きます。

## FPGA design の制限

書き換える RBF のデザインは、「起動に使った Preloader と同一の Preloader で動作するデザイン」という条件に合ったデザイン(RBF)にする必要があります。
「起動に使った Preloader と同一の Preloader で動作するデザイン」を言い換えると、「hand_off file が同一となるデザイン」と言えますが、より具体的には、Platform Builder で設定している HPS IP の設定(例えば Bus bridge の設定等) が同一である、ということになります（デザインプロジェクトの hps_isw_handoff フォルダ下のファイルを diff してみるのがより確実な確認方法です）。HPS IP の設定は、RBF でなく、Preloader の実行により反映されるものなので、至極当然といえば当然のことなのですが。
FPGA design を修正している際には、FPGA2SDRAM のバス幅等の設定を変えたりしたくなる場合もありますが、この設定変更は、Preloader コードの変更も伴うものとなるので、注意が必要です。 HPS IP の設定まで変更する場合は、Preloader も作り直して Sd card に書き込み、起動時に uboot でコンフィグレーションする RBF も入れ替える、というところから行う必要があります。

なお、当然のことながら、この点については、DeviceTree Overlay を使ってコンフィグレーションし直す場合にも当てはまります。


## Debugfs の仕組みを使うことによる注意点

Kernel Source の Documentation/fpga/debugfs.txt の最後のセクションに以下の注意書きがあります。

> 
This interface does not handle bridges or loading/unloading of soft IP device
drivers.  This makes it really easy to mess things up by doing things like
reprogramming the hardware out from under a driver or reprogramming while a
bridge is enabled, causing gunk to go out on a cpu bus.  It should go without
saying that this interface is for debug only.  Not intended for production use.


Bridge のハンドリングをしていないこと、soft IP (FPGA にインプリメントした IP ) 用のデバイスドライバのアンロード・ロードを行ってないことを注意点として挙げています。「このあたりのケアをしっかりしないとシステムがハングアップする可能性があります、ということでこの手法はデバッグ用途のみで使うべき」と書かれています（だから DebugFS 経由の方法なんだ）。

確かにその通りです。FPGA コンフィグレーションをし直すというのは、FPGA の回路を一旦消し去る、ということなので、FPGA のレジスタをアクセスするソフトウェアはすべて停止しておかなければなりません。FPGA の回路を消し去っている時に、FPGA のレジスタをアクセスすると、そのバスアクセスに対するレスポンスが返って来ないので、HPS 内のバス（インターコネクト）がハングアップし、CPU も即死となります。そのために、FPGA 内の soft IP をアクセスするための デバイスドライバは、全て削除してからFPGAコンフィグレーションをするべきです。また、デバイスドライバをきれいに削除(unload)するには、アプリケーションソフトウェアも FPGA をアクセスするものに関しては全て停止しておく必要があります（マルチプロセスの Linux だと思わぬソフトウェアがバックグラウンドで動いていた、という場合もありますので）。

デバイスドライバで言うと、特にFPGAからの割り込みを受け付けるデバイスドライバは、必ず削除しておく必要があるでしょう。FPGA の回路を消した(= nConfig assert した)ことで信号状態に変化が起こり、割り込みとして CPU に伝わり、割り込み処理ルーチンが FPGA レジスタをアクセスに行きハングアップ...という状態が起こり得ます。とはいえ、起動時に DeviceTree により load されているドライバは、DeviceTree Overlay でないと unload が困難というのは事実です。

ということで、この DebugFS を介しての FPGAコンフィグレーションは、

- そもそも FPGA soft IP 用の Kernel ドライバなんぞ使わない人
- FPGA soft IP 用のドライバは使うけど、insmod および rmmod で手作業でロード・アンロードを行う気概がある人

という人に向いている、と言えるかと。

ちなみに、前のセクションの動作確認では、FPGA soft IP をアクセスするドライバはもともと load されていない状態の Kernel だったので問題なくコンフィグレーションができておりました (デフォルトの socfpga_cyclone5_de0_sockit.dtb = soc_system.dtb では、FPGA 内 soft IP 用の ドライバは登録しない記述となっているので安心して再コンフィグレーションできます）。

あと、残るは bridge の件ですが、せっかくの機会なので、一応 bridge のケアについても調べてみました。次のセクションに書いておきます。

なお、私の経験談[^5],[^6]ですが、ソフトウェア側で FPGA をアクセスしないようケア（ドライバ削除やアプリの停止）をしていれば、bridge はそのままにしてコンフィグレーションを行っても問題に遭遇したことはないこと、は事実です。

[^5]: ばりばり JTAG 経由とかでも CPU 動作中に FPGA 書き換えを行ってきました

[^6]: 「は？お前の経験なぞ、なんの役に立つ」というツッコミ ごもっとも...

# FPGA bridge もケアしてみる

FPGA bridge についてもケアする方法です。
Fig.1 の緑色の箱が FPGA bridge です。FPGA をコンフィグレーションしている最中に、FPGA 側から変な信号がCPU側に入って来ないようにするためです。
Devicetree Overlay を使った方法では、fpga-region ドライバに操られ fpga-bridge ドライバがこの制御（レジスタ設定）を行っているのですが、残念ながら ユーザプログラムから fpga-bridge ドライバを動作させるパスは見当たりませんでした[^7]。

[^7]: sysfs 経由で、各 bridge の状態を観測できるようにはなってます。例えば "cat /sys/class/fpga_bridge/br?/state" . でも書き込みができる path は用意されてません.

その代わりとして、ここでは memtool というユーティリティ（参照: [SoC FPGA: Linux で使うときの小ネタ](https://qiita.com/eofz/items/8c4b9cf776a5e5225323)）を使って、bridge をコントロールするレジスタアクセスを行ってしまおうと思います（少々 力技ですが）。
Kernel source の中の fpga-bridge ドライバのコードで実際に CycloneV SoC のbridge 制御をしているファイル(drivers/fpga/altera-fpga2sdram.c, altera-hps2fpga.c) を読むと、以下の3つのレジスタにアクセスしています。これらのレジスタの動作については、CycloneV SoC の Hard Processor System Technical Reference Manual  のレジスタ定義にて以下の様に説明されてます。

- fpgaportrst レジスタ：アドレス 0xffc25080： f2s bridge の制御, bit-13..0:  各ビット 1 で enable , 0で disable
- brgmodrst レジスタ: アドレス 0xffd0501c :  h2f, lwh2f, f2h bridge のreset制御 :  bit-0: h2f, bit-1:lwh2f, bit-2 f2h , 各ビット 1 で reset, 0で reset 解除
- remap レジスタ : アドレス 0xff800000 : h2f, lwh2f bridge のenable制御: bit-3: h2f, bit-4: lwh2f, 各ビット 1 で enable , 0で disable

これらのレジスタのビットを、実際のデザインに応じて制御すれば良いことになります。ここで問題となるのは、実際のデザインでどの bridge が使われているかを知る方法ですが、altera-fpga2sdram.c のドライバでやっているように、System manager 内の hand_off Register 情報[^6]を使う、という手段で行きたいと思います。hand_off Register の内容内訳ですが（preloader/uboot のコードも参照しながら読み取ったところ）、
  - fpgaportrst に設定すべき値が、hand_off[3] (= 物理アドレス0xffd0808c）に
  - brgmodrst に設定すべき値が、hand_off[0] (= 物理アドレス0xffd08080）に
  - remap に設定すべき値が、hand_off[1]  (= 物理アドレス0xffd08084）に
それぞれ書かれている、と判明しました。ということで、全体フローは、


[^6]: 物理アドレス 0xffd08080-0xffd0809C. この情報は、Preloader が起動時に設定しており、uboot でも FPGA コンフィグレーション後にこの情報を元に brige の制御を行っています.



- 全 FPGA bridge を disable にする 
- FPGA をコンフィグレーションする
- 必要な FPGA bridge を hand_off Register 情報に従い enable にする

となります。

この一連の作業を bash script で書いた例を以下に張り付けます。 `./config.sh image.rbf` というように 第一引数に RBF ファイルを指定して使えるようにしています。

```bash:config.sh
#!/bin/bash

echo "FPGA re-configuration...start."
BSIZE=8M

remap_handoff=$(memtool ffd08084 1 | grep "^0x" |awk '{print $2}')
brgmodrst_handoff=$(memtool ffd08080 1 | grep "^0x" |awk '{print $2}')
fpgaportrst_handoff=$(memtool ffd0808c 1 | grep "^0x" |awk '{print $2}')

#Disable
echo " Disabling Brides"

fpgaportrst_disable=0
brgmodrst_disable=7
remap_disable=1

memtool ffc25080=$fpgaportrst_disable  > /dev/null
memtool ffd0501c=$brgmodrst_disable  > /dev/null
memtool ff800000=$remap_disable > /dev/null

dd bs=$BSIZE if=$1 of=/sys/kernel/debug/fpga_manager/fpga0/image &> /dev/null

fpga_state=$(cat /sys/class/fpga_manager/fpga0/state)

echo "  fpga_manager state \"$fpga_state\""

if [[ "$fpga_state" == "operating" ]]; then
  echo "  Conf Done."
else
  echo "  FPGA re-configuration failed..."
fi

#Enable
echo " Enabling Brides"
memtool ffc25080=$fpgaportrst_handoff  > /dev/null
memtool ffd0501c=$brgmodrst_handoff  > /dev/null
memtool ff800000=$remap_handoff > /dev/null
echo "FPGA re-configuration...END."
```
ConfDone チェックやらを入れたりしたらちょっと長くなってしまいました...  
hand_off register の値の読み出しは、memtool の出力文字列を awk を使って抜き出す作戦を採用しました。remap_disable の値を 1 とした理由は、ドライバコード(altera-hps2fpga.c) がそのようになっていた からです。

実際に実行するとこんな感じの表示となります。

```
root@DE10_NANO:~/Config# ./config.sh image.rbf
FPGA re-configuration...start.
 Disabling Brides
  fpga_manager state "operating"
  Conf Done.
 Enabling Brides
FPGA re-configuration...END.
root@DE10_NANO:~/Config#
```

# おわりに
DeviceTree Overlay について調べている時に Kernel Source 中のドキュメントDocumentation/fpga/debugfs.txt を見つけ、興味を持ったのがきっかけで "DebugFS を介した" FPGA コンフィグレーションについて、Kernel Source を主な調査資料とし　"調べて・試した"　内容を書かせていただきました。

`CONFIG_FPGA_MGR_DEBUG_FS=y` とした Kernel を準備すれば、DeviceTree Overlay を使う方法に比べ、より簡単にFPGA コンフィグレーションが行えることが確認できました（bridge のケアまでしようとするとちょっと面倒かもしれませんが）。

冒頭にも書きましたが、Linux を生かしたまま FPGA をコンフィグレーションする、という場面は多くはないかもしれませんが、debug 用途などで、いくつかの FPGA デザインをサッと試したい、といったマニアック？な場面で活躍可能かと思います。あと、最近話題の Cloud との連携で、リモートから FPGA を再コンフィグレーションしたい、といった場合に使えるかも、と思ったりもしてます。。。。

以上、最後までお読みいただき、有難うございました。


# 参考資料・リンク
[debugfs Wikipedia page](https://en.wikipedia.org/wiki/Debugfs)
[Linux Kernel 4.10 でのFPGAのサポート事情](https://qiita.com/ikwzm/items/2ff7d5429da8ace7c0bd)
[デバイスツリー Overlay について調べてみた](https://qiita.com/eofz/items/fbc72b39c6a176995444)
[linux-socfpga Git リポジトリ](https://github.com/altera-opensource/linux-socfpga)
[u-boot-socfpga Git リポジトリ](https://github.com/altera-opensource/u-boot-socfpga)
[Cyclone V Hard Processor System Technical Reference Manual](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/cyclone-v/cv_5v4.pdf)
[Cyclone V HPS Register Address Map and Definitions](https://www.intel.com/content/www/us/en/programmable/hps/cyclone-v/hps.html)


# Notices & Disclaimers
Intel technologies may require enabled hardware, software or service activation.
No product or component can be absolutely secure. 
Your costs and results may vary. 

© Intel Corporation.  Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries.  Other names and brands may be claimed as the property of others. 

The products described may contain design defects or errors known as errata which may cause the product to deviate from published specifications.  Current characterized errata are available on request.​

Intel disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade.