ここ最近、メインラインのu-bootとLinux Kernelのソースコードを眺めている。
u-bootを眺めていたら、ずいぶん進化していたのでZYBO向けに取り込んでみた。
今回、使用したu-bootは2015.07でu-bootのversionコマンドでは次のように表示される。
U-Boot 2015.07-rc3-00054-g891b487-dirty (Jul 09 2015 - 13:28:00 +0900)
arm-poky-linux-gnueabi-gcc (GCC) 4.9.2
GNU ld (GNU Binutils) 2.25.0
SPL
最新のu-boot環境ではSPLという、ブートローダが追加されている。
SPLとはSecond Program Loaderの略でありVivado SDKでいう、FSBL(First Stage Boot Loader)に取って代わるブートローダである。
SPLのおかげでVivado SDKでFSBLを生成する手間が一つ省けるようになった。
さらに、SPLはfalconブートという、u-bootを抜いて一気にLinux Kernelなどを起動するモードも存在する。
高速起動などが必要な場合は、falconブートを使用すると良いだろう。
ただ、FPGA(PL)のデバッグなどでu-bootはその力を発揮するので当面はu-bootを使用したままにしておく。
DTS
Linux Kernelではお馴染みのDevice Freeだが、u-bootでも採用されるようになった。
従って、今後、Device Treeはu-boot用とLinux Kernel用があることを認識しておかなければいけない。
u-boot用のDevice Treeはあくまで起動で必要なペリフェラルの設定だけを含めるように心がける。
余計なものを設定しているとそれだけ、容量と起動が遅くなるだけだ。
Linux Kernel用のDevice Treeは使用する全てのペリフェラルの設定を記載する。
FIT
FITとはFlat Image Treeの略で、Linux Kernel、InitRam、Device Treeなどをパック化したイメージである。
最近のu-bootはデフォルトでこのFITを使用して、Linux Kernelを起動するようになっているが、Linux Kernelのデバイスドライバなどの開発時はドライバを組み込んではFITを生成しなおすという手間が発生するので、従来通り、作業しやすいようにuImage、DeviceTreeなどを別々でロードしてLinux Kernelを起動する方法を採用する。
FITはLinux KernelをFixした時に使用するだけに留めるのが良いだろう。
クロス環境
何はともあれ、まず最初にクロス環境の準備である。
% source /opt/poky/1.8+snapshot/environment-setup-cortexa9-vfp-neon-poky-linux-gnueabi
クロスコンパイル環境はYocto 1.8というか、いつものように最新版でTool Chainを作成している。
通常、クロスコンパイル環境で行う次の儀式も環境変数のセットアップに含まれているので上記のコマンド一発でクロス開発環境になる。
export ARCH=arm
export CROSS_COMPILE=arm-poky-linux-gnueabi-
u-bootのダウンロード
次のようにdenxのgitリポジトリからu-bootをcloneする。
% git clone git://git.denx.de/u-boot.git
% cd u-boot
ps7_init.[ch]生成方法
SPLには、Vivado SDKで生成できるPS7の初期化コードが必要である。
これはFSBLをビルドするときと同じであり、VivadoからExport Hardwareを行うと、ZYBO.sdk/ZYBO_hw_platform_XにHDFファイルが生成される。
このHDFファイルを使用して、PS7の初期化コードのps7_init_gpl.[ch]を生成することになる。
ps7_init_gpl.[ch]は従来のFSBLをビルドするように生成しても構わないが、hsiコマンドで生成することができる。
% cd /usr/bin
% sudo ln -s make gmake
% hsi
** hsi v2015.1 (64-bit)
**** SW Build 1215546 on Mon Apr 27 19:19:00 MDT 2015
** Copyright 1986-2015 Xilinx, Inc. All Rights Reserved.
hsi% open_hw_design ZYBO_wrapper.hdf
ZYBO_wrapper
hsi% generate_app -hw ZYBO_wrapper -os standalone -proc ps7_cortexa9_0 -app zynq_fsbl -sw fsbl -dir zynq_fsbl
WARNING : No interface that uses file system is available
hsi::generate_target: Time (s): cpu = 00:00:05 ; elapsed = 00:00:05 . Memory (MB): peak = 447.406 ; gain = 0.914 ; free physical = 4366 ; free virtual = 13970
hsi::generate_app: Time (s): cpu = 00:00:05 ; elapsed = 00:00:05 . Memory (MB): peak = 447.406 ; gain = 0.914 ; free physical = 4369 ; free virtual = 13970
hsi% quit
これでFSBLでお馴染みのps7_init.[ch]が生成される。
この2つのファイルをu-bootのboard/xilinx/zynq/custom_hw_platformへ次のようにコピーする。
% cp HOGEHOGE/ps7_init.c board/xilinx/zynq/custom_hw_platform/ps7_init_gpl.c
% cp HOGEHOGE/ps7_init.h board/xilinx/zynq/custom_hw_platform
ただ、hsiコマンドだけのためにVivado SDKをインストールしておかなければいけないがhsiコマンドのおかげでLinuxを起動するまでVivado SDKを立ち上げることは無くなった。
つまり、VivadoからLaunch SDKもしなくて良くなったのだ。
今後、hsiコマンドもVivado本体に取り込まれることを期待しよう。
環境変数
include/configs/zynq-common.h
/ Default environment /
"fit_image=fit.itb\0"
"load_addr=0x2000000\0"
"fit_size=0x800000\0"
"flash_off=0x100000\0"
"nor_flash_off=0xE2100000\0"
"fdt_high=0x20000000\0"
"initrd_high=0x20000000\0"
"norboot=echo Copying FIT from NOR flash to RAM... && "
"cp.b ${nor_flash_off} ${load_addr} ${fit_size} && "
"bootm ${load_addr}\0"
"sdboot=echo Copying FIT from SD to RAM... && "
"load mmc 0 ${load_addr} ${fit_image} && "
"bootm ${load_addr}\0"
"jtagboot=echo TFTPing FIT to RAM... && "
"tftpboot ${load_addr} ${fit_image} && "
"bootm ${load_addr}\0"
"usbboot=if usb start; then "
"echo Copying FIT from USB to RAM... && "
"load usb 0 ${load_addr} ${fit_image} && "
"bootm ${load_addr}\0"
"fi\0"
DFU_ALT_INFO
bootmodeはM0〜M4の設定によって決まる。
norboot、sdboot,jtagbootの3種類がある。
そこで、次のsdbootを変更する。
"sdboot=echo Copying FIT from SD to RAM... && "
"load mmc 0 ${load_addr} ${fit_image} && "
"bootm ${load_addr}\0"
bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0
kernel_image=uImage
devicetree_image=devicetree.dtb
kernel_load_address=0x2080000
devicetree_load_address=0x2000000
uenvcmd=echo Copying Linux from SD to RAM... && mmcinfo && fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} ${devicetree_image} && bootm ${kernel_load_address} - ${devicetree_load_address}
u-bootのビルド
% make zynq_zybo_defconfig
% make
ビルドが完了すると、u-boot-dtb.img、spl/u-boot-spl.binが生成されている。
使用するバイナリファイルはこの2つでZynqのu-boot起動までの環境を作成する。
boot.binの生成
boot.binは従来はbootgenコマンドを使用して、FSBL、Bitストリーム、u-bootをパックにして生成していたが、今回はPythonスクリプトで生成する。
boot.binを生成するスクリプトを取得する
これだけはu-bootのメインラインに入っていないのでXilinxのu-boot-xlnxリポジトリから借用する。
% git clone git://github.com/Xilinx/u-boot-xlnx
% cp u-boot-xlnx/tools/zynq-boot-bin.py ~/bin
% zynq-boot-bin.py -o boot.bin -u spl/u-boot-spl.bin
SPL(u-boot-spl.bin)はこの方法でboot.binを生成しないと正常起動しないので注意しなければいけない。
生成されたboot.binとu-boot-dtb.imgをSDカードにコピーする。
% cp boot.bin SDCARD
% cp u-boot-dtb.img SDCARD
ついでにBitストリームもコピーしよう。
% cp ZYBO.bit SDCARD
起動
さぁ、準備が整ったので起動しよう。
U-Boot 2015.07-rc3-00054-g891b487-dirty (Jul 09 2015 - 13:28:00 +0900)
Model: Zynq ZED Board
I2C: ready
DRAM: ECC disabled 512 MiB
MMC: zynq_sdhci: 0
Using default environment
In: serial
Out: serial
Err: serial
Model: Zynq ZED Board
Net: Gem.e000b000
Error: Gem.e000b000 address not set.
Hit any key to stop autoboot: 0
以前よりも凄く手順が簡単になった。
u-bootからBit Streamのロード方法
FPGAのロードはu-boot上から行うことができる。
次の2つのコマンドを使用するだけだ。
load mmc 0 0x1000000 ZYBO.bit
fpga loadb 0 0x1000000 4045659
zynq-uboot> load mmc 0 0x1000000 ZYBO.bit
reading ZYBO.bit
4045659 bytes read in 367 ms (10.5 MiB/s)
zynq-uboot> fpga loadb 0 0x1000000 4045659
design filename = "ZYBO;UserID=0XFFFFFFFF"
part number = "7z020clg484"
date = "2014/07/24"
time = "10:59:12"
bytes in bitstream = 4045564
zynq_align_dma_buffer: Align buffer at 100005f to ffffe0(swap 1)
FPGAをロードするときの注意として、Bitストリームをアドレスの0x0000_0000へロードしてしまうと正常にBitストリームがロードできない。
SDカード
パーティション1はFAT、パーティーション2はext4でLinuxのrootfs
パーティーション1には次のものが入る。
boot.bin
uImage
u-boot-dtb.img
devicetree.dtb
ZYBO.bit
開発環境
開発順序は次のようになるなぁ。
1.Vivado Design SuiteでIP開発
2.Vivado Design SuiteでIP IntegratorでSoCモデリング
3.Vivado Design Suiteで論理合成/配置配線
1.Linuxディストリビューション構築
2.クロス開発環境構築
4.u-bootでSPL、u-bootビルド
4.Linux Kernelビルド/Linux Kernelドライバ開発
5.Qt5アプリケーション開発/アプリケーション開発