とあるエンジニアの備忘log
2014年7月15日火曜日
U-Boot と Linux Kernel のメインラインで Zynq を動かす 2014年7月版
本日 U-Boot 2014.07 がリリースされました。 [前回](/2014/05/u-boot-linux-kernel-zynq-201404.html)から U-Boot の方のやり方が少し変わったので、今回もまとめておきます。 具体的には、 v2014.04 で動かなくなっていた DTB を使った U-Boot のブートシーケンスが動くようになっていたり、 煩雑な工程のいくつかが不要になっています。 使用するのは、 - U-Boot 2014.07 - Linux Kernel 3.15 - Zynq ZC706 ボード とします。 ### STEP0: DTC (Device Tree Compiler) の準備 ##### Input Files Required - None ##### Output Files Produced - `dtc`: Device Tree Compiler ##### Task Description U-Boot を Device Tree 付きでビルドするには version 1.4 以降の DTC が必要になる。 ディストリビューションに標準で用意されている DTC では不足するかもしれないのでバージョンを確認。 $ dtc -v Version: DTC 1.3.0 バージョンが 1.4.0 よりも古い場合は、自分でビルドします。 $ git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git でソースを取ってきて $ make $ make install でビルドとインストールができる。 `$(HOME)/bin` の下に `dtc` が入るので PATH を通しておく。 ### STEP1: U-Boot のビルド ##### Input Files Required - `dtc` - ARM Cross Compiler - `ps7_init.c`: ISE / Vivado で "Export Hardware for SDK" を実行すると出力される - `ps7_init.h`: ISE / Vivado で "Export Hardware for SDK" を実行すると出力される ##### Output Files Produced - `u-boot-dtb.bin`: U-Boot の RAWバイナリと u-boot をコンフィグレーションする DTB を連結したもの - `u-boot-dtb.img`: `u-boot-dtb.bin` に uImage ヘッダーをつけたもの - `spl/u-boot-spl.bin`: U-Boot SPLの RAWバイナリ - `tools/mkimage`: U-Boot で扱うイメージを生成するツール。 ##### Task Description $ git clone git://git.denx.de/u-boot.git $ cd u-boot $ git checkout v2014.07 でソース取得して、v2014.07 タグをチェックアウト。 (何かあっても自分で対処できる人は masterブランチでやってもOK) あとで、Kernel を TFTP でダウンロードしたいので、`include/configs/zynq-common.h` を開いて、適当なところに #define CONFIG_IPADDR 192.168.11.2 #define CONFIG_SERVERIP 192.168.11.1 #define CONFIG_ETHADDR 00:0a:35:00:01:22 の3行を足す。 `CONFIG_IPADDR` は Zynqボードに割り振る IPアドレス、 `CONFIG_SERVERIP` は TFTP サーバーのアドレスに合わせて下さい。 MACアドレスは、(他のネットワーク機器と被らなければ)適当でいい。 TFTP サーバーがなくても、動かすことはできるので、ない人は上記はスキップして下さい。 さらに、 `ps7_init.c`, `ps7_init.h` を U-Boot の `board/xilinx/zynq` ディレクトリにコピーする。 このファイルが、 FSBL の代わりをするための、肝になるファイルです。 あとは $ make zynq_zc70x_config $ make CROSS_COMPILE=arm-linux-gnueabi- DEVICE_TREE=zynq-zc706 のようにして、コンフィグレーションとビルドをする。 もしくは $ make zynq_zc70x_config all CROSS_COMPILE=arm-linux-gnueabi- DEVICE_TREE=zynq-zc706 のように 1行で、コンフィグレーションとビルドを同時にすることもできる。 `ps7_init.c` と `ps7_init.h` が warning を出しますが、気にしなくてもOK。 気になる人は、関数のプロトタイプの引数部に `void` を足してください。 ### STEP2: Linux Kernel のビルド ##### Input Files Required - ARM Cross Compiler ##### Output Files Produced - `arch/arm/boot/zImage`: Kernel Image - `arch/arm/boot/dts/zynq-zc706.dtb`: Kernel をコンフィグレーションする DTB (Device Tree Blob) (従来、 U-Boot から Kernel を起動するときは `arch/arm/boot/uImage` を使っていたが、これは使わない。) ##### Task Description $ git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git $ cd linux $ git checkout v3.15 でソース取得して、v3.15 タグをチェックアウト。 (何かあっても自分で対処できる人は masterブランチでやってもOK) 以下のようにして ARMv7 Multi な設定にする。 $ make ARCH=arm multi_v7_defconfig ここで $ make ARCH=arm menuconfig をして、少々設定をいじる。 Device Drivers ---> Block devices ---> [*] RAM block device support (16384) Default RAM disk size (kbytes) のようにたどり、 `RAM block device support` にチェックを入れ、 `Default RAM disk size` を `16384` に設定する。 もう一つ Device Drivers ---> Character devices ---> [ ] Legacy (BSD) PTY support のようにたどり、`Legacy (BSD) PTY support` のチェックを外す。 あとは $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- でビルド。 ### STEP3: Ramdisk のダウンロード ##### Input Files Required - None ##### Output Files Produced - `arm_ramdisk.image.gz`: Kernel がマウントする init ramdisk (を gzip 圧縮したもの) ##### Task Description [こちら](http://www.wiki.xilinx.com/Build+and+Modify+a+Rootfs) から arm_ramdisk.image.gz をダウンロードする。 ### STEP4: ITB (Image Tree Blob) の生成 ##### Input Files Required - `linux/arch/arm/boot/zImage` - `arm_ramdisk.image.gz` - `linux/arch/arm/boot/dts/zynq-zc706.dtb` - `u-boot/tools/mkimage` カレントディレクトリから見て、上記の配置になっているとする。 ##### Output Files Produced - `fit.itb`: U-Boot から Kernel を起動するためのイメージ ##### Task Description Kernel Image, Ramdisk, DTB (Device Tree Blob) を一つにまとめた ITB というのを作ります。 ITB を作るには、 ITS(Image Tree Source) を記述して、 `mkimage` に食わせます。 以下の内容を `fit.its` というファイルに記述する。 /dts-v1/; / { description = "Kernel, ramdisk and FDT blob"; #address-cells = <1>; images { kernel@1 { description = "Linux Kernel 3.15 configured with multi_v7_defconfig"; data = /incbin/("linux/arch/arm/boot/zImage"); type = "kernel"; arch = "arm"; os = "linux"; compression = "none"; load = <0x00008000>; entry = <0x00008000>; hash@1 { algo = "md5"; }; }; ramdisk@1 { description = "Ramdisk for Zynq"; data = /incbin/("arm_ramdisk.image.gz"); type = "ramdisk"; arch = "arm"; os = "linux"; compression = "gzip"; load = <0x00000000>; entry = <0x00000000>; hash@1 { algo = "sha1"; }; }; fdt@1 { description = "FDT for ZC706"; data = /incbin/("linux/arch/arm/boot/dts/zynq-zc706.dtb"); type = "flat_dt"; arch = "arm"; compression = "none"; hash@1 { algo = "crc32"; }; }; }; configurations { default = "config@1"; config@1 { description = "Zynq ZC706 Configuration"; kernel = "kernel@1"; ramdisk = "ramdisk@1"; fdt = "fdt@1"; }; }; }; あとは以下のようにすれば、`fit.itb` ができる。 $ u-boot/tools/mkimage -f fit.its fit.itb ### STEP5: JTAG (Slave Boot) から U-Boot と Linux を起動する ##### Input Files Required - `u-boot-dtb.bin`: STEP1 で作成したもの - `fit.itb`: STEP4 で作成したもの - `xmd`: ISE / Vivado のインストールディレクトリに入っている - `ps7_init.tcl`: ISE / Vivado から "Export Hardware for SDK" を実行すると出力される - `stub.tcl`: Xilinx のページからダウンロードできる `ug873-design-files.zip` の中に入っている - `fpga.bit`: ISE / Vivado で生成した FPGA bit file (Optional) ##### Task Description `fit.itb` を TFTP の公開ディレクトリに置く。(TFTP 環境のない人はスキップして下さい) Zynq ボードのブートモードの選択スイッチを JTAG に合わせて電源入れる。JTAG でボードと接続し、XMD を開く。 $ xmd XMD のプロンプトから以下を実行する。(FPGA は必要なければダウンロードしなくても良い) XMD% connect arm hw ;# Open JTAG connection XMD% rst -slcr ;# Reset the whole system XMD% fpga -f fpga.bit ;# Download FPGA bit file (Optional) XMD% source ps7_init.tcl XMD% ps7_init ;# Initialize DDR, IO pins, etc. XMD% ps7_post_config ;# Enable level shifter XMD% source stub.tcl ;# start CPU1 XMD% targets 64 ;# connect to CPU0 XMD% dow -data u-boot-dtb.bin 0x04000000 ;# Download u-boot to address 0x04000000 XMD% con 0x04000000 ;# start CPU0 from address 0x04000000 なお、毎回これを打ち込むのも面倒ですので、 `foo.tcl` に書いておきましょう。 XMD% source foo.tcl で XMD から読み込むか、シェルから $ xmd -tcl foo.tcl とすればよいです。 U-Boot のプロンプトが出た後、放っておくと、自動的に TFTPサーバーから `fit.itb` をダウンロードして、 Linux が起動する。 TFTP サーバーがない場合は、`con 0x04000000` の前に XMD% dow -data fit.itb 0x02000000 とすれば、 JTAG 経由で `fit.itb` をダウンロードできるので(時間かかりますが、、) あとは U-Boot のプロンプトから > bootm 2000000 と入力して Linux を起動させる。 ### STEP6: SDカード用のブートイメージを作成する ##### Input Files Required - `u-boot/spl/u-boot-spl.bin`: STEP1 で作成したもの ##### Output Files Produced - `boot.bin` ##### Task Description `bootgen` を使わずに `boot.bin` を作成する方法を紹介します。 u-boot-xlnx のコードを取ってきます。 git clone git://github.com/Xilinx/u-boot-xlnx.git `tools` ディレクトリの下に `zynq-boot-bin.py` という Python スクリプトが 入っているので、これを `~/bin` かどこか適当な PATH にコピーする。 あとは zynq-boot-bin.py -o boot.bin -u u-boot/spl/u-boot-spl.bin とすれば、 `boot.bin` ができます。 BIF ファイルを記述しなくてもいい分、こちらの方が簡単だと思います。 ### Step7: SDカードから U-Boot と Linux Kernel を起動する ##### Input Files Required - `boot.bin`: STEP6 または STEP6B で作成したもの - `u-boot-dtb.img`: STEP1 で作成したもの - `fit.itb`: STEP4 で作成したもの ##### Task Description FAT でフォーマットしたSDカードに `boot.bin`, `u-boot-dtb.img`, `fit.itb` をコピー。 SDカードを Zynq ボードに挿し、ブートモードの選択スイッチを SD カードに合わせて電源入れる。 ### 補足 U-Boot の起動時に以下の Warning メッセージが出ると思いますが、気にしなくていいです。 Warning: Your board does not use generic board. Please read doc/README.generic-board and take action. Boards not upgraded by the late 2014 may break or be removed. これは開発者向けの情報です。次回のリリースでは修正されているはず。 消したい人は `include/configs/zynq-common.h` に #define CONFIG_SYS_GENERIC_BOARD を足す。
新しい投稿
前の投稿
ホーム
登録:
投稿 (Atom)