Kyoto Maker

Software & Hardware Laboratory Found In Kyoto, 2015.

Helioボード: LinuxとFPGAでSDRAMをシェアする

はじめに

Helioボードには1GBのDDR3-SDRAMが実装されています。 デフォルトの設定ではLinuxが1GBすべてを使用します。 ただ、そうすると、FPGAからSDRAMを読み書きしようとした場合、Linuxが同じメモリー領域にアクセスされると困ります。

そこで、今回はLinuxが使用するSDRAMのメモリー領域を実装メモリーの半分に制限して、OSから邪魔されずFPGAが独占的に使用できるSDRAM領域を確保してみます。動作確認として、FPGA側とLinuxのユーザーランドでSDRAMを読み書きしてみます。

flickr: Sharing Flavored, Colored Ice

変更手順

U-Bootのパラメータを変更することでLinuxが認識するメモリーサイズを変更できます。 具体的には、mmcbootで定義されているbootargsに「mem=<サイズ>M」を追加します。 今回は、1GBの半分、512MBを認識させることにします。

では、Helioボードを起動します。

U-Bootのカウントダウンが始まるので、任意のキーを入力します。

すると、以下のプロントが表示されます。

SOCFPGA_CYCLONE5 #

まず、既存の設定を確認します。ボードのリビジョンによって異なる場合があるかもしれないので、mmcbootの行をメモしておきます。

SOCFPGA_CYCLONE5 # printenv
[...]
mmcboot=setenv bootargs console=ttyS0,115200 root=${mmcroot} rw rootwait;bootz ${loadaddr} - ${fdtaddr}

他の項目は変えず、「mem=512M」を追加します。

SOCFPGA_CYCLONE5 # editenv mmcboot
setenv bootargs mem=512M console=ttyS0,115200 root=${mmcroot} rw rootwait;bootz ${loadaddr} - ${fdtaddr}mmcboot=setenv bootargs console=ttyS0,115200 root=${mmcroot} rw rootwait;bootz ${loadaddr} - ${fdtaddr}

設定できたことを確認します。

SOCFPGA_CYCLONE5 # printenv
[...]
mmcboot=setenv bootargs mem=512M console=ttyS0,115200 root=${mmcroot} rw rootwait;bootz ${loadaddr} - ${fdtaddr}

ここでsaveenvすることで設定保存できますが、はじめての場合は不安なのでこのままLinuxを起動します。設定保存していないので、Linuxを再起動したら設定はデフォルトに戻ります。

SOCFPGA_CYCLONE5 # boot

Linux起動後、メモリーサイズを確認します。確かに512MBとして認識するようになりました。

root@socfpga:~# cat /proc/meminfo | grep MemTotal
MemTotal:         512812 kB

期待通りメモリーサイズを制限できたら、もう一度同じ手順を繰り返し、bootする前にsaveenvコマンドで設定を保存しておきます。

動作確認

以前紹介したQuartus II付属のシステムコンソールを使うことでFPGAから来た信号として代替できます。 FPGA側からSDRAMの512MB目(0x20000000)に0xDEADBEEFを書き込んでみます。

% set m0 [lindex [get_service_paths master] 0]
% open_service master $m0
% master_write_32 $m0 0x20000000 0xDEADBEEF

補足すると、$m0は、リファレンスデザインで実装されている、f2sdram_only_masterインスタンスのサービスパスです。 f2sdram_only_masterは、hps_0のf2h_sdram0_dataポートと接続されていて、JTAG経由で読み書きできるように設計されています。 ですので、$m0を通してSDRAMを読み書きできます。

Linuxからは、以前紹介したユーティリティで書き込んだ値が読み込めるか確認します。正しく読めました。

root@socfpga:~# ./devmem2 0x20000000 w
/dev/mem opened.
Memory mapped at address 0x76f0e000.
Value at address 0x20000000 (0x76f0e000): 0xDEADBEEF

おわりに

LinuxFPGASDRAMをシェアできるようになりました。 ただし、SoCでこの手法が一般的かは不明です^^; 次回は、FPGAで生成した信号をSDRAMに書き込む実験ができればと思います。