ZYBOに最新のLinux Kernelを乗っけて立ち上げる

#はじめに
自身の覚書のようなものです。
本稿ではProgrammableSoCの一種、ZynqにLinuxを搭載して立ち上げるところまでを説明します。
対象とするのはDigilent社の開発ボードZYBOです。
とりあえずLinuxが立ち上がることが目標なのでPL側(FPGA)は一切触りません。

#環境
※Windowsマシン(全てLinux環境下で済ませられるのであれば無くてもよい)
Linuxマシン(Ubuntu推奨)
Vivado 2014.4以上のバージョン(Linux上にインストール必須、SDKのインストール必須)

Linuxオンリー or Windows + Linux
これは好みで分かれますので好きなようにしてもらえば良いです。

#準備
１．Linux上の適当な場所にワークスペースをつくる
　わかりやすくZYBOという名前のディレクトリを作っておきましょう。
　`mkdir ZYBO`
　`cd ZYBO`
２．gitのリポジトリからu-bootおよびLinux Kernelのソースコードを取得する
　`git clone git://git.denx.de/u-boot.git`
　`git clone git://git.kernel.org/pub/scm/linux/kernel/git/torcalds/linux.git`
３．それぞれブランチを切り替える
 　u-bootはZybo用にブランチを切り替える
 　`cd u-boot`
 　`git checkout -b zynq-zybo`
 　`cd ../`
 　Linux Kernelは最新版へブランチを切り替える(作成時2017/1/13，自分の環境でコンパイルした最新がv4.8)
 　`cd linux`
 　`git checkout v4.8`
 　`cd ../`

これで前準備は整ったので次に移ります。

#BOOT.binの生成
これまでの開発フローではbitファイル、FBSLファイル、u-boot.elfファイルを統合してBOOT.binを生成してました。
最新のu-bootでは上記データ生成の手間をすっ飛ばせます。
PL(FPGA)の制御となると話は別ですが今回はLinuxを起動することが目的なので楽をしてu-bootソースからBOOT.binを生成します。

まずはZYBO用の設定を適用します。
`cd u-boot`
`make zynq_zybo_defconfig`
ARMクロスコンパイラの指定をします。
インストールしたVivadoのバージョンによって下のコマンドは変わります。(下の例は2016.3をインストールしたもの)
`source /opt/Xilinx/SDK/2016.3/setting64.sh`
※yoctoなどの他のARMクロスコンパイラでも動作すると思う。(要検証)
環境変数も設定します。
`export ARCH=arm`
`export CROSS_COMPILE=arm-xilinx-linux-gnueabi-`
linuxのカーネルを呼び出すのに必要な命令がこの時点でセッティングされていないので追加していきます。
u-boot内の環境変数や起動時に実行するコマンドを追加します。
`include/configs/zynq-common.h`
このファイルがコマンドや環境変数が格納されているファイルです。
CONFIG_BOOTCOMMANDは起動時に実行されるコマンド、CONFIG_EXTRA_ENV_SETTINGSは環境変数になります。
これらにいろいろ書き込んでいきます。

```ruby:zynq-common.h 
#define CONFIG_BOOTCOMMAND "run fpgaboot; run linuxboot;"

#define CONFIG_EXTRA_ENV_SETTINGS \
"rootd=/dev/mmcblk0p2\0" \
"fpgaboot=mmc rescan;mmcinfo ;load mmc 0 0x100000 system.bit;fpga loadb 0 0x1000000 $filesize\0 " \
"lseq=mmc rescan;fatload mmc 0:1 0x8000 zImage;fatload mmc 0:1 0x100 system.dtb\0 " \
"bseq=setenv bootargs console=ttyPS0,115200 root=${rootd} rw rootwait;bootz 0x8000 - 0x100\0 " \
"linuxboot=run lseq;run bseq\0 " \
DFU_ALT_INFO

{以下略}

#define CONFIG_CMD_BOOTZ　//←ここ一文最後の行に追加
```

