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