とあるエンジニアの備忘log
2014年1月31日金曜日
Zynq のビルドプロセスをスクリプト化する
Zynq の話なんですが、そこそこ慣れてくると、Vivado や XSDK の GUI が使いにくく思えてきます。 GUI というのは、最初は何となくわかりやすいような印象を与えるが、ある程度使いこなせるようになると、 CUI の方がありがたいです。 基本的に、開発中というのは「ソースコードの修正」→「ビルド」→「動作確認」の繰り返しです。 いちいち、GUI を開いて、FPGA をコンパイルしたり、ハードウェアをエクスポートして、 XSDK に食わせたりとかのルーチンワークを手動でやりたくないのです。 幸い、Vivado には Tcl インターフェースがあるので、GUI でできることは、CUI でもできるのです。 私がこれをやりたい理由を挙げると、 - GUI は重い - GUI は自動実行できないので、繰り返し作業に向いていない - GUI は間違えやすい チームでの開発になったりすると、中には詳しくないメンバーもいたりする。 特に Zynq はビルド手順がかなり複雑になってしまっているので、 GUI でのビルド手順を習得するには、それなりに時間がかかるし、操作ミスも発生する。 ビルドプロセスを完全にスクリプト化してしまえば、「とりあえず "make" って打っとけや」で済む。 - GUI のプロジェクトはバージョンコントロール(git) での管理が難しい バージョン管理をせずに仕事を進めるというのは、恐ろしいことである。 これをしないと、ソースを過去に戻したり、開発プロセスを他のメンバーと共有できない。 しかしながら、Vivado のプロジェクトとバージョン管理は相性が悪い、 というかそもそもバージョン管理のことを考えてないんじゃないかと思う。 FPGA の時はプロジェクトが管理するのは RTL と制約ファイルぐらいだったから、 RTL と 制約ファイルをバージョン管理して、プロジェクトはその都度、再構築すればよかった。 しかし、Zynq の場合は、ARM 周りの設定とか、IP 間の接続とか、いろんなものがプロジェクトで管理されている。 プロジェクト自体を git に登録するのは、一体何がソースで、 何がジェネレートされたファイルなのかよくわからないので無理がある。 そこで、RTL や 制約ファイルとともに Vivado を制御するスクリプトを Tcl で書き、これらを git で管理することにした。 なに、大した知識は必要ない。 Tcl の初歩的な文法がわかればよい。(知らなくても 半日もあれば勉強できる。) あとは、Vivado をコントロールするコマンド群だが、これも簡単にわかる。 Vivado を起動した時に、カレントディレクトリに `.jou` という拡張子のファイル (Journal File) が作られるが、このファイルに、 Vivado が実行した操作が Tcl のコマンドとして記録されていく。 なので、知りたいコマンドがあるときは、GUI から一度実行してみて、Journal File を見れば、対応するコマンドが一目瞭然なのだ。 例えば、プロジェクトを作成するのは `create_prj` だし、RTL を追加するには `import_files`、合成は `launch_runs systh_1` でよいというのがわかる。 詳しいコマンドの意味を調べたいときは "Vivado Design Suite Tcl Command Reference Guide" というドキュメントがある。 そんな感じで、プロジェクト作って、RTL と 制約ファイル追加して、合成して、配置配線して、 Bit ファイル作って、HW 情報をエクスポートして、なんてのをスクリプトで組んでいけばよい。 あとは Block Design だが、これも Tcl スクリプト化できる。 Block Design を開いた状態で、 Vivado のメニューから 「File → Export → Export Block Design...」 を選べば、Tcl スクリプトに出力できる。 Block Design を Tcl からプロジェクトへリストアするには、その Tclスクリプトを `source` で読み込んで `save_bd_design` でよい。 このようにして組んだ Tcl スクリプトをバッチモードで実行するには以下のようにする。 $ vivado -mode batch -source
これで、Vivado の GUI を開く必要がなくなった。 GUI を使うのは Block Design を編集するときぐらいである。 さらには Makefile も作って、FSBL, U-Boot, Linux など他のコンポーネントも自動でビルドするようにして、 XMD からブートさせるところまで、自動化してしまいます。 このようにして作った、非常に軽量な完全自動化プロジェクトを git で履歴管理します。快適です。 PetaLinux も Xilinx が用意してくれているオールインの環境(あまり詳しくない)だと思うが、こちらはかなり重そう。。
2014年1月21日火曜日
U-Boot と Linux Kernel のメインラインで Zynq を動かす
[以前](/2014/01/zynq-2.html)、U-Boot と Linux をソースからビルドして Zynq 上で動かすには、[Wiki Page](http://www.wiki.xilinx.com/) を読むのがわかりやすいと書きました。 このページを参照しながら、やっている人も多いのではと思います。 Xilinx は GitHub に[ローカルな開発リポジトリ](https://github.com/Xilinx) を持っていて、 Wiki Page もこのリポジトリを使っています。 ここでは、Xilinx のリポジトリではなく、U-Boot と Linux Kernel のメインラインからコードを持ってきて、 Linux をブートさせるやり方を紹介します。 ちょうど、本日(=2014.1.21) U-Boot 2014.01 がリリースされました。 このリリースから Zynq の各種ボードサポートが U-Boot のメインラインにマージされたので、 Xilinx ローカルリポジトリを追跡しなくても動かせるようになりました。 また、前日 (=2014.1.20) には Linux 3.13 がリリースされましたので、これを使ってみます。 今回使うのは - U-Boot 2014.01 - Linux Kernel 3.13 - Zynq ZC706 ボード です。 ただし、Wiki Page で紹介されているやり方と結構違います。主な違いは - U-Boot 自身のコンフィグレーションにも Device Tree が必要 - Kernel のイメージは、従来のレガシー uImage ではなく、 FIT (Flattened uImage Tree) を使う - Kernel の defconfig は `multi_v7_defconfig` を使う 入門者には何言っているかわからないかもしれないが、以下で丁寧に手順を説明します。 ### STEP0: DTC (Device Tree Compiler) の準備 ##### Input Files Required - None ##### Output Files Produced - `dtc`: Device Tree Compiler ##### Task Description U-Boot を Device Tree 付きでビルドするには version 1.4 以降の DTC が必要になる。 ディストリビューションに標準で用意されている DTC では不足するかもしれないのでバージョンを確認。 $ dtc -v Version: DTC 1.3.0 バージョンが 1.4.0 よりも古い場合は、自分でビルドします。 $ git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git でソースを取ってきて $ make $ make install でビルドとインストールができる。 `$(HOME)/bin` の下に `dtc` が入るので PATH を通しておく。 ### STEP1: U-Boot のビルド ##### Input Files Required - `dtc` - ARM Cross Compiler ##### Output Files Produced - `u-boot-dtb.bin`: U-Boot の RAWバイナリと U-Boot をコンフィグレーションする DTB を連結したもの - `tools/mkimage`: U-Boot で扱うイメージを生成するツール。 (Wiki Page では `u-boot` を使っているが、これは使わない。) ##### Task Description $ git clone git://git.denx.de/u-boot.git $ cd u-boot $ git checkout v2014.01 でソース取得して、v2014.01 タグをチェックアウト。 (何かあっても自分で対処できる人は masterブランチでやってもOK) あとで、Kernel を TFTP でダウンロードしたいので、`include/configs/zynq-common.h` を開いて、適当なところに #define CONFIG_IPADDR 192.168.11.2 #define CONFIG_SERVERIP 192.168.11.1 #define CONFIG_ETHADDR 00:0a:35:00:01:22 の3行を足す。 `CONFIG_IPADDR` は Zynqボードに割り振る IPアドレス、 `CONFIG_SERVERIP` は TFTP サーバーのアドレスに合わせて下さい。 MACアドレスは、(他のネットワーク機器と被らなければ)適当でいい。 TFTP サーバーがなくても、動かすことはできるので、ない人は上記はスキップして下さい。 あとは $ make zynq_zc70x_config $ make CROSS_COMPILE=arm-linux-gnueabi- DEVICE_TREE=zynq-zc706 のようにして、コンフィグレーションとビルドをする。 もしくは $ make zynq_zc70x CROSS_COMPILE=arm-linux-gnueabi- DEVICE_TREE=zynq-zc706 のように 1行で、コンフィグレーションとビルドを同時にすることもできる。 ### STEP2: Linux Kernel のビルド ##### Input Files Required - ARM Cross Compiler ##### Output Files Produced - `arch/arm/boot/zImage`: Kernel Image - `arch/arm/boot/dts/zynq-zc706.dtb`: Kernel をコンフィグレーションする DTB (Device Tree Blob) (従来、 U-Boot から Kernel を起動するときは `arch/arm/boot/uImage` を使っていたが、これは使わない。) ##### Task Description $ git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $ cd linux $ git checkout v3.13 でソース取得して、v3.13 タグをチェックアウト。 (何かあっても自分で対処できる人は masterブランチでやってもOK) 以下のようにして ARMv7 Multi な設定にする。 $ make ARCH=arm multi_v7_defconfig ここで $ make ARCH=arm menuconfig をして、少々設定をいじる。 Device Drivers ---> Block devices ---> [*] RAM block device support (16384) Default RAM disk size (kbytes) のようにたどり、 `RAM block device support` にチェックを入れ、 `Default RAM disk size` を `16384` に設定する。 もう一つ Device Drivers ---> Character devices ---> [ ] Legacy (BSD) PTY support のようにたどり、`Legacy (BSD) PTY support` のチェックを外す。 あとは $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- でビルド。 ### STEP3: Ramdisk のダウンロード ##### Input Files Required - None ##### Output Files Produced - `arm_ramdisk.image.gz`: Kernel がマウントする init ramdisk (を gzip 圧縮したもの) ##### Task Description [こちら](http://www.wiki.xilinx.com/Build+and+Modify+a+Rootfs) から arm_ramdisk.image.gz をダウンロードする。 ### STEP4: ITB (Image Tree Blob) の生成 ##### Input Files Required - `linux/arch/arm/boot/zImage` - `arm_ramdisk.image.gz` - `linux/arch/arm/boot/dts/zynq-zc706.dtb` - `u-boot/tools/mkimage` カレントディレクトリから見て、上記の配置になっているとする。 ##### Output Files Produced - `fit.itb`: U-Boot から Kernel を起動するためのイメージ ##### Task Description Kernel Image, Ramdisk, DTB (Device Tree Blob) を一つにまとめた ITB というのを作ります。 ITB を作るには、 ITS(Image Tree Source) を記述して、 `mkimage` に食わせます。 以下の内容を `fit.its` というファイルに記述する。 /dts-v1/; / { description = "Kernel, ramdisk and FDT blob"; #address-cells = <1>; images { kernel@1 { description = "Linux Kernel 3.13 configured with multi_v7_defconfig"; data = /incbin/("linux/arch/arm/boot/zImage"); type = "kernel"; arch = "arm"; os = "linux"; compression = "none"; load = <0x00008000>; entry = <0x00008000>; hash@1 { algo = "md5"; }; }; ramdisk@1 { description = "Ramdisk for Zynq"; data = /incbin/("arm_ramdisk.image.gz"); type = "ramdisk"; arch = "arm"; os = "linux"; compression = "gzip"; load = <0x00000000>; entry = <0x00000000>; hash@1 { algo = "sha1"; }; }; fdt@1 { description = "FDT for ZC706"; data = /incbin/("linux/arch/arm/boot/dts/zynq-zc706.dtb"); type = "flat_dt"; arch = "arm"; compression = "none"; hash@1 { algo = "crc32"; }; }; }; configurations { default = "config@1"; config@1 { description = "Zynq ZC706 Configuration"; kernel = "kernel@1"; ramdisk = "ramdisk@1"; fdt = "fdt@1"; }; }; }; あとは以下のようにすれば、`fit.itb` ができる。 $ u-boot/tools/mkimage -f fit.its fit.itb ### STEP5: JTAG (Slave Boot) から U-Boot と Linux を起動する ##### Input Files Required - `u-boot-dtb.bin`: STEP1 で作成したもの - `fit.itb`: STEP4 で作成したもの - `xmd`: ISE / Vivado のインストールディレクトリに入っている - `ps7_init.tcl`: ISE / Vivado から "Export Hardware for SDK" を実行すると出力される - `stub.tcl`: Xilinx のページからダウンロードできる `ug873-design-files.zip` の中に入っている - `fpga.bit`: ISE / Vivado で生成した FPGA bit file (Optional) ##### Task Description `fit.itb` を TFTP の公開ディレクトリに置く。(TFTP 環境のない人はスキップして下さい) Zynq ボードのブートモードの選択スイッチを JTAG に合わせて電源入れる。JTAG でボードと接続し、XMD を開く。 $ xmd XMD のプロンプトから以下を実行する。(FPGA は必要なければダウンロードしなくても良い) XMD% connect arm hw ;# Open JTAG connection XMD% rst -slcr ;# Reset the whole system XMD% fpga -f fpga.bit ;# Download FPGA bit file (Optional) XMD% source ps7_init.tcl XMD% ps7_init ;# Initialize DDR, IO pins, etc. XMD% ps7_post_config ;# Enable level shifter XMD% source stub.tcl ;# start CPU1 XMD% targets 64 ;# connect to CPU0 XMD% dow -data u-boot-dtb.bin 0x04000000 ;# Download u-boot to address 0x04000000 XMD% con 0x04000000 ;# start CPU0 from address 0x04000000 なお、毎回これを打ち込むのも面倒ですので、 `foo.tcl` に書いておきましょう。 XMD% source foo.tcl で XMD から読み込むか、シェルから $ xmd -tcl foo.tcl とすればよいです。 U-Boot のプロンプトが出た後、放っておくと、自動的に TFTPサーバーから `fit.itb` をダウンロードして、 Linux が起動する。 TFTP サーバーがない場合は、`con 0x04000000` の前に XMD% dow -data fit.itb 0x02000000 とすれば、 JTAG 経由で `fit.itb` をダウンロードできるので(時間かかりますが、、) あとは U-Boot のプロンプトから > bootm 2000000 と入力して Linux を起動させる。 ### STEP6: SDカード用のブートイメージを作成する ##### Input Files Required - `fsbl.elf`: FSBL (First Stage Boot Loader)。XSDK で生成。 - `fpga.bit`: FPGA bit file (Optional) - `u-boot/u-boot-dtb.bin`: STEP1 で作成したもの - `bootgen`: ISE / Vivado のインストールディレクトリに入っている ##### Output Files Produced - `boot.bin` ##### Task Description `foo.bif` というファイル(名前適当でよい)に以下のように記述する。 image: { [bootloader]fsbl.elf fpga.bit [load=0x04000000,startup=0x04000000]u-boot/u-boot-dtb.bin } FPGA Bit file のダウンロードが不要なら `fpga.bit` の行は削除してよい。 ELF ファイルはロードアドレスとエントリーアドレスを自動抽出してくれるが、 バイナリの場合は `load=` と `startup=` で指定する必要がある。 あとは $ bootgen -image foo.bif -w on -o boot.bin とすると、`boot.bin` ができる。SDカードのブートイメージは必ず `boot.bin` というファイル名でないといけないので注意する。 ### Step7: SDカードから U-Boot と Linux Kernel を起動する ##### Input Files Required - `boot.bin`: STEP6 で作成したもの - `fit.itb`: STEP4 で作成したもの ##### Task Description FAT でフォーマットしたSDカードに `boot.bin` と `fit.itb` をコピー。 SDカードを Zynq ボードに挿し、ブートモードの選択スイッチを SD カードに合わせて電源入れる。 ### ZC706 以外のボードの場合 動作確認はしていないが、上記とほぼ同じやり方でできずはず。 U-Boot のビルドの部分が、ZC702 ボードなら $ make zynq_zc70x CROSS_COMPILE=arm-linux-gnueabi- ZED ボードならば $ make zynq_zed CROSS_COMPILE=arm-linux-gnueabi- となる。 U-Boot の `boards.cfg` というファイルを見れば、自分のボードに対応するコマンドがわかる。 Linux の Device Tree も `arch/arm/boot/dts` ディレクトリに各ボードごとの DTB ができているので、それを使う。 ### その他参照資料 - Device Tree を用いた U-Boot のコンフィグレーションについて知りたい場合は U-Boot ソースツリーの `doc/README.fdt-control` を参照 - ITS (Image Tree Source) の書き方を知りたい場合は U-Boot ソースツリーの `doc/uImage.FIT/` 以下のドキュメント参照 - XMD の使い方は Xilinx の資料 "Embedded System Tools Reference Manual" 参照 - FSBL の作り方は Xilinx の資料 "Zynq-7000 All Programmable SoC: Concepts, Tools, and Techniques" 5章を参照 - Bootgen をもっと詳しく知りたい場合は Xilinx の資料 "Zynq-7000 All Programmable SoC Software Developers Guide" 参照 ### ご注意 ここに記載の内容は 2014年1月時点のソースでのやり方ですので、今後もこのやり方が通用するかはわかりません。 コードはめまぐるしく変わっていきますので。
2014年1月10日金曜日
Vivado で FPGA をリモートコンフィグレーション
### サーバー/クライアントモデルになった FPGA コンフィグレーション Vivado で便利だと思ったのが、リモートで FPGA のコンフィグレーションが行えることです。 どういうことかというと、Vivado が起動している PC と ボードが繋がっている PC が別々でもいいのです。 |-------| |-------| JTAG | | LAN | | cable |------------| | PC1 |----------| PC2 |---------| FPGA Board | | | | | |------------| |-------| |-------| 図のように LAN でつながった PC1 と PC2 があったとする。 Vivado は PC1 上で動作している。 Vivado がサクサク動くように PC1 は高速なサーバーマシンだとしよう。 PC2 は作業者が実際に操作するクライアント端末である。非力なマシンでもOK。 PC1 には触らないので、別の部屋にあってもよい。 Zynq ボードは、LED をモニタしたり、ディップスイッチを押したりしたいので、ボードは PC2 に接続する。 この状況で、PC1 上で動作している Vivado から PC2 につながったボード上の FPGA をコンフィグレーションできます。 #### 手順 作業者は PC2 から PC1 へ ssh などでログインし、Vivado を起動する。 PC2 にボードを接続し、PC2 上で `vcse_server` というのを起動する。 $ vcse_server Vivado Cse Server Version 2013.2 - Compiled Jun 15 2013 11:11:22 Vivado Cse Server: Opened server at port: 60001 To exit the server, type command 'exit' VCSE % cse_server がポート番号 60001 を開いたというのが表示されました。 PC1 上の Vivado で FPGA の bit stream を作成したら、「Program and Debug」→ 「Open Hardware Session」→「Open a new hardware target」と選択すると、 接続する Cse Server を設定するダイアログが開きます。 [![Open Hardware Session](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyzIjS_h4GhKU4Nx8sAAiOoRUhNQoMgMmsgwm7qndUYCONdEUb0elCiAwIebLGYZijjjGNFMD19e6JOe-tsanfhFIdUTdRf1rz83KEnH12rguwGCeammUHmRQT4U74B4At8pyv9YEnzZQ/s320/hardware_session.png)](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyzIjS_h4GhKU4Nx8sAAiOoRUhNQoMgMmsgwm7qndUYCONdEUb0elCiAwIebLGYZijjjGNFMD19e6JOe-tsanfhFIdUTdRf1rz83KEnH12rguwGCeammUHmRQT4U74B4At8pyv9YEnzZQ/s1600/hardware_session.png) 通常は、 Vivado の動作しているPC (この場合はPC1)のIPアドレスがデフォルトで入っていると思いますが、 これをさっき vcse_server を起動したPC (PC2) のIPアドレスに修正します。 ポート番号もさっきの番号 60001 になっているのを確認しておきます。 すると PC2 につながったボードに接続できるので、あとはいつもの感じで FPGA へ bit stream をダウンロードします。 全く同様に Vivado Logic Analyzer (ISE のときの ChipScope みたいなもの)もリモートで使えます。 ### XSDK もリモートでデバッグする Zynq を動かすには ARM 用のソフトウェアと FPGA のハードウェアの両方を開発する必要があります。 FPGA 開発がリモートで行えるのならば、XSDK (Eclipse を Xilinx 用に拡張したもの) もリモートでやりたいところです。 2つやり方を見つけたので記録。 #### やり方その1: xmd を使う ボードを JTAG ケーブルで PC2 に接続し、PC2 上で xmd を起動し、`connect arm hw` を実行。 $ xmd Xilinx Microprocessor Debugger (XMD) Engine Xilinx EDK 14.6 Build EDK_P.68d Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved. XMD% XMD% connect arm hw JTAG chain configuration -------------------------------------------------- Device ID Code IR Length Part Name 1 4ba00477 4 Cortex-A9 2 23731093 6 XC7Z045 -------------------------------------------------- Enabling extended memory access checks for Zynq. Writes to reserved memory are not permitted and reads return 0. To disable this feature, run "debugconfig -memory_access_check disable". -------------------------------------------------- CortexA9 Processor Configuration ------------------------------------- Version.............................0x00000003 User ID.............................0x00000000 No of PC Breakpoints................6 No of Addr/Data Watchpoints.........4 Connected to "arm" target. id = 64 Starting GDB server for "arm" target (id = 64) at TCP port no 1234 XMD% TCPポート 1234 番が開いたのがわかる。 PC1 上で動作している XSDK で プロジェクトを右クリックし、 「Debug As」→「Debug Configurations...」と選ぶ。 [![Debug Configuration](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ_fRDFGBFjmPCNR1wY10aL65kZYzFDzUNYgbRuOKGJt-41bgH7TzFKP3bVd5fY_yy-O5RJfXe4Ueybj1dJptPoL2nvVy92ICn4QeLc0UMUndhrN3wjuPLiFo9yJ_C4UXRlxs01_MEb5Y/s320/debug_config.png)](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ_fRDFGBFjmPCNR1wY10aL65kZYzFDzUNYgbRuOKGJt-41bgH7TzFKP3bVd5fY_yy-O5RJfXe4Ueybj1dJptPoL2nvVy92ICn4QeLc0UMUndhrN3wjuPLiFo9yJ_C4UXRlxs01_MEb5Y/s1600/debug_config.png) Xilinx C/C++ application (GDB) を右クリックし、「New」を選択。 「Remote Debug」というタブがあるので、「IP Address」の欄の localhost を消し、 PC2 の IPアドレスを入力する。 「Port」の欄には、 PC2 側が待っている 1234 番が入っているのを確認する。 あとは「Debug」ボタンを押す。ステップ実行などができる。 #### 方法その2: hw_server を使う 基本的に [http://www.xilinx.com/support/documentation/sw_manuals_j/xilinx14_6/SDK_Doc/tasks/sdk_t_tcf_remote_debug.htm](http://www.xilinx.com/support/documentation/sw_manuals_j/xilinx14_6/SDK_Doc/tasks/sdk_t_tcf_remote_debug.htm) にしたがってやれば OK。 PC2 上で `hw_server` 起動 $ hw_server -s tcp::3122 ****** Xilinx hw_server v2013.4 **** Build date : Dec 9 2013-17:26:10 ** Copyright 1986-1999, 2001-2013 Xilinx, Inc. All Rights Reserved. INFO: hw_server application started INFO: Use Ctrl-C to exit hw_server application PC1 上で動いている XSDK 上で メニュー「Xilinx Tools」→「Configure JTAG Settings」を選び、 - Type: Xilinx Hardware Server - Hostname: hw_server を起動したPC (この場合PC2) のIPアドレス - Port: hw_server で開いているポート (この場合 3122) を設定する。 プロジェクトを右クリックし、「Debug As」→「Launch Hardware (System Debugger)」を選ぶ。
2014年1月8日水曜日
Zynq 事始め2
[前回](/2013/12/zynq-1.html)は、ツールに慣れる意味でも、 Zynq の FPGA 部だけを動かしてみました。 しかし、ARM を起動しないと Zynq を使う意味がありませんので、次は ARM + FPGA で動かしましょう。 ここから当面は Xilinx のドキュメントに沿って進めるのがよいと思います。 ### Zynq-7000 All Programmable SoC: Concepts, Tools, and Techniques (CTT) 入門者にとっておすすめのドキュメントは "Zynq-7000 All Programmable SoC: Concepts, Tools, and Techniques (CTT)" というチュートリアルです。 表紙のリリース日を見て、新しいものを選ぶようにしてください。 日本語版も出ているがバージョンが古いのでおすすめできません。 非常にわかりやすく、これに沿って5章ぐらいまでやっていけば、基本的な使い方は覚えられるでしょう。 唯一の欠点は、現時点では ISE を対象に書かれていて、Vivado に対応していないことです。 そこで、いったんドキュメント通りに ISE でやってみて、 同じことを Vivado でもやってみるのがよいと思います。 Vivado を選択するほうが、最終的に使い勝手がよいと思いますが、 ISE も一応理解はしておいた方がよいと思います。 以下、各章でやることをさらっとまとめました。 #### Chapter 1: Introduction ツールや用語の説明。 PS と PL という用語は何度も出てくるので抑えておきましょう。 - PS (Processing System): CPU 部のこと。ARM と周辺のハード。 - PL (Programmable Logic): FPGA 部のこと #### Chapter 2: Embedded System Design Using the Zynq Processing System ARM を動かし、UART から Hello World を出す。FPGA は動かさない。 XPS で PS の設定をし、ハードウェア情報をエクスポート。 それを XSDK にインポートし、Hello World のスタンドアローンアプリを作成します。 #### Chapter 3: Embedded System Design Using the Zynq Processing System and Programmable Logic ARM の周りにいくつか IP をくっつけて、ARM + FPGA で動かす。 JTAG 経由で FPGA のビットストリームと ARM 用のプログラムをダウンロードします。 #### Chapter4: Debugging with SDK and ChipScope XSDK を用いたソフトウェアのデバッグ、ChipScope を用いたハードウェアのデバッグ #### Chapter5: Linux Booting and Application Debugging Using SDK U-Boot と Linux を起動する。 U-Boot も Linux Kernel もコンパイル済みのイメージをダウンロードしてきて使用します。 XMD を開いて、JTAG 経由で U-Boot と Linux をダウンロードし、起動する。(Slave Boot) Master Boot に使うブートイメージの作り方を学ぶ。 そのブートイメージを U-Boot を使って、 QSPI に書き込み、 QSPI から起動させる。 また SDカードからも起動させる。(Master Boot) ### チュートリアルの内容を Vivado でやるときの差分 基本的に、チュートリアルの内容と同等のことが Vivado できるはずですが、差分をいくつかピックアップ。 - ISE で XPS でやっている部分は、Vivado では 「IP Integrator」 → 「Create Block Design」で行う。 - Chapter3 で「Chipscope AXI Monitor」という IP を接続していますが、 これは Vivado にはないので、飛ばします。 Vivado には Chipscope 自体がありませんので。 普通に Vivado Logic Analyzer で AXI バスをモニタすればいいので、なくても困りません。 - Chapter6 で 「AXI Central DMA」 というIP を接続していますが、 Vivado では 「AXI Central Direct Memory Access」という名前になっています。 検索ボックスに 「DMA」といれてもヒットしなくて、しばらく考え込みました。。 ### 起動シーケンスまとめ どういう仕組みで動いているのかがわかった方がいいので、簡単にまとめておきます。 Zynq は 5つの起動モードがあります。 電源投入時に、特定の端子が Pull Up されているか Pull Down されているかで起動モードを選択できます。 - QSPI - NAND - NOR - SD card - JTAG QSPI, NAND, NOR, SD card から起動するのを Master Boot といいます。 JTAG ブートは Slave Boot といいます。 Master Boot は ARM が自発的に起動しますが、 Slave Boot は JTAG コマンド待ちのループに入るので、 JTAG からプログラムをダウンロードし、適切なアドレスから実行させる必要があります。 当然ながら最終製品では Master Boot を使いますが、開発中に便利なのは Slave Boot です。 #### Master Boot 用のブートイメージ |------------------------| | Header | |------------------------| | (IMG1) FSBL | |------------------------| | (IMG2) FPGA bit stream | |------------------------| | (IMG3) User Program | |------------------------| | ... | Bootgen というプログラムを使って、いくつかのバイナリーを結合し、Master Boot 用の起動イメージを作ります。 先頭にヘッダー情報が付加されます。各イメージの先頭にも小さなヘッダーが付きます。 1番目のイメージは FSBL (First Stage Boot Loader)です。 FSBL を自前で記述することも可能ですが、普通はツール (XSDK) が作ってくれるものをそのまま使います。 ISE/Vivado から Export した ハードウェア情報を XSDK にインポートし、FSBL を生成します。 通常、2番目のイメージは FPGA の bit stream ですが、FPGA を動かさないなら、なくても構いません。 3番目以降がユーザープログラムです。 これは、XSDK で作成したスタンドアロンプログラムだったり、U-Boot などの別のブートローダーだったりします。 上記の起動イメージを QSPI, NAND, NOR, SD Card のいずれかに書き込みます。 SD Card の場合、FAT でフォーマットされたカードに `boot.bin` というファイル名でコピーする必要があります。 なお、ピン数の関係で 5つの起動モードをすべて同時に使えるわけではありません。 私の使っている ZC706 というボードでは QSPI, SD Card, JTAG が使えます。 余談ですが、ZC706 にのっている QSPI の容量が 16MB しかありません。 ZC706 にのっている Zynq (xc7z045ffg900) の FPGA の bit stream は 13MB 近くあります。 残り 3MB で Linux Kernel やら Ramdisk やらを格納するのはほぼ無理です。 つまり、FPGA 動かすなら、QSPI は使えないですね。 なんで、もうちょっと容量の大きいのをのせてくれなかったんだろう? #### Master Boot のブートシーケンス Zynq はリセット解除後、(Master Boot も Slave Bootも)必ず Boot ROM から実行を開始します。 1. Boot ROM Mask Rom なので変更不可。 端子情報を元に、 QSPI/NAND/Nor/SD card のいずれかから起動イメージを読み出す。 FSBL を SRAM へロードし、FSBL に制御を移す。 2. FSBL (First Stage Boot Loader) (XSDK で生成した FSBL の場合) 起動イメージに FPGA の bit stream が含まれていれば、FPGA へダウンロードする。 必要なピン設定や DDR の初期化を行い、 User Program を DDR へロードし、 User Program に制御を移す。 3. User Program 何をするかは User Program の作り方次第ですが、Linux を動かすのなら、 この User Program の部分は U-Boot でしょう。 U-Boot がなんらかの不揮発デバイスから(またはネットワーク経由で)Kernel をロードします。 #### Slave Boot のブートシーケンス JTAG ブートの場合、起動後、簡単な初期化をした後、すぐに JTAG コマンド待ちのループに入ります。 ARM が自発的に何かをすることがないので、Slave Boot と言います。 SoC の初期化や、プログラムコードをメモリ上に置き、ARM をキックするところまで JTAG 経由で行う必要があります。 以下が、そのシーケンスです。 1. Boot ROM ARM は簡単な初期化をした後、JTAG コマンド待ちのループに入る。 2. FPGA コンフィグレーション (もし必要なら)JTAG経由で FPGA の bit stream をダウンロードする。 3. JTAG から ピン設定や DDR の初期化を行う。 4. JTAG から User Program を DDR (または SRAM) へダウンロードし、CPU を走らせる。 チュートリアルの Chapter 2 ~ Chapter 4 でやっているのはこの Slave Boot です。 Master Boot と違って、FSBL なしで、User Program を実行することができます。 その代わり、 FSBL が行うのと同等の設定を JTAG 経由で行うための Tcl スクリプトが用意されています。 ISE/Vivado でハードウェア情報をエクスポートしたときに吐き出されるファイルの中に `ps7_init.tcl` みたいなものあると思いますが、これです。 「3. JTAG から ピン設定や DDR 初期化」 にはこの Tcl スクリプトを用います。 `ps7_init.c` (FSBL を作るために必要な Cコード) と、内容は同等のはずです。 XMD のプロンプトから % source ps7_init.tcl % ps7_init % ps7_post_config とやれば OK。 あれ? チュートリアルの Chapter 2 ~ Chapter 4 をやったときには、いちいち `ps7_init.tcl` を実行しなかったよ?と思うかもしれません。 はい。 XSDK は、User Program ダウンロード時に、`ps7_init.tcl` も自動で実行してくれています。 XMD の場合は、自分で実行する必要があります。 ### 次は何をやるか CTT の Chapter 5 くらいまでやれば、ツールの基本的な使い方は身につくと思います。 Chapter 6 以降は必要に応じてやっていけばいいと思います。 Zynq の仕様についてもっと知るために "Zynq-7000 All Programmable SoC Technical Reference Manual" も合わせて読んでいくのもよいでしょう。 私は基本的にソフトの人なので、引き続き [Wiki Page](http://www.wiki.xilinx.com/) に沿って動かしてみました。 U-Boot や Linux Kernel をソースからコンパイルして動かす方法が非常に丁寧に説明してあります。
新しい投稿
前の投稿
ホーム
登録:
投稿 (Atom)