※何故かmenuconfigでzbootの起動にチェックを入れても動作しないので必ずCONFIG_CMD_BOOTZの追加を忘れずに。
　fpgabootは追加しなくてもlinuxは立ち上がりますが今後PL部を使うときのために記述してます。
　念押しで今回は使いません。

さらにカスタマイズしたい場合はここで以下のコマンドを入力して弄りましょう。
`make menuconfig`
あとはmakeする。
`make`
`cd ../`

１～２分ほどでコンパイルが完了するはずです。(環境によって時間は上下します)

splフォルダの中にBOOT.binが、トップのディレクトリの中にu-boot.imgが出来ていると思います。
これらはあとでまた使うので覚えておいてください。

#Linux Kernelのコンパイル
次にLinuxのカーネルを生成します。
ZYBO用のカーネルを生成するのですがカーネルの中にZYBO用の設定ファイルはありません。
ですので汎用の設定ファイルを利用します。
BOOT.binの生成時と同じ要領でまずはディレクトリに入って設定ファイルの適用を行います。
`cd Linux`
`make ARCH=arm multi_v7_defconfig`
もう少しカスタマイズをしたいのであれば以下のコマンドで追加してください。
`make ARCH=arm menuconfig`
あとはコンパイル。結構時間がかかるので気長に待ちましょう。
自分のところでは4~50分くらい
(環境によって(ry)

`make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- zImage`
BOOT.bin生成時にzbootコマンドを有効にしたのはこのzImageでlinuxを立ち上げるためです。

ついでにデバイスツリーの生成もしておきます。
`make zynq-zybo.dtb`
arch/arm/boot/dtsの中にzynq-zybo.dtbが生成されていると思います。
`cd ../`

#SDカードにコピー

※この項はあまり詳しく説明しません。

データを移す前にSDカードのフォーマットとパーティションの作成を行わなければいけません。
Windows+Linuxで行うならSDカードフォーマッターでフォーマットをした後にfdiskを使いパーティションを分割する。
Linux上のみで行う場合はGPartedを使ってフォーマット、パーティション分割両方と良いです。
第一パーティションをFATで作成、第二パーティションをEXT4で作成します。
FATにこれまでの手順で作成したブートローダなどを配置、EXT4にはLinuxファイルシステムのデータを配置するのであまりFATを大きくデータを取っても意味が無く、またEXT4を小さくしすぎるとファイルシステムのデータが入らなくなるので注意です。

上記の処理が完了したら生成物のboot.bin, u-boot.img, zynq-zybo.dtb, zImageを第一パーティションにコピーします。
※FATへのアクセスはWindowsからでも行えます。

第二パーティションへLinuxのファイルシステムを展開します。
他の方もよく使われているubuntuのroot file systemを展開するのがよいでしょう。

#動作
SDカードをzyboへ挿入しジャンパピン設定を確認し電源を入れます。
シリアル通信(TeraTerm ボーレート115200bps, データ8bit, パリティnone, ストップ1bit, フロー制御noneに設定)でzyboに接続するとブートローダの起動、Linuxカーネルの読み込み、ubuntuの起動が行われていることが確認できると思います。

#まとめ
足早の説明でしたがこれで最新のLinuxカーネルを使ってzynqを動かすことができました。
これだけの設定ではPL部の使用はできませんのでもう少し手を加える必要があります。

※追記(2018/12/09)
Xilinxが出すPetaLinux(Linuxのディストリビューションではなくこれがツール名)がライセンスフリーで、しかも内部的にはYocto使っているらしい。なので一からYoctoを使うよりも簡単にZynqにLinux環境整えられそうなのでYoctoの練習をしたいということでなければ素直にPetaLinuxを使った方が良いかもしれないです。

#参考
http://qiita.com/ikwzm/items/efacec8d8e0744e17d45
https://keitetsu.blogspot.jp/2015/01/zyboubuntu.html
http://fpga.blog.jp/archives/53818202.html
http://ryuz.txt-nifty.com/blog/2014/02/zynqlinux-c466.html