2018年12月27日
Xilinx QEMU上でToppersを動かしてみる(APU編)
以前の記事で Xilinx QEMU を Ubuntu 18.04 上でビルドしましたが、その QEMU を使って、Zynq UltraScale+ MPSoC(以後 ZynqMP) の APU パート、AArch64 (a53) 4 コアターゲットの Toppers FMP を動かして見ました。
Toppers も、QEMU と同じ Ubuntu Linux 環境でクロスビルドします。
何か所かハマったので、正解ルートだけではなく、あえてハマったポイントと回避策も記録として残しますので、少々冗長になります。
Toppers も、QEMU と同じ Ubuntu Linux 環境でクロスビルドします。
何か所かハマったので、正解ルートだけではなく、あえてハマったポイントと回避策も記録として残しますので、少々冗長になります。
QEMU をビルドした環境を引き続き使用するので、Toppers FMP のビルドに必要な perl と GNU make、tar や unzip 等の基本ツールは既にインストールされていることを前提とします。
〇 作業ディレクトリの作成と Toppers ソースの入手
Toppers は Linux のように、全てのソースがまとめて配布されているわけではなく、共通部分とターゲット依存部を、ターゲットに合わせて適切に組み合わせる必要があります。今回のターゲットである ZynqMP は既に必要なものが全部まとまった簡易パッケージが用意されていますので、それを使用します。
README.txt や doc/user.txt を見ても「ASPカーネルから変更なし.」としか書いてません!
しかたないので、ASP カーネル(ASP3 カーネルはまたちょっと違うので注意)を適当に持ってきて展開、doc/user.txt を確認します。FMP は ASP をベースに開発されているので、基本的に同じとはいえ…。
とりあえず Linaro の aarch64 ベアメタルの最新を持ってきて PATH を通しました。
Windows の場合は同梱されていますが、Linux の場合は準備が必要です。自分でビルドしても良いのですが、64 bit の Linux でのビルドには問題があるそうなので、32 bit 版が廃止された Ubuntu では、公式配布されているバイナリを使用した方が良さそうです。
しかし、Ubuntu 18.04 はデフォルトでは 32 bit アプリが動作しなかったので、少しハマりました。
ドキュメントに従い、ビルドディレクトリを掘り、configure (perl スクリプト)を実行します。-T オプションでターゲットを指定することが必須です。何も付けないで実行すると、以下のように target ディレクトリ以下の候補が表示されるので、指定します。(簡易パッケージは一つだけなので迷いません。)
〇 作業ディレクトリの作成と Toppers ソースの入手
Toppers は Linux のように、全てのソースがまとめて配布されているわけではなく、共通部分とターゲット依存部を、ターゲットに合わせて適切に組み合わせる必要があります。今回のターゲットである ZynqMP は既に必要なものが全部まとまった簡易パッケージが用意されていますので、それを使用します。
$ mkdir -p test/fmp/aarch64 $ cd test/fmp/aarch64/ $ wget http://www.toppers.jp/download.cgi/fmp_zynqmp_a53_arm64_gcc-20170523.zip $ unzip fmp_zynqmp_a53_arm64_gcc-20170523.zip〇 ビルド手順の確認
README.txt や doc/user.txt を見ても「ASPカーネルから変更なし.」としか書いてません!
しかたないので、ASP カーネル(ASP3 カーネルはまたちょっと違うので注意)を適当に持ってきて展開、doc/user.txt を確認します。FMP は ASP をベースに開発されているので、基本的に同じとはいえ…。
wget https://www.toppers.jp/download.cgi/asp_gr_peach_gcc-20160315.zip unzip asp_gr_peach_gcc-20160315.zip〇 ツールチェーンの準備
とりあえず Linaro の aarch64 ベアメタルの最新を持ってきて PATH を通しました。
$ wget https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-elf/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-elf.tar.xz $ tar xvf gcc-linaro-7.3.1-2018.05-x86_64_aarch64-elf.tar.xz $ /home/kmc/test/fmp/aarch64/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-elf/bin/aarch64-elf-gcc -v 。。。 スレッドモデル: single gcc バージョン 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05) $ export PATH=/home/kmc/test/fmp/aarch64/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-elf/bin/:$PATH $ aarch64-elf-gcc -v 。。。〇 コンフィギュレータの準備
Windows の場合は同梱されていますが、Linux の場合は準備が必要です。自分でビルドしても良いのですが、64 bit の Linux でのビルドには問題があるそうなので、32 bit 版が廃止された Ubuntu では、公式配布されているバイナリを使用した方が良さそうです。
しかし、Ubuntu 18.04 はデフォルトでは 32 bit アプリが動作しなかったので、少しハマりました。
$ wget https://www.toppers.jp/download.cgi/cfg-linux-static-1_9_6.gz $ gunzip cfg-linux-static-1_9_6.gz $ chmod +x cfg-linux-static-1_9_6 $ ./cfg-linux-static-1_9_6 -h -bash: ./cfg-linux-static-1_9_6: そのようなファイルやディレクトリはありませんこのエラー、最初意味がわかりませんでした。32bit のランタイムを apt-get する必要があります。
$ sudo apt-get install lib32ncurses5 lib32z1 $ ./cfg-linux-static-1_9_6 -h ./cfg-linux-static-1_9_6: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directorylibstdc++ も必要でした。
$ sudo apt-get install lib32stdc++6 $ ./cfg-linux-static-1_9_6 cfg: error: pass # is not specified cfg: fatal error無事に動いたようです。fmp_1.4.0/configure を確認すると、この cfg は、デフォルトでは fmp_1.4.0/cfg/cfg 以下に存在すると仮定されているようなので、そこに移動します。適当な場所に置いて -g オプションで指定しても良さそうです。
$ mv cfg-linux-static-1_9_6 fmp_1.4.0/cfg/cfg/cfg $ ls fmp_1.4.0/cfg/cfg cfg cfg.exe〇 コンフィギュレーションとビルド
ドキュメントに従い、ビルドディレクトリを掘り、configure (perl スクリプト)を実行します。-T オプションでターゲットを指定することが必須です。何も付けないで実行すると、以下のように target ディレクトリ以下の候補が表示されるので、指定します。(簡易パッケージは一つだけなので迷いません。)
$ cd fmp_1.4.0/ $ mkdir OBJ $ cd OBJ $ perl ../configure configure: -T option is mandatory Installed targets are: zynqmp_a53_arm64_gcc $ perl ../configure -T zynqmp_a53_arm64_gcc configure: Generating Makefile from ../sample/Makefile. configure: Generating sample1.c from ../sample/sample1.c. configure: Generating sample1.h from ../sample/sample1.h. configure: Generating sample1.cfg from ../sample/sample1.cfg.ASP のドキュメントには、make depend せよとありますが、どうも無いようです。(再度 FMP のドキュメントを確認したら、「依存関係ファイルの生成方法をASPから変更したため,make depend のステップが必要ない.」と書いてありました。)また、ツールの名前が aarch64-none-elf に決め打ちになってるようで、最新の Linaro は aarch64-elf なのでエラーになりました。
$ make depend make: *** ターゲット 'depend' を make するルールがありません. 中止. $ make ../cfg/cfg/cfg --pass 1 --kernel fmp -I. -I../include -I../arch -I.. -I../target/zynqmp_a53_arm64_gcc -I../arch/arm64_gcc/mpcore -I../arch/arm64_gcc/common --api-table ../kernel/kernel_api.csv --cfg1-def-table ../kernel/kernel_def.csv --cfg1-def-table ../arch/arm64_gcc/mpcore/chip_def.csv --cfg1-def-table ../arch/arm64_gcc/common/core_def.csv sample1.cfg aarch64-none-elf-gcc -o obj/cfg1_out.o -c -mlittle-endian -mgeneral-regs-only -I/app/lib/libsafeg/ -g -MD -Wall -O2 -DTOPPERS_SAFEG_SECURE -DSECURE_LOC_DRAM -DG_SYSLOG -DTOPPERS_OMIT_DATA_INIT -DINIT_MONITOR -DINIT_HYPERVISOR -DTARGET_PRC1_NS_START_ADDR=0xe0000000 -I. -I../include -I../arch -I.. -I../target/zynqmp_a53_arm64_gcc -I../arch/arm64_gcc/mpcore -I../arch/arm64_gcc/common -L obj -DALLFUNC -I../kernel cfg1_out.c make: aarch64-none-elf-gcc: Command not found Makefile:467: recipe for target 'obj/cfg1_out.o' failed make: *** [obj/cfg1_out.o] Error 127このツールの名前はターゲット依存部分の Makefile.target で決まってるようなので、とりあえず直接修正して、全部消してやり直しました。これで make が成功しました。
$ vim ../target/zynqmp_a53_arm64_gcc/Makefile.target -GCC_TARGET = aarch64-none-elf +GCC_TARGET = aarch64-elf $ rm -rf * $ perl ../configure -T zynqmp_a53_arm64_gcc $ makeできた fmp を以下のようにして、無事に Windows 上で実行できました。(ホームディレクトリを U ドライブにマウントしてあります。)
>install\qemu-system-aarch64.exe -nographic -M arm-generic-fdt -dtb C:/Xilinx/SDK/2018.2/data/qemu/zynqMP/SINGLE_ARCH/zcu102-arm.dtb -device loader,file=U:/test/fmp/aarch64/fmp_1.4.0/OBJ/fmp,cpu-num=0 -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 TOPPERS/FMP Kernel Release 1.4.0 for Xilinx ZynqMP A53(AArch64 Secure) (Dec 27 2018, 12:22:19) Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory Toyohashi Univ. of Technology, JAPAN Copyright (C) 2004-2015 by Embedded and Real-Time Systems Laboratory Graduate School of Information Science, Nagoya Univ., JAPAN Processor 1 start. local_inirtn exinf = 1, counter = 1 Processor 3 start. local_inirtn exinf = 3, counter = 2 Processor 2 start. Processor 4 start. local_inirtn exinf = 4, counter = 3 local_inirtn exinf = 2, counter = 4 Server task 2 starts. Server task 4 starts. Server task 3 starts. System logging task is started on port 1. Server task 1 starts. Sample program starts (exinf = 1). select tskno 0x11 select cycid 1 select almid 1 select processor 1 select class 1 task1_1 is running (001). | task1_1 is running (002). | task1_1 is running (003). | task1_1 is running (004). | task1_1 is running (005). | task1_1 is running (006). | task1_1 is running (007). | task1_1 is running (008). | task1_1 is running (009). | task1_1 is running (010). | task1_1 is running (011). | 。。。