Zybo の SPL を QSPI で動かす

# SPL ってなんですか？
私は最初この言葉に躓きました。SPI と一文字違いだし。Second Program Loader の略で u-boot で使われる言葉であるらしい。Zynq では FSBL に相当し、u-boot 本体を呼ぶプログラムの事を指すようだ。

参考資料
 [FPGA+SoC+Linuxのブートシーケンス(ZYNQ+U-Boot-SPL編)](http://qiita.com/ikwzm/items/efacec8d8e0744e17d45)

Yocto で作ってしまうと、とにかく boot.bin までできるので便利ではある。

# Yocto にお願いする
概略さえ分かってしまえば、あとはもう、Yocto にお任せする。ps7_init.c や ps7_init.h も持ってたりするから（あまり考えずに作業をすると危険な気もするが）、Vivado のデザインなんか気にせずに（それじゃだめですから）、Yocto にお願いする。

参考資料（っていうかこの通りにすれば出来ちゃう）
[Zybo Board bringup using Yocto Project](https://emcongiu.wordpress.com/2015/03/10/zybo-board-bringup-using-yocto-project/)

## dizzy を clone する。
Yocto の meta 情報は git でもってくる。Zybo 以外のそして Yocto のバージョン違いをインストールもしたくなることがある人は --bare でもってきて、そこから clone するとよい。ここでは dizzy をつかっている。ちょっと古いぞ。tmp のバージョン違いがあるので tmp を共有したい場合は注意が必要。

```
mkdir sources
cd sources
git clone --bare git://git.yoctoproject.org/poky
git clone --bare git://git.yoctoproject.org/meta-xilinx
git clone --bare https://github.com/emcongiu/meta-zybo.git
cd ..
git clone -b dizzy sources/poky.git build-zybo
cd build-zybo
git clone -b dizzy ../sources/meta-xilinx.git
git clone -b dizzy ../sources/meta-zybo.git
source oe-init-build-env
```

## bblayers.conf の修正

```txt:bblayers.conf
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
  /home/ryos/Yocto/build-zybo/meta \
  /home/ryos/Yocto/build-zybo/meta-yocto \
  /home/ryos/Yocto/build-zybo/meta-yocto-bsp \
  \
  /home/ryos/Yocto/build-zybo/meta-xilinx \
  /home/ryos/Yocto/build-zybo/meta-zybo \
  "
BBLAYERS_NON_REMOVABLE ?= " \
  /home/ryos/Yocto/build-zybo/meta \
  /home/ryos/Yocto/build-zybo/meta-yocto \
  "
```

## local.conf の修正
TMPDIR と DL_DIR と SSTATE_DIR を適切に使うとダウンロード時間のたしゅくになるはず。

uramdisk.image.gz を作るために
IMAGE_FSTYPES = "ext4.gz.u-boot"
という記述を追加している。

```txt:local.conf
MACHINE ??= 'zybo-zynq7'
DISTRO ?= "poky"

PACKAGE_CLASSES ?= "package_rpm"
EXTRA_IMAGE_FEATURES = "debug-tweaks"

USER_CLASSES ?= "buildstats image-mklibs image-prelink"

PATCHRESOLVE = "noop"

BB_DISKMON_DIRS = "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    ABORT,${TMPDIR},100M,1K \
    ABORT,${DL_DIR},100M,1K \
    ABORT,${SSTATE_DIR},100M,1K"

PACKAGECONFIG_append_pn-qemu-native = " sdl"
PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl"
ASSUME_PROVIDED += "libsdl-native"

CONF_VERSION = "1"

BB_NUMBER_THREADS = '2'
PARALLEL_MAKE = '-j 2'
IMAGE_FSTYPES = "ext4.gz.u-boot"

TMPDIR = "/opt/Yocto/tmp/"
DL_DIR ?= "/opt/Yocto/Cache/downloads"
SSTATE_DIR ?= "/opt/Yocto/Cache/sstate-cache"
```

## そして bitbake
bitbake core-image-minimal

でシンプルなイメージを作る。必要に応じて今後は local.conf にレシピを追加していけばよい。
結果は /opt/Yocto/tmp/deploy/images/zybo-zynq7 にできる。

- boot.bin (これが u-boot-spl)
- u-boot.img　(これが u-boot 本体）
- uEnv.txt
- uImage
- modules-zybo-zynq7.tgz （今回は使わなかった）
- core-image-minimal-zybo-zynq7-20160617183143.rootfs.ext4.gz (uramdisk.image.gz に rename する)

## SD カードでとりあえずテスト
上記のファイル群を SD カードに入れるとちゃんと立ち上がるでしょう。（たぶん）ただし、ここでは fpga.bin とか用意していないので FPGA は初期化されずに done の LED もつきません。（そこはこの記事のカバー外ということで）

# QSPI に焼く
いまどき ROM に焼くと書く人はいない。消去に紫外線もいらない。

そもそも、なんでこんなことしているかというと、Zybo の Factory セッティングを間違って消してしまったから。u-boot で saveenv とたたいたら立ち上がらなくなってしまった。どうも Factory セッティングは中途半端になっているらしい。

上記、Yocto でできた u-boot は QSPI が使えて次の前提がなされている。

- u-boot-spl は 0x00000 - 0xe0000 
- セッティングは 0xe0000 - 0x100000
- 0x100000 以降に u-boot.img 

これは u-boot にハードコーディングされている。それ以外の設定は saveenv や uEnv.txt で変更できる。

SD から立ち上げた u-boot で次々と QSPI に書いていけばよい

## u-boot-spl を書き込む
```
zynq-uboot> sf probe
SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB
zynq-uboot> sf erase 0 0xe0000
SF: 917504 bytes @ 0x0 Erased: OK
zynq-uboot> mw.b 0x3000000 0xff 0xe0000
zynq-uboot> fatload mmc 0 0x3000000 boot.bin
reading boot.bin
55464 bytes read in 28 ms (1.9 MiB/s)
zynq-uboot> sf write 0x3000000 0 0xe0000
SF: 917504 bytes @ 0x0 Written: OK
```

## u-boot の環境を消去
```
zynq-uboot> sf probe
SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB
zynq-uboot> sf erase 0xe0000 0x10000
SF: 65536 bytes @ 0xe0000 Erased: OK
```

## u-boot.img を書き込む
```
zynq-uboot> sf write 0x3000000 0 0xe0000
SF: 917504 bytes @ 0x0 Written: OK
zynq-uboot> fatls mmc 0
    55464   boot.bin
   333952   u-boot.img
      293   uenv.txt
    24156   zybo-zynq7.dtb
  3260392   uimage
  6136848   uramdisk.image.gz

6 file(s), 2 dir(s)

zynq-uboot> mw.b 0x3000000 0xff 0x60000
zynq-uboot> fatload mmc 0 0x3000000 u-boot.img
reading u-boot.img
333952 bytes read in 51 ms (6.2 MiB/s)
zynq-uboot> sf erase 0x100000  0x60000
SF: 393216 bytes @ 0x100000 Erased: OK
zynq-uboot> sf write 0x3000000 0x100000 0x60000
SF: 393216 bytes @ 0x100000 Written: OK
```
# Linux の設定は？
QSPI 自身にパーティション情報はない。dtb に設定するようだ。

```
[    0.834191] m25p80 spi32764.0: found s25fl128s1, expected n25q128
[    0.840261] m25p80 spi32764.0: s25fl128s1 (16384 Kbytes)
[    0.845524] 4 ofpart partitions found on MTD device spi32764.0
[    0.851419] Creating 4 MTD partitions on "spi32764.0":
[    0.856473] 0x000000000000-0x000000400000 : "qspi-fsbl-uboot"
[    0.863744] 0x000000400000-0x000000900000 : "qspi-linux"
[    0.870507] 0x000000900000-0x000000920000 : "qspi-device-tree"
[    0.877724] 0x000000920000-0x000001000000 : "qspi-user"
```

なぜか Yocto で作った dtb の設定で Linux を立ち上げると demsg にこんな感じに表示される。混乱しないように Linux と u-boot の設定は合わせておくようにしよう(と自分に言い聞かせる）。