ZYBO で FreeBSD が動くまで (1)

Digilent から出ている ZYBO という、Xilinx Zynq-7000 SoC を積んだボードがお手頃価格なので、研究室で何枚か買ってみました。Zynq は FPGA と ARM がひとつのチップに乗った SoC (system on a chip) で、ARM では Linux も動くし、FPGA 部分に載せた回路を周辺デバイスとして動かすこともできるので、けっこう面白いことができそう。ZYBO に載っているチップ (XC7Z010) の FPGA 部分は今となってはそれほど大きいサイズではないのだけれど…
で、僕は Linux のデバイスドライバとかよくわからない (一応書けるけども… なんか苦手) ので、FreeBSD 動くといいなー、と。
同様のボードでひと回り大きいチップを積んだ Zedboard というボードもあり、こちらは FreeBSD 10.1-RELEASE から (まだ Tier1 ではないものの) サポートされている ので、なんとかなるのでは、と思って試しはじめたものの、boot の仕組みから何から全然わからなくて、ちゃんと使えるようになるまで3日かかった。ということで、いちおう記録にまとめておこうと思います。FreeBSD のカーネル構築なんかしたことないよ、とか、FPGA 触ったことないよ、という人にはあまり参考にならないかもしれないけれど。
Step 0: 必要なもの
以下のものが必要です。今回は 1. の部分を書いていきます。Xilinx Vivado が動く開発環境が必要です。僕は Linux でやっていますが、Windows でも大丈夫かもしれません。
1. BOOT.bin 3点セット: Zynq SoCの構成情報, FSBL (First stage boot loader), u-boot
2. Device tree blob + uenv.txt
3. ubldr + FreeBSD
Step 1: SoC を構成する
Zynq は PS (Processing System) と PL (Programmable Logic) のふたつの部分に分かれており、AXI インタフェイスで接続されています。PL 部分はふつうの FPGA だと思えば OK です。
PS には ARM と、メモリコントローラや USB コントローラなどの周辺回路が入っているのだけれど、ただ Micro SD カードにブートローダーを書き込んだだけでは起動できません。Zynq に載っている PLL を使って、ARM コアや SDRAM をはじめとする各所のクロックをどうするか、とか、USB コントローラなどの各種周辺回路をどの MIO (Multiplexed I/O) ピンに引き出すか、といった設定が必要です。Zynq の場合、これらは PL 部分の構成情報といっしょに書き込む必要があります。
とりあえず FreeBSD を動かす、というだけの場合、FPGA の部分についてはあまり考えることはありませんし、HDL を書いて自分で回路を作る、という必要もありません。今回は手っ取り早く Digilent の ZYBO のページにある “ZYBO Base System Design” を使います。同じページにある “Embedded Linux hands-on tutorial for the ZYBO” にこれの説明があります。基本的には、Xilinx の設計ツールである Vivado で、次のような画面でブロックをつないでいくだけです。
block-design.png
Base System Design では HDMI を動かしたりするいろいろが含まれており、PS 以外にもいろいろなブロックが配置されていますが、FreeBSD をきどうするだけならこれらは必須ではありません。この場合のポイントは、Zynq7 Processing System の設定で、
– MIO Configuration: USB0 (MIO28-39), SD0 (MIO40-45), UART1 (MIO48-49), Bank 1: 1.8V
– Clock Configuration: Input Frequency = 50MHz
– DDR Configuration: Memory part = MT41K128M16 JT125
といったあたりです。Base System Design では このあたりは ZYBO のボード事情に合わせて正しく設定されています。Digilent tutorial の通りにして、Vivado で “Generate Bitstream” すると、Zynq の回路を構成するための .bit ファイルが生成されます。
Step 2: u-boot をコンパイルする
順序的には SoC が構成されたあと、FSBL が読み込まれて、そこから u-boot が起動するのですが、FSBL を使うときは Xilinx SDK が出てくるので、先に u-boot の話をしておきます。
u-boot は組み込みシステム向けの、OS 非依存なブートローダで、SD カードや tftp を使って起動することができます。Digilent が配布しているものを使いました (これもチュートリアルにある通りです)。設定とかはないので、make するだけです。
[code:plain]
% git clone -b master-next https://github.com/DigilentInc/u-boot-Digilent-Dev.git
% cd u-boot-Digilent-Dev
% make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_zybo_config
% make CROSS_COMPILE=arm-xilinx-linux-gnueabi-
[/code]
これで u-boot というファイルができるので、それを u-boot.elf に rename しておきます。
Step 3: First stage boot loader をコンパイルする
Zynq PS のアドレスマップなどはハードウェアの構成によって変わるので、Vivado で作ったハードウェアに合わせたブートローダを作る必要があります。これも、Digilent のチュートリアルにある通りの方法で作ることができます。
基本的には、
– Vivado で File → Export Hardware で SDK 用にハードウェアの構成情報を書き出す
– 続いて Vivado で File → Launch SDK を選んで Xilinx SDK を起動する
– File → New → Application Project でプロジェクトを作る際のテンプレートとして Zynq FSBL を選択
– fsbl_hooks.c を Base System Design の配布ファイルにあるものと差し替え (これやらないと MAC アドレスが毎回変わるのだとか…)
という流れです。Vivado 側で (PS から見た) ハードウェアの構成が変化した場合には作り直す必要がありますが、OS 非依存ですので Linux でも FreeBSD でも同じです。
SDK のフォルダの下の、FSBL/Debug/ (FSBL は Application project 名) に FSBL.elf ができるはずです。これが FSBL のバイナリです。
Step 4: BOOT.bin を作る
.bit ファイル → FSBL → u-boot の順で SD カードから読み込まれて Zynq が起動するわけですが、これらは Zynq Boot Image (BOOT.bin) としてひとつのファイルにまとめて SD カードに書き込みます。SDK のメニューバーで、Xilinx Tools → Create Zynq Boot Image を選ぶと作ることができます。
一番下の boot image partitions というところに、
– FSBL.elf
– (自分のFPGA構成情報).bit
– u-boot.elf
をこの順番に Add していけば OK です。FSBL.elf のところには [bootloader] という表示がつきますので、確認してください。
指定したディレクトリに BOOT.bin と、つかったファイルのリストの .bif ファイルが生成されれば、OS を起動する準備はおおむね準備完了です。
(続く、といいなあ)

コメントを残す