Ubuntu
FPGA
zynq

zynq (Zed board)でubuntuを動かす

More than 1 year has passed since last update.

ADV7511リファレンスデザインをインプリメントしたZed boardでUbuntuをSDカードからブートします。
HDMIディスプレイとUSBキーボードが使えます。
また、Ubuntuなのでapt-getがあります。pythonも最初から動きます。便利!

参考:
Avnetのチュートリアル
http://zedboard.org/content/zedboard-ubuntu-vivado-20134

Yet Another Guide to Running Linaro Ubuntu Linux Desktop on Xilinx Zynq on the ZedBoard
http://fpga.org/2013/05/24/yet-another-guide-to-running-linaro-ubuntu-desktop-on-xilinx-zynq-on-the-zedboard/

Embedded Linux Wiki - Parallella Linaro Nano
http://elinux.org/Parallella_Linaro_Nano

Xilinx wiki
http://www.wiki.xilinx.com/Build+kernel

前提

環境

  • xubuntu 14.04
  • Vivado 2015.2
  • Zed board rev.D

その他

基本的に上記のAvnetチュートリアルをやっていきます。ただし内容が古い部分が多く、そのままではできなかったので、そこを補足しながらやっていく感じです。
ハードウェアはADV7511リファレンスデザインを前提にしています。
(こちら:https://wiki.analog.com/resources/fpga/xilinx/kc705/adv7511)
(記事も書きました:http://qiita.com/yuichiroTCY/items/aa621b1b432f7ceaf909)
そのため、Linuxカーネルなどもこのリファレンスデザイン用に用意されたものを使います。カスタマイズはまた別の話で。

作業ディレクトリ

作業用に適当なディレクトリを用意します。
以下のパスはすべてそのディレクトリからの相対パスとして記述します。

U-bootのビルド

second stage boot loaderであるu-bootをビルドします。

ダウンロード

$ git clone git@github.com:Xilinx/u-boot-xlnx.git
$ cd u-boot-xlnx
$ git checkout xilinx-v2015.2

ブートオプション編集

include/configs/zynq-common.hの内容が基本的な設定です。これがzynq_zed.hにインクルードされ、さらにその中でオーバーライドされます。
zynq_zed.hを編集してさらに必要な設定をオーバーライドします。
今回、ext4パーティション上にRoot file systemを用意してLinuxを立ち上げるので、そのための設定のようです。

  1. include/configs/zynq-common.hからCONFIG_EXTRA_ENV_SETTINGSの定義(複数行の長い#define)をコピーして include/configs/zynq_zed.hの末尾に貼り付け。
  2. sdbootでgrepし、当該部分を書き換え

    "sdboot=if mmcinfo; then " \
                "run uenvboot; " \
    -           "echo Copying Linux from SD to RAM... && " \
    +           "echo Copying Linux from SD to RAM... RFS in ext4 && " \
                "load mmc 0 ${kernel_load_address} ${kernel_image} && " \
                "load mmc 0 ${devicetree_load_address} ${devicetree_image} && " \
    -           "load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " \
    -           "bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \
    +           "bootm ${kernel_load_address} - ${devicetree_load_address}; " \
    
  3. #define CONFIG_EXTRA_ENV_SETTINGSの前に

    #ifdef CONFIG_EXTRA_ENV_SETTINGS 
    #undef CONFIG_EXTRA_ENV_SETTINGS 
    #endif
    

    を追記

  4. (Optional) 自分の好みに応じて、同様に#define CONFIG_SYS_PROMPT#define CONFIG_BOOTDELAYなどをオーバーライドしてもよい

ビルド

$ export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
$ make distclean
$ make zynq_zed_config
$ make

環境変数CROSS_COMPILEを正しく設定しないとビルドできません。.bashrcとかに書いてしまっても良いかも
参考:http://www.wiki.xilinx.com/Install+Xilinx+tools

ビルドが完了すると、u-boot-xlnxディレクトリ直下にu-bootが生成されます。

また、tools/mkimageというファイルもできています。あとで使うので、パスを通しておきます。

$ export PATH=/path/to/dir/u-boot-xlnx/tools/:${PATH}

これも.bashrcに書いてしまって良いかも

SDカードの準備

fdiskやGPartedでFAT32とext4のパーティションを1つずつ作ります。
FAT32の方をZED_BOOT、ext4の方をrootfsと名づけました。
サイズは1GBと3GBにしました。多分こんなにいらない。特にFAT32の方。

FSBLの作成

ADV7511のリファレンスデザインでビットストリームの作成、SDKにエクスポートまでやっておきます。
1. SDKを起動します。
2. メニューからNew->Application Projectを選びます
3. 適当に名前をつけます。今回はzynq_fsbl_0にします。Nextを押して次の画面に行きます。
4. Zynq FSBLを選んでFinishを押します。
5. ツリービューでzynq_fsbl_0を選択した状態で、メニューからXilinx Tools -> Create Zynq Boot Imageを選びます。
6. Output BIF file pathを適宜設定します。今回はファイル名をubuntu.bifに変えました。
7. ダイアログ下部のBoot image partitionsにはすでにbootloaderとビットストリームが読み込まれているはずです。無ければ、適宜Addします。
8. 上で作ったu-bootをu-boot.elfとリネームして適当な場所にコピーしておきます。Boot image partitionsにAddします。Partition typeはdatafileです。
9. 適宜Output pathを設定します。
10. Create Imageを押します。Output pathで指定した場所にBOOT.binができます。

この段階で、u-bootの起動までを確認してみます。
SDカードのZED_BOOTパーティション(FAT32のパーティション)に上で作成したBOOT.binをコピーします。
次にZed BoardのピンをSDブートモードにし、SDカードを挿し、PCとUSBケーブルでつないで電源を入れます。
PCからシリアルコンソールで見ると、ブートの様子が見えます。
この段階ではまだLinuxのファイルを用意していないので、

Copying Linux from SD to RAM...RFS in ext4
reading uImage
** Unable to read file uImage **

という出力を吐いてとまり、入力受付状態になります。

この状態で

env default –a –f
printenv sdboot
saveenv

と打って環境変数を保存するらしいです。Avnetのチュートリアルにそう書いてありました。
もし将来u-bootの設定などを変えてビルドしなおしたとき、この操作をやり直さないと古い設定が残ったままになってしまう(?)

ちなみに、Zed boardのBTN7はPS_RSTボタンなので、押すとブートをやり直せます。

Linuxカーネルのビルド

$ git clone git@github.com:analogdevicesinc/linux.git analogdevices_linux
$ cd analogdevices_linux
$ git checkout xcomm_zynq
$ make ARCH=arm distclean
$ make ARCH=arm zynq_xcomm_adv7511_defconfig
$ make ARCH=arm uImage LOADADDR=0x8000

ここで上で作ったmkimageが使われるので、エラーが出る場合はパスが通っているかチェック。

arch/arm/boot/uImageができるので、SDカードのZED_BOOTパーティションにコピー。

devicetree作成

作業ディレクトリは前章と同じ。

$ make ARCH=arm zynq-zed-adv7511.dtb

arch/arm/boot/dts/zynq‐zed‐adv7511.dtbができるので、devicetree.dtbとリネームしてSDカードのZED_BOOTパーティションにコピーする。

Root file system作成

ダウンロード

Avnetのチュートリアルで使っているubuntu desktop 12.04はリンク切れだったので、http://elinux.org/Parallella_Linaro_Nano を参考に使用するRFSを変更しました。
nanoという名前から察するにたぶんこちらのほうがコンパクト。GUI入っていないし。
自分の用途にはそれで十分。

$ wget http://releases.linaro.org/15.04/ubuntu/utopic-images/nano/linaro-utopic-nano-20150421-702.tar.gz

他のイメージを使いたい場合、
http://www.linaro.org/downloads/historic/
から好きなのを探してください。
あまり古いとサポートが切れていてaptのリポジトリがなくなっていたりするのでおすすめしません。設定をいじる場所が増えます。

SDカードへ展開

SDカードをPCに挿し、マウントした状態で以下を実行します。
/media/foo/rootfsはSDカードのrootfsパーティションがマウントされた場所です。自分の環境に合わせて適宜変えます。

$ sudo tar --strip-components=1 -C /media/foo/rootfs -xzpf linaro-utopic-nano-20150421-702.tar.gz

わりと時間がかかります。
また、展開後は

$ sudo sync

を実行します。(メモリ上のキャッシュをすべてSDに書き込んでいる?)結構時間がかかります。
もしくは、GUIでSDカードのマウントを解除してもよいです。多分内部でsyncしているので、それでも時間はかかります。

Ubuntu起動

以上までで準備は完了です。
作成したSDカードをZed boardに挿し、電源を入れるとubuntuが起動します。
HDMIディスプレイを接続しておくと画面にコンソールが表示されますし、
USBキーボードをUSB OTGポートに接続しておくと直接キーボードから入力できます。(USB->mini USB変換ケーブルはZed boardについています)

もしブートシーケンスが途中で止まって、u-bootが入力待ち状態になってしまう場合は、その状態でresetコマンドを入力するとブートがやり直され、うまく行く場合があります。

ネットワーク設定

http://elinux.org/Parallella_Linaro_Nano#Extract_rootfs そのままです。

Zed boardの電源を切り、SDカードをPCにマウントします。
/media/foo/rootfsにマウントされるとします。

$ sudo vi /media/foo/rootfs/etc/network/interfaces

以下のように設定します。適宜自分のネットワーク環境に合わせて書き換えます。

source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

auto eth0

# static network settings
iface eth0 inet static
   address 192.168.0.2
   netmask 255.255.255.0
   gateway 192.168.0.1
   up sleep 3; mii-tool -F 1000baseT-FD

# If you prefer DHCP, comment out the above 5 lines, uncomment the below.
#iface eth0 inet dhcp
#   up sleep 3; mii-tool -F 1000baseT-FD
$ sudo vi /media/foo/rootfs/etc/resolv.conf

以下のように設定します。自分のネットワーク環境に合わせて適宜書き換えます。

nameserver 192.168.0.1

sudo syncの後SDをカードをアンマウントし、EthernetケーブルをZed boardに挿して再度Linuxを起動します。
今度はネットも使えます。apt-getが使える!
IPアドレスが固定なのでDHCPの設定など注意してください。

最後に

チュートリアルを見ながら何とか起動できたという感じなので、理解が甘かったり記述が間違っていたりするところもあると思います。
変なところを見つけたらぜひ指摘してください。