SPL ってなんですか?
私は最初この言葉に躓きました。SPI と一文字違いだし。Second Program Loader の略で u-boot で使われる言葉であるらしい。Zynq では FSBL に相当し、u-boot 本体を呼ぶプログラムの事を指すようだ。
参考資料
FPGA+SoC+Linuxのブートシーケンス(ZYNQ+U-Boot-SPL編)
Yocto で作ってしまうと、とにかく boot.bin までできるので便利ではある。
Yocto にお願いする
概略さえ分かってしまえば、あとはもう、Yocto にお任せする。ps7_init.c や ps7_init.h も持ってたりするから(あまり考えずに作業をすると危険な気もするが)、Vivado のデザインなんか気にせずに(それじゃだめですから)、Yocto にお願いする。
参考資料(っていうかこの通りにすれば出来ちゃう)
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 の修正
# 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"
という記述を追加している。
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 の設定は合わせておくようにしよう(と自分に言い聞かせる)